import random import string from django.db import models from django.contrib.auth.models import User from django.utils.translation import gettext_lazy as _ def generate_uid(): return ''.join(random.choices(string.digits, k=6)) class SiteSettings(models.Model): site_name = models.CharField(max_length=100, default="BitCrypto", verbose_name=_("网站名称")) customer_service_url = models.URLField(blank=True, null=True, verbose_name=_("在线客服链接")) terms_content = models.TextField(blank=True, verbose_name=_("服务条款内容")) privacy_content = models.TextField(blank=True, verbose_name=_("隐私政策内容")) # Global Market Control is_pinning_active = models.BooleanField(default=False, verbose_name=_("全局插针激活"), help_text=_("开启后,所有币种将向手动设置的价格靠拢")) class Meta: verbose_name = _("系统设置") verbose_name_plural = _("系统设置") def __str__(self): return self.site_name class Cryptocurrency(models.Model): symbol = models.CharField(max_length=20, unique=True, verbose_name=_("币种代码")) name = models.CharField(max_length=100, verbose_name=_("币种名称")) icon_url = models.URLField(null=True, blank=True, verbose_name=_("图标URL")) current_price = models.DecimalField(max_digits=30, decimal_places=8, default=0, verbose_name=_("当前价格")) manual_price = models.DecimalField(max_digits=30, decimal_places=8, null=True, blank=True, verbose_name=_("插针价格 (留空则使用当前价格)")) change_24h = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name=_("24h 涨跌幅")) is_active = models.BooleanField(default=True, verbose_name=_("是否启用")) class Meta: verbose_name = _("加密货币") verbose_name_plural = _("加密货币管理") def __str__(self): return f"{self.symbol} - {self.name}" class Account(models.Model): ACCOUNT_TYPES = ( ('SIMULATED', _('模拟账户')), ('REAL', _('真实账户')), ) KYC_STATUS = ( ('UNVERIFIED', _('未认证')), ('PENDING', _('审核中')), ('VERIFIED', _('已认证')), ('REJECTED', _('已拒绝')), ) user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True) uid = models.CharField(max_length=6, unique=True, default=generate_uid, verbose_name=_("UID")) session_key = models.CharField(max_length=100, null=True, blank=True, unique=True) account_type = models.CharField(max_length=20, choices=ACCOUNT_TYPES, default='SIMULATED', verbose_name=_("账户类型")) balance = models.DecimalField(max_digits=30, decimal_places=8, default=0, verbose_name=_("可用余额 (USDT)")) credit_score = models.IntegerField(default=80, verbose_name=_("信用分")) kyc_status = models.CharField(max_length=20, choices=KYC_STATUS, default='UNVERIFIED', verbose_name=_("实名认证状态")) win_loss_control = models.IntegerField(default=0, help_text=_("控制胜率: -100 (必输) 到 100 (必赢), 0 为随机"), verbose_name=_("输赢控制")) language = models.CharField(max_length=10, default='zh-hans', verbose_name=_("语言偏好")) created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("创建时间")) class Meta: verbose_name = _("账户") verbose_name_plural = _("账户管理") def __str__(self): return f"Account {self.uid} ({self.get_account_type_display()})" class Asset(models.Model): account = models.ForeignKey(Account, on_delete=models.CASCADE, related_name='assets') currency = models.CharField(max_length=10, verbose_name=_("币种")) balance = models.DecimalField(max_digits=30, decimal_places=8, default=0, verbose_name=_("余额")) frozen = models.DecimalField(max_digits=30, decimal_places=8, default=0, verbose_name=_("冻结")) class Meta: unique_together = ('account', 'currency') verbose_name = _("资产") verbose_name_plural = _("资产管理") @property def total(self): return self.balance + self.frozen def __str__(self): return f"{self.account.uid} - {self.currency}: {self.balance}" class Order(models.Model): SIDE_CHOICES = (('BUY', _('买入/做多')), ('SELL', _('卖出/做空'))) TYPE_CHOICES = (('LIMIT', _('限价')), ('MARKET', _('市价'))) TRADE_TYPE_CHOICES = (('SPOT', _('现货')), ('CONTRACT', _('合约'))) STATUS_CHOICES = ( ('LIVE', _('进行中')), ('PARTIALLY_FILLED', _('部分成交')), ('FILLED', _('已成交')), ('CANCELED', _('已撤销')), ('CLOSED', _('已平仓')), ) account = models.ForeignKey(Account, on_delete=models.CASCADE, related_name='orders') symbol = models.CharField(max_length=20, default='BTC-USDT', verbose_name=_("交易对")) trade_type = models.CharField(max_length=20, choices=TRADE_TYPE_CHOICES, default='SPOT', verbose_name=_("交易类型")) side = models.CharField(max_length=10, choices=SIDE_CHOICES, verbose_name=_("方向")) order_type = models.CharField(max_length=10, choices=TYPE_CHOICES, verbose_name=_("类型")) price = models.DecimalField(max_digits=30, decimal_places=8, null=True, blank=True, verbose_name=_("委托价格")) amount = models.DecimalField(max_digits=30, decimal_places=8, verbose_name=_("数量")) filled_amount = models.DecimalField(max_digits=30, decimal_places=8, default=0, verbose_name=_("已成交数量")) leverage = models.IntegerField(default=1, verbose_name=_("杠杆倍数")) entry_price = models.DecimalField(max_digits=30, decimal_places=8, null=True, blank=True, verbose_name=_("入场价格")) close_price = models.DecimalField(max_digits=30, decimal_places=8, null=True, blank=True, verbose_name=_("平仓价格")) profit_loss = models.DecimalField(max_digits=30, decimal_places=8, default=0, verbose_name=_("盈亏")) status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='LIVE', verbose_name=_("状态")) created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("创建时间")) class Meta: verbose_name = _("订单") verbose_name_plural = _("订单管理") def __str__(self): return f"{self.trade_type} {self.side} {self.amount} {self.symbol}" class Transaction(models.Model): TX_TYPE = (('deposit', _('充值')), ('withdraw', _('提现'))) TX_STATUS = (('pending', _('待处理')), ('completed', _('成功')), ('failed', _('失败'))) account = models.ForeignKey(Account, on_delete=models.CASCADE, related_name='transactions') transaction_type = models.CharField(max_length=20, choices=TX_TYPE, default='deposit', verbose_name=_("类型")) currency = models.CharField(max_length=10, default='USDT', verbose_name=_("币种")) amount = models.DecimalField(max_digits=30, decimal_places=8, default=0, verbose_name=_("金额")) tx_hash = models.CharField(max_length=255, null=True, blank=True, verbose_name=_("交易哈希")) status = models.CharField(max_length=20, choices=TX_STATUS, default='pending', verbose_name=_("状态")) timestamp = models.DateTimeField(auto_now_add=True, verbose_name=_("时间")) class Meta: verbose_name = _("充提记录") verbose_name_plural = _("充提管理")