角色定位相关

master
expressgy 1 year ago
parent cc81b40b58
commit 8d942bd107
  1. 1
      src/Gdecorator/userinfoDecorator/userinfoDecorator.decorator.ts
  2. 70
      src/starlight/dto/position.dto.ts
  3. 74
      src/starlight/starlight.controller.ts
  4. 459
      src/starlight/starlight.service.ts
  5. 9
      src/starlight/verify.guard.ts

@ -16,6 +16,7 @@ export const UserInfoDecorator = (...args: string[]) =>
// ? ? // ? ?
export class userinfoDto { export class userinfoDto {
uuid: string; uuid: string;
username: string;
} }
// ? ? // ? ?

@ -1,4 +1,14 @@
import { IsNumber, IsString, Length } from 'class-validator'; import {
ArrayMinSize,
IsArray,
IsNotEmpty,
IsNumber,
IsOptional,
IsString,
Length,
} from 'class-validator';
import { Transform, Type } from 'class-transformer';
import { ValidationPipe } from '@nestjs/common';
export class PositionCreateDTO { export class PositionCreateDTO {
// @ 父id // @ 父id
@ -18,7 +28,7 @@ export class PositionCreateDTO {
// @ 角色标识 // @ 角色标识
@Length(1, 128, { message: '请将角色定位标识长度控制在8到128位之间!' }) @Length(1, 128, { message: '请将角色定位标识长度控制在8到128位之间!' })
@IsString({ message: '角色定位标识应为字符串格式!' }) @IsString({ message: '角色定位标识应为字符串格式!' })
index: string; pointer: string;
// @ 描述 // @ 描述
@Length(1, 128, { message: '请将角色定位描述长度控制在8到128位之间!' }) @Length(1, 128, { message: '请将角色定位描述长度控制在8到128位之间!' })
@ -30,3 +40,59 @@ export class PositionCreateDTO {
@IsString({ message: '角色定位图标地址应为字符串格式!' }) @IsString({ message: '角色定位图标地址应为字符串格式!' })
ico: string; ico: string;
} }
// 删除指定角色
export class PositionDeleteDTO {
// @ 角色id
// @Param(new ValidationPipe({ transform: true }))
// @Transform((val) => {
// if (Number(val)) {
// return Number(val);
// } else {
// throw new Error('角色id必须为数字!');
// }
// })
// id: number;
@IsNotEmpty({ message: '角色id不可以为空' })
@ArrayMinSize(1, { message: '角色id至少有一个' })
// 文档建议如果是字符串的数组,使用字符串约束更好,因为js其实不存在数字数组,字符串数组等
@Type(() => Number)
// 上面虽然解决了不是字符串的数组的问题,但是如果传进来的是一个字符串呢?这就太tm难了,所以再在编译时检查一下算了吧,运行时不管了
@IsArray({ message: '角色id必须是一个数组' })
readonly id: number[];
}
// 更新角色信息DTO
export class PositionUpdateDTO extends PositionCreateDTO {
// @ 父id
@IsOptional()
@IsNumber({}, { message: '父id必须为数字!' })
fatherid: number;
// @ 父id
@IsNumber({}, { message: 'id必须为数字!' })
id: number;
}
// 角色列表
export class PositionListDTO {
// @ 角色列表
@IsNotEmpty({ message: '角色id不可以为空' })
@ArrayMinSize(1, { message: '角色id至少有一个' })
// 文档建议如果是字符串的数组,使用字符串约束更好,因为js其实不存在数字数组,字符串数组等
@Type(() => Number)
// 上面虽然解决了不是字符串的数组的问题,但是如果传进来的是一个字符串呢?这就太tm难了,所以再在编译时检查一下算了吧,运行时不管了
@IsArray({ message: '角色id必须是一个数组' })
readonly positionId: number[];
}
// 关联角色定位
export class PositionRelationDTO extends PositionListDTO {
// @ 用户列表
@IsNotEmpty({ message: 'uuid不可以为空' })
@ArrayMinSize(1, { message: 'uuid至少有一个' })
@IsString({ each: true, message: 'uuid必须为字符串' })
@Length(32, 32, { each: true, message: 'uuid长度必须为32位' })
@IsArray({ message: 'uuid必须是一个数组' })
readonly uuidList: string[];
}

@ -17,6 +17,8 @@ import {
Inject, Inject,
ExecutionContext, ExecutionContext,
createParamDecorator, createParamDecorator,
ValidationPipe,
Put,
} from '@nestjs/common'; } from '@nestjs/common';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import { ApiTags } from '@nestjs/swagger'; import { ApiTags } from '@nestjs/swagger';
@ -40,7 +42,13 @@ import {
SignInPasswdEntryDto, SignInPasswdEntryDto,
} from '@/starlight/dto/signIn.dto'; } from '@/starlight/dto/signIn.dto';
import { VerifyGuard } from '@/starlight/verify.guard'; import { VerifyGuard } from '@/starlight/verify.guard';
import { PositionCreateDTO } from '@/starlight/dto/position.dto'; import {
PositionCreateDTO,
PositionDeleteDTO,
PositionListDTO,
PositionRelationDTO,
PositionUpdateDTO,
} from '@/starlight/dto/position.dto';
// C C // C C
// C 类名称: StarlightController // C 类名称: StarlightController
@ -150,7 +158,7 @@ export class StarlightController {
//#endregion //#endregion
//#region //#region 角色定位
// ? ? // ? ?
// ? 函数名称: positionCreate // ? 函数名称: positionCreate
// ? 函数描述: 创建角色 // ? 函数描述: 创建角色
@ -164,6 +172,68 @@ export class StarlightController {
return this.starlightService.positionCreate(body, userInfo); return this.starlightService.positionCreate(body, userInfo);
} }
// ? ?
// ? 函数名称: positionAll
// ? 函数描述: 获取所有角色定位信息
// ? ?
@UseGuards(VerifyGuard)
@Get('position/all')
positionAll(): Promise<object> {
return this.starlightService.positionAll();
}
// ? ?
// ? 函数名称: positionDelete
// ? 函数描述: 删除指定角色信息
// ? ?
@UseGuards(VerifyGuard)
@Delete('position/delete')
positionDelete(
@Body()
body: PositionDeleteDTO,
): Promise<object> {
return this.starlightService.positionDelete(body);
}
// ? ?
// ? 函数名称: positionUpdate
// ? 函数描述: 更新指定定位角色信息
// ? ?
@UseGuards(VerifyGuard)
@Patch('position/update')
positionUpdate(@Body() body: PositionUpdateDTO): Promise<object> {
return this.starlightService.positionUpdate(body);
}
// ? ?
// ? 函数名称: positionDefault
// ? 函数描述: 设置默认角色
// ? ?
@UseGuards(VerifyGuard)
@Patch('position/default')
positionDefault(@Body() body: PositionListDTO): Promise<object> {
return this.starlightService.positionDefault(body);
}
// ? ?
// ? 函数名称: getDefaultPosittion
// ? 函数描述: 获取默认角色
// ? ?
@Get('/position/default')
getDefaultPosittion(): Promise<object> {
return this.starlightService.getDefaultPosition();
}
// ? ?
// ? 函数名称: positionRelationUUID
// ? 函数描述: 关联用户角色定位
// ? ?
@UseGuards(VerifyGuard)
@Post('position/relation')
positionRelationUUID(@Body() body: PositionRelationDTO): Promise<object> {
return this.starlightService.positionRelationUUID(body);
}
//#endregion //#endregion
//#region 测试 //#region 测试

@ -13,7 +13,13 @@ import {
RegisterEmailSignUpDto, RegisterEmailSignUpDto,
sex, sex,
} from './dto/register.dto'; } from './dto/register.dto';
import { PositionCreateDTO } from './dto/position.dto'; import {
PositionCreateDTO,
PositionDeleteDTO,
PositionListDTO,
PositionRelationDTO,
PositionUpdateDTO,
} from './dto/position.dto';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import { GloggerService } from '@/Gservice/GLOGGER/glogger.service'; import { GloggerService } from '@/Gservice/GLOGGER/glogger.service';
import { GdatabaseService } from '@/Gservice/GDATABASE/gdatabase.service'; import { GdatabaseService } from '@/Gservice/GDATABASE/gdatabase.service';
@ -608,14 +614,455 @@ export class StarlightService {
const fatherid = body.fatherid, const fatherid = body.fatherid,
type = body.type.trim(), type = body.type.trim(),
name = body.name.trim(), name = body.name.trim(),
index = body.index.trim().toLowerCase(), pointer = body.pointer.trim().toLowerCase(),
describe = body.describe.trim(), describe = body.describe.trim(),
ico = body.ico.trim(); ico = body.ico.trim();
this.logger.info(userinfo); this.logger.info(userinfo);
this.logger.info(fatherid, type, name, index, describe, ico); this.logger.info(fatherid, type, name, pointer, describe, ico);
// 查重标识位 // ! 判断父定位是否存在
// 写入标识位 if (fatherid != 0) {
return {}; try {
const SQL = `SELECT * FROM user_position WHERE id = ? AND is_delete != 1`;
const [rows] = await this.database.DB.execute(SQL, [fatherid]);
this.logger.info(rows);
if (rows.length != 1) {
const message = '未找到父级定位!';
return {
data: {},
message,
success: false,
};
}
} catch (e) {
this.logger.error(e);
const message = '查找定位信息出现错误!';
return {
data: {},
message,
success: false,
};
}
}
// ! 查重标识
try {
const SQL = `SELECT pointer FROM user_position WHERE pointer = ?`;
const [rows, fault] = await this.database.DB.execute(SQL, [
pointer,
]);
if (rows.length > 0) {
const message = '定位标识重复!';
return {
data: {},
message,
success: false,
};
}
} catch (e) {
this.logger.error(e);
const message = '查找定位信息标识重名出现错误!';
return {
data: {},
message,
success: false,
};
}
// ! 判断同级定位是否重名
try {
const SQL = `SELECT name FROM user_position WHERE fatherid = ? AND is_delete != 1`;
const [rows, fault] = await this.database.DB.execute(SQL, [
fatherid,
]);
for (const i of rows) {
if (i.name == name) {
const message = '同级定位重名!';
return {
data: {},
message,
success: false,
};
}
}
} catch (e) {
this.logger.error(e);
const message = '查找定位信息名称重名出现错误!';
return {
data: {},
message,
success: false,
};
}
// ! 写入定位
try {
const createTime = new Date();
const SQL = `INSERT INTO user_position (pointer, name, type, position_describe, fatherid, ico, creator, createtime) VALUES (?, ?, ?, ?, ?, ?, ?, ?);`;
const [rows] = await this.database.DB.execute(SQL, [
pointer,
name,
type,
describe,
fatherid,
ico,
userinfo.uuid,
createTime,
]);
this.logger.info(rows);
} catch (e) {
this.logger.error(e);
const message = '写入定位信息出现错误!';
return {
data: {},
message,
success: false,
};
}
return {
data: {},
message: '创建定位成功!',
};
}
// ? ?
// ? 函数名称: positionAll
// ? 函数描述: 获取所有角色定位信息
// ? ?
public async positionAll() {
try {
const SQL = `SELECT * FROM user_position WHERE is_delete != 1`;
const [rows] = await this.database.DB.execute(SQL, []);
const creatorList = {};
for (const i of rows) {
if (!creatorList[i.creator]) {
// 获取创建角色用户信息
const getUserDataSQL = `SELECT nickname FROM user_info_extra WHERE uuid = ?`;
const [rows2] = await this.database.DB.execute(
getUserDataSQL,
[i.creator],
);
creatorList[i.creator] = rows2.slice(-1)[0];
}
i.creatorData = creatorList[i.creator];
}
return {
data: rows,
};
} catch (e) {
const message = '获取角色定位信息失败!';
this.logger.error({
message,
data: e,
});
return {
message,
success: false,
data: {},
};
}
}
// ? ?
// ? 函数名称: positionDelete
// ? 函数描述: 删除指定角色信息
// ? ?
public async positionDelete(body: PositionDeleteDTO) {
const { id } = body;
const deleteSQL = `UPDATE user_position SET is_delete = 1 WHERE id = ?;`;
const successList = [],
errorList = [],
errorObj = [];
for (const item of id) {
try {
const [row] = await this.database.DB.execute(deleteSQL, [item]);
successList.push(item);
} catch (e) {
errorObj.push(e);
errorList.push(item);
}
}
if (errorList.length > 0) {
this.logger.error({
message: '删除角色定位失败!',
data: errorObj,
});
return {
data: {},
message: '删除角色定位失败!',
success: false,
};
}
return {
data: {},
message: '删除角色定位成功!',
success: true,
};
}
// ? ?
// ? 函数名称: positionUpdate
// ? 函数描述: 更新指定定位角色信息
// ? ?
public async positionUpdate(body: PositionUpdateDTO) {
// 去除空格,小写标识位
const id = body.id,
type = body.type.trim(),
name = body.name.trim(),
pointer = body.pointer.trim().toLowerCase(),
describe = body.describe.trim(),
ico = body.ico.trim();
// ! 查父id
let fatherid: number;
try {
const SQL = `SELECT fatherid FROM user_position WHERE id = ? AND is_delete != 1`;
const [rows, fault] = await this.database.DB.execute(SQL, [id]);
if (rows.length == 0) {
const message = '未找到该角色定位!';
return {
message,
data: {},
success: false,
};
} else {
fatherid = rows[0].fatherid;
}
} catch (e) {
this.logger.error({
message: '查找角色父ID失败!',
data: e,
});
const message = '查找角色父ID失败!';
return {
message,
data: {},
success: false,
};
}
// ! 查重名和标识
try {
const checkPointerSQL = `SELECT pointer FROM user_position WHERE pointer = ? AND id != ? AND is_delete != 1`;
const [rows, fault] = await this.database.DB.execute(
checkPointerSQL,
[pointer, id],
);
if (rows.length != 0) {
const message = '角色定位标识重复!';
return {
data: {},
message,
success: false,
};
}
} catch (e) {
const message = '查冲角色定位标识失败!';
this.logger.error({
data: e,
message,
});
return {
data: {},
message,
success: false,
};
}
try {
const checkNameSQL = `SELECT name FROM user_position WHERE name=? AND fatherid = ? AND id != ? AND is_delete != 1`;
const [rows, fault] = await this.database.DB.execute(checkNameSQL, [
name,
fatherid,
id,
]);
if (rows.length != 0) {
const message = '角色名称重复!';
return {
data: {},
message,
success: false,
};
}
} catch (e) {
const message = '查冲角色名称失败!';
this.logger.error({
data: e,
message,
});
return {
data: {},
message,
success: false,
};
}
// ! 写入
try {
const SQL =
'UPDATE user_position SET name = ?, pointer = ?, type = ?, position_describe = ?, ico = ? WHERE id = ?';
const [rows, fault] = await this.database.DB.execute(SQL, [
name,
pointer,
type,
describe,
ico,
id,
]);
} catch (e) {
const message = '更新角色定位信息失败!';
this.logger.info({
message,
data: e,
});
return {
data: {},
success: false,
message,
};
}
return {
message: '修改角色定位信息成功!',
success: true,
data: {},
};
}
// ? ?
// ? 函数名称: positionDefault
// ? 函数描述: 设置默认角色
// ? ?
public async positionDefault(body: PositionListDTO) {
// ! 清空默认设置
try {
const clearSQL = `UPDATE user_position SET default_position = 0;`;
const [rows, fault] = await this.database.DB.execute(clearSQL, []);
} catch (e) {
const message = '清空默认角色失败!';
this.logger.info({
data: e,
message,
});
return {
data: {},
message,
success: false,
};
}
// ! 设置新的默认角色
const setDefaultSQL = `UPDATE user_position SET default_position = 1 WHERE id = ?;`;
const successList = [],
errorList = [],
errObj = [[]];
for (const item of body.positionId) {
try {
const [rows, fault] = await this.database.DB.execute(
setDefaultSQL,
[item],
);
successList.push(item);
} catch (e) {
errorList.push(item);
errObj.push(e);
const message = '设置默认角色失败!';
this.logger.info({
data: errObj,
message,
});
return {
data: {},
message,
success: false,
};
}
}
return {
data: {},
success: true,
message: '设置默认角色成功!',
};
}
// ? ?
// ? 函数名称: getDefaultPosittion
// ? 函数描述: 获取默认角色
// ? ?
public async getDefaultPosition() {
try {
const SQL = `SELECT * FROM user_position WHERE default_position = 1 AND is_delete != 1`;
const [rows, fault] = await this.database.DB.execute(SQL, []);
return {
data: rows,
message: '获取默认角色信息成功!',
success: true,
};
} catch (e) {
const message = '获取默认角色信息失败';
this.logger.error({
data: e,
message,
});
return {
message,
success: false,
data: {},
};
}
}
// ? ?
// ? 函数名称: positionRelationUUID
// ? 函数描述: 关联用户角色定位
// ? ?
public async positionRelationUUID(body: PositionRelationDTO) {
// ! 剔除不存在的用户
// ! 删除原有的用户角色定位关联
const clearSQL = `UPDATE user_position_relation SET is_delete = 1 WHERE uuid = ?`;
for (const item of body.uuidList) {
try {
const [rows, fault] = await this.database.DB.execute(clearSQL, [
item,
]);
} catch (e) {
const message = 'ERROR,重大错误,清除用户角色关联失败。';
this.logger.info({
message,
data: e,
});
return {
data: e,
success: false,
message,
};
}
}
// ! 遍历加入新的角色定位关联
const createTime = new Date();
const insertSQL = `INSERT INTO user_position_relation (uuid, position_id, createtime) VALUES ?;`;
for (const item of body.uuidList) {
try {
const insertData = body.positionId.map((i) => [
item,
i,
createTime,
]);
this.logger.info(insertData);
const [rows, faault] = await this.database.DB.query(insertSQL, [
insertData,
]);
} catch (e) {
const message = 'ERROR,重大错误,关联用户角色定位信息失败!';
this.logger.info({
data: e,
message,
});
return {
data: e,
message,
success: false,
};
}
}
return {
data: {},
success: true,
message: '关联用户角色定位成功!',
};
} }
//#endregion //#endregion

@ -27,10 +27,17 @@ export class VerifyGuard implements CanActivate {
// this.logger.info(data); // this.logger.info(data);
if (data.token) { if (data.token) {
const userinfo: userinfoDto = { const userinfo: userinfoDto = {
uuid: 'xx', uuid: data.data.uuid,
username: data.data.username,
}; };
context.switchToHttp().getRequest().userinfo = userinfo; context.switchToHttp().getRequest().userinfo = userinfo;
// this.logger.info(request.user); // this.logger.info(request.user);
} else {
throw new UnauthorizedException({
statusCode: 401,
message: '登陆过期!',
error: 'Forbidden',
});
} }
// console.log(request); // console.log(request);
// console.log(request.url);request.headers // console.log(request.url);request.headers

Loading…
Cancel
Save