新增 zdcx/zdhf 接口及订单表指定响应字段,供抢单页想接/不想接/等会接。 Co-authored-by: Cursor <cursoragent@cursor.com>
1152 lines
40 KiB
Python
1152 lines
40 KiB
Python
"""订单模块数据模型
|
||
|
||
包含订单全生命周期相关模型:
|
||
|
||
- **Order** — 订单主表
|
||
- **PlatformOrderExt** — 平台订单扩展表(发单平台=1 时使用)
|
||
- **MerchantOrderExt** — 商家订单扩展表(发单平台=2 时使用)
|
||
- **EscortOrder** — 陪护订单表
|
||
- **OrderPlayerHistory** — 订单打手变更历史
|
||
- **Penalty** — 罚单表
|
||
- **PenaltyAppealImage** — 罚单申诉图片
|
||
- **PenaltyBonus** — 罚单分红
|
||
- **PenaltyBonusRate** — 罚单分红费率配置
|
||
- **PlayerDeliveryImage** — 打手交付图片
|
||
- **PlayerRating** — 打手评分
|
||
- **CommissionRate** — 分成利率配置
|
||
- **PenaltyRecord** — 处罚记录
|
||
- **PenaltyEvidenceImage** — 处罚证据图片
|
||
- **RefundRecord** — 退款记录
|
||
- **PlatformCashFlow** — 平台流水统计
|
||
- **ChatSession** — 聊天会话
|
||
"""
|
||
from django.db import models
|
||
from gvsdsdk.model_base import QModel
|
||
|
||
|
||
# ===========================================================================
|
||
# 订单核心模型
|
||
# ===========================================================================
|
||
|
||
class Order(QModel):
|
||
"""订单主表
|
||
|
||
状态码含义:
|
||
1=待抢单, 2=进行中, 3=已完成, 4=退款审核中, 5=已退款,
|
||
7=指定中, 8=结算中, 9=未支付, 14=支付失败, 25=已废弃
|
||
|
||
发单平台(fadan_pingtai):
|
||
1=平台发单(老板微信支付), 2=商家发单(商家余额扣款)
|
||
"""
|
||
|
||
OrderID = models.CharField(
|
||
max_length=32, unique=True, db_index=True,
|
||
db_column='dingdan_id', verbose_name='订单ID',
|
||
)
|
||
Status = models.IntegerField(
|
||
default=1, null=True, blank=True, db_index=True,
|
||
db_column='zhuangtai', verbose_name='订单状态',
|
||
)
|
||
Platform = models.IntegerField(
|
||
null=True, blank=True,
|
||
db_column='fadan_pingtai', verbose_name='发单平台',
|
||
)
|
||
ClubID = models.CharField(
|
||
max_length=16, default='xq', db_index=True,
|
||
db_column='club_id', verbose_name='所属俱乐部',
|
||
)
|
||
# ---- 金额 ----
|
||
Amount = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True,
|
||
db_column='jine', verbose_name='订单金额',
|
||
)
|
||
PlayerCommission = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True,
|
||
db_column='dashou_fencheng', verbose_name='打手分成',
|
||
)
|
||
ManagerCommission = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True, default=0,
|
||
db_column='guanshi_fencheng', verbose_name='管事分成',
|
||
)
|
||
# ---- 用户与商品关联 ----
|
||
PlayerID = models.CharField(
|
||
max_length=32, null=True, db_index=True, blank=True,
|
||
db_column='jiedan_dashou_id', verbose_name='接单打手ID',
|
||
)
|
||
PlayerRemark = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='dashou_liuyan', verbose_name='打手留言',
|
||
)
|
||
AssignedID = models.CharField(
|
||
max_length=32, null=True, blank=True,
|
||
db_column='zhiding_id', verbose_name='指定ID',
|
||
)
|
||
AssignedResponse = models.PositiveSmallIntegerField(
|
||
null=True, blank=True,
|
||
db_column='zhiding_hf', verbose_name='指定打手响应 1想接 2不想接 3等会接',
|
||
)
|
||
AssignedResponseAt = models.DateTimeField(
|
||
null=True, blank=True,
|
||
db_column='zhiding_hf_sj', verbose_name='指定响应时间',
|
||
)
|
||
AssignedLaterNote = models.CharField(
|
||
max_length=100, blank=True, default='',
|
||
db_column='zhiding_dhj_sm', verbose_name='等会接说明',
|
||
)
|
||
ProductID = models.IntegerField(
|
||
null=True, blank=True,
|
||
db_column='shangpin_id', verbose_name='商品ID',
|
||
)
|
||
ProductTypeID = models.PositiveIntegerField(
|
||
null=True, blank=True,
|
||
db_column='leixing_id', verbose_name='商品类型ID',
|
||
)
|
||
ImageURL = models.CharField(
|
||
max_length=500, null=True, blank=True,
|
||
db_column='tupian', verbose_name='商品图片URL',
|
||
)
|
||
# ---- 抢单要求 ----
|
||
GrabRequirement = models.PositiveIntegerField(
|
||
null=True, blank=True,
|
||
db_column='yaoqiuleixing', verbose_name='抢单要求类型',
|
||
)
|
||
MembershipID = models.CharField(
|
||
max_length=6, null=True, blank=True,
|
||
db_column='huiyuan_id', verbose_name='会员ID',
|
||
)
|
||
CommissionReq = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True,
|
||
db_column='yongjin', verbose_name='佣金要求',
|
||
)
|
||
# ---- 描述 ----
|
||
Description = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='jieshao', verbose_name='订单介绍',
|
||
)
|
||
Remark = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='beizhu', verbose_name='订单备注',
|
||
)
|
||
Nickname = models.CharField(
|
||
max_length=50, null=True, blank=True,
|
||
db_column='nicheng', verbose_name='游戏昵称',
|
||
)
|
||
User1ID = models.CharField(
|
||
max_length=30, null=True, db_index=True,
|
||
db_column='user1_id', verbose_name='用户1标识',
|
||
)
|
||
User2ID = models.CharField(
|
||
max_length=30, null=True, db_index=True,
|
||
db_column='user2_id', verbose_name='用户2打手标识',
|
||
)
|
||
# ---- 延时任务与调度 ----
|
||
AutoTaskID = models.CharField(
|
||
max_length=255, blank=True, default='',
|
||
db_column='auto_task_id', verbose_name='延时任务ID',
|
||
)
|
||
AutoExpireAt = models.DateTimeField(
|
||
null=True, blank=True,
|
||
db_column='auto_expire_at', verbose_name='计划过期时间',
|
||
)
|
||
PendingDispatch = models.BooleanField(
|
||
default=False, db_index=True,
|
||
db_column='pending_dispatch', verbose_name='待调度标记',
|
||
)
|
||
SettlementTime = models.DateTimeField(
|
||
null=True, blank=True,
|
||
db_column='status_8_time', verbose_name='状态变为8的时间',
|
||
)
|
||
# ---- 时间戳 ----
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
UpdateTime = models.DateTimeField(
|
||
auto_now=True,
|
||
verbose_name='更新时间',
|
||
)
|
||
# ---- 客服与退款 ----
|
||
AssignedCS = models.CharField(
|
||
max_length=20, null=True, db_index=True,
|
||
db_column='clkf', verbose_name='处理客服',
|
||
)
|
||
RefundReason = models.CharField(
|
||
max_length=500, blank=True, null=True,
|
||
db_column='tkly', verbose_name='退款/拒绝理由',
|
||
)
|
||
WechatTransactionID = models.CharField(
|
||
max_length=64, blank=True, null=True, db_index=True,
|
||
db_column='wechat_transaction_id', verbose_name='微信支付订单号',
|
||
)
|
||
ExternalOrderID = models.CharField(
|
||
max_length=64, blank=True, null=True, db_index=True,
|
||
db_column='waibu_dingdan_id', verbose_name='外部平台订单号',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'dingdan'
|
||
verbose_name = '订单'
|
||
verbose_name_plural = '订单'
|
||
indexes = [
|
||
models.Index(fields=['Status']),
|
||
models.Index(fields=['OrderID']),
|
||
models.Index(fields=['PlayerID']),
|
||
models.Index(fields=['WechatTransactionID']),
|
||
]
|
||
|
||
def __str__(self):
|
||
return self.OrderID
|
||
|
||
|
||
class PlatformOrderExt(QModel):
|
||
"""平台订单扩展表(当 Order.Platform=1 时使用)
|
||
|
||
OneToOne 关联 Order,记录平台发单的额外信息:
|
||
老板ID、平台收益、店铺收益、上级分红快照等。
|
||
"""
|
||
|
||
Order = models.OneToOneField(
|
||
Order, on_delete=models.CASCADE,
|
||
related_name='pingtai_kuozhan',
|
||
db_column='dingdan_id', verbose_name='订单',
|
||
)
|
||
BossID = models.CharField(
|
||
max_length=32, null=True, blank=True, db_index=True,
|
||
db_column='laoban_id', verbose_name='老板ID',
|
||
)
|
||
BossReview = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='laoban_pingjia', verbose_name='老板评价',
|
||
)
|
||
RejectSettlementFlag = models.IntegerField(
|
||
default=0,
|
||
db_column='jjjs_biaoshi', verbose_name='拒绝结算标记(1表示拒绝结算)',
|
||
)
|
||
# ---- 收益 ----
|
||
PlatformIncome = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True, default=0.00,
|
||
db_column='pingtai_shouyi', verbose_name='平台收益',
|
||
)
|
||
ShopIncome = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True, default=0.00,
|
||
db_column='dianpu_shouyi', verbose_name='店铺收益',
|
||
)
|
||
ShopID = models.PositiveIntegerField(
|
||
null=True, blank=True, db_index=True,
|
||
db_column='dianpu_id', verbose_name='所属店铺ID',
|
||
)
|
||
# ---- 上级分红快照 ----
|
||
ParentShopID = models.PositiveIntegerField(
|
||
null=True, blank=True, db_index=True,
|
||
db_column='shangji_dianpu_id', verbose_name='该订单的上级店铺ID',
|
||
)
|
||
ParentBonus = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True, default=0.00,
|
||
db_column='shangji_fenhong', verbose_name='上级分红金额',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'dingdan_pingtai'
|
||
verbose_name = '平台订单扩展'
|
||
verbose_name_plural = '平台订单扩展'
|
||
indexes = [
|
||
models.Index(fields=['BossID']),
|
||
models.Index(fields=['ShopID']),
|
||
]
|
||
|
||
def __str__(self):
|
||
return f"平台扩展-{self.Order.OrderID}"
|
||
|
||
|
||
class MerchantOrderExt(QModel):
|
||
"""商家发单扩展表(当 Order.Platform=2 时使用)
|
||
|
||
OneToOne 关联 Order,记录商家发单的额外信息:
|
||
商家ID、处罚相关、上一个订单ID等。
|
||
"""
|
||
|
||
Order = models.OneToOneField(
|
||
Order, on_delete=models.CASCADE,
|
||
related_name='shangjia_kuozhan',
|
||
db_column='dingdan_id', verbose_name='订单',
|
||
)
|
||
MerchantID = models.CharField(
|
||
max_length=32, null=True, blank=True, db_index=True,
|
||
db_column='shangjia_id', verbose_name='商家ID',
|
||
)
|
||
MerchantReview = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='shangjia_pingjia', verbose_name='商家评价',
|
||
)
|
||
PenaltyReason = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='cfliyou', verbose_name='商家处罚理由',
|
||
)
|
||
PenaltyApplyStatus = models.IntegerField(
|
||
default=0, null=True, blank=True,
|
||
db_column='sqzhuangtai', verbose_name='处罚申请状态:0待处理,1成功,2驳回',
|
||
)
|
||
RejectReason = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='bhliyou', verbose_name='驳回商家处罚理由',
|
||
)
|
||
MerchantNickname = models.CharField(
|
||
max_length=50, null=True,
|
||
db_column='sjnicheng', verbose_name='商家昵称',
|
||
)
|
||
PrevOrderID = models.CharField(
|
||
max_length=32, null=True, blank=True,
|
||
db_column='shangyige_dingdan_id', verbose_name='上一个订单ID',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'dingdan_shangjia'
|
||
verbose_name = '商家订单扩展'
|
||
verbose_name_plural = '商家订单扩展'
|
||
indexes = [
|
||
models.Index(fields=['MerchantID']),
|
||
]
|
||
|
||
def __str__(self):
|
||
return f"商家扩展-{self.Order.OrderID}"
|
||
|
||
|
||
class EscortOrder(QModel):
|
||
"""陪护订单表(一个订单最多2个陪护打手)
|
||
|
||
陪护订单依附于主订单,状态码:
|
||
1=待抢单, 2=已抢待确认, 3=进行中, 4=已完成, 5=已取消, 7=指定状态
|
||
"""
|
||
|
||
OrderID = models.CharField(
|
||
max_length=32, unique=True, db_index=True,
|
||
db_column='dingdan_id', verbose_name='订单ID',
|
||
)
|
||
MainPlayerID = models.CharField(
|
||
max_length=32, db_index=True,
|
||
db_column='zhudashou_id', verbose_name='主打手ID',
|
||
)
|
||
Escort1ID = models.CharField(
|
||
max_length=32, null=True, blank=True, db_index=True,
|
||
db_column='peihu1_id', verbose_name='陪护1打手ID',
|
||
)
|
||
Escort2ID = models.CharField(
|
||
max_length=32, null=True, blank=True, db_index=True,
|
||
db_column='peihu2_id', verbose_name='陪护2打手ID',
|
||
)
|
||
Status = models.IntegerField(
|
||
default=1,
|
||
db_column='zhuangtai', verbose_name='陪护订单状态',
|
||
)
|
||
# ---- 需求配置 ----
|
||
EscortCount = models.IntegerField(
|
||
default=1,
|
||
db_column='peihu_xuqiu_shuliang', verbose_name='陪护需求数量',
|
||
)
|
||
CommissionReq = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True,
|
||
db_column='yongjin_yaoqiu', verbose_name='抢单佣金要求',
|
||
)
|
||
Escort1LevelReq = models.PositiveIntegerField(
|
||
null=True, blank=True,
|
||
db_column='peihu1_dengji_xuqiu', verbose_name='陪护1等级需求(称号ID)',
|
||
)
|
||
Escort2LevelReq = models.PositiveIntegerField(
|
||
null=True, blank=True,
|
||
db_column='peihu2_dengji_xuqiu', verbose_name='陪护2等级需求(称号ID)',
|
||
)
|
||
# ---- 处罚与分红比例 ----
|
||
Escort1BombLiability = models.CharField(
|
||
max_length=10, null=True, blank=True,
|
||
db_column='peihu1_zhadan_danze', verbose_name='陪护1炸单担责比例',
|
||
)
|
||
Escort2BombLiability = models.CharField(
|
||
max_length=10, null=True, blank=True,
|
||
db_column='peihu2_zhadan_danze', verbose_name='陪护2炸单担责比例',
|
||
)
|
||
Escort1BonusRate = models.CharField(
|
||
max_length=10, null=True, blank=True,
|
||
db_column='peihu1_fenhong', verbose_name='陪护1分红比例',
|
||
)
|
||
Escort2BonusRate = models.CharField(
|
||
max_length=10, null=True, blank=True,
|
||
db_column='peihu2_fenhong', verbose_name='陪护2分红比例',
|
||
)
|
||
# ---- 指定陪护 ----
|
||
AssignedEscort1 = models.CharField(
|
||
max_length=32, null=True, blank=True,
|
||
db_column='zhiding_peihu1', verbose_name='指定陪护1 ID',
|
||
)
|
||
AssignedEscort2 = models.CharField(
|
||
max_length=32, null=True, blank=True,
|
||
db_column='zhiding_peihu2', verbose_name='指定陪护2 ID',
|
||
)
|
||
# ---- 时间戳 ----
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
UpdateTime = models.DateTimeField(
|
||
auto_now=True,
|
||
verbose_name='更新时间',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'dingdan_peihu'
|
||
verbose_name = '陪护订单'
|
||
verbose_name_plural = verbose_name
|
||
indexes = [
|
||
models.Index(fields=['MainPlayerID']),
|
||
models.Index(fields=['Escort1ID']),
|
||
models.Index(fields=['Escort2ID']),
|
||
models.Index(fields=['Status']),
|
||
]
|
||
|
||
|
||
class OrderPlayerHistory(QModel):
|
||
"""订单打手变更历史表,记录订单每次更换打手的操作。"""
|
||
|
||
OrderID = models.CharField(
|
||
max_length=32, db_index=True,
|
||
db_column='dingdan_id', verbose_name='订单ID',
|
||
)
|
||
PlayerID = models.CharField(
|
||
max_length=7, db_index=True,
|
||
db_column='dashou_id', verbose_name='打手ID',
|
||
)
|
||
Times = models.PositiveSmallIntegerField(verbose_name='第几次接单(从1开始)')
|
||
Operator = models.CharField(
|
||
max_length=11,
|
||
db_column='operator', verbose_name='操作客服ID',
|
||
)
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'order_dashou_history'
|
||
verbose_name = '订单打手变更历史'
|
||
verbose_name_plural = '订单打手变更历史'
|
||
indexes = [
|
||
models.Index(fields=['OrderID']),
|
||
models.Index(fields=['PlayerID']),
|
||
]
|
||
|
||
def __str__(self):
|
||
return f"{self.OrderID} -> {self.PlayerID} 第{self.Times}次"
|
||
|
||
|
||
# ===========================================================================
|
||
# 罚单相关模型
|
||
# ===========================================================================
|
||
|
||
class Penalty(QModel):
|
||
"""罚单表——平台各类处罚信息
|
||
|
||
状态码:1=待缴纳, 2=已缴纳, 3=申诉中, 4=已驳回
|
||
被处罚者身份(shenfen):1=打手, 2=管事, 3=商家, 4=组长
|
||
"""
|
||
|
||
id = models.AutoField(primary_key=True, verbose_name='自增主键')
|
||
PenalizedUserID = models.CharField(
|
||
max_length=20, db_index=True,
|
||
db_column='beichufa_id', verbose_name='被处罚用户ID',
|
||
)
|
||
ApplicantID = models.CharField(
|
||
max_length=20, blank=True, null=True,
|
||
db_column='shenqing_chufa', verbose_name='申请处罚者ID',
|
||
)
|
||
Identity = models.IntegerField(
|
||
choices=[(1, '打手'), (2, '管事'), (3, '商家'), (4, '组长')],
|
||
default=1,
|
||
db_column='shenfen', verbose_name='被处罚者身份',
|
||
)
|
||
Reason = models.TextField(
|
||
blank=True, null=True,
|
||
db_column='chufaliyou', verbose_name='处罚理由',
|
||
)
|
||
FineAmount = models.DecimalField(
|
||
max_digits=10, decimal_places=2, default=0.00,
|
||
db_column='fakuanjine', verbose_name='罚款金额',
|
||
)
|
||
RelatedOrderID = models.CharField(
|
||
max_length=32, blank=True, null=True, db_index=True,
|
||
db_column='guanliandingdan_id', verbose_name='关联订单ID',
|
||
)
|
||
Status = models.IntegerField(
|
||
choices=[(1, '待缴纳'), (2, '已缴纳'), (3, '申诉中'), (4, '已驳回')],
|
||
default=1, db_index=True,
|
||
db_column='zhuangtai', verbose_name='罚单状态',
|
||
)
|
||
AffectsGrabbing = models.IntegerField(
|
||
choices=[(1, '影响抢单'), (0, '不影响抢单')],
|
||
default=1, db_index=True,
|
||
db_column='yingxiang_qiangdan', verbose_name='是否影响抢单',
|
||
)
|
||
AppealReason = models.TextField(
|
||
blank=True, null=True,
|
||
db_column='shensuliyou', verbose_name='申诉理由',
|
||
)
|
||
ApproveReason = models.TextField(
|
||
blank=True, null=True,
|
||
db_column='tongyi_chufaliyou', verbose_name='同意处罚理由',
|
||
)
|
||
RejectReason = models.TextField(
|
||
blank=True, null=True,
|
||
db_column='bohuiliyou', verbose_name='驳回理由',
|
||
)
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
UpdateTime = models.DateTimeField(
|
||
auto_now=True,
|
||
verbose_name='更新时间',
|
||
)
|
||
ApplicantIdentity = models.IntegerField(
|
||
choices=[(1, '客服'), (2, '售后'), (3, '管理员'), (4, '店铺'), (5, '商家')],
|
||
default=1,
|
||
db_column='shenqingren_shenfen', verbose_name='申请处罚人身份',
|
||
)
|
||
ProcessorIdentity = models.IntegerField(
|
||
choices=[(1, '客服'), (2, '售后'), (3, '管理员'), (5, '商家')],
|
||
default=2,
|
||
db_column='chulizhe_shenfen', verbose_name='处理者身份',
|
||
)
|
||
ProcessorID = models.CharField(
|
||
max_length=20, blank=True, null=True,
|
||
db_column='chulizhe', verbose_name='处理者',
|
||
)
|
||
ApplicantBonusAmount = models.DecimalField(
|
||
max_digits=12, decimal_places=2, default=0.00,
|
||
db_column='shenqingren_fenhong_jine', verbose_name='申请人分红金额',
|
||
)
|
||
ApplicantBonusRate = models.DecimalField(
|
||
max_digits=5, decimal_places=4, default=0.0000,
|
||
db_column='shenqingren_fenhong_lilv', verbose_name='申请人分红锁定利率',
|
||
)
|
||
BonusCredited = models.BooleanField(
|
||
default=False,
|
||
db_column='fenhong_yiruzhang', verbose_name='分红是否已入账',
|
||
)
|
||
ClubID = models.CharField(
|
||
max_length=16, default='xq', db_index=True,
|
||
db_column='club_id', verbose_name='所属俱乐部',
|
||
)
|
||
ShopStaffUserID = models.CharField(
|
||
max_length=20, blank=True, null=True,
|
||
db_column='dianpu_kefu_id', verbose_name='店铺客服用户ID',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'fadan'
|
||
verbose_name = '罚单'
|
||
verbose_name_plural = '罚单'
|
||
indexes = [
|
||
models.Index(fields=['PenalizedUserID', 'AffectsGrabbing', 'Status'], name='fadan_qiangdan_check'),
|
||
models.Index(fields=['RelatedOrderID'], name='fadan_dingdan_idx'),
|
||
]
|
||
|
||
def __str__(self):
|
||
return f"{self.PenalizedUserID} - 罚款{self.FineAmount}元 - 状态{self.Status}"
|
||
|
||
|
||
class PenaltyAppealImage(QModel):
|
||
"""罚款申诉图片,关联罚单。
|
||
|
||
用途(yongtu):1=处罚证据图片, 2=申诉图片
|
||
"""
|
||
|
||
Penalty = models.ForeignKey(
|
||
Penalty, on_delete=models.CASCADE,
|
||
related_name='shensu_tupians',
|
||
db_column='fadan_id', verbose_name='关联罚单',
|
||
)
|
||
PenalizedUserID = models.CharField(
|
||
max_length=7, db_index=True,
|
||
db_column='beichufa_id', verbose_name='被处罚用户ID',
|
||
)
|
||
ImageURL = models.CharField(
|
||
max_length=500,
|
||
db_column='tupian_url', verbose_name='图片相对URL',
|
||
)
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
Purpose = models.IntegerField(
|
||
choices=[(1, '处罚证据图片'), (2, '申诉图片')],
|
||
default=2,
|
||
db_column='yongtu', verbose_name='图片用途',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'fadan_shensu_tupian'
|
||
verbose_name = '罚款申诉图片'
|
||
verbose_name_plural = '罚款申诉图片'
|
||
indexes = [
|
||
models.Index(fields=['Penalty']),
|
||
models.Index(fields=['PenalizedUserID']),
|
||
]
|
||
|
||
|
||
class PenaltyBonus(QModel):
|
||
"""罚款分红表——记录罚款产生的分红信息
|
||
|
||
分红者身份(shenfen):1=商家, 2=客服, 3=平台管理者, 4=店铺, 5=售后
|
||
"""
|
||
|
||
id = models.AutoField(primary_key=True, verbose_name='自增主键')
|
||
BeneficiaryID = models.CharField(
|
||
max_length=20, db_index=True,
|
||
db_column='fenhongzhe_id', verbose_name='分红者ID',
|
||
)
|
||
TotalAmount = models.DecimalField(
|
||
max_digits=12, decimal_places=2, default=0.00,
|
||
db_column='zonge', verbose_name='分红总额',
|
||
)
|
||
WithdrawableAmount = models.DecimalField(
|
||
max_digits=12, decimal_places=2, default=0.00,
|
||
db_column='ketixian_fenhong', verbose_name='可提现分红',
|
||
)
|
||
Identity = models.IntegerField(
|
||
choices=[(1, '商家'), (2, '客服'), (3, '平台管理者'), (4, '店铺'), (5, '售后')],
|
||
default=1,
|
||
db_column='shenfen', verbose_name='分红者身份',
|
||
)
|
||
BonusCount = models.IntegerField(
|
||
default=0,
|
||
db_column='fenhong_cishu', verbose_name='分红次数',
|
||
)
|
||
IsIndividualRate = models.BooleanField(
|
||
default=False,
|
||
db_column='is_individual_rate', verbose_name='是否单独开启分红利率',
|
||
)
|
||
IndividualRate = models.DecimalField(
|
||
max_digits=5, decimal_places=4, default=0.0000,
|
||
db_column='yingde_lilv', verbose_name='分红应得利率',
|
||
)
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
UpdateTime = models.DateTimeField(
|
||
auto_now=True,
|
||
verbose_name='更新时间',
|
||
)
|
||
ClubID = models.CharField(
|
||
max_length=16, default='xq', db_index=True,
|
||
db_column='club_id', verbose_name='所属俱乐部',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'fadan_fenhong'
|
||
verbose_name = '罚款分红'
|
||
verbose_name_plural = '罚款分红'
|
||
indexes = [
|
||
models.Index(fields=['BeneficiaryID'], name='fadan_fenhong_zhe_idx'),
|
||
models.Index(fields=['Identity'], name='fadan_fenhong_sf_idx'),
|
||
]
|
||
|
||
def __str__(self):
|
||
return f"{self.BeneficiaryID} - 分红{self.WithdrawableAmount}元"
|
||
|
||
|
||
class PenaltyBonusRate(QModel):
|
||
"""罚款分红费率配置表,按身份设置分红费率。
|
||
|
||
身份(shenfen):1=客服, 2=售后, 3=管理员, 4=店铺, 5=商家
|
||
"""
|
||
|
||
Identity = models.IntegerField(
|
||
primary_key=True,
|
||
choices=[(1, '客服'), (2, '售后'), (3, '管理员'), (4, '店铺'), (5, '商家')],
|
||
db_column='shenfen', verbose_name='申请处罚人身份',
|
||
)
|
||
Rate = models.DecimalField(
|
||
max_digits=5, decimal_places=4, default=0.0000,
|
||
db_column='lilv', verbose_name='分红费率',
|
||
)
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
UpdateTime = models.DateTimeField(
|
||
auto_now=True,
|
||
verbose_name='更新时间',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'fadan_fenhong_lilv'
|
||
verbose_name = '罚款分红费率配置'
|
||
verbose_name_plural = verbose_name
|
||
|
||
def __str__(self):
|
||
return f"身份{self.Identity} - 费率{self.Rate}"
|
||
|
||
|
||
# ===========================================================================
|
||
# 证据/图片/记录模型
|
||
# ===========================================================================
|
||
|
||
class PlayerDeliveryImage(QModel):
|
||
"""打手交付图片表"""
|
||
|
||
OrderID = models.CharField(
|
||
max_length=32, db_index=True, null=True,
|
||
db_column='dingdan_id', verbose_name='订单ID',
|
||
)
|
||
PlayerID = models.CharField(
|
||
max_length=32, null=True, blank=True, db_index=True,
|
||
db_column='dashou', verbose_name='接单打手ID',
|
||
)
|
||
ImageURL = models.CharField(
|
||
max_length=500, null=True, blank=True,
|
||
db_column='tupian', verbose_name='打手提交图片URL',
|
||
)
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
UpdateTime = models.DateTimeField(
|
||
auto_now=True,
|
||
verbose_name='更新时间',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'dashoutupian'
|
||
indexes = [
|
||
models.Index(fields=['PlayerID']),
|
||
models.Index(fields=['OrderID']),
|
||
]
|
||
|
||
|
||
class PlayerRating(QModel):
|
||
"""打手评分表"""
|
||
|
||
PlayerID = models.CharField(
|
||
max_length=32, null=True, blank=True, db_index=True,
|
||
db_column='dashou', verbose_name='接单打手ID',
|
||
)
|
||
TotalScore = models.PositiveIntegerField(
|
||
default=0,
|
||
db_column='zongfen', verbose_name='总分',
|
||
)
|
||
RatingCount = models.PositiveIntegerField(
|
||
default=0,
|
||
db_column='cishu', verbose_name='评分次数',
|
||
)
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
UpdateTime = models.DateTimeField(
|
||
auto_now=True,
|
||
verbose_name='更新时间',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'pingfenbiao'
|
||
verbose_name = '评分表'
|
||
indexes = [
|
||
models.Index(fields=['PlayerID']),
|
||
]
|
||
|
||
def __str__(self):
|
||
return f"{self.PlayerID} - 平均分: {self.average_score():.2f}"
|
||
|
||
def average_score(self) -> float:
|
||
"""计算平均分"""
|
||
if self.RatingCount > 0:
|
||
return float(self.TotalScore) / self.RatingCount
|
||
return 0.0
|
||
|
||
|
||
class PenaltyRecord(QModel):
|
||
"""处罚记录表"""
|
||
|
||
PlayerID = models.CharField(
|
||
max_length=7, null=True, db_index=True,
|
||
db_column='dashouid', verbose_name='被罚打手ID',
|
||
)
|
||
ApplicantID = models.CharField(
|
||
max_length=11, null=True, db_index=True,
|
||
db_column='qingqiuid', verbose_name='请求处罚ID',
|
||
)
|
||
ProcessorID = models.CharField(
|
||
max_length=11, null=True, db_index=True,
|
||
db_column='chuliid', verbose_name='处理处罚ID',
|
||
)
|
||
PenaltyReason = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='cfliyou', verbose_name='处罚理由',
|
||
)
|
||
AppealReason = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='ssliyou', verbose_name='打手申诉理由',
|
||
)
|
||
ApplyStatus = models.IntegerField(
|
||
default=0, null=True, blank=True,
|
||
db_column='sqzhuangtai', verbose_name='处罚申请状态:0待处理,1成功,2驳回',
|
||
)
|
||
RejectReason = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='bhliyou', verbose_name='驳回处罚理由',
|
||
)
|
||
DeductedPoints = models.IntegerField(
|
||
default=0,
|
||
db_column='jifen', verbose_name='扣除打手积分',
|
||
)
|
||
OrderID = models.CharField(
|
||
max_length=32, null=True, db_index=True,
|
||
db_column='dingdan_id', verbose_name='订单ID',
|
||
)
|
||
ClubID = models.CharField(
|
||
max_length=16, default='xq', db_index=True,
|
||
db_column='club_id', verbose_name='所属俱乐部',
|
||
)
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
UpdateTime = models.DateTimeField(
|
||
auto_now=True,
|
||
verbose_name='更新时间',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'chufajilu'
|
||
indexes = [
|
||
models.Index(fields=['PlayerID']),
|
||
models.Index(fields=['ApplicantID']),
|
||
models.Index(fields=['ProcessorID']),
|
||
models.Index(fields=['OrderID']),
|
||
]
|
||
|
||
|
||
class PenaltyEvidenceImage(QModel):
|
||
"""处罚证据图片表"""
|
||
|
||
OrderID = models.CharField(
|
||
max_length=32, db_index=True, null=True,
|
||
db_column='dingdan_id', verbose_name='订单ID',
|
||
)
|
||
UserID = models.CharField(
|
||
max_length=32, null=True, blank=True, db_index=True,
|
||
db_column='yonghuid', verbose_name='用户ID',
|
||
)
|
||
ImageURL = models.CharField(
|
||
max_length=500, null=True, blank=True,
|
||
db_column='tupian', verbose_name='证据图片URL',
|
||
)
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
UpdateTime = models.DateTimeField(
|
||
auto_now=True,
|
||
verbose_name='更新时间',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'chufatupian'
|
||
indexes = [
|
||
models.Index(fields=['UserID']),
|
||
models.Index(fields=['OrderID']),
|
||
]
|
||
|
||
|
||
class RefundRecord(QModel):
|
||
"""退款记录表"""
|
||
|
||
OrderID = models.CharField(
|
||
max_length=32, unique=True,
|
||
db_column='dingdan_id', verbose_name='订单ID',
|
||
)
|
||
PlayerID = models.CharField(
|
||
max_length=7, null=True,
|
||
db_column='dashouid', verbose_name='接单打手ID',
|
||
)
|
||
ApplicantID = models.CharField(
|
||
max_length=7, null=True,
|
||
db_column='qingqiuid', verbose_name='请求用户ID',
|
||
)
|
||
ProcessorID = models.CharField(
|
||
max_length=11, null=True, db_index=True,
|
||
db_column='chuliid', verbose_name='处理人ID',
|
||
)
|
||
Reason = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='liyou', verbose_name='理由',
|
||
)
|
||
ApplyStatus = models.IntegerField(
|
||
default=0, null=True, blank=True, db_index=True,
|
||
db_column='sqzhuangtai', verbose_name='申请状态:0待处理,1成功,2驳回',
|
||
)
|
||
RejectReason = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='bhliyou', verbose_name='驳回理由',
|
||
)
|
||
Amount = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True,
|
||
db_column='jine', verbose_name='订单金额',
|
||
)
|
||
PlayerCommission = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True,
|
||
db_column='dashou_fencheng', verbose_name='打手分成',
|
||
)
|
||
Description = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='jieshao', verbose_name='订单介绍',
|
||
)
|
||
Remark = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='beizhu', verbose_name='订单备注',
|
||
)
|
||
Nickname = models.CharField(
|
||
max_length=50, null=True, blank=True,
|
||
db_column='nicheng', verbose_name='游戏昵称',
|
||
)
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
UpdateTime = models.DateTimeField(
|
||
auto_now=True,
|
||
verbose_name='更新时间',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'tuikuanjilu'
|
||
indexes = [
|
||
models.Index(fields=['ProcessorID']),
|
||
models.Index(fields=['ApplyStatus']),
|
||
]
|
||
|
||
|
||
# ===========================================================================
|
||
# 配置/统计模型
|
||
# ===========================================================================
|
||
|
||
class CommissionRate(QModel):
|
||
"""分成利率配置表
|
||
|
||
Platform 字段标识发单平台:1=平台, 2=商家
|
||
"""
|
||
|
||
Rate = models.DecimalField(
|
||
max_digits=5, decimal_places=4, null=True,
|
||
db_column='lilu', verbose_name='平台分成利率',
|
||
)
|
||
Platform = models.CharField(
|
||
max_length=10, null=True,
|
||
db_column='fadanpingtai', verbose_name='订单所属平台',
|
||
)
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
UpdateTime = models.DateTimeField(
|
||
auto_now=True,
|
||
verbose_name='更新时间',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'lilubiao'
|
||
|
||
|
||
class PlatformCashFlow(QModel):
|
||
"""平台流水统计表"""
|
||
|
||
TotalIncome = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True,
|
||
db_column='zonge', verbose_name='收取总金额',
|
||
)
|
||
TotalPayout = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True,
|
||
db_column='zhichuzonge', verbose_name='支出总金额',
|
||
)
|
||
TotalProfit = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True,
|
||
db_column='zongshouyi', verbose_name='总收益',
|
||
)
|
||
DailyIncome = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True,
|
||
db_column='rizonge', verbose_name='日收取',
|
||
)
|
||
DailyPayout = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True,
|
||
db_column='rizhichu', verbose_name='日支出',
|
||
)
|
||
DailyProfit = models.DecimalField(
|
||
max_digits=10, decimal_places=2, null=True, blank=True,
|
||
db_column='rishouyi', verbose_name='日收益',
|
||
)
|
||
TotalIncomeCount = models.IntegerField(
|
||
default=0,
|
||
db_column='zongshoucishu', verbose_name='总收取次数',
|
||
)
|
||
DailyIncomeCount = models.IntegerField(
|
||
default=0,
|
||
db_column='rishoucishu', verbose_name='日收取次数',
|
||
)
|
||
TotalPayoutCount = models.IntegerField(
|
||
default=0,
|
||
db_column='zongzhichucishu', verbose_name='总支出次数',
|
||
)
|
||
DailyPayoutCount = models.IntegerField(
|
||
default=0,
|
||
db_column='rizhichucishu', verbose_name='日支出次数',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'ptliushui'
|
||
|
||
|
||
class ChatSession(QModel):
|
||
"""聊天会话表
|
||
|
||
状态码:1=开启中, 0=已关闭
|
||
"""
|
||
|
||
id = models.BigAutoField(primary_key=True, verbose_name='主键ID')
|
||
User1ID = models.CharField(
|
||
max_length=30, db_index=True,
|
||
db_column='user1_id', verbose_name='用户1标识',
|
||
)
|
||
User2ID = models.CharField(
|
||
max_length=30, db_index=True,
|
||
db_column='user2_id', verbose_name='用户2标识',
|
||
)
|
||
OrderID = models.CharField(
|
||
max_length=32, unique=True,
|
||
db_column='dingdan_id', verbose_name='订单ID',
|
||
)
|
||
Status = models.IntegerField(
|
||
default=1, db_index=True,
|
||
choices=[(1, '开启中'), (0, '已关闭')],
|
||
db_column='zhuangtai', verbose_name='聊天状态',
|
||
)
|
||
CreateTime = models.DateTimeField(
|
||
auto_now_add=True,
|
||
verbose_name='创建时间',
|
||
)
|
||
UpdateTime = models.DateTimeField(
|
||
auto_now=True,
|
||
verbose_name='更新时间',
|
||
)
|
||
|
||
class Meta:
|
||
db_table = 'liaotian'
|
||
indexes = [
|
||
models.Index(fields=['User1ID']),
|
||
models.Index(fields=['User2ID']),
|
||
models.Index(fields=['Status']),
|
||
]
|
||
|
||
def __str__(self):
|
||
return f'{self.User1ID} <-> {self.User2ID} ({self.Status})'
|
||
|
||
|
||
class FakeGrabOrder(QModel):
|
||
"""抢单大厅假单(仅展示,不可抢单结算)。"""
|
||
|
||
OrderID = models.CharField(
|
||
max_length=32, unique=True, db_index=True,
|
||
db_column='dingdan_id', verbose_name='订单ID',
|
||
)
|
||
Amount = models.DecimalField(
|
||
max_digits=10, decimal_places=2,
|
||
db_column='jine', verbose_name='订单价格(展示为打手分红)',
|
||
)
|
||
ProductTypeID = models.IntegerField(
|
||
db_column='leixing_id', verbose_name='订单类型ID',
|
||
)
|
||
Description = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='jieshao', verbose_name='订单介绍',
|
||
)
|
||
Remark = models.TextField(
|
||
null=True, blank=True,
|
||
db_column='beizhu', verbose_name='订单备注',
|
||
)
|
||
DispatcherUserID = models.CharField(
|
||
max_length=32, null=True, blank=True,
|
||
db_column='paidan_yonghuid', verbose_name='派单者用户ID',
|
||
)
|
||
DispatcherAvatar = models.CharField(
|
||
max_length=500, null=True, blank=True,
|
||
db_column='paidan_touxiang', verbose_name='派单者头像(展示用默认头像)',
|
||
)
|
||
MerchantNickname = models.CharField(
|
||
max_length=50, null=True, blank=True,
|
||
db_column='shangjia_nicheng', verbose_name='商家名称(假单展示)',
|
||
)
|
||
IsPremiumMerchant = models.BooleanField(
|
||
default=False,
|
||
db_column='is_youzhi_shangjia', verbose_name='是否优质商家',
|
||
)
|
||
Platform = models.IntegerField(
|
||
default=1,
|
||
db_column='fadan_pingtai', verbose_name='发单平台:1平台2商家',
|
||
)
|
||
ClubID = models.CharField(
|
||
max_length=16, default='xq', db_index=True,
|
||
db_column='club_id', verbose_name='所属俱乐部',
|
||
)
|
||
SortOrder = models.IntegerField(default=0, verbose_name='排序(大在前)')
|
||
CreateTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||
|
||
class Meta:
|
||
db_table = 'fake_grab_order'
|
||
indexes = [
|
||
models.Index(fields=['ClubID', 'ProductTypeID']),
|
||
]
|
||
|
||
|
||
class FakeGrabOrderShuffleState(QModel):
|
||
"""假单列表全局打乱时刻(仅 id=1 一条记录,全用户共用)。"""
|
||
|
||
id = models.PositiveSmallIntegerField(
|
||
primary_key=True, default=1, verbose_name='固定主键=1',
|
||
)
|
||
LastShuffleTime = models.DateTimeField(
|
||
verbose_name='上次打乱时刻',
|
||
)
|
||
IntervalSeconds = models.PositiveIntegerField(
|
||
default=120, verbose_name='打乱间隔秒数(默认2分钟)',
|
||
)
|
||
OrderSequence = models.JSONField(
|
||
default=dict, blank=True,
|
||
verbose_name='各俱乐部+类型已打乱顺序',
|
||
help_text='形如 {"xq|1": {"last_shuffle_time": "...", "order_ids": ["JD...", ...]}}',
|
||
)
|
||
UpdateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||
|
||
class Meta:
|
||
db_table = 'fake_grab_order_shuffle'
|
||
|
||
|
||
# ===========================================================================
|
||
# 兼容别名(渐进迁移,全部迁移完成后可删除)
|
||
# ===========================================================================
|
||
|
||
Dingdan = Order
|
||
DingdanPingtai = PlatformOrderExt
|
||
DingdanShangjia = MerchantOrderExt
|
||
DingdanPeihu = EscortOrder
|
||
Fadan = Penalty
|
||
FadanShensuTupian = PenaltyAppealImage
|
||
FadanFenhong = PenaltyBonus
|
||
FadanFenhongLilv = PenaltyBonusRate
|
||
Dashoutupian = PlayerDeliveryImage
|
||
Pingfen = PlayerRating
|
||
Lilubiao = CommissionRate
|
||
Chufajilu = PenaltyRecord
|
||
Chufatupian = PenaltyEvidenceImage
|
||
Tuikuanjilu = RefundRecord
|
||
Ptliushui = PlatformCashFlow
|
||
Liaotian = ChatSession
|