feat: 抢单大厅假单池,仅改造 ddhq 接口
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
34
orders/migrations/0010_fakegraborder.py
Normal file
34
orders/migrations/0010_fakegraborder.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('orders', '0009_penalty_bonus_lock_fields'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='FakeGrabOrder',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('OrderID', models.CharField(db_column='dingdan_id', db_index=True, max_length=32, unique=True, verbose_name='订单ID')),
|
||||
('Amount', models.DecimalField(db_column='jine', decimal_places=2, max_digits=10, verbose_name='订单价格(展示为打手分红)')),
|
||||
('ProductTypeID', models.IntegerField(db_column='leixing_id', verbose_name='订单类型ID')),
|
||||
('Description', models.TextField(blank=True, db_column='jieshao', null=True, verbose_name='订单介绍')),
|
||||
('Remark', models.TextField(blank=True, db_column='beizhu', null=True, verbose_name='订单备注')),
|
||||
('DispatcherUserID', models.CharField(blank=True, db_column='paidan_yonghuid', max_length=32, null=True, verbose_name='派单者用户ID')),
|
||||
('DispatcherAvatar', models.CharField(blank=True, db_column='paidan_touxiang', max_length=500, null=True, verbose_name='派单者头像(展示用默认头像)')),
|
||||
('IsPremiumMerchant', models.BooleanField(db_column='is_youzhi_shangjia', default=False, verbose_name='是否优质商家')),
|
||||
('Platform', models.IntegerField(db_column='fadan_pingtai', default=1, verbose_name='发单平台:1平台2商家')),
|
||||
('ClubID', models.CharField(db_column='club_id', db_index=True, default='xq', max_length=16, 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='更新时间')),
|
||||
],
|
||||
options={
|
||||
'db_table': 'fake_grab_order',
|
||||
'indexes': [models.Index(fields=['ClubID', 'ProductTypeID'], name='fake_grab_o_club_id_6a8f2a_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1037,6 +1037,59 @@ class ChatSession(QModel):
|
||||
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='派单者头像(展示用默认头像)',
|
||||
)
|
||||
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']),
|
||||
]
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# 兼容别名(渐进迁移,全部迁移完成后可删除)
|
||||
# ===========================================================================
|
||||
|
||||
107
orders/services/fake_order_pool.py
Normal file
107
orders/services/fake_order_pool.py
Normal file
@@ -0,0 +1,107 @@
|
||||
"""抢单大厅假单:无资格/封禁打手仅展示假数据。"""
|
||||
from decimal import Decimal
|
||||
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from rest_framework.response import Response
|
||||
|
||||
from backend.utils import fmt_datetime, pick_leixing_id
|
||||
from jituan.services.club_context import resolve_effective_club_id
|
||||
from jituan.services.dashou_exam import user_has_active_member
|
||||
from orders.models import FakeGrabOrder
|
||||
|
||||
DEFAULT_DISPATCHER_AVATAR = 'a_long/morentouxiang.jpg'
|
||||
|
||||
|
||||
def dashou_should_use_fake_pool(user):
|
||||
"""
|
||||
打手是否只能看假单:
|
||||
- 账号封禁(zhanghaozhuangtai != 1)
|
||||
- 或未开通有效会员 且 押金不大于 5
|
||||
"""
|
||||
try:
|
||||
dashou = user.DashouProfile
|
||||
except ObjectDoesNotExist:
|
||||
return True
|
||||
|
||||
if dashou.zhanghaozhuangtai != 1:
|
||||
return True
|
||||
|
||||
yajin = Decimal(str(dashou.yajin or 0))
|
||||
if yajin > Decimal('5'):
|
||||
return False
|
||||
|
||||
if user_has_active_member(user.UserUID):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def _format_fake_row(row):
|
||||
"""字段与 DashouDingdanHuoquView 真实单列表保持一致。"""
|
||||
avatar = DEFAULT_DISPATCHER_AVATAR
|
||||
platform = int(row.Platform or 1)
|
||||
oid = row.OrderID
|
||||
price = float(row.Amount or 0)
|
||||
ct = fmt_datetime(row.CreateTime)
|
||||
zid = (row.DispatcherUserID or '').strip()
|
||||
|
||||
return {
|
||||
'dingdan_id': oid,
|
||||
'zhuangtai': 1,
|
||||
'pingtai': platform,
|
||||
'dashou_fencheng': price,
|
||||
'leixing_id': row.ProductTypeID or 0,
|
||||
'tupian': avatar,
|
||||
'yaoqiuleixing': 0,
|
||||
'huiyuan_id': '',
|
||||
'yajin': 0.0,
|
||||
'jieshao': row.Description or '',
|
||||
'beizhu': row.Remark or '',
|
||||
'creat_time': ct,
|
||||
'create_time': ct,
|
||||
'sjnicheng': '',
|
||||
'sj_avatar': avatar if platform == 2 else '',
|
||||
'zhiding_uid': zid,
|
||||
'zhiding_avatar': avatar,
|
||||
'zhiding_nicheng': '',
|
||||
'xuqiu_biaoqian': [],
|
||||
'dashou_biaoqian': [],
|
||||
'shangjia_biaoqian': [],
|
||||
'shangjia_identity_biaoqian': [],
|
||||
'zhiding_identity_biaoqian': [],
|
||||
'shangjia_youzhi': bool(row.IsPremiumMerchant) if platform == 2 else False,
|
||||
}
|
||||
|
||||
|
||||
def build_fake_order_pool_response(request):
|
||||
data = request.data
|
||||
leixing_id = pick_leixing_id(data)
|
||||
page = max(1, int(data.get('page', 1)))
|
||||
page_size = max(1, min(int(data.get('page_size', 10)), 50))
|
||||
|
||||
club_id = resolve_effective_club_id(request, getattr(request, 'user', None))
|
||||
|
||||
qs = FakeGrabOrder.query.filter(ClubID=club_id)
|
||||
if leixing_id is not None:
|
||||
qs = qs.filter(ProductTypeID=leixing_id)
|
||||
|
||||
qs = qs.order_by('-SortOrder', '-CreateTime')
|
||||
total = qs.count()
|
||||
offset = (page - 1) * page_size
|
||||
rows = list(qs[offset:offset + page_size])
|
||||
|
||||
formatted_list = [_format_fake_row(r) for r in rows]
|
||||
has_more = (page * page_size) < total
|
||||
|
||||
return Response({
|
||||
'code': 200,
|
||||
'msg': '获取成功',
|
||||
'data': {
|
||||
'list': formatted_list,
|
||||
'has_more': has_more,
|
||||
'total': total,
|
||||
'current_page': page,
|
||||
'page_size': page_size,
|
||||
'total_pages': (total + page_size - 1) // page_size if page_size else 0,
|
||||
},
|
||||
})
|
||||
@@ -3050,6 +3050,13 @@ class DashouDingdanHuoquView(APIView):
|
||||
|
||||
def post(self, request):
|
||||
try:
|
||||
from orders.services.fake_order_pool import (
|
||||
dashou_should_use_fake_pool,
|
||||
build_fake_order_pool_response,
|
||||
)
|
||||
if dashou_should_use_fake_pool(request.user):
|
||||
return build_fake_order_pool_response(request)
|
||||
|
||||
# 1. 获取请求参数
|
||||
data = request.data
|
||||
leixing_id = pick_leixing_id(data)
|
||||
|
||||
Reference in New Issue
Block a user