Skip to content

Commit

Permalink
🎈 perf<后端>: 备忘录分类
Browse files Browse the repository at this point in the history
  • Loading branch information
yuanjunjie committed Jul 25, 2024
1 parent ed8bd39 commit 57f6ba0
Show file tree
Hide file tree
Showing 19 changed files with 503 additions and 29 deletions.
21 changes: 21 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [

{
"type": "node",
"request": "launch",
"name": "启动程序",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}\\nest-admin\\servers\\src\\website\\memorandum-management\\category\\memorandum-category.service.ts",
"outFiles": [
"${workspaceFolder}/**/*.js"
]
}
]
}
5 changes: 5 additions & 0 deletions nest-admin/servers/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import { RoleModule } from './system/role/role.module'
import { PermModule } from './system/perm/perm.module'
import { OssModule } from './system/oss/oss.module'

import { MemorandumCategoryModule } from './website/memorandum-management/category/memorandum-category.module'
import { MemorandumModule } from './website/memorandum-management/memorandum/memorandum.module'

@Module({
imports: [
// 配置模块
Expand Down Expand Up @@ -95,6 +98,8 @@ import { OssModule } from './system/oss/oss.module'
PermModule,
OssModule,
// 业务功能模块
MemorandumCategoryModule,
// MemorandumModule
],
// app module 守卫,两个守卫分别依赖 UserService、PermService, 而 UserService、PermService 没有设置全局模块,
// 所以这俩 守卫 不能再 main.ts 设置全局守卫
Expand Down
7 changes: 7 additions & 0 deletions nest-admin/servers/src/common/enums/common.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ export enum StatusValue {
NORMAL = 1
}

export enum StatusValue2 {
/** 否 */
NO = 0,
/** 是 */
YES = 1
}

export enum MenuType {
/** 菜单 */
MENU = 1,
Expand Down
18 changes: 18 additions & 0 deletions nest-admin/servers/src/common/utils/req-query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ApiProperty } from '@nestjs/swagger'

export class ReqQuery {
@ApiProperty({ description: '创建人' })
createdBy?: string

@ApiProperty({ description: '更新人' })
updatedBy?: string

@ApiProperty({ description: '更新时间' })
updatedAt?: Date

@ApiProperty({ description: '删除人' })
deletedBy?: string

@ApiProperty({ description: '删除时间' })
deletedAt?: Date
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { ApiProperty } from '@nestjs/swagger'
import { IsString, Length, IsOptional, IsNotEmpty } from 'class-validator'
import { ReqListQuery } from 'src/common/utils/req-list-query'
import { ReqQuery } from 'src/common/utils/req-query'

export class AddMemorandumCategoryDto extends ReqQuery {
@ApiProperty({ description: '名称' })
@IsString({ message: 'name 类型错误, 正确类型 string' })
@IsNotEmpty({ message: 'name 不能为空' })
@Length(0, 20, { message: 'name 字符长度在 0~20' })
name: string

@ApiProperty({ description: '角色备注', required: false })
@IsString({ message: 'description 类型错误, 正确类型 string' })
@Length(0, 200, { message: 'description 字符长度在 0~200' })
@IsOptional()
description?: string
}

export class UpdateMemorandumCategoryDto extends AddMemorandumCategoryDto {
@ApiProperty({ description: 'id' })
@IsString({ message: 'id 类型错误,正确类型 number' })
@IsNotEmpty({ message: 'id 不能为空' })
id: string
}

export class DeleteMemorandumCategoryDto extends ReqQuery {
@ApiProperty({ description: 'id' })
@IsString({ message: 'id 类型错误,正确类型 number' })
@IsNotEmpty({ message: 'id 不能为空' })
id: string
}

export class FindPageDto extends ReqListQuery {

@ApiProperty({ description: '昵称模糊搜索', required: false })
name?: string

@ApiProperty({ description: '开始时间', required: false })
startDate?: Date

@ApiProperty({ description: '开始时间', required: false })
endDate?: Date
}

export class FindListDto {

@ApiProperty({ description: '昵称模糊搜索', required: false })
name?: string

@ApiProperty({ description: '开始时间', required: false })
startDate?: Date

@ApiProperty({ description: '开始时间', required: false })
endDate?: Date
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Controller, Get, Post, UseInterceptors, Query, Body, Delete, Put } from '@nestjs/common'
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger'
import { ResultData } from 'src/common/utils/result'
import { UpdateInterceptor } from 'src/common/guards/update.interceptor'
import { ApiResult } from 'src/common/decorators/api-result.decorator'

import { AddMemorandumCategoryDto, DeleteMemorandumCategoryDto, FindListDto, FindPageDto, UpdateMemorandumCategoryDto } from './dto/memorandum-category.dto'
import { MemorandumCategoryEntity } from './memorandum-category.entity'
import { MemorandumCategoryService } from './memorandum-category.service'

@ApiTags('备忘录类型')
@ApiBearerAuth()
@Controller('memorandum-category')
export class MemorandumCategoryController {
constructor(private readonly service: MemorandumCategoryService) {}

@Post()
@ApiOperation({ summary: '新增' })
@ApiResult()
@UseInterceptors(UpdateInterceptor)
async create(@Body() dto: AddMemorandumCategoryDto): Promise<ResultData> {
return await this.service.add(dto)
}

@Delete()
@ApiOperation({ summary: '删除' })
@ApiResult()
@UseInterceptors(UpdateInterceptor)
async delete(@Body() dto: DeleteMemorandumCategoryDto): Promise<ResultData> {
return await this.service.delete(dto)
}

@Put()
@ApiOperation({ summary: '更新' })
@ApiResult()
@UseInterceptors(UpdateInterceptor)
async update(@Body() dto: UpdateMemorandumCategoryDto): Promise<ResultData> {
return await this.service.update(dto)
}

@Get('getPage')
@ApiOperation({ summary: '查询分页数据列表' })
@ApiResult(MemorandumCategoryEntity, true, true)
async getPage(@Query() dto: FindPageDto): Promise<ResultData> {
return await this.service.getPage(dto)
}

@Get('getList')
@ApiOperation({ summary: '查询不分页数据列表' })
@ApiResult(MemorandumCategoryEntity, true, true)
async getList(@Query() dto: FindListDto): Promise<ResultData> {
return await this.service.getList(dto)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Column, Entity, JoinTable, ManyToMany } from 'typeorm'
import { ApiProperty } from '@nestjs/swagger'
import { CommonEntity } from '../../../entities/common.entity'
import { MemorandumEntity } from '../memorandum/memorandum.entity'

@Entity('website_memorandum_category')
export class MemorandumCategoryEntity extends CommonEntity{

@ApiProperty({ type: String, description: '名称' })
@Column({ type: 'varchar', length: 32, comment: '名称' })
public name: string

@ApiProperty({ description: '描述' })
@Column({ type: 'varchar', length: 200, default: '', comment: '描述' })
public description: string

// @ManyToMany(() => MemorandumEntity, i=> i.categories)
// @JoinTable()
// memorandums: MemorandumEntity[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Module } from "@nestjs/common"
import { TypeOrmModule } from "@nestjs/typeorm"
import { MemorandumCategoryController } from './memorandum-category.controller'
import { MemorandumCategoryEntity } from './memorandum-category.entity'
import { MemorandumCategoryService } from "./memorandum-category.service"

@Module({
imports: [TypeOrmModule.forFeature([MemorandumCategoryEntity])],
providers: [MemorandumCategoryService],
controllers: [MemorandumCategoryController]
})

export class MemorandumCategoryModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import { Injectable } from '@nestjs/common'
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm'
import { Between, EntityManager, Like, Not, Repository } from 'typeorm'
import { MemorandumCategoryEntity } from './memorandum-category.entity'
import {
AddMemorandumCategoryDto,
DeleteMemorandumCategoryDto,
FindListDto,
FindPageDto,
UpdateMemorandumCategoryDto,
} from './dto/memorandum-category.dto'
import { ResultData } from 'src/common/utils/result'
import { AppHttpCode } from 'src/common/enums/code.enum'
import { plainToInstance } from 'class-transformer'

@Injectable()
export class MemorandumCategoryService {
constructor(
@InjectRepository(MemorandumCategoryEntity)
private readonly repository: Repository<MemorandumCategoryEntity>,
@InjectEntityManager()
private readonly manager: EntityManager,
) {}

/**
* # 添加一条新的数据
* @param data 保存的数据
*/
async add(data: AddMemorandumCategoryDto): Promise<ResultData> {
try {
const existing = await this.getDetail(null, data.name)
if (existing) {
return ResultData.fail(AppHttpCode.SERVICE_ERROR, '名称已存在,请调整后重新提交!')
}

const __data__ = plainToInstance(MemorandumCategoryEntity, data)
const result = await this.manager.transaction(async (transactionalEntityManager) => {
return await transactionalEntityManager.save<MemorandumCategoryEntity>(__data__)
})

if (!result) {
return ResultData.fail(AppHttpCode.SERVICE_ERROR, '创建失败, 请稍后重试')
}

return ResultData.ok(result)
} catch (error) {
return ResultData.fail(AppHttpCode.SERVICE_ERROR, '发生错误, 请稍后重试')
}
}

/**
* # 根据ID删除一条数据
* @param dto
*/
async delete(dto: DeleteMemorandumCategoryDto) {
try {
const existing = await this.getDetail(dto.id)
if (!existing) return ResultData.fail(AppHttpCode.ROLE_NOT_FOUND, '当前分类不存在或已被删除')

// todo 该分类存在备忘录数据, 则不允许被删除
// let len = 0;
// if (len > 0)
// return ResultData.fail(AppHttpCode.ROLE_NOT_DEL, '当前分类还有绑定的备忘录,需要解除关联后删除')

const { affected } = await this.manager.transaction(async (transactionalEntityManager) => {
const __data__ = plainToInstance(MemorandumCategoryEntity, {
...dto,
isDeleted: true,
})
return await transactionalEntityManager.update<MemorandumCategoryEntity>(
MemorandumCategoryEntity,
__data__.id,
__data__,
)
})
if (!affected) return ResultData.fail(AppHttpCode.SERVICE_ERROR, '删除失败, 请稍后重试')

return ResultData.ok(affected)
} catch (error) {
return ResultData.fail(AppHttpCode.SERVICE_ERROR, '发生错误, 请稍后重试')
}
}

/**
* # 修改一条数据
* @param data 修改的数据实体
*/
async update(data: UpdateMemorandumCategoryDto): Promise<ResultData> {
try {
const existing = await this.getDetail(data.id)
if (!existing) return ResultData.fail(AppHttpCode.ROLE_NOT_FOUND, '当前分类不存在或已被删除')
if (data.name && (await this.getDetail(data.id, data.name, true)))
return ResultData.fail(AppHttpCode.USER_CREATE_EXISTING, '名称已存在,请调整后重新提交!')

const { affected } = await this.manager.transaction(async (transactionalEntityManager) => {
const __data__ = plainToInstance(MemorandumCategoryEntity, data)
return await transactionalEntityManager.update<MemorandumCategoryEntity>(
MemorandumCategoryEntity,
__data__.id,
__data__,
)
})
if (!affected) return ResultData.fail(AppHttpCode.SERVICE_ERROR, '更新失败, 请稍后重试')

return ResultData.ok(affected)
} catch (error) {
return ResultData.fail(AppHttpCode.SERVICE_ERROR, '发生错误, 请稍后重试')
}
}

/**
* 查询分页数据列表
*/
async getPage(dto: FindPageDto): Promise<ResultData> {
const { page, size, name } = dto
const where: any = {
...(name ? { account: Like(`%${name}%`) } : null),
isDeleted: false,
}
if (dto.startDate && dto.endDate) {
where.createdAt = Between(dto.startDate, dto.endDate)
}
const [list, total] = await this.repository.findAndCount({
order: { createdAt: 'DESC' },
skip: size * (page - 1),
take: size,
where,
})
return ResultData.ok({ list, total })
}

/**
* 查询不分页数据列表
*/
async getList(dto: FindListDto): Promise<ResultData> {
const { name } = dto
const where: any = {
...(name ? { account: Like(`%${name}%`) } : null),
isDeleted: false,
}
if (dto.startDate && dto.endDate) {
where.createdAt = Between(dto.startDate, dto.endDate)
}
const list = await this.repository.find({
order: { createdAt: 'DESC' },
where,
})
return ResultData.ok({ list, total: list.length })
}

/**
* ## 获取详情对象
* @param id ID
* @param name 名称
* @param exclude 是否排除当前id
*/
async getDetail(id: string = null, name: string = null, exclude = false): Promise<MemorandumCategoryEntity> {
let obj = {
name: name || null,
isDeleted: false,
id: exclude ? Not(id || null) : (id || null),
}
return await this.repository.findOne({ where: obj })
}
}
Loading

0 comments on commit 57f6ba0

Please sign in to comment.