Files
invest-mind-store/apps/api/src/modules/position/position.entity.ts
T
2026-01-16 18:01:41 +08:00

229 lines
5.5 KiB
TypeScript

import {
Entity,
Column,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
Index,
Unique,
} from 'typeorm';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
@Entity('positions')
@Unique(['userId', 'brokerId', 'symbol', 'market', 'assetType'])
export class Position {
@ApiProperty({ description: '持仓ID', example: 1 })
@PrimaryGeneratedColumn({ name: 'position_id' })
positionId: number;
@ApiProperty({
description: '用户ID',
example: 1,
})
@Column({
name: 'user_id',
type: 'bigint',
transformer: {
to: (value: number) => value,
from: (value: string) => (value ? parseInt(value, 10) : null),
},
})
@Index()
userId: number;
@ApiPropertyOptional({
description: '券商ID(可选)',
example: 1,
})
@Column({
name: 'broker_id',
type: 'bigint',
nullable: true,
transformer: {
to: (value: number | null | undefined) => value ?? null,
from: (value: string | null) =>
value ? parseInt(value, 10) : null,
},
})
@Index()
brokerId?: number;
@ApiProperty({
description: '资产类型',
example: 'stock',
enum: ['stock', 'fund', 'cash', 'bond', 'other'],
})
@Column({
name: 'asset_type',
type: 'varchar',
length: 20,
})
@Index()
assetType: string;
@ApiProperty({
description: '资产代码(股票代码、基金代码等)',
example: '600519',
maxLength: 50,
})
@Column({ name: 'symbol', type: 'varchar', length: 50 })
@Index()
symbol: string;
@ApiProperty({
description: '资产名称',
example: '贵州茅台',
maxLength: 100,
})
@Column({ name: 'name', type: 'varchar', length: 100 })
name: string;
@ApiPropertyOptional({
description: '市场(A股/港股/美股等)',
example: 'sh',
maxLength: 20,
})
@Column({ name: 'market', type: 'varchar', length: 20, nullable: true })
market?: string;
@ApiProperty({
description: '持仓份额/数量',
example: 100,
})
@Column({
name: 'shares',
type: 'decimal',
precision: 18,
scale: 4,
default: 0,
transformer: {
to: (value: number) => value,
from: (value: string) => (value ? parseFloat(value) : 0),
},
})
shares: number;
@ApiProperty({
description: '成本价(每股/每份)',
example: 1600.0,
})
@Column({
name: 'cost_price',
type: 'decimal',
precision: 18,
scale: 4,
transformer: {
to: (value: number) => value,
from: (value: string) => (value ? parseFloat(value) : null),
},
})
costPrice: number;
@ApiPropertyOptional({
description: '最新市场价(系统自动更新)',
example: 1850.0,
})
@Column({
name: 'current_price',
type: 'decimal',
precision: 18,
scale: 4,
nullable: true,
transformer: {
to: (value: number | undefined) => value,
from: (value: string | null) => (value ? parseFloat(value) : null),
},
})
currentPrice?: number;
@ApiPropertyOptional({
description: '上一次的价格(用于对比显示红绿色)',
example: 1800.0,
})
@Column({
name: 'previous_price',
type: 'decimal',
precision: 18,
scale: 4,
nullable: true,
transformer: {
to: (value: number | undefined) => value,
from: (value: string | null) => (value ? parseFloat(value) : null),
},
})
previousPrice?: number;
@ApiProperty({
description: '货币类型',
example: 'CNY',
default: 'CNY',
maxLength: 10,
})
@Column({
name: 'currency',
type: 'varchar',
length: 10,
default: 'CNY',
})
currency: string;
@ApiPropertyOptional({
description: '汇率(用于多货币)',
example: 1.0,
default: 1,
})
@Column({
name: 'exchange_rate',
type: 'decimal',
precision: 10,
scale: 6,
default: 1,
transformer: {
to: (value: number | undefined) => value,
from: (value: string | null) => (value ? parseFloat(value) : 1),
},
})
exchangeRate?: number;
@ApiProperty({
description: '是否自动更新价格(付费用户功能)',
example: false,
default: false,
})
@Column({
name: 'auto_price_update',
type: 'boolean',
default: false,
})
autoPriceUpdate: boolean;
@ApiProperty({
description: '状态',
example: 'active',
enum: ['active', 'suspended', 'delisted'],
default: 'active',
})
@Column({
name: 'status',
type: 'varchar',
length: 20,
default: 'active',
})
@Index()
status: string;
@ApiProperty({
description: '创建时间',
example: '2024-01-01T00:00:00.000Z',
})
@CreateDateColumn({ name: 'created_at' })
createdAt: Date;
@ApiProperty({
description: '更新时间',
example: '2024-01-01T00:00:00.000Z',
})
@UpdateDateColumn({ name: 'updated_at' })
updatedAt: Date;
}