feat: 开发我的持仓列表

This commit is contained in:
R524809
2026-01-13 16:46:18 +08:00
parent 838a021ce5
commit b7972153cc
29 changed files with 1325 additions and 211 deletions

View File

@@ -0,0 +1,149 @@
import {
Injectable,
NotFoundException,
ForbiddenException,
Logger,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { PositionChange } from './position-change.entity';
import { CreatePositionChangeDto } from './dto/create-position-change.dto';
import { UpdatePositionChangeDto } from './dto/update-position-change.dto';
import { QueryPositionChangeDto } from './dto/query-position-change.dto';
import { PaginationInfo } from '@/common/dto/pagination.dto';
import { Position } from '../position/position.entity';
@Injectable()
export class PositionChangeService {
private readonly logger = new Logger(PositionChangeService.name);
constructor(
@InjectRepository(PositionChange)
private readonly positionChangeRepository: Repository<PositionChange>,
@InjectRepository(Position)
private readonly positionRepository: Repository<Position>,
) {}
/**
* 分页查询单个持仓的所有变更记录
*/
async findAllByPositionId(
positionId: number,
userId: number,
queryDto: QueryPositionChangeDto,
): Promise<{
list: PositionChange[];
pagination: PaginationInfo;
}> {
// 验证持仓是否属于当前用户
const position = await this.positionRepository.findOne({
where: { positionId, userId },
});
if (!position) {
throw new NotFoundException(`持仓不存在ID ${positionId}`);
}
// 分页参数
const page = queryDto.page || 1;
const limit = queryDto.limit || 10;
const skip = (page - 1) * limit;
// 查询总数
const total = await this.positionChangeRepository.count({
where: { positionId },
});
// 查询分页数据(按变更日期和创建时间倒序)
const list = await this.positionChangeRepository.find({
where: { positionId },
order: {
changeDate: 'DESC',
createdAt: 'DESC',
},
skip,
take: limit,
});
// 计算总页数
const total_page = Math.ceil(total / limit);
return {
list,
pagination: {
total,
total_page,
page_size: limit,
current_page: page,
},
};
}
/**
* 创建持仓变更记录
*/
async create(
userId: number,
createPositionChangeDto: CreatePositionChangeDto,
): Promise<PositionChange> {
// 验证持仓是否属于当前用户
const position = await this.positionRepository.findOne({
where: {
positionId: createPositionChangeDto.positionId,
userId,
},
});
if (!position) {
throw new NotFoundException(
`持仓不存在ID ${createPositionChangeDto.positionId}`,
);
}
// 创建变更记录
const positionChange = this.positionChangeRepository.create({
...createPositionChangeDto,
changeDate: new Date(createPositionChangeDto.changeDate),
});
return this.positionChangeRepository.save(positionChange);
}
/**
* 更新持仓变更记录的备注/思考
*/
async update(
changeId: number,
userId: number,
updatePositionChangeDto: UpdatePositionChangeDto,
): Promise<PositionChange> {
// 查找变更记录
const positionChange = await this.positionChangeRepository.findOne({
where: { changeId },
relations: [], // 不加载关联,后面手动验证
});
if (!positionChange) {
throw new NotFoundException(`变更记录不存在ID ${changeId}`);
}
// 验证持仓是否属于当前用户
const position = await this.positionRepository.findOne({
where: {
positionId: positionChange.positionId,
userId,
},
});
if (!position) {
throw new ForbiddenException('无权访问该持仓的变更记录');
}
// 只更新备注字段
if (updatePositionChangeDto.notes !== undefined) {
positionChange.notes = updatePositionChangeDto.notes;
}
return this.positionChangeRepository.save(positionChange);
}
}