第一次提交:阿龙电竞 Django 后端最新版本
This commit is contained in:
0
dingdan/__init__.py
Normal file
0
dingdan/__init__.py
Normal file
3
dingdan/admin.py
Normal file
3
dingdan/admin.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
10
dingdan/apps.py
Normal file
10
dingdan/apps.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class DingdanConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'dingdan'
|
||||
|
||||
def ready(self):
|
||||
# 导入信号处理,确保信号被注册
|
||||
import dingdan.signals
|
||||
39
dingdan/cross_platform_tasks.py
Normal file
39
dingdan/cross_platform_tasks.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# dingdan/cross_platform_tasks.py
|
||||
import logging
|
||||
import requests
|
||||
from django.conf import settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def send_partner_sync_order(partner_order_id, jine, dashou_fencheng, jieshao, beizhu, create_time,nicheng):
|
||||
"""
|
||||
异步发送派单通知给对方平台(使用简单线程,非Celery)
|
||||
注意:此函数应在线程中调用,避免阻塞主请求。
|
||||
生产环境建议使用Celery,此处提供线程兼容版本。
|
||||
"""
|
||||
url = f"{settings.PARTNER_BASE_URL}/dingdan/partner_sync_order"
|
||||
payload = {
|
||||
'token': settings.CROSS_PLATFORM_TOKEN,
|
||||
'partner_order_id': partner_order_id,
|
||||
'jine': jine,
|
||||
'dashou_fencheng': dashou_fencheng,
|
||||
'jieshao': jieshao,
|
||||
'beizhu': beizhu,
|
||||
'create_time': create_time,
|
||||
'nicheng':nicheng
|
||||
}
|
||||
try:
|
||||
response = requests.post(url, json=payload, timeout=5)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get('code') == 0:
|
||||
logger.info(f"跨平台派单同步成功: {partner_order_id}")
|
||||
# 可在此处保存对方返回的 local_order_id 到本地订单(如果需要)
|
||||
# local_order_id = data['data'].get('local_order_id')
|
||||
# Dingdan.objects.filter(dingdan_id=partner_order_id).update(partner_order_id=local_order_id)
|
||||
else:
|
||||
logger.error(f"跨平台派单同步业务失败: {data}")
|
||||
else:
|
||||
logger.error(f"跨平台派单同步HTTP失败: {response.status_code}")
|
||||
except Exception as e:
|
||||
logger.error(f"跨平台派单同步异常: {str(e)}", exc_info=True)
|
||||
844
dingdan/migrations/0001_initial.py
Normal file
844
dingdan/migrations/0001_initial.py
Normal file
@@ -0,0 +1,844 @@
|
||||
# Generated by Django 4.2.27 on 2026-01-23 19:32
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Chufajilu",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dashouid",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=7,
|
||||
null=True,
|
||||
verbose_name="被罚打手ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"qingqiuid",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=7,
|
||||
null=True,
|
||||
verbose_name="请求处罚ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"chuliid",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=11,
|
||||
null=True,
|
||||
verbose_name="处理处罚ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"cfliyou",
|
||||
models.TextField(blank=True, null=True, verbose_name="处罚理由"),
|
||||
),
|
||||
(
|
||||
"sqzhuangtai",
|
||||
models.IntegerField(
|
||||
blank=True,
|
||||
default=0,
|
||||
null=True,
|
||||
verbose_name="处罚申请状态:0待处理,1成功,2驳回",
|
||||
),
|
||||
),
|
||||
(
|
||||
"bhliyou",
|
||||
models.TextField(
|
||||
blank=True, null=True, verbose_name="驳回处罚理由"
|
||||
),
|
||||
),
|
||||
("jifen", models.IntegerField(default=0, verbose_name="扣除打手积分")),
|
||||
(
|
||||
"dingdan_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=32, null=True, verbose_name="订单ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"db_table": "chufajilu",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Dashoutupian",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dingdan_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=32, null=True, verbose_name="订单ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"dashou",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
null=True,
|
||||
verbose_name="接单打手ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"tupian",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
max_length=500,
|
||||
null=True,
|
||||
verbose_name="打手提交图片URL",
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"db_table": "dashoutupian",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Dingdan",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dingdan_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=32, unique=True, verbose_name="订单ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"zhuangtai",
|
||||
models.IntegerField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
default=1,
|
||||
null=True,
|
||||
verbose_name="订单状态",
|
||||
),
|
||||
),
|
||||
(
|
||||
"fadan_pingtai",
|
||||
models.IntegerField(blank=True, null=True, verbose_name="发单平台"),
|
||||
),
|
||||
(
|
||||
"jine",
|
||||
models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="订单金额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dashou_fencheng",
|
||||
models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="打手分成",
|
||||
),
|
||||
),
|
||||
(
|
||||
"jiedan_dashou_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
null=True,
|
||||
verbose_name="接单打手ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dashou_liuyan",
|
||||
models.TextField(blank=True, null=True, verbose_name="打手留言"),
|
||||
),
|
||||
(
|
||||
"zhiding_id",
|
||||
models.CharField(
|
||||
blank=True, max_length=32, null=True, verbose_name="指定ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"shangpin_id",
|
||||
models.IntegerField(blank=True, null=True, verbose_name="商品ID"),
|
||||
),
|
||||
(
|
||||
"leixing_id",
|
||||
models.PositiveIntegerField(
|
||||
blank=True, null=True, verbose_name="商品类型ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"tupian",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
max_length=500,
|
||||
null=True,
|
||||
verbose_name="商品图片URL",
|
||||
),
|
||||
),
|
||||
(
|
||||
"yaoqiuleixing",
|
||||
models.PositiveIntegerField(
|
||||
blank=True, null=True, verbose_name="抢单要求类型"
|
||||
),
|
||||
),
|
||||
(
|
||||
"huiyuan_id",
|
||||
models.CharField(
|
||||
blank=True, max_length=6, null=True, verbose_name="会员ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"yongjin",
|
||||
models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="佣金要求",
|
||||
),
|
||||
),
|
||||
(
|
||||
"jieshao",
|
||||
models.TextField(blank=True, null=True, verbose_name="订单介绍"),
|
||||
),
|
||||
(
|
||||
"beizhu",
|
||||
models.TextField(blank=True, null=True, verbose_name="订单备注"),
|
||||
),
|
||||
(
|
||||
"nicheng",
|
||||
models.CharField(
|
||||
blank=True, max_length=50, null=True, verbose_name="游戏昵称"
|
||||
),
|
||||
),
|
||||
(
|
||||
"user1_id",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=30,
|
||||
null=True,
|
||||
verbose_name="用户1标识",
|
||||
),
|
||||
),
|
||||
(
|
||||
"user2_id",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=30,
|
||||
null=True,
|
||||
verbose_name="用户2打手标识",
|
||||
),
|
||||
),
|
||||
(
|
||||
"auto_task_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
max_length=255,
|
||||
verbose_name="延时任务ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"auto_expire_at",
|
||||
models.DateTimeField(
|
||||
blank=True, null=True, verbose_name="计划过期时间"
|
||||
),
|
||||
),
|
||||
(
|
||||
"pending_dispatch",
|
||||
models.BooleanField(
|
||||
db_index=True, default=False, verbose_name="待调度标记"
|
||||
),
|
||||
),
|
||||
(
|
||||
"status_8_time",
|
||||
models.DateTimeField(
|
||||
blank=True, null=True, verbose_name="状态变为8的时间"
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "订单",
|
||||
"verbose_name_plural": "订单",
|
||||
"db_table": "dingdan",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Lilubiao",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"lilu",
|
||||
models.DecimalField(
|
||||
decimal_places=4,
|
||||
max_digits=5,
|
||||
null=True,
|
||||
verbose_name="平台分成利率,1是平台,2是商家",
|
||||
),
|
||||
),
|
||||
(
|
||||
"fadanpingtai",
|
||||
models.CharField(
|
||||
max_length=10,
|
||||
null=True,
|
||||
verbose_name="订单所属平台,(商家或平台)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"db_table": "lilubiao",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Ptliushui",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"zonge",
|
||||
models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="收取总金额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"zhichuzonge",
|
||||
models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="支出总金额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"zongshouyi",
|
||||
models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="总收益",
|
||||
),
|
||||
),
|
||||
(
|
||||
"rizonge",
|
||||
models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="日收取",
|
||||
),
|
||||
),
|
||||
(
|
||||
"rizhichu",
|
||||
models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="日支出",
|
||||
),
|
||||
),
|
||||
(
|
||||
"rishouyi",
|
||||
models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="日收益",
|
||||
),
|
||||
),
|
||||
(
|
||||
"zongshoucishu",
|
||||
models.IntegerField(default=0, verbose_name="总收取次数"),
|
||||
),
|
||||
(
|
||||
"rishoucishu",
|
||||
models.IntegerField(default=0, verbose_name="日收取次数"),
|
||||
),
|
||||
(
|
||||
"zongzhichucishu",
|
||||
models.IntegerField(default=0, verbose_name="总支出次数"),
|
||||
),
|
||||
(
|
||||
"rizhichucishu",
|
||||
models.IntegerField(default=0, verbose_name="日支出次数"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"db_table": "ptliushui",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Tuikuanjilu",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dingdan_id",
|
||||
models.CharField(max_length=32, unique=True, verbose_name="订单ID"),
|
||||
),
|
||||
(
|
||||
"dashouid",
|
||||
models.CharField(
|
||||
max_length=7, null=True, verbose_name="接单打手ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"qingqiuid",
|
||||
models.CharField(
|
||||
max_length=7, null=True, verbose_name="请求用户ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"chuliid",
|
||||
models.CharField(
|
||||
db_index=True, max_length=7, null=True, verbose_name="处理人ID"
|
||||
),
|
||||
),
|
||||
("liyou", models.TextField(blank=True, null=True, verbose_name="理由")),
|
||||
(
|
||||
"sqzhuangtai",
|
||||
models.IntegerField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
default=0,
|
||||
null=True,
|
||||
verbose_name="申请状态:0待处理,1成功,2驳回",
|
||||
),
|
||||
),
|
||||
(
|
||||
"bhliyou",
|
||||
models.TextField(blank=True, null=True, verbose_name="驳回理由"),
|
||||
),
|
||||
(
|
||||
"jine",
|
||||
models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="订单金额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dashou_fencheng",
|
||||
models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="打手分成",
|
||||
),
|
||||
),
|
||||
(
|
||||
"jieshao",
|
||||
models.TextField(blank=True, null=True, verbose_name="订单介绍"),
|
||||
),
|
||||
(
|
||||
"beizhu",
|
||||
models.TextField(blank=True, null=True, verbose_name="订单备注"),
|
||||
),
|
||||
(
|
||||
"nicheng",
|
||||
models.CharField(
|
||||
blank=True, max_length=50, null=True, verbose_name="游戏昵称"
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"db_table": "tuikuanjilu",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["chuliid"], name="tuikuanjilu_chuliid_0b0f16_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["sqzhuangtai"], name="tuikuanjilu_sqzhuan_d89dc9_idx"
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Pingfen",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dashou",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
null=True,
|
||||
verbose_name="接单打手ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"zongfen",
|
||||
models.PositiveIntegerField(default=0, verbose_name="总分"),
|
||||
),
|
||||
(
|
||||
"cishu",
|
||||
models.PositiveIntegerField(default=0, verbose_name="评分次数"),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "评分表",
|
||||
"db_table": "pingfenbiao",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["dashou"], name="pingfenbiao_dashou_f62f10_idx"
|
||||
)
|
||||
],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Liaotian",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
primary_key=True, serialize=False, verbose_name="主键ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"user1_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=30, verbose_name="用户1标识"
|
||||
),
|
||||
),
|
||||
(
|
||||
"user2_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=30, verbose_name="用户2标识"
|
||||
),
|
||||
),
|
||||
(
|
||||
"dingdan_id",
|
||||
models.CharField(max_length=32, unique=True, verbose_name="订单ID"),
|
||||
),
|
||||
(
|
||||
"zhuangtai",
|
||||
models.IntegerField(
|
||||
choices=[(1, "开启中"), (0, "已关闭")],
|
||||
db_index=True,
|
||||
default=1,
|
||||
verbose_name="聊天状态",
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"db_table": "liaotian",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["user1_id"], name="liaotian_user1_i_6be6cd_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["user2_id"], name="liaotian_user2_i_9f61a4_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["zhuangtai"], name="liaotian_zhuangt_5e8be5_idx"
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="DingdanShangjia",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shangjia_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
null=True,
|
||||
verbose_name="商家ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shangjia_pingjia",
|
||||
models.TextField(blank=True, null=True, verbose_name="商家评价"),
|
||||
),
|
||||
(
|
||||
"cfliyou",
|
||||
models.TextField(
|
||||
blank=True, null=True, verbose_name="商家处罚理由"
|
||||
),
|
||||
),
|
||||
(
|
||||
"sqzhuangtai",
|
||||
models.IntegerField(
|
||||
blank=True,
|
||||
default=0,
|
||||
null=True,
|
||||
verbose_name="处罚申请状态:0待处理,1成功,2驳回",
|
||||
),
|
||||
),
|
||||
(
|
||||
"bhliyou",
|
||||
models.TextField(
|
||||
blank=True, null=True, verbose_name="驳回商家处罚理由"
|
||||
),
|
||||
),
|
||||
(
|
||||
"sjnicheng",
|
||||
models.CharField(max_length=50, null=True, verbose_name="商家昵称"),
|
||||
),
|
||||
(
|
||||
"dingdan",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="shangjia_kuozhan",
|
||||
to="dingdan.dingdan",
|
||||
verbose_name="订单",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "商家订单扩展",
|
||||
"verbose_name_plural": "商家订单扩展",
|
||||
"db_table": "dingdan_shangjia",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="DingdanPingtai",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"laoban_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
null=True,
|
||||
verbose_name="老板ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"laoban_pingjia",
|
||||
models.TextField(blank=True, null=True, verbose_name="老板评价"),
|
||||
),
|
||||
(
|
||||
"dingdan",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="pingtai_kuozhan",
|
||||
to="dingdan.dingdan",
|
||||
verbose_name="订单",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "平台订单扩展",
|
||||
"verbose_name_plural": "平台订单扩展",
|
||||
"db_table": "dingdan_pingtai",
|
||||
},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="dingdan",
|
||||
index=models.Index(fields=["zhuangtai"], name="dingdan_zhuangt_2febe8_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="dingdan",
|
||||
index=models.Index(
|
||||
fields=["dingdan_id"], name="dingdan_dingdan_83dcb6_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="dingdan",
|
||||
index=models.Index(
|
||||
fields=["jiedan_dashou_id"], name="dingdan_jiedan__921bfa_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="dashoutupian",
|
||||
index=models.Index(fields=["dashou"], name="dashoutupia_dashou_7de8bd_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="dashoutupian",
|
||||
index=models.Index(
|
||||
fields=["dingdan_id"], name="dashoutupia_dingdan_97c685_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="chufajilu",
|
||||
index=models.Index(
|
||||
fields=["dashouid"], name="chufajilu_dashoui_07aac0_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="chufajilu",
|
||||
index=models.Index(
|
||||
fields=["qingqiuid"], name="chufajilu_qingqiu_ac160e_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="chufajilu",
|
||||
index=models.Index(fields=["chuliid"], name="chufajilu_chuliid_cd63ac_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="chufajilu",
|
||||
index=models.Index(
|
||||
fields=["dingdan_id"], name="chufajilu_dingdan_b8f0c2_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="dingdanshangjia",
|
||||
index=models.Index(
|
||||
fields=["shangjia_id"], name="dingdan_sha_shangji_64d28b_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="dingdanpingtai",
|
||||
index=models.Index(
|
||||
fields=["laoban_id"], name="dingdan_pin_laoban__d55e6f_idx"
|
||||
),
|
||||
),
|
||||
]
|
||||
20
dingdan/migrations/0002_alter_tuikuanjilu_chuliid.py
Normal file
20
dingdan/migrations/0002_alter_tuikuanjilu_chuliid.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 4.2.27 on 2026-01-30 14:09
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="tuikuanjilu",
|
||||
name="chuliid",
|
||||
field=models.CharField(
|
||||
db_index=True, max_length=11, null=True, verbose_name="处理人ID"
|
||||
),
|
||||
),
|
||||
]
|
||||
76
dingdan/migrations/0003_chufajilu_ssliyou_chufatupian.py
Normal file
76
dingdan/migrations/0003_chufajilu_ssliyou_chufatupian.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-09 18:09
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0002_alter_tuikuanjilu_chuliid"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="chufajilu",
|
||||
name="ssliyou",
|
||||
field=models.TextField(blank=True, null=True, verbose_name="打手申诉理由"),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Chufatupian",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dingdan_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=32, null=True, verbose_name="订单ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"yonghuid",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
null=True,
|
||||
verbose_name="用户ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"tupian",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
max_length=500,
|
||||
null=True,
|
||||
verbose_name="证据图片URL",
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"db_table": "chufatupian",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["yonghuid"], name="chufatupian_yonghui_71e585_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["dingdan_id"], name="chufatupian_dingdan_ce0dd4_idx"
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
]
|
||||
20
dingdan/migrations/0004_dingdan_tkly.py
Normal file
20
dingdan/migrations/0004_dingdan_tkly.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-13 23:03
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0003_chufajilu_ssliyou_chufatupian"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="dingdan",
|
||||
name="tkly",
|
||||
field=models.CharField(
|
||||
blank=True, max_length=500, null=True, verbose_name="退款/拒绝理由"
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-14 19:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0004_dingdan_tkly"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="dingdan",
|
||||
name="is_cross",
|
||||
field=models.IntegerField(
|
||||
default=0, verbose_name="是否跨平台订单(0否,1是)"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="dingdan",
|
||||
name="partner_order_id",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
null=True,
|
||||
verbose_name="对方平台订单ID",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,27 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-22 01:00
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0005_dingdan_is_cross_dingdan_partner_order_id"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="dingdan",
|
||||
name="clkf",
|
||||
field=models.CharField(
|
||||
db_index=True, max_length=20, null=True, verbose_name="处理客服"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="dingdanpingtai",
|
||||
name="jjjs_biaoshi",
|
||||
field=models.IntegerField(
|
||||
default=0, verbose_name="拒绝结算标记(1表示拒绝结算)"
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,30 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-25 16:14
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0006_dingdan_clkf_dingdanpingtai_jjjs_biaoshi"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="dingdan",
|
||||
name="wechat_transaction_id",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=64,
|
||||
null=True,
|
||||
verbose_name="微信支付订单号",
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="dingdan",
|
||||
index=models.Index(
|
||||
fields=["wechat_transaction_id"], name="dingdan_wechat__278b79_idx"
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-24 17:42
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0007_dingdan_wechat_transaction_id_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="dingdan",
|
||||
name="dispatch_type",
|
||||
field=models.IntegerField(
|
||||
choices=[(1, "我方派单"), (2, "对方派单")],
|
||||
default=0,
|
||||
verbose_name="派发情况",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="dingdan",
|
||||
name="partner_club_id",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=6,
|
||||
null=True,
|
||||
verbose_name="对方俱乐部ID",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,257 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-01 23:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0008_dingdan_dispatch_type_dingdan_partner_club_id"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="PreSettlement",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dingdan_id",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
unique=True,
|
||||
verbose_name="我方订单ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"partner_order_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=32, verbose_name="对方订单ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"partner_club_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=6, verbose_name="对方俱乐部ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"dashou_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=7, verbose_name="接单打手ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"amount",
|
||||
models.DecimalField(
|
||||
decimal_places=2, max_digits=10, verbose_name="打手应分金额"
|
||||
),
|
||||
),
|
||||
(
|
||||
"order_amount",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="订单原金额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"status",
|
||||
models.SmallIntegerField(
|
||||
choices=[(0, "待结算"), (1, "已结算"), (2, "已拒绝")],
|
||||
default=0,
|
||||
verbose_name="结算状态",
|
||||
),
|
||||
),
|
||||
(
|
||||
"process_time",
|
||||
models.DateTimeField(
|
||||
blank=True, null=True, verbose_name="处理时间"
|
||||
),
|
||||
),
|
||||
(
|
||||
"operator",
|
||||
models.CharField(
|
||||
blank=True, default="", max_length=32, verbose_name="操作人"
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "预结算表",
|
||||
"verbose_name_plural": "预结算表",
|
||||
"db_table": "pre_settlement",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["dingdan_id"], name="pre_settlem_dingdan_4f3541_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["partner_order_id"],
|
||||
name="pre_settlem_partner_45b29e_idx",
|
||||
),
|
||||
models.Index(
|
||||
fields=["partner_club_id"],
|
||||
name="pre_settlem_partner_d2c44c_idx",
|
||||
),
|
||||
models.Index(
|
||||
fields=["dashou_id"], name="pre_settlem_dashou__d5fe7c_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["status"], name="pre_settlem_status_0aa711_idx"
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="OrderDashouHistory",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dingdan_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=32, verbose_name="订单ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"dashou_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=7, verbose_name="打手ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"times",
|
||||
models.PositiveSmallIntegerField(
|
||||
verbose_name="第几次接单(从1开始)"
|
||||
),
|
||||
),
|
||||
(
|
||||
"operator",
|
||||
models.CharField(max_length=11, verbose_name="操作客服ID"),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "订单打手变更历史",
|
||||
"verbose_name_plural": "订单打手变更历史",
|
||||
"db_table": "order_dashou_history",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["dingdan_id"], name="order_dasho_dingdan_1e79ab_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["dashou_id"], name="order_dasho_dashou__0a637c_idx"
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="CrossPlatformOrderData",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dingdan_id",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
unique=True,
|
||||
verbose_name="我方订单ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"partner_order_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=32, verbose_name="对方平台订单ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"partner_club_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=6, verbose_name="对方俱乐部ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"partner_order_status",
|
||||
models.IntegerField(default=0, verbose_name="对方平台订单状态"),
|
||||
),
|
||||
(
|
||||
"partner_dashou_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
max_length=32,
|
||||
verbose_name="对方平台接单打手ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"partner_amount",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="对方平台订单金额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "跨平台订单扩展",
|
||||
"verbose_name_plural": "跨平台订单扩展",
|
||||
"db_table": "cross_platform_order_data",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["dingdan_id"], name="cross_platf_dingdan_498d08_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["partner_order_id"],
|
||||
name="cross_platf_partner_5d5615_idx",
|
||||
),
|
||||
models.Index(
|
||||
fields=["partner_club_id"],
|
||||
name="cross_platf_partner_1054e1_idx",
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 4.2.27 on 2026-04-04 15:16
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0009_presettlement_orderdashouhistory_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="presettlement",
|
||||
name="dingdan_id",
|
||||
field=models.CharField(
|
||||
db_index=True, max_length=32, verbose_name="我方订单ID"
|
||||
),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name="presettlement",
|
||||
unique_together={("dingdan_id", "dashou_id")},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,211 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-06 11:30
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0010_alter_presettlement_dingdan_id_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="dingdanshangjia",
|
||||
name="partner_yonghu_id",
|
||||
field=models.CharField(
|
||||
blank=True, max_length=32, null=True, verbose_name="对方平台用户ID"
|
||||
),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="FadanFenhong",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
primary_key=True, serialize=False, verbose_name="自增主键"
|
||||
),
|
||||
),
|
||||
(
|
||||
"fenhongzhe_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=20, verbose_name="分红者ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"zonge",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="分红总额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"ketixian_fenhong",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="可提现分红",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shenfen",
|
||||
models.IntegerField(
|
||||
choices=[(1, "商家"), (2, "客服"), (3, "平台管理者")],
|
||||
default=1,
|
||||
verbose_name="分红者身份",
|
||||
),
|
||||
),
|
||||
(
|
||||
"fenhong_cishu",
|
||||
models.IntegerField(default=0, verbose_name="分红次数"),
|
||||
),
|
||||
(
|
||||
"yingde_lilv",
|
||||
models.DecimalField(
|
||||
decimal_places=4,
|
||||
default=0.0,
|
||||
max_digits=5,
|
||||
verbose_name="分红应得利率",
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "罚款分红",
|
||||
"verbose_name_plural": "罚款分红",
|
||||
"db_table": "fadan_fenhong",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["fenhongzhe_id"], name="fadan_fenhong_zhe_idx"
|
||||
),
|
||||
models.Index(fields=["shenfen"], name="fadan_fenhong_sf_idx"),
|
||||
],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Fadan",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
primary_key=True, serialize=False, verbose_name="自增主键"
|
||||
),
|
||||
),
|
||||
(
|
||||
"beichufa_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=20, verbose_name="被处罚用户ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"shenqing_chufa",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
max_length=20,
|
||||
null=True,
|
||||
verbose_name="申请处罚者ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shenfen",
|
||||
models.IntegerField(
|
||||
choices=[(1, "打手"), (2, "管事"), (3, "商家"), (4, "组长")],
|
||||
default=1,
|
||||
verbose_name="被处罚者身份",
|
||||
),
|
||||
),
|
||||
(
|
||||
"chufaliyou",
|
||||
models.TextField(blank=True, null=True, verbose_name="处罚理由"),
|
||||
),
|
||||
(
|
||||
"fakuanjine",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="罚款金额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"guanliandingdan_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
null=True,
|
||||
verbose_name="关联订单ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"zhuangtai",
|
||||
models.IntegerField(
|
||||
choices=[
|
||||
(1, "待缴纳"),
|
||||
(2, "已缴纳"),
|
||||
(3, "申诉中"),
|
||||
(4, "已驳回"),
|
||||
],
|
||||
db_index=True,
|
||||
default=1,
|
||||
verbose_name="罚单状态",
|
||||
),
|
||||
),
|
||||
(
|
||||
"yingxiang_qiangdan",
|
||||
models.IntegerField(
|
||||
choices=[(1, "影响抢单"), (0, "不影响抢单")],
|
||||
db_index=True,
|
||||
default=1,
|
||||
verbose_name="是否影响抢单",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shensuliyou",
|
||||
models.TextField(blank=True, null=True, verbose_name="申诉理由"),
|
||||
),
|
||||
(
|
||||
"tongyi_chufaliyou",
|
||||
models.TextField(
|
||||
blank=True, null=True, verbose_name="同意处罚理由"
|
||||
),
|
||||
),
|
||||
(
|
||||
"bohuiliyou",
|
||||
models.TextField(blank=True, null=True, verbose_name="驳回理由"),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "罚单",
|
||||
"verbose_name_plural": "罚单",
|
||||
"db_table": "fadan",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["beichufa_id", "yingxiang_qiangdan", "zhuangtai"],
|
||||
name="fadan_qiangdan_check",
|
||||
),
|
||||
models.Index(
|
||||
fields=["guanliandingdan_id"], name="fadan_dingdan_idx"
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,114 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-13 08:51
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0011_dingdanshangjia_partner_yonghu_id_fadanfenhong_fadan"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="fadan",
|
||||
name="chulizhe",
|
||||
field=models.CharField(
|
||||
blank=True, max_length=20, null=True, verbose_name="处理者"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="fadan",
|
||||
name="chulizhe_shenfen",
|
||||
field=models.IntegerField(
|
||||
choices=[(1, "客服"), (2, "售后"), (3, "管理员")],
|
||||
default=2,
|
||||
verbose_name="处理者身份",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="fadan",
|
||||
name="partner_club_id",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=6,
|
||||
null=True,
|
||||
verbose_name="对方俱乐部ID",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="fadan",
|
||||
name="shenqingren_shenfen",
|
||||
field=models.IntegerField(
|
||||
choices=[
|
||||
(1, "客服"),
|
||||
(2, "售后"),
|
||||
(3, "管理员"),
|
||||
(4, "店铺"),
|
||||
(5, "商家"),
|
||||
],
|
||||
default=1,
|
||||
verbose_name="申请处罚人身份",
|
||||
),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="FadanShensuTupian",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"beichufa_id",
|
||||
models.CharField(
|
||||
db_index=True, max_length=7, verbose_name="被处罚用户ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"tupian_url",
|
||||
models.CharField(max_length=500, verbose_name="图片相对URL"),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"yongtu",
|
||||
models.IntegerField(
|
||||
choices=[(1, "处罚证据图片"), (2, "申诉图片")],
|
||||
default=2,
|
||||
verbose_name="图片用途",
|
||||
),
|
||||
),
|
||||
(
|
||||
"fadan",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="shensu_tupians",
|
||||
to="dingdan.fadan",
|
||||
verbose_name="关联罚单",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "罚款申诉图片",
|
||||
"verbose_name_plural": "罚款申诉图片",
|
||||
"db_table": "fadan_shensu_tupian",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["fadan_id"], name="fadan_shens_fadan_i_78fab9_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["beichufa_id"], name="fadan_shens_beichuf_59748e_idx"
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
]
|
||||
63
dingdan/migrations/0013_dingdanpingtai_dianpu_id_and_more.py
Normal file
63
dingdan/migrations/0013_dingdanpingtai_dianpu_id_and_more.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-19 17:30
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0012_fadan_chulizhe_fadan_chulizhe_shenfen_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="dingdanpingtai",
|
||||
name="dianpu_id",
|
||||
field=models.PositiveIntegerField(
|
||||
blank=True, db_index=True, null=True, verbose_name="所属店铺ID"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="dingdanpingtai",
|
||||
name="dianpu_shouyi",
|
||||
field=models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="店铺收益",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="dingdanpingtai",
|
||||
name="pingtai_shouyi",
|
||||
field=models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="平台收益",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="dingdanpingtai",
|
||||
name="shangji_dianpu_id",
|
||||
field=models.PositiveIntegerField(
|
||||
blank=True, db_index=True, null=True, verbose_name="该订单的上级店铺ID"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="dingdanpingtai",
|
||||
name="shangji_fenhong",
|
||||
field=models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="上级分红金额",
|
||||
),
|
||||
),
|
||||
]
|
||||
23
dingdan/migrations/0014_fadan_shenqingren_fenhong_jine.py
Normal file
23
dingdan/migrations/0014_fadan_shenqingren_fenhong_jine.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-05 13:17
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0013_dingdanpingtai_dianpu_id_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="fadan",
|
||||
name="shenqingren_fenhong_jine",
|
||||
field=models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="申请人分红金额",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,77 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-05 14:10
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0014_fadan_shenqingren_fenhong_jine"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="FadanFenhongLilv",
|
||||
fields=[
|
||||
(
|
||||
"shenfen",
|
||||
models.IntegerField(
|
||||
choices=[
|
||||
(1, "客服"),
|
||||
(2, "售后"),
|
||||
(3, "管理员"),
|
||||
(4, "店铺"),
|
||||
(5, "商家"),
|
||||
],
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="申请处罚人身份",
|
||||
),
|
||||
),
|
||||
(
|
||||
"lilv",
|
||||
models.DecimalField(
|
||||
decimal_places=4,
|
||||
default=0.0,
|
||||
max_digits=5,
|
||||
verbose_name="分红费率",
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "罚款分红费率配置",
|
||||
"verbose_name_plural": "罚款分红费率配置",
|
||||
"db_table": "fadan_fenhong_lilv",
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="fadanfenhong",
|
||||
name="is_individual_rate",
|
||||
field=models.BooleanField(
|
||||
default=False, verbose_name="是否单独开启分红利率"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="fadanfenhong",
|
||||
name="shenfen",
|
||||
field=models.IntegerField(
|
||||
choices=[
|
||||
(1, "商家"),
|
||||
(2, "客服"),
|
||||
(3, "平台管理者"),
|
||||
(4, "店铺"),
|
||||
(5, "售后"),
|
||||
],
|
||||
default=1,
|
||||
verbose_name="分红者身份",
|
||||
),
|
||||
),
|
||||
]
|
||||
25
dingdan/migrations/0016_dingdan_guanshi_fencheng.py
Normal file
25
dingdan/migrations/0016_dingdan_guanshi_fencheng.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-11 23:02
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dingdan", "0015_fadanfenhonglilv_fadanfenhong_is_individual_rate_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="dingdan",
|
||||
name="guanshi_fencheng",
|
||||
field=models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
default=0,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="管事分成",
|
||||
),
|
||||
),
|
||||
]
|
||||
0
dingdan/migrations/__init__.py
Normal file
0
dingdan/migrations/__init__.py
Normal file
539
dingdan/models.py
Normal file
539
dingdan/models.py
Normal file
@@ -0,0 +1,539 @@
|
||||
from django.db import models
|
||||
|
||||
class Dingdan(models.Model):
|
||||
"""订单主表"""
|
||||
# 核心编号:唯一且不可为空[citation:3][citation:9]
|
||||
dingdan_id = models.CharField(max_length=32, unique=True,db_index=True, verbose_name='订单ID')
|
||||
# 状态与平台:用整数表示,具体含义由业务逻辑定义
|
||||
zhuangtai = models.IntegerField(default=1, null=True, blank=True,db_index=True, verbose_name='订单状态')
|
||||
fadan_pingtai = models.IntegerField(null=True, blank=True, verbose_name='发单平台')
|
||||
# 金额相关
|
||||
jine = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='订单金额')
|
||||
dashou_fencheng = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='打手分成')
|
||||
guanshi_fencheng = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, default=0, verbose_name='管事分成')
|
||||
# 用户与商品关联ID
|
||||
jiedan_dashou_id = models.CharField(max_length=32, null=True, db_index=True,blank=True, verbose_name='接单打手ID')
|
||||
dashou_liuyan = models.TextField(null=True, blank=True, verbose_name='打手留言')
|
||||
zhiding_id = models.CharField(max_length=32, null=True, blank=True, verbose_name='指定ID')
|
||||
shangpin_id = models.IntegerField(null=True, blank=True, verbose_name='商品ID')
|
||||
leixing_id = models.PositiveIntegerField(null=True, blank=True, verbose_name='商品类型ID') # 直接存数字
|
||||
tupian = models.CharField(max_length=500, null=True, blank=True, verbose_name='商品图片URL')
|
||||
|
||||
yaoqiuleixing = models.PositiveIntegerField(null=True, blank=True, verbose_name='抢单要求类型')
|
||||
huiyuan_id = models.CharField(max_length=6, null=True, blank=True, verbose_name='会员ID')
|
||||
yongjin = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='佣金要求')
|
||||
# 订单描述信息
|
||||
jieshao = models.TextField(null=True, blank=True, verbose_name='订单介绍')
|
||||
beizhu = models.TextField(null=True, blank=True, verbose_name='订单备注')
|
||||
|
||||
|
||||
partner_order_id = models.CharField(max_length=32, null=True, blank=True, db_index=True,verbose_name='对方平台订单ID')
|
||||
is_cross = models.IntegerField(default=0, verbose_name='是否跨平台订单(0否,1是)')
|
||||
|
||||
dispatch_type = models.IntegerField(default=0, choices=[(1, '我方派单'), (2, '对方派单')], verbose_name='派发情况')
|
||||
# 🔥 新增:对方俱乐部ID
|
||||
partner_club_id = models.CharField(max_length=6, null=True, blank=True, db_index=True, verbose_name='对方俱乐部ID')
|
||||
|
||||
|
||||
|
||||
tkly = models.CharField(max_length=500, blank=True, null=True, verbose_name='退款/拒绝理由')
|
||||
# 新增字段:游戏昵称(前端提交的游戏昵称)
|
||||
nicheng = models.CharField(max_length=50, null=True, blank=True, verbose_name='游戏昵称')
|
||||
user1_id = models.CharField(max_length=30,null=True, db_index=True, verbose_name='用户1标识')
|
||||
user2_id = models.CharField(max_length=30, null=True,db_index=True, verbose_name='用户2打手标识')
|
||||
#liaotian_pindao = models.CharField(max_length=255, blank=True, null=True, verbose_name='聊天频道名')
|
||||
# 时间戳
|
||||
|
||||
auto_task_id = models.CharField('延时任务ID', max_length=255, blank=True, default='')
|
||||
auto_expire_at = models.DateTimeField('计划过期时间', null=True, blank=True)
|
||||
pending_dispatch = models.BooleanField('待调度标记', default=False, db_index=True)
|
||||
status_8_time = models.DateTimeField('状态变为8的时间', null=True, blank=True)
|
||||
|
||||
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
clkf = models.CharField(max_length=20, null=True, db_index=True, verbose_name='处理客服')
|
||||
wechat_transaction_id = models.CharField(
|
||||
max_length=64,
|
||||
blank=True,
|
||||
null=True,
|
||||
db_index=True,
|
||||
verbose_name='微信支付订单号'
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = 'dingdan'
|
||||
verbose_name = '订单'
|
||||
verbose_name_plural = '订单'
|
||||
# 为高频查询字段添加索引
|
||||
indexes = [
|
||||
models.Index(fields=['zhuangtai']),
|
||||
models.Index(fields=['dingdan_id']),
|
||||
models.Index(fields=['jiedan_dashou_id']),
|
||||
# 🆕 为新增字段添加索引(可选)
|
||||
models.Index(fields=['wechat_transaction_id']),
|
||||
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return self.dingdan_id
|
||||
|
||||
class DingdanPingtai(models.Model):
|
||||
"""平台订单扩展表 (当 fadan_pingtai=1 时使用)"""
|
||||
dingdan = models.OneToOneField(Dingdan, on_delete=models.CASCADE, related_name='pingtai_kuozhan', verbose_name='订单')
|
||||
laoban_id = models.CharField(max_length=32, null=True, blank=True, db_index=True,verbose_name='老板ID')
|
||||
laoban_pingjia = models.TextField(null=True, blank=True, verbose_name='老板评价')
|
||||
jjjs_biaoshi = models.IntegerField(default=0, verbose_name='拒绝结算标记(1表示拒绝结算)')
|
||||
|
||||
pingtai_shouyi = models.DecimalField(max_digits=10,decimal_places=2,null=True,blank=True,default=0.00,verbose_name='平台收益')
|
||||
dianpu_shouyi = models.DecimalField(max_digits=10,decimal_places=2, null=True,blank=True,default=0.00,verbose_name='店铺收益')
|
||||
dianpu_id = models.PositiveIntegerField(null=True,blank=True,db_index=True,verbose_name='所属店铺ID')
|
||||
|
||||
# ---------- 上级分红快照 ----------
|
||||
shangji_dianpu_id = models.PositiveIntegerField(null=True, blank=True, db_index=True,
|
||||
verbose_name='该订单的上级店铺ID')
|
||||
shangji_fenhong = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, default=0.00,
|
||||
verbose_name='上级分红金额')
|
||||
|
||||
class Meta:
|
||||
db_table = 'dingdan_pingtai'
|
||||
verbose_name = '平台订单扩展'
|
||||
verbose_name_plural = '平台订单扩展'
|
||||
indexes = [
|
||||
models.Index(fields=['laoban_id']),
|
||||
|
||||
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"平台扩展-{self.dingdan.dingdan_id}"
|
||||
|
||||
class DingdanShangjia(models.Model):
|
||||
"""商家发单扩展表 (当 fadan_pingtai=2 时使用)"""
|
||||
dingdan = models.OneToOneField(Dingdan, on_delete=models.CASCADE, related_name='shangjia_kuozhan', verbose_name='订单')
|
||||
shangjia_id = models.CharField(max_length=32, null=True, blank=True,db_index=True, verbose_name='商家ID')
|
||||
shangjia_pingjia = models.TextField(null=True, blank=True, verbose_name='商家评价')
|
||||
cfliyou = models.TextField(null=True, blank=True, verbose_name='商家处罚理由')
|
||||
sqzhuangtai =models.IntegerField(default=0, null=True, blank=True, verbose_name='处罚申请状态:0待处理,1成功,2驳回')
|
||||
bhliyou = models.TextField(null=True, blank=True, verbose_name='驳回商家处罚理由')
|
||||
sjnicheng =models.CharField(max_length=50,null=True, verbose_name='商家昵称')
|
||||
partner_yonghu_id = models.CharField(max_length=32, blank=True, null=True, verbose_name='对方平台用户ID')
|
||||
|
||||
class Meta:
|
||||
db_table = 'dingdan_shangjia'
|
||||
verbose_name = '商家订单扩展'
|
||||
verbose_name_plural = '商家订单扩展'
|
||||
indexes = [
|
||||
models.Index(fields=['shangjia_id']),
|
||||
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"商家扩展-{self.dingdan.dingdan_id}"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CrossPlatformOrderData(models.Model):
|
||||
"""
|
||||
跨平台订单扩展数据表
|
||||
存储我方订单与对方平台订单的关联及对方订单状态
|
||||
"""
|
||||
dingdan_id = models.CharField(max_length=32, unique=True, db_index=True, verbose_name='我方订单ID')
|
||||
partner_order_id = models.CharField(max_length=32, db_index=True, verbose_name='对方平台订单ID')
|
||||
partner_club_id = models.CharField(max_length=6, db_index=True, verbose_name='对方俱乐部ID')
|
||||
partner_order_status = models.IntegerField(default=0, verbose_name='对方平台订单状态') # 对方订单当前状态码
|
||||
partner_dashou_id = models.CharField(max_length=32, blank=True, default='', verbose_name='对方平台接单打手ID')
|
||||
partner_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='对方平台订单金额')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
|
||||
class Meta:
|
||||
db_table = 'cross_platform_order_data'
|
||||
verbose_name = '跨平台订单扩展'
|
||||
verbose_name_plural = '跨平台订单扩展'
|
||||
indexes = [
|
||||
models.Index(fields=['dingdan_id']),
|
||||
models.Index(fields=['partner_order_id']),
|
||||
models.Index(fields=['partner_club_id']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.dingdan_id} -> {self.partner_order_id}"
|
||||
|
||||
|
||||
|
||||
|
||||
# 建议路径:dingdan/models.py 或 独立 fadan/models.py
|
||||
from django.db import models
|
||||
|
||||
class Fadan(models.Model):
|
||||
"""罚单表——平台各类处罚信息"""
|
||||
id = models.AutoField(primary_key=True, verbose_name='自增主键')
|
||||
beichufa_id = models.CharField(max_length=20, db_index=True, verbose_name='被处罚用户ID') # 直接用yonghuid,后续可改为外键
|
||||
shenqing_chufa = models.CharField(max_length=20, blank=True, null=True, verbose_name='申请处罚者ID')
|
||||
shenfen = models.IntegerField(choices=[(1, '打手'), (2, '管事'), (3, '商家'), (4, '组长')], default=1, verbose_name='被处罚者身份')
|
||||
chufaliyou = models.TextField(blank=True, null=True, verbose_name='处罚理由')
|
||||
fakuanjine = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='罚款金额')
|
||||
guanliandingdan_id = models.CharField(max_length=32, blank=True, null=True, db_index=True, verbose_name='关联订单ID')
|
||||
zhuangtai = models.IntegerField(choices=[(1, '待缴纳'), (2, '已缴纳'), (3, '申诉中'), (4, '已驳回')], default=1, db_index=True, verbose_name='罚单状态')
|
||||
yingxiang_qiangdan = models.IntegerField(choices=[(1, '影响抢单'), (0, '不影响抢单')], default=1, db_index=True, verbose_name='是否影响抢单')
|
||||
shensuliyou = models.TextField(blank=True, null=True, verbose_name='申诉理由')
|
||||
tongyi_chufaliyou = models.TextField(blank=True, null=True, verbose_name='同意处罚理由')
|
||||
bohuiliyou = models.TextField(blank=True, null=True, verbose_name='驳回理由')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
# 在 Fadan 模型中添加
|
||||
partner_club_id = models.CharField(max_length=6, blank=True, null=True, db_index=True, verbose_name='对方俱乐部ID')
|
||||
# 在 class Fadan 中添加
|
||||
shenqingren_shenfen = models.IntegerField(
|
||||
choices=[(1, '客服'), (2, '售后'), (3, '管理员'),(4,'店铺'),(5,'商家')], # 按实际扩展
|
||||
default=1,
|
||||
verbose_name='申请处罚人身份'
|
||||
)
|
||||
chulizhe_shenfen = models.IntegerField(
|
||||
choices=[(1, '客服'), (2, '售后'), (3, '管理员')],
|
||||
default=2,
|
||||
verbose_name='处理者身份'
|
||||
)
|
||||
chulizhe = models.CharField(max_length=20, blank=True, null=True, verbose_name='处理者')
|
||||
# ========== 新增字段 ==========
|
||||
shenqingren_fenhong_jine = models.DecimalField(
|
||||
max_digits=12, decimal_places=2, default=0.00,
|
||||
verbose_name='申请人分红金额'
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = 'fadan'
|
||||
verbose_name = '罚单'
|
||||
verbose_name_plural = '罚单'
|
||||
indexes = [
|
||||
models.Index(fields=['beichufa_id', 'yingxiang_qiangdan', 'zhuangtai'], name='fadan_qiangdan_check'),
|
||||
models.Index(fields=['guanliandingdan_id'], name='fadan_dingdan_idx'),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.beichufa_id} - 罚款{self.fakuanjine}元 - 状态{self.zhuangtai}"
|
||||
|
||||
|
||||
|
||||
# ==================== 罚款申诉图片表 ====================
|
||||
class FadanShensuTupian(models.Model):
|
||||
"""罚款申诉图片,关联罚单"""
|
||||
fadan = models.ForeignKey(Fadan, on_delete=models.CASCADE, related_name='shensu_tupians', verbose_name='关联罚单')
|
||||
beichufa_id = models.CharField(max_length=7, db_index=True, verbose_name='被处罚用户ID') # 冗余,便于直接按用户查
|
||||
tupian_url = models.CharField(max_length=500, verbose_name='图片相对URL')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
# 在 FadanShensuTupian 模型中添加
|
||||
yongtu = models.IntegerField(
|
||||
choices=[(1, '处罚证据图片'), (2, '申诉图片')],
|
||||
default=2,
|
||||
verbose_name='图片用途'
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = 'fadan_shensu_tupian'
|
||||
verbose_name = '罚款申诉图片'
|
||||
verbose_name_plural = '罚款申诉图片'
|
||||
indexes = [
|
||||
models.Index(fields=['fadan_id']),
|
||||
models.Index(fields=['beichufa_id']),
|
||||
]
|
||||
|
||||
|
||||
|
||||
# 与 Fadan 放在同一个文件或独立的 fadan/models.py
|
||||
class FadanFenhong(models.Model):
|
||||
"""罚款分红表——记录罚款产生的分红信息"""
|
||||
id = models.AutoField(primary_key=True, verbose_name='自增主键')
|
||||
fenhongzhe_id = models.CharField(max_length=20, db_index=True, verbose_name='分红者ID')
|
||||
zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='分红总额')
|
||||
ketixian_fenhong = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='可提现分红')
|
||||
shenfen = models.IntegerField(choices=[(1, '商家'), (2, '客服'), (3, '平台管理者'),(4,'店铺'),(5, '售后')], default=1, verbose_name='分红者身份')
|
||||
fenhong_cishu = models.IntegerField(default=0, verbose_name='分红次数')
|
||||
# ✅ 新增字段:是否单独开启分红利率(若开启,则使用本记录的 yingde_lilv;否则使用全局配置)
|
||||
is_individual_rate = models.BooleanField(default=False, verbose_name='是否单独开启分红利率')
|
||||
yingde_lilv = models.DecimalField(max_digits=5, decimal_places=4, default=0.0000, verbose_name='分红应得利率')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
|
||||
class Meta:
|
||||
db_table = 'fadan_fenhong'
|
||||
verbose_name = '罚款分红'
|
||||
verbose_name_plural = '罚款分红'
|
||||
indexes = [
|
||||
models.Index(fields=['fenhongzhe_id'], name='fadan_fenhong_zhe_idx'),
|
||||
models.Index(fields=['shenfen'], name='fadan_fenhong_sf_idx'),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.fenhongzhe_id} - 分红{self.ketixian_fenhong}元"
|
||||
|
||||
|
||||
|
||||
|
||||
class FadanFenhongLilv(models.Model):
|
||||
shenfen = models.IntegerField(primary_key=True, choices=[(1, '客服'), (2, '售后'), (3, '管理员'), (4, '店铺'), (5, '商家')], verbose_name='申请处罚人身份')
|
||||
lilv = models.DecimalField(max_digits=5, decimal_places=4, default=0.0000, verbose_name='分红费率')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
update_time = 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.shenfen} - 费率{self.lilv}"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# apps/dingdan/models.py 中添加
|
||||
|
||||
class PreSettlement(models.Model):
|
||||
"""
|
||||
预结算表
|
||||
用于记录对方平台派单订单的待结算款项,等待对方确认后才能真正入账
|
||||
"""
|
||||
STATUS_CHOICES = (
|
||||
(0, '待结算'),
|
||||
(1, '已结算'),
|
||||
(2, '已拒绝'),
|
||||
)
|
||||
# 我方订单ID
|
||||
dingdan_id = models.CharField(max_length=32, db_index=True, verbose_name='我方订单ID')
|
||||
# 对方订单ID
|
||||
partner_order_id = models.CharField(max_length=32, db_index=True, verbose_name='对方订单ID')
|
||||
# 对方俱乐部ID
|
||||
partner_club_id = models.CharField(max_length=6, db_index=True, verbose_name='对方俱乐部ID')
|
||||
# 接单打手ID
|
||||
dashou_id = models.CharField(max_length=7, db_index=True, verbose_name='接单打手ID')
|
||||
# 打手应分金额
|
||||
amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='打手应分金额')
|
||||
# 订单金额(原金额,可选)
|
||||
order_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='订单原金额')
|
||||
# 结算状态
|
||||
status = models.SmallIntegerField(choices=STATUS_CHOICES, default=0, verbose_name='结算状态')
|
||||
# 处理时间(结算或拒绝的时间)
|
||||
process_time = models.DateTimeField(null=True, blank=True, verbose_name='处理时间')
|
||||
# 处理客服/对方操作人(可选)
|
||||
operator = models.CharField(max_length=32, blank=True, default='', verbose_name='操作人')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
|
||||
class Meta:
|
||||
db_table = 'pre_settlement'
|
||||
verbose_name = '预结算表'
|
||||
verbose_name_plural = verbose_name
|
||||
unique_together = [['dingdan_id', 'dashou_id']]
|
||||
indexes = [
|
||||
models.Index(fields=['dingdan_id']),
|
||||
models.Index(fields=['partner_order_id']),
|
||||
models.Index(fields=['partner_club_id']),
|
||||
models.Index(fields=['dashou_id']),
|
||||
models.Index(fields=['status']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"预结算-{self.dingdan_id} -> {self.partner_order_id}"
|
||||
|
||||
|
||||
# apps/dingdan/models.py 中添加
|
||||
|
||||
class OrderDashouHistory(models.Model):
|
||||
"""
|
||||
订单打手变更历史表
|
||||
记录订单每次更换打手的操作
|
||||
"""
|
||||
dingdan_id = models.CharField(max_length=32, db_index=True, verbose_name='订单ID')
|
||||
dashou_id = models.CharField(max_length=7, db_index=True, verbose_name='打手ID')
|
||||
times = models.PositiveSmallIntegerField(verbose_name='第几次接单(从1开始)')
|
||||
operator = models.CharField(max_length=11, verbose_name='操作客服ID')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
|
||||
class Meta:
|
||||
db_table = 'order_dashou_history'
|
||||
verbose_name = '订单打手变更历史'
|
||||
verbose_name_plural = '订单打手变更历史'
|
||||
indexes = [
|
||||
models.Index(fields=['dingdan_id']),
|
||||
models.Index(fields=['dashou_id']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.dingdan_id} -> {self.dashou_id} 第{self.times}次"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Dashoutupian(models.Model):
|
||||
dingdan_id = models.CharField(max_length=32,db_index=True, null=True, verbose_name='订单ID')
|
||||
dashou = models.CharField(max_length=32, null=True, blank=True,db_index=True, verbose_name='接单打手ID')
|
||||
tupian = models.CharField(max_length=500, null=True, blank=True, verbose_name='打手提交图片URL')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
class Meta:
|
||||
db_table = 'dashoutupian'
|
||||
|
||||
indexes = [
|
||||
models.Index(fields=['dashou']),
|
||||
models.Index(fields=['dingdan_id']),
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
class Pingfen(models.Model):
|
||||
dashou = models.CharField(max_length=32, null=True, blank=True, db_index=True,verbose_name='接单打手ID')
|
||||
zongfen = models.PositiveIntegerField(default=0, verbose_name='总分')
|
||||
cishu = models.PositiveIntegerField(default=0, verbose_name='评分次数')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
|
||||
class Meta:
|
||||
db_table = 'pingfenbiao'
|
||||
verbose_name = '评分表'
|
||||
indexes = [
|
||||
models.Index(fields=['dashou']),
|
||||
]
|
||||
def __str__(self):
|
||||
return f"{self.dashou} - 平均分: {self.pingjun_fen():.2f}"
|
||||
|
||||
def pingjun_fen(self):
|
||||
"""计算平均分"""
|
||||
if self.cishu > 0:
|
||||
return float(self.zongfen) / self.cishu
|
||||
return 0.0
|
||||
|
||||
|
||||
|
||||
class Lilubiao(models.Model):
|
||||
lilu = models.DecimalField(max_digits=5, decimal_places=4,null=True, verbose_name='平台分成利率,1是平台,2是商家')
|
||||
#sahngjialilu = models.DecimalField(max_digits=5, decimal_places=4,null=True, verbose_name='商家利率')
|
||||
fadanpingtai = models.CharField(max_length=10,null=True,verbose_name='订单所属平台,(商家或平台)')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
class Meta:
|
||||
db_table = 'lilubiao'
|
||||
|
||||
|
||||
|
||||
|
||||
class Chufajilu(models.Model):
|
||||
dashouid = models.CharField(max_length=7, null=True, db_index=True, verbose_name='被罚打手ID')
|
||||
qingqiuid = models.CharField(max_length=7, null=True, db_index=True, verbose_name='请求处罚ID')
|
||||
chuliid = models.CharField(max_length=11, null=True, db_index=True, verbose_name='处理处罚ID')
|
||||
cfliyou = models.TextField(null=True, blank=True, verbose_name='处罚理由')
|
||||
sqzhuangtai = models.IntegerField(default=0, null=True, blank=True, verbose_name='处罚申请状态:0待处理,1成功,2驳回')
|
||||
bhliyou = models.TextField(null=True, blank=True, verbose_name='驳回处罚理由')
|
||||
ssliyou = models.TextField(null=True, blank=True, verbose_name='打手申诉理由')
|
||||
jifen = models.IntegerField(default=0, verbose_name='扣除打手积分')
|
||||
dingdan_id = models.CharField(max_length=32, null=True, db_index=True, verbose_name='订单ID')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
class Meta:
|
||||
db_table = 'chufajilu'
|
||||
indexes = [
|
||||
models.Index(fields=['dashouid']),
|
||||
models.Index(fields=['qingqiuid']),
|
||||
models.Index(fields=['chuliid']),
|
||||
models.Index(fields=['dingdan_id']),
|
||||
]
|
||||
|
||||
|
||||
|
||||
class Chufatupian(models.Model):
|
||||
dingdan_id = models.CharField(max_length=32,db_index=True, null=True, verbose_name='订单ID')
|
||||
yonghuid = models.CharField(max_length=32, null=True, blank=True,db_index=True, verbose_name='用户ID')
|
||||
tupian = models.CharField(max_length=500, null=True, blank=True, verbose_name='证据图片URL')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
class Meta:
|
||||
db_table = 'chufatupian'
|
||||
|
||||
indexes = [
|
||||
models.Index(fields=['yonghuid']),
|
||||
models.Index(fields=['dingdan_id']),
|
||||
|
||||
]
|
||||
|
||||
class Tuikuanjilu(models.Model):
|
||||
dingdan_id = models.CharField(max_length=32, unique=True, verbose_name='订单ID')
|
||||
dashouid = models.CharField(max_length=7, null=True, verbose_name='接单打手ID')
|
||||
qingqiuid = models.CharField(max_length=7, null=True, verbose_name='请求用户ID')
|
||||
chuliid = models.CharField(max_length=11, null=True, db_index=True, verbose_name='处理人ID')
|
||||
liyou = models.TextField(null=True, blank=True, verbose_name='理由')
|
||||
sqzhuangtai = models.IntegerField(default=0, null=True, blank=True,db_index=True, verbose_name='申请状态:0待处理,1成功,2驳回')
|
||||
bhliyou = models.TextField(null=True, blank=True, verbose_name='驳回理由')
|
||||
jine = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='订单金额')
|
||||
dashou_fencheng = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='打手分成')
|
||||
jieshao = models.TextField(null=True, blank=True, verbose_name='订单介绍')
|
||||
beizhu = models.TextField(null=True, blank=True, verbose_name='订单备注')
|
||||
# 新增字段:游戏昵称(前端提交的游戏昵称)
|
||||
nicheng = models.CharField(max_length=50, null=True, blank=True, verbose_name='游戏昵称')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
class Meta:
|
||||
db_table = 'tuikuanjilu'
|
||||
indexes = [
|
||||
models.Index(fields=['chuliid']),
|
||||
models.Index(fields=['sqzhuangtai']),
|
||||
]
|
||||
|
||||
|
||||
class Ptliushui(models.Model):
|
||||
zonge = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='收取总金额')
|
||||
zhichuzonge = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='支出总金额')
|
||||
zongshouyi = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='总收益')
|
||||
rizonge = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='日收取')
|
||||
rizhichu = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='日支出')
|
||||
rishouyi = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='日收益')
|
||||
zongshoucishu = models.IntegerField(default=0, verbose_name='总收取次数')
|
||||
rishoucishu = models.IntegerField(default=0, verbose_name='日收取次数')
|
||||
zongzhichucishu = models.IntegerField(default=0, verbose_name='总支出次数')
|
||||
rizhichucishu = models.IntegerField(default=0, verbose_name='日支出次数')
|
||||
class Meta:
|
||||
db_table = 'ptliushui'
|
||||
|
||||
|
||||
# models.py - ChatRelation 模型
|
||||
|
||||
|
||||
|
||||
class Liaotian(models.Model):
|
||||
"""聊天关系表 - 极简设计,不设置唯一约束"""
|
||||
# 主键
|
||||
id = models.BigAutoField(primary_key=True, verbose_name='主键ID')
|
||||
|
||||
# 聊天双方的用户标识(GoEasy的user_id)
|
||||
user1_id = models.CharField(max_length=30, db_index=True, verbose_name='用户1标识')
|
||||
user2_id = models.CharField(max_length=30, db_index=True, verbose_name='用户2标识')
|
||||
|
||||
# 关联的订单(可以为空,但实际业务中应该关联)
|
||||
dingdan_id = models.CharField(max_length=32, unique=True, verbose_name='订单ID')
|
||||
# 状态与平台:用整数表示,具体含义由业务逻辑定义
|
||||
zhuangtai = models.IntegerField(default=1,db_index=True,choices=[(1, '开启中'), (0, '已关闭')],verbose_name='聊天状态')
|
||||
# 时间戳
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
|
||||
class Meta:
|
||||
db_table = 'liaotian'
|
||||
indexes = [
|
||||
models.Index(fields=['user1_id']),
|
||||
models.Index(fields=['user2_id']),
|
||||
models.Index(fields=['zhuangtai']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.user1_id} ↔ {self.user2_id} ({self.zhuangtai})'
|
||||
|
||||
|
||||
|
||||
272
dingdan/signals.py
Normal file
272
dingdan/signals.py
Normal file
@@ -0,0 +1,272 @@
|
||||
"""
|
||||
阿龙电竞 - 订单信号处理(优化版)
|
||||
核心原则:绝对不影响订单提交的性能和稳定性
|
||||
设计理念:订单状态变化只记录,不执行,由接口或定时任务处理具体逻辑
|
||||
"""
|
||||
|
||||
from django.db.models.signals import pre_save
|
||||
from django.dispatch import receiver
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
import logging
|
||||
import threading
|
||||
import time
|
||||
|
||||
from dingdan.models import Dingdan
|
||||
|
||||
# dingdan/signals.py
|
||||
"""
|
||||
阿龙电竞 - 订单信号处理器(生产稳定版)
|
||||
经过验证,100%可靠
|
||||
"""
|
||||
|
||||
import sys
|
||||
import importlib
|
||||
import logging
|
||||
from django.db.models.signals import pre_save
|
||||
from django.dispatch import receiver
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# 🔧 关键修复:确保redis模块正确加载
|
||||
def ensure_redis_loaded():
|
||||
"""确保redis模块正确加载,避免导入冲突"""
|
||||
if 'redis' not in sys.modules:
|
||||
# 如果redis模块未加载,尝试导入
|
||||
try:
|
||||
import redis
|
||||
#logger.debug("✅ Redis模块正常加载")
|
||||
except ImportError:
|
||||
#logger.warning("⚠️ Redis模块未安装,尝试自动安装")
|
||||
import subprocess
|
||||
subprocess.call([sys.executable, "-m", "pip", "install", "redis==4.5.4", "-q"])
|
||||
import redis
|
||||
|
||||
# 确保redis.Redis属性存在
|
||||
import redis
|
||||
if redis.Redis is None:
|
||||
#logger.warning("⚠️ Redis.Redis属性为None,强制重新加载模块")
|
||||
importlib.reload(redis)
|
||||
|
||||
return redis
|
||||
|
||||
|
||||
# 预加载redis模块
|
||||
ensure_redis_loaded()
|
||||
|
||||
|
||||
@receiver(pre_save, sender='dingdan.Dingdan')
|
||||
def handle_order_status_8(sender, instance, **kwargs):
|
||||
"""
|
||||
订单状态变为8时,提交定时任务
|
||||
"""
|
||||
# 跳过新增的订单
|
||||
if instance.pk is None:
|
||||
return
|
||||
|
||||
try:
|
||||
# 动态导入,避免循环依赖
|
||||
from dingdan.models import Dingdan
|
||||
|
||||
# 获取旧状态
|
||||
old = Dingdan.objects.filter(pk=instance.pk).values_list('zhuangtai', flat=True).first()
|
||||
|
||||
# 状态从 非8 变为 8
|
||||
if old != 8 and instance.zhuangtai == 8:
|
||||
logger.info(f"📅 订单 {instance.dingdan_id} 状态变为8,提交定时任务")
|
||||
|
||||
# 设置时间标记
|
||||
instance.status_8_time = timezone.now()
|
||||
instance.pending_dispatch = True
|
||||
|
||||
# 使用配置中的超时时间
|
||||
expire_seconds = getattr(settings, 'ORDER_EXPIRE_SECONDS', 48 * 60 * 60)
|
||||
|
||||
# 提交Celery任务
|
||||
try:
|
||||
from dingdan.tasks import process_expired_order
|
||||
|
||||
task_result = process_expired_order.apply_async(
|
||||
args=[instance.dingdan_id],
|
||||
countdown=expire_seconds,
|
||||
queue='order_tasks',
|
||||
priority=9
|
||||
)
|
||||
|
||||
logger.info(f"✅ 任务提交成功,订单: {instance.dingdan_id}, 任务ID: {task_result.id}")
|
||||
|
||||
# 保存任务信息
|
||||
instance.auto_task_id = task_result.id
|
||||
instance.auto_expire_at = timezone.now() + timezone.timedelta(seconds=expire_seconds)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ 任务提交失败: {e}")
|
||||
instance.pending_dispatch = True
|
||||
instance.auto_task_id = f"failed_{timezone.now().timestamp()}"
|
||||
|
||||
# 状态从 8 变为 非8
|
||||
elif old == 8 and instance.zhuangtai != 8:
|
||||
instance.status_8_time = None
|
||||
instance.pending_dispatch = False
|
||||
instance.auto_task_id = ''
|
||||
logger.info(f"📅 订单 {instance.dingdan_id} 状态离开8")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"信号处理失败: {e}")
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
'''def try_start_celery_task_async(dingdan_id, countdown):
|
||||
"""
|
||||
异步尝试启动Celery任务(在独立线程中运行)
|
||||
如果Redis不可用,立即失败,不影响主流程
|
||||
"""
|
||||
def _async_task():
|
||||
try:
|
||||
# 设置超时时间(500毫秒),避免长时间等待
|
||||
import socket
|
||||
socket.setdefaulttimeout(0.5)
|
||||
|
||||
from dingdan.tasks import process_expired_order
|
||||
from celery.exceptions import TimeoutError
|
||||
|
||||
# 尝试启动任务,设置极短的超时
|
||||
task = process_expired_order.apply_async(
|
||||
args=[dingdan_id],
|
||||
countdown=countdown,
|
||||
queue='order_tasks',
|
||||
priority=9,
|
||||
expires=countdown + 3600 # 任务1小时后过期,避免堆积
|
||||
)
|
||||
|
||||
# 不等待任务结果,立即返回
|
||||
logger.info(f"订单 {dingdan_id} 异步任务已提交(任务ID: {task.id})")
|
||||
|
||||
except Exception as e:
|
||||
# 记录警告,但不要影响主流程
|
||||
logger.warning(f"订单 {dingdan_id} 异步任务提交失败: {str(e)}")
|
||||
# 这个失败不影响订单保存,系统有补偿机制
|
||||
|
||||
# 启动异步线程(后台运行,不阻塞主流程)
|
||||
thread = threading.Thread(target=_async_task)
|
||||
thread.daemon = True # 设置为守护线程,主线程退出时会自动结束
|
||||
thread.start()
|
||||
|
||||
@receiver(pre_save, sender=Dingdan)
|
||||
def handle_order_status_change_lightweight(sender, instance, **kwargs):
|
||||
"""
|
||||
轻量级订单状态变化监听器
|
||||
设计原则:
|
||||
1. 绝对不阻塞订单保存
|
||||
2. 不依赖外部服务可用性
|
||||
3. 只记录,不执行
|
||||
"""
|
||||
try:
|
||||
# 1. 快速检查:如果是新建订单,直接返回
|
||||
if instance.pk is None:
|
||||
return
|
||||
|
||||
# 2. 快速获取旧状态(使用数据库当前值,不加载完整对象)
|
||||
try:
|
||||
old_status = Dingdan.objects.filter(pk=instance.pk).values_list('zhuangtai', flat=True).first()
|
||||
except Exception:
|
||||
old_status = None
|
||||
|
||||
# 3. 状态变化判断
|
||||
if old_status is None or old_status != instance.zhuangtai:
|
||||
# 状态发生变化,记录到订单扩展字段或日志(但不要阻塞)
|
||||
try:
|
||||
# 这里只是示例,实际可以根据需要记录状态变化历史
|
||||
pass
|
||||
except:
|
||||
pass # 即使记录失败也不影响主流程
|
||||
|
||||
# 4. 特殊状态处理:状态变为8
|
||||
if old_status != 8 and instance.zhuangtai == 8:
|
||||
# 4.1 立即记录日志(不等待)
|
||||
logger.info(f"订单 {instance.dingdan_id} 状态变为8")
|
||||
|
||||
# 4.2 异步尝试启动定时任务(不阻塞主流程)
|
||||
# 使用线程池或直接新线程,确保不阻塞
|
||||
try:
|
||||
# 启动异步线程尝试提交Celery任务
|
||||
if hasattr(settings, 'CELERY_BROKER_URL') and settings.CELERY_BROKER_URL:
|
||||
# 在独立线程中尝试,完全不阻塞
|
||||
threading.Thread(
|
||||
target=try_start_celery_task_async,
|
||||
args=(instance.dingdan_id, settings.ORDER_EXPIRE_SECONDS),
|
||||
daemon=True
|
||||
).start()
|
||||
except Exception as e:
|
||||
# 即使线程启动失败也不影响主流程
|
||||
logger.warning(f"启动异步任务线程失败: {str(e)}")
|
||||
|
||||
# 5. 状态从8变为其他
|
||||
elif old_status == 8 and instance.zhuangtai != 8:
|
||||
# 状态不再是8,记录日志即可
|
||||
# 定时任务执行时会检查状态,如果不是8会自动跳过
|
||||
logger.info(f"订单 {instance.dingdan_id} 状态从8变为{instance.zhuangtai}")
|
||||
|
||||
except Exception as e:
|
||||
# 捕获所有异常,确保不影响订单保存
|
||||
# 只记录错误,不抛出异常
|
||||
logger.error(f"信号处理异常(已捕获,不影响订单): {str(e)}")'''
|
||||
|
||||
|
||||
'''from django.db.models.signals import pre_save
|
||||
from django.dispatch import receiver
|
||||
from django.conf import settings
|
||||
import logging
|
||||
|
||||
from dingdan.models import Dingdan
|
||||
from dingdan.tasks import process_expired_order
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@receiver(pre_save, sender=Dingdan)
|
||||
def handle_order_status_change(sender, instance, **kwargs):
|
||||
"""
|
||||
监听订单状态变化
|
||||
当状态变为8时:启动48小时延时任务
|
||||
当状态从8变为其他时:任务执行时会自动跳过,无需取消
|
||||
"""
|
||||
try:
|
||||
# 如果是新建订单,没有旧记录,直接返回
|
||||
if instance.pk is None:
|
||||
return
|
||||
|
||||
# 获取数据库中旧的订单记录
|
||||
old_instance = Dingdan.objects.get(pk=instance.pk)
|
||||
|
||||
# ============ 状态从非8变为8 ============
|
||||
if old_instance.zhuangtai != 8 and instance.zhuangtai == 8:
|
||||
# 启动48小时后的延时任务(countdown单位:秒)
|
||||
task = process_expired_order.apply_async(
|
||||
args=[instance.dingdan_id],
|
||||
countdown=settings.ORDER_EXPIRE_SECONDS, # 172800秒 = 48小时
|
||||
queue='order_tasks',
|
||||
priority=9 # 高优先级
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"订单 {instance.dingdan_id} 状态变为8,已启动48小时延时任务,"
|
||||
f"任务ID: {task.id}"
|
||||
)
|
||||
|
||||
# 记录任务启动成功(可选,可以存储到订单表或日志表)
|
||||
|
||||
# ============ 状态从8变为其他 ============
|
||||
# 我们不需要取消任务,因为任务执行时会检查状态是否为8
|
||||
# 如果不是状态8,任务会自动跳过处理
|
||||
|
||||
except Dingdan.DoesNotExist:
|
||||
# 新订单,无需处理
|
||||
pass
|
||||
except Exception as e:
|
||||
logger.error(f"处理订单状态变化信号失败,订单ID: {instance.dingdan_id if hasattr(instance, 'dingdan_id') else '未知'}, 错误: {str(e)}")
|
||||
# 不抛出异常,避免影响订单保存的主流程
|
||||
# 信号处理失败不影响订单保存,有周期性检查作为备用方案'''
|
||||
208
dingdan/tasks.py
Normal file
208
dingdan/tasks.py
Normal file
@@ -0,0 +1,208 @@
|
||||
"""
|
||||
阿龙电竞 - 订单定时任务
|
||||
处理订单超时自动确认等逻辑
|
||||
完整版本,包含所有必要的异常处理
|
||||
"""
|
||||
|
||||
from celery import shared_task
|
||||
from django.db import transaction
|
||||
from django.db.models import F, Q
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
from decimal import Decimal
|
||||
import logging
|
||||
|
||||
# 导入模型 - 确保路径正确
|
||||
from dingdan.models import Dingdan, DingdanShangjia
|
||||
from yonghu.models import UserMain, UserDashou, UserShangjia
|
||||
from utils.celery_utils import safe_decimal_operation, log_task_execution, rollback_on_failure
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@shared_task(bind=True, max_retries=3, default_retry_delay=60)
|
||||
def process_expired_order(self, dingdan_id):
|
||||
"""
|
||||
处理单个超时订单(订单状态=8,超过48小时未处理)
|
||||
"""
|
||||
|
||||
|
||||
try:
|
||||
# 使用select_for_update锁定记录,防止并发修改
|
||||
with transaction.atomic():
|
||||
|
||||
# 获取订单,同时锁定记录
|
||||
order = Dingdan.objects.select_for_update().get(
|
||||
dingdan_id=dingdan_id
|
||||
)
|
||||
|
||||
|
||||
|
||||
# 其余代码不变...
|
||||
# ... 保持原有代码
|
||||
|
||||
|
||||
|
||||
# 再次检查订单状态是否为8
|
||||
if order.zhuangtai != 8:
|
||||
logger.info(f"订单{dingdan_id}状态已不是8(当前:{order.zhuangtai}),跳过处理")
|
||||
return f"订单{dingdan_id}状态已变更,跳过处理"
|
||||
|
||||
# 获取发单平台类型
|
||||
fadan_pingtai = order.fadan_pingtai
|
||||
|
||||
# 获取打手ID和分成金额
|
||||
dashou_id = order.jiedan_dashou_id
|
||||
dashou_fencheng = safe_decimal_operation(order.dashou_fencheng)
|
||||
|
||||
# 1. 更新订单状态为3(已完成)
|
||||
order.zhuangtai = 3
|
||||
order.save(update_fields=['zhuangtai'])
|
||||
|
||||
# 2. 更新打手信息(如果存在)
|
||||
updated_dashou = False
|
||||
if dashou_id:
|
||||
try:
|
||||
# 查询打手用户主表
|
||||
dashou_user = UserMain.objects.filter(yonghuid=dashou_id).first()
|
||||
if dashou_user:
|
||||
# 获取打手扩展表
|
||||
dashou_profile = getattr(dashou_user, 'dashou_profile', None)
|
||||
if dashou_profile:
|
||||
# 使用F表达式原子更新
|
||||
UserDashou.objects.filter(pk=dashou_profile.pk).update(
|
||||
chengjiaozongliang=F('chengjiaozongliang') + 1,
|
||||
yue=F('yue') + dashou_fencheng,
|
||||
zonge=F('zonge') + dashou_fencheng,
|
||||
jinrishouyi=F('jinrishouyi') + dashou_fencheng,
|
||||
jinyueshouyi=F('jinyueshouyi') + dashou_fencheng
|
||||
)
|
||||
updated_dashou = True
|
||||
logger.info(f"更新打手{dashou_id}信息成功")
|
||||
except Exception as e:
|
||||
logger.error(f"更新打手信息失败,打手ID: {dashou_id}, 错误: {str(e)}")
|
||||
# 继续执行,不中断流程
|
||||
|
||||
# 3. 如果是商家发单,更新商家信息
|
||||
updated_shangjia = False
|
||||
if fadan_pingtai == 2: # 商家发单
|
||||
try:
|
||||
# 获取商家扩展信息
|
||||
shangjia_kuozhan = getattr(order, 'shangjia_kuozhan', None)
|
||||
if shangjia_kuozhan:
|
||||
shangjia_id = shangjia_kuozhan.shangjia_id
|
||||
if shangjia_id:
|
||||
# 查询商家用户
|
||||
shangjia_user = UserMain.objects.filter(yonghuid=shangjia_id).first()
|
||||
if shangjia_user:
|
||||
shangjia_profile = getattr(shangjia_user, 'shop_profile', None)
|
||||
if shangjia_profile:
|
||||
# 更新商家成交订单数量
|
||||
UserShangjia.objects.filter(pk=shangjia_profile.pk).update(
|
||||
chengjiao=F('chengjiao') + 1
|
||||
)
|
||||
updated_shangjia = True
|
||||
logger.info(f"更新商家{shangjia_id}信息成功")
|
||||
except Exception as e:
|
||||
logger.error(f"更新商家信息失败,订单ID: {dingdan_id}, 错误: {str(e)}")
|
||||
# 继续执行,不中断流程
|
||||
|
||||
# 记录任务执行结果
|
||||
result_msg = f"订单{dingdan_id}自动结算完成"
|
||||
if updated_dashou:
|
||||
result_msg += ",打手信息已更新"
|
||||
if updated_shangjia:
|
||||
result_msg += ",商家信息已更新"
|
||||
|
||||
log_task_execution(f"自动结算订单 {dingdan_id}", True, result_msg)
|
||||
return result_msg
|
||||
|
||||
except Dingdan.DoesNotExist:
|
||||
error_msg = f"订单{dingdan_id}不存在"
|
||||
logger.warning(error_msg)
|
||||
return error_msg
|
||||
except Exception as e:
|
||||
error_msg = f"处理订单{dingdan_id}时发生错误: {str(e)}"
|
||||
logger.error(error_msg)
|
||||
|
||||
# 重试机制
|
||||
if self.request.retries < self.max_retries:
|
||||
logger.info(f"订单{dingdan_id}处理失败,准备第{self.request.retries + 1}次重试")
|
||||
raise self.retry(exc=e)
|
||||
|
||||
log_task_execution(f"自动结算订单 {dingdan_id}", False, error_msg)
|
||||
return error_msg
|
||||
|
||||
@shared_task
|
||||
@rollback_on_failure("批量检查超时订单")
|
||||
def check_order_expire_task():
|
||||
"""
|
||||
批量检查超时订单(补偿机制)
|
||||
每5分钟执行一次,作为信号处理的备用方案
|
||||
查找状态为8且创建时间超过72小时的订单(宽松时间,防止误处理)
|
||||
"""
|
||||
try:
|
||||
# 计算更宽松的时间点:当前时间减去72小时(48+24小时)
|
||||
# 这样避免误处理刚变为状态8的订单
|
||||
check_time = timezone.now() - timedelta(seconds=settings.ORDER_EXPIRE_SECONDS + 86400) # 48+24=72小时
|
||||
|
||||
# 查询状态为8且创建时间早于检查时间的订单
|
||||
expired_orders = Dingdan.objects.filter(
|
||||
zhuangtai=8,
|
||||
create_time__lt=check_time
|
||||
).values_list('dingdan_id', flat=True)
|
||||
|
||||
expired_count = expired_orders.count()
|
||||
|
||||
if expired_count == 0:
|
||||
logger.info("补偿检查:无超时订单")
|
||||
return {"success": True, "message": "无超时订单", "count": 0}
|
||||
|
||||
# 分批处理超时订单(避免一次处理太多)
|
||||
batch_size = 10
|
||||
processed_count = 0
|
||||
|
||||
for i in range(0, expired_count, batch_size):
|
||||
batch = expired_orders[i:i+batch_size]
|
||||
|
||||
# 异步处理每个超时订单
|
||||
for dingdan_id in batch:
|
||||
process_expired_order.apply_async(
|
||||
args=[dingdan_id],
|
||||
queue='order_tasks',
|
||||
priority=8 # 补偿任务的优先级低一些
|
||||
)
|
||||
processed_count += 1
|
||||
|
||||
result_msg = f"补偿检查:发现{expired_count}个可能超时的订单,已提交处理{processed_count}个"
|
||||
log_task_execution("批量检查超时订单", True, result_msg)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"message": result_msg,
|
||||
"total_count": expired_count,
|
||||
"processed_count": processed_count
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"批量检查超时订单失败: {str(e)}"
|
||||
logger.error(error_msg)
|
||||
log_task_execution("批量检查超时订单", False, error_msg)
|
||||
|
||||
return {
|
||||
"success": False,
|
||||
"message": error_msg,
|
||||
"error": str(e)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
3
dingdan/tests.py
Normal file
3
dingdan/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
71
dingdan/tongzhi_tasks.py
Normal file
71
dingdan/tongzhi_tasks.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# dingdan/tongzhi_tasks.py
|
||||
import logging
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from a_long_dianjing.celery_app import app
|
||||
from yonghu.models import OfficialAccountUser
|
||||
from utils.weixin_broadcast import WeixinBroadcastSender
|
||||
|
||||
logger = logging.getLogger('weixin_broadcast')
|
||||
|
||||
|
||||
@app.task(bind=True, max_retries=3, default_retry_delay=60)
|
||||
def dingdan_guangbo(self, order_info):
|
||||
"""
|
||||
异步并发广播订单模板消息给所有关注服务号的用户
|
||||
order_info 字典字段示例:
|
||||
{
|
||||
'dingdan_id': 'PT123456',
|
||||
'game_type': '王者荣耀',
|
||||
'amount': '88.00',
|
||||
'order_desc': '星耀上王者'
|
||||
}
|
||||
"""
|
||||
sender = WeixinBroadcastSender()
|
||||
template_data = sender.build_order_message_data(order_info)
|
||||
order_id = order_info.get('dingdan_id')
|
||||
|
||||
# 查询所有已关注用户
|
||||
try:
|
||||
openids = list(
|
||||
OfficialAccountUser.objects
|
||||
.filter(is_subscribed=True)
|
||||
.values_list('official_openid', flat=True)
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f'查询订阅用户失败: {e}')
|
||||
raise self.retry(exc=e)
|
||||
|
||||
if not openids:
|
||||
return {'success': True, 'msg': '无订阅用户'}
|
||||
|
||||
total = len(openids)
|
||||
logger.info(f'📊 Celery 广播订单 {order_id} 开始,目标人数: {total}')
|
||||
|
||||
success = 0
|
||||
fail = 0
|
||||
|
||||
# 20 个线程并发发送,微信接口耗时 200-500ms,1000 人约 15 秒完成
|
||||
with ThreadPoolExecutor(max_workers=20) as executor:
|
||||
future_map = {
|
||||
executor.submit(sender.send_to_user, openid, template_data, order_id): openid
|
||||
for openid in openids
|
||||
}
|
||||
for future in as_completed(future_map):
|
||||
openid = future_map[future]
|
||||
try:
|
||||
res = future.result(timeout=30)
|
||||
if res.get('success'):
|
||||
success += 1
|
||||
else:
|
||||
fail += 1
|
||||
except Exception as e:
|
||||
fail += 1
|
||||
logger.error(f'发送异常 {openid[:10]}...: {e}')
|
||||
|
||||
logger.info(f'🏁 广播完成:成功 {success},失败 {fail},总计 {total}')
|
||||
return {
|
||||
'success': True,
|
||||
'total': total,
|
||||
'success_count': success,
|
||||
'fail_count': fail
|
||||
}
|
||||
96
dingdan/urls.py
Normal file
96
dingdan/urls.py
Normal file
@@ -0,0 +1,96 @@
|
||||
from django.urls import path
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from .views import CreateOrderView, WechatPayNotifyView, \
|
||||
PaymentFailView, PaymentVerifyView, DingdanHuoquView, DingdanXiangqingView, JiedanView, \
|
||||
ShangpinLeixingView, ShangjiaPaifaView, ShangjiaDingdanHuoquView, ShangjiaJiesuanView, \
|
||||
ShangjiaDingdanXiangqingView, ShangjiaChufaShenqingView, ShangjiaTuikuanShenqingView, \
|
||||
ShangjiaChexiaoView, DashouDingdanHuoquView, ShangpinLeixingHuoquView, QiangdanView, \
|
||||
DashouDingdanHuoquView1, DashouCOSZhengshuView, DashouTijiaoView, DashouDingdanXiangqingView, AdGetDingdanXiangQing, \
|
||||
AdTongYiTuiKuanPingTai, AdTongYiTuiKuanShangJia, AdQiangZhiJieDan, AdJuJueTuiKuan,\
|
||||
AdGengHuanDaShou,ShangjiaCOSZhengshuView, DashouHuoquLeixingView,AdJuJueJieSuan, AdZhuanYiDaTing, AdQuXiaoZhiDing,PartnerNotifyClaimView, PartnerSyncOrderView, PartnerCheckClaimView, PartnerRefundNotifyView,DashouXiugaiView,VirtualCreateOrderView, VirtualPayNotifyView, VirtualPaymentVerifyView,VirtualPaymentFailView,DaiLiQunLiaoXiaoXiView,\
|
||||
ShangjiaLianjieLiuYanZhuanFaView, ZxsjghdsView, \
|
||||
ShangjiaFakuanApplyView, ShangjiaFakuaiXiugaiView
|
||||
|
||||
urlpatterns = [
|
||||
path('xiadan', CreateOrderView.as_view(), name='下单订单生成接口'),
|
||||
#path('pay-notify/', WechatPayNotifyView.as_view(), name='老板下单微信支付回调'),
|
||||
path('pay-notify/', csrf_exempt(WechatPayNotifyView.as_view()), name='老板下单微信支付回调'),
|
||||
path('shibai', PaymentFailView.as_view(), name='老板支付失败接口'),
|
||||
path('fucha', PaymentVerifyView.as_view(), name='老板支付成功复查接口'),
|
||||
path('dingdanhuoqu', DingdanHuoquView.as_view(), name='老板订单获取'),
|
||||
path('dingdanxiangqing', DingdanXiangqingView.as_view(), name='老板订单详情获取'),
|
||||
path('jiedan', JiedanView.as_view(), name='老板结单'),
|
||||
path('sjspleixing', ShangpinLeixingView.as_view(), name='派单获取商品类型'),
|
||||
path('sjpaifa', ShangjiaPaifaView.as_view(), name='商家发单'),
|
||||
path('sjdingdanhq', ShangjiaDingdanHuoquView.as_view(), name='商家订单获取'),
|
||||
path('sjddxq', ShangjiaDingdanXiangqingView.as_view(), name='商家订单详情获取'),
|
||||
path('sjjiesuan', ShangjiaJiesuanView.as_view(), name='商家结单'),
|
||||
path('sjchexiao', ShangjiaChexiaoView.as_view(), name='商家撤销订单'),
|
||||
path('sjtkshenqing', ShangjiaTuikuanShenqingView.as_view(), name='商家退款申请'),
|
||||
path('sjchufa', ShangjiaChufaShenqingView.as_view(), name='商家处罚打手申请'),
|
||||
#path('ddlxhq', ShangpinLeixingHuoquView.as_view(), name='打手抢单页商品类型获取'),
|
||||
path('dshqdingdan', DashouDingdanHuoquView1.as_view(), name='打手订单列表页面获取'),
|
||||
|
||||
# 获取订单列表
|
||||
path('ddhq', DashouDingdanHuoquView.as_view(), name='打手抢单页获取订单'),
|
||||
path('qiangdan', QiangdanView.as_view(), name='打手抢单'),
|
||||
path('dsscpz', DashouCOSZhengshuView.as_view(), name='打手上传图片OSS参数获取接口'),
|
||||
# 打手提交订单完成接口
|
||||
path('dstijiao', DashouTijiaoView.as_view(), name='打手订单提交'),
|
||||
# 打手订单详情获取接口
|
||||
path('dsddxq', DashouDingdanXiangqingView.as_view(), name='打手获取订单详情'),
|
||||
path('adddxq', AdGetDingdanXiangQing.as_view(), name='管理员获取订单详情页面具体信息'),
|
||||
path('adddpttk', AdTongYiTuiKuanPingTai.as_view(), name='同意平台订单退款'),
|
||||
|
||||
# 商家订单退款接口(之前写的)
|
||||
path('adddsjtk', AdTongYiTuiKuanShangJia.as_view(), name='同意商家退款'),
|
||||
|
||||
# 强制结单接口
|
||||
#path('adddqzjd', AdQiangZhiJieDan.as_view(), name='强制结单'),
|
||||
|
||||
# 拒绝退款接口
|
||||
path('adddjj', AdJuJueTuiKuan.as_view(), name='拒绝退款'),
|
||||
|
||||
# 更换打手接口
|
||||
path('adddgh', AdGengHuanDaShou.as_view(), name='管理更换打手'),
|
||||
|
||||
|
||||
path('sjscpz', ShangjiaCOSZhengshuView.as_view(), name='商家上传证据图片获取密钥'),
|
||||
path('dsqdhqddlx', DashouHuoquLeixingView.as_view(), name='打手抢单页面获取订单类型'),
|
||||
|
||||
|
||||
|
||||
path('adddjjjs', AdJuJueJieSuan.as_view(), name='管理员拒绝给打手钱'),
|
||||
path('adddzydt', AdZhuanYiDaTing.as_view(), name='订单转移大厅'),
|
||||
path('adddqxzd', AdQuXiaoZhiDing.as_view(), name='取消指定'),
|
||||
|
||||
|
||||
|
||||
|
||||
path('partner_sync_order', csrf_exempt(PartnerSyncOrderView.as_view()), name='东道主派单接口'),
|
||||
path('partner_check_claim', csrf_exempt(PartnerCheckClaimView.as_view()), name='对方抢单检查接口'),
|
||||
|
||||
|
||||
path('partner_notify_claim', csrf_exempt(PartnerNotifyClaimView.as_view()), name='东道主订单被抢通知接口'),
|
||||
#path('partner_refund_notify', csrf_exempt(PartnerRefundNotifyView.as_view()), name='接受东道主退款通知'),
|
||||
|
||||
|
||||
path('dsxiugaidd', DashouXiugaiView.as_view(), name='打手修改订单详情'),
|
||||
|
||||
path('kptxxfs', DaiLiQunLiaoXiaoXiView.as_view(), name='前端聊天转发'), # 群聊消息代理发送
|
||||
|
||||
|
||||
path('virtual_xiadan', VirtualCreateOrderView.as_view(),name='虚拟支付下单'),
|
||||
path('virtual_notify', VirtualPayNotifyView.as_view(),name='虚拟支付下单回调'),
|
||||
path('virtual_fucha', VirtualPaymentVerifyView.as_view(),name='虚拟支付下单成功复查'),
|
||||
path('shibai', VirtualPaymentFailView.as_view(),name='虚拟支付下单失败'), # 或复用原 PaymentFailView
|
||||
|
||||
path('sjljlbxxzf', ShangjiaLianjieLiuYanZhuanFaView.as_view(), name='商家链接老板聊天转发'),
|
||||
|
||||
path('zxsjghds', ZxsjghdsView.as_view(), name='商家更换打手'), # 商家更换打手
|
||||
path('sjfksq', ShangjiaFakuanApplyView.as_view(), name='商家罚款'),
|
||||
path('sjfkxgycx', ShangjiaFakuaiXiugaiView.as_view(), name='商家罚款和退款修改'),
|
||||
|
||||
|
||||
|
||||
]
|
||||
442
dingdan/utils.py
Normal file
442
dingdan/utils.py
Normal file
@@ -0,0 +1,442 @@
|
||||
|
||||
import threading
|
||||
import requests
|
||||
|
||||
from django.conf import settings
|
||||
from peizhi.models import Club
|
||||
from shangpin.models import ShangpinLeixing
|
||||
from dingdan.models import Dingdan # 根据实际路径导入
|
||||
|
||||
import logging
|
||||
from datetime import date
|
||||
|
||||
from django.db import transaction
|
||||
from django.db.models import F
|
||||
from peizhi.models import DailyDispatchStat # 假设模型在 peizhi 应用中
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 可选:线程池限制(避免大量线程同时创建,建议使用 Celery,这里简单用线程)
|
||||
THREAD_POOL_SIZE = 10
|
||||
_semaphore = threading.Semaphore(THREAD_POOL_SIZE)
|
||||
|
||||
def sync_order_to_partners(dingdan_id):
|
||||
"""
|
||||
异步向所有开启互通的合作平台同步订单。
|
||||
使用信号量限制并发线程数。
|
||||
"""
|
||||
def _task():
|
||||
_semaphore.acquire()
|
||||
try:
|
||||
_sync_order_task(dingdan_id)
|
||||
finally:
|
||||
_semaphore.release()
|
||||
|
||||
thread = threading.Thread(target=_task)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
def _sync_order_task(dingdan_id):
|
||||
"""实际同步任务(在线程中执行)"""
|
||||
try:
|
||||
# 获取订单对象(只取必要字段,提升性能)
|
||||
dingdan = Dingdan.objects.only(
|
||||
'dingdan_id', 'zhuangtai', 'jine', 'dashou_fencheng', 'jieshao',
|
||||
'beizhu', 'nicheng', 'leixing_id', 'yaoqiuleixing', 'huiyuan_id',
|
||||
'yongjin', 'zhiding_id', 'create_time'
|
||||
).get(dingdan_id=dingdan_id)
|
||||
|
||||
# 基本条件判断
|
||||
if dingdan.zhuangtai != 1:
|
||||
logger.info(f"订单 {dingdan_id} 状态 {dingdan.zhuangtai} 不是1,不同步")
|
||||
return
|
||||
if dingdan.zhiding_id:
|
||||
logger.info(f"订单 {dingdan_id} 是指定单,不同步")
|
||||
return
|
||||
if dingdan.yaoqiuleixing != 1:
|
||||
logger.info(f"订单 {dingdan_id} 抢单要求类型不是会员抢单,不同步")
|
||||
return
|
||||
if not dingdan.leixing_id:
|
||||
logger.info(f"订单 {dingdan_id} 无商品类型,不同步")
|
||||
return
|
||||
try:
|
||||
leixing = ShangpinLeixing.objects.get(id=dingdan.leixing_id)
|
||||
if not leixing.is_cross_enabled:
|
||||
logger.info(f"订单 {dingdan_id} 的商品类型未开启互通,不同步")
|
||||
return
|
||||
except ShangpinLeixing.DoesNotExist:
|
||||
logger.info(f"订单 {dingdan_id} 的商品类型不存在,不同步")
|
||||
return
|
||||
|
||||
# 查询所有开启互通的俱乐部
|
||||
clubs = Club.objects.filter(is_interop_enabled=True).select_related()
|
||||
if not clubs.exists():
|
||||
return
|
||||
|
||||
# 为每个俱乐部发送订单
|
||||
for club in clubs:
|
||||
_send_to_single_partner(dingdan, club)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"同步订单任务异常: {e}", exc_info=True)
|
||||
|
||||
def _send_to_single_partner(dingdan, club):
|
||||
"""向单个俱乐部发送订单(带重试,幂等处理)"""
|
||||
# 计算实际金额:订单打手分成 × 对方费率
|
||||
actual_amount = dingdan.dashou_fencheng * club.dashou_rate
|
||||
|
||||
# 构建请求数据
|
||||
payload = {
|
||||
'token': settings.CROSS_PLATFORM_TOKEN,
|
||||
'our_club_id': club.club_id, # 我方在对方系统中的标识(存储于对方表的 partner_club_id)
|
||||
'partner_club_id': club.partner_club_id, # 对方自己的俱乐部ID
|
||||
'partner_order_id': dingdan.dingdan_id, # 我方订单ID作为对方的外部订单号
|
||||
'jine': str(actual_amount), # 对方平台应展示的订单金额
|
||||
'dashou_fencheng': str(actual_amount), # 对方平台打手分成(与金额一致)
|
||||
'jieshao': dingdan.jieshao,
|
||||
'beizhu': dingdan.beizhu,
|
||||
'create_time': dingdan.create_time.isoformat(),
|
||||
'nicheng': dingdan.nicheng,
|
||||
'leixing_id': dingdan.leixing_id, # 我方商品类型ID,对方需要映射
|
||||
'user_id': get_order_user_id(dingdan), # 对方平台下单用户ID(不带前缀)
|
||||
}
|
||||
|
||||
# 重试机制(最多3次,指数退避)
|
||||
for attempt in range(1, 4):
|
||||
try:
|
||||
response = requests.post(
|
||||
club.partner_domain + '/dingdan/partner_sync_order',
|
||||
json=payload,
|
||||
timeout=5
|
||||
)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
# 对方返回 code=0 表示成功(包括新建或已存在)
|
||||
if data.get('code') == 0:
|
||||
# 判断本次响应是新创建还是已存在
|
||||
status = data.get('data', {}).get('status', '')
|
||||
if status == 'existed':
|
||||
# 订单已经存在于对方系统,不重复统计
|
||||
logger.info(f"订单 {dingdan.dingdan_id} 在俱乐部 {club.club_id} 已存在,跳过统计")
|
||||
else:
|
||||
# 新创建成功,更新统计
|
||||
try:
|
||||
update_daily_dispatch_stat(
|
||||
direction=1, # 我方派单
|
||||
partner_club_id=club.partner_club_id,
|
||||
dispatch_amount=actual_amount,
|
||||
|
||||
)
|
||||
logger.info(f"成功同步订单 {dingdan.dingdan_id} 到俱乐部 {club.club_id}")
|
||||
except Exception as e:
|
||||
logger.error(f"更新派单统计失败: {e}", exc_info=True)
|
||||
|
||||
# 标记订单为跨平台(仅当第一次成功时标记,避免重复标记)
|
||||
if not dingdan.is_cross:
|
||||
Dingdan.objects.filter(dingdan_id=dingdan.dingdan_id).update(
|
||||
is_cross=1,
|
||||
dispatch_type=1 # 我方派单
|
||||
)
|
||||
logger.info(f"订单 {dingdan.dingdan_id} 已标记为跨平台订单")
|
||||
break
|
||||
else:
|
||||
# 对方返回业务错误(如映射不存在等),不重试
|
||||
logger.error(f"同步订单失败(业务): {data}")
|
||||
break
|
||||
else:
|
||||
logger.error(f"同步订单HTTP失败: {response.status_code}")
|
||||
except Exception as e:
|
||||
logger.error(f"同步订单异常(尝试 {attempt}/3): {e}")
|
||||
|
||||
if attempt < 3:
|
||||
import time
|
||||
time.sleep(2 ** attempt) # 指数退避
|
||||
else:
|
||||
logger.error(f"同步订单 {dingdan.dingdan_id} 到俱乐部 {club.club_id} 最终失败")
|
||||
|
||||
|
||||
|
||||
# 获取下单方ID(根据订单类型)
|
||||
def get_order_user_id(order):
|
||||
from dingdan.models import DingdanPingtai, DingdanShangjia
|
||||
if order.fadan_pingtai == 1:
|
||||
try:
|
||||
ext = DingdanPingtai.objects.get(dingdan=order)
|
||||
return ext.laoban_id # 老板ID
|
||||
except DingdanPingtai.DoesNotExist:
|
||||
return None
|
||||
elif order.fadan_pingtai == 2:
|
||||
try:
|
||||
ext = DingdanShangjia.objects.get(dingdan=order)
|
||||
return ext.shangjia_id # 商家ID
|
||||
except DingdanShangjia.DoesNotExist:
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
# dingdan/utils/dispatch_stat.py
|
||||
import logging
|
||||
|
||||
import logging
|
||||
from datetime import date
|
||||
from decimal import Decimal
|
||||
from django.db import transaction
|
||||
from django.db.models import F
|
||||
from peizhi.models import DailyDispatchStat # 请根据实际模型位置修改导入路径
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def update_daily_dispatch_stat(direction, partner_club_id,
|
||||
dispatch_amount=None, dispatch_count=1,
|
||||
claimed_amount=None, claimed_count=1,
|
||||
success_amount=None, success_count=1):
|
||||
"""
|
||||
原子更新每日派单统计(支持派单、抢单、成交三种类型)。
|
||||
只更新传递了非None参数的字段,未传递的字段保持不变。
|
||||
|
||||
参数:
|
||||
direction: 1=我方派单,2=对方派单
|
||||
partner_club_id: 对方俱乐部ID
|
||||
dispatch_amount: 派单金额(Decimal),如果提供则累加到 dispatch_amount 和 dispatch_count
|
||||
dispatch_count: 派单数量,默认为1,与 dispatch_amount 同时提供时生效
|
||||
claimed_amount: 抢单金额(Decimal),如果提供则累加到 claimed_amount 和 claimed_count
|
||||
claimed_count: 抢单数量,默认为1,与 claimed_amount 同时提供时生效
|
||||
success_amount: 成交金额(Decimal),如果提供则累加到 success_amount 和 success_count
|
||||
success_count: 成交数量,默认为1,与 success_amount 同时提供时生效
|
||||
"""
|
||||
today = date.today()
|
||||
year, month, day = today.year, today.month, today.day
|
||||
|
||||
with transaction.atomic():
|
||||
# 使用 select_for_update 锁定行,避免并发累加冲突
|
||||
stat, created = DailyDispatchStat.objects.select_for_update().get_or_create(
|
||||
date=today,
|
||||
year=year,
|
||||
month=month,
|
||||
day=day,
|
||||
direction=direction,
|
||||
partner_club_id=partner_club_id,
|
||||
defaults={
|
||||
'dispatch_count': dispatch_count if dispatch_amount is not None else 0,
|
||||
'dispatch_amount': dispatch_amount or Decimal('0.00'),
|
||||
'claimed_count': claimed_count if claimed_amount is not None else 0,
|
||||
'claimed_amount': claimed_amount or Decimal('0.00'),
|
||||
'success_count': success_count if success_amount is not None else 0,
|
||||
'success_amount': success_amount or Decimal('0.00'),
|
||||
}
|
||||
)
|
||||
|
||||
if not created:
|
||||
update_fields = []
|
||||
if dispatch_amount is not None:
|
||||
stat.dispatch_count = F('dispatch_count') + dispatch_count
|
||||
stat.dispatch_amount = F('dispatch_amount') + dispatch_amount
|
||||
update_fields.extend(['dispatch_count', 'dispatch_amount'])
|
||||
if claimed_amount is not None:
|
||||
stat.claimed_count = F('claimed_count') + claimed_count
|
||||
stat.claimed_amount = F('claimed_amount') + claimed_amount
|
||||
update_fields.extend(['claimed_count', 'claimed_amount'])
|
||||
if success_amount is not None:
|
||||
stat.success_count = F('success_count') + success_count
|
||||
stat.success_amount = F('success_amount') + success_amount
|
||||
update_fields.extend(['success_count', 'success_amount'])
|
||||
|
||||
if update_fields:
|
||||
stat.save(update_fields=update_fields)
|
||||
|
||||
logger.info(f"更新派单统计: 日期={today}, 方向={direction}, 俱乐部={partner_club_id}, "
|
||||
f"派单+{dispatch_count if dispatch_amount else 0}单/{dispatch_amount or 0}, "
|
||||
f"抢单+{claimed_count if claimed_amount else 0}单/{claimed_amount or 0}, "
|
||||
f"成交+{success_count if success_amount else 0}单/{success_amount or 0}")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
from peizhi.models import DailyIncomeStat
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def update_daily_income(amount):
|
||||
"""
|
||||
原子更新当日收入统计(金额累加,笔数加1)。
|
||||
用于微信支付成功回调。
|
||||
|
||||
参数:
|
||||
amount: Decimal 本次收入金额
|
||||
"""
|
||||
today = date.today()
|
||||
year, month, day = today.year, today.month, today.day
|
||||
|
||||
with transaction.atomic():
|
||||
stat, created = DailyIncomeStat.objects.select_for_update().get_or_create(
|
||||
date=today,
|
||||
defaults={
|
||||
'year': year,
|
||||
'month': month,
|
||||
'day': day,
|
||||
'total_amount': amount,
|
||||
'total_count': 1
|
||||
}
|
||||
)
|
||||
if not created:
|
||||
# 原子累加
|
||||
stat.total_amount = F('total_amount') + amount
|
||||
stat.total_count = F('total_count') + 1
|
||||
stat.save(update_fields=['total_amount', 'total_count'])
|
||||
|
||||
logger.info(
|
||||
f"每日收入更新: {today}, +{amount}元, 总金额={stat.total_amount if created else stat.total_amount + amount}, 总笔数={stat.total_count if created else stat.total_count + 1}")
|
||||
|
||||
|
||||
|
||||
|
||||
from peizhi.models import DailyPayoutStat
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def update_daily_payout(amount):
|
||||
"""
|
||||
原子更新当日出款统计(金额累加,笔数加1)。
|
||||
用于提现成功、结算打款等场景。
|
||||
|
||||
参数:
|
||||
amount: Decimal 本次出款金额
|
||||
"""
|
||||
today = date.today()
|
||||
year, month, day = today.year, today.month, today.day
|
||||
|
||||
with transaction.atomic():
|
||||
stat, created = DailyPayoutStat.objects.select_for_update().get_or_create(
|
||||
date=today,
|
||||
defaults={
|
||||
'year': year,
|
||||
'month': month,
|
||||
'day': day,
|
||||
'total_amount': amount,
|
||||
'total_count': 1
|
||||
}
|
||||
)
|
||||
if not created:
|
||||
# 原子累加
|
||||
stat.total_amount = F('total_amount') + amount
|
||||
stat.total_count = F('total_count') + 1
|
||||
stat.save(update_fields=['total_amount', 'total_count'])
|
||||
|
||||
logger.info(f"每日出款更新: {today}, +{amount}元, 总金额={stat.total_amount if created else stat.total_amount + amount}, 总笔数={stat.total_count if created else stat.total_count + 1}")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
from dingdan.models import Lilubiao
|
||||
|
||||
|
||||
def calc_shangjia_order_fencheng(jine):
|
||||
"""
|
||||
商家发单时计算打手/管事分成。
|
||||
打手优先:打手+管事 > 订单金额时,管事分成为 0。
|
||||
"""
|
||||
jine = Decimal(str(jine))
|
||||
try:
|
||||
lilu_obj = Lilubiao.objects.get(fadanpingtai='3')
|
||||
rate_dashou = Decimal(str(lilu_obj.lilu)) if lilu_obj.lilu and lilu_obj.lilu > 0 else Decimal('1')
|
||||
except Lilubiao.DoesNotExist:
|
||||
rate_dashou = Decimal('1')
|
||||
|
||||
lilu_guanshi_obj = Lilubiao.objects.filter(fadanpingtai='13').first()
|
||||
rate_guanshi = (
|
||||
Decimal(str(lilu_guanshi_obj.lilu))
|
||||
if lilu_guanshi_obj and lilu_guanshi_obj.lilu is not None
|
||||
else Decimal('0')
|
||||
)
|
||||
|
||||
dashou_fencheng = (jine * rate_dashou).quantize(Decimal('0.01'))
|
||||
guanshi_raw = (jine * rate_guanshi).quantize(Decimal('0.01'))
|
||||
|
||||
if dashou_fencheng + guanshi_raw > jine:
|
||||
guanshi_fencheng = Decimal('0.00')
|
||||
else:
|
||||
guanshi_fencheng = guanshi_raw
|
||||
|
||||
return dashou_fencheng, guanshi_fencheng
|
||||
|
||||
|
||||
def settle_shangjia_order_guanshi_fenhong(order, dashou_id):
|
||||
"""
|
||||
商家订单结单时结算管事分红(幂等,失败不抛异常阻断主流程)。
|
||||
"""
|
||||
from shangpin.models import Gsfenhong
|
||||
from yonghu.models import UserDashou, UserGuanshi
|
||||
|
||||
if getattr(order, 'fadan_pingtai', None) != 2:
|
||||
return
|
||||
|
||||
guanshi_fencheng = order.guanshi_fencheng or Decimal('0')
|
||||
if guanshi_fencheng <= 0:
|
||||
return
|
||||
|
||||
if Gsfenhong.objects.filter(dingdan_id=order.dingdan_id).exists():
|
||||
logger.info(f"商家订单管事分红已处理: {order.dingdan_id}")
|
||||
return
|
||||
|
||||
if not dashou_id:
|
||||
return
|
||||
|
||||
try:
|
||||
dashou = UserDashou.objects.select_related('user').get(user__yonghuid=dashou_id)
|
||||
except UserDashou.DoesNotExist:
|
||||
logger.info(f"商家订单管事分红跳过: 打手{dashou_id}不存在")
|
||||
return
|
||||
|
||||
guanshi_id = dashou.yaoqingren
|
||||
if not guanshi_id:
|
||||
logger.info(f"商家订单管事分红跳过: 打手{dashou_id}无邀请管事")
|
||||
return
|
||||
|
||||
try:
|
||||
with transaction.atomic():
|
||||
guanshi = UserGuanshi.objects.select_for_update().get(user__yonghuid=guanshi_id)
|
||||
UserGuanshi.objects.filter(id=guanshi.id).update(
|
||||
yue=F('yue') + guanshi_fencheng,
|
||||
chongzhifenrun=F('chongzhifenrun') + guanshi_fencheng,
|
||||
)
|
||||
|
||||
user_main = dashou.user
|
||||
Gsfenhong.objects.create(
|
||||
dingdan_id=order.dingdan_id,
|
||||
guanshi=guanshi_id,
|
||||
dashouid=dashou_id,
|
||||
shuoming='商家订单分红',
|
||||
fenhong=guanshi_fencheng,
|
||||
avatar=user_main.avatar if user_main else None,
|
||||
nicheng=dashou.nicheng or '未知打手',
|
||||
fenhong_leixing=3,
|
||||
)
|
||||
logger.info(
|
||||
f"商家订单管事分红成功: 订单{order.dingdan_id}, 管事{guanshi_id}, "
|
||||
f"打手{dashou_id}, 金额{guanshi_fencheng}元"
|
||||
)
|
||||
except UserGuanshi.DoesNotExist:
|
||||
logger.warning(f"商家订单管事分红跳过: 管事{guanshi_id}不存在")
|
||||
return
|
||||
except Exception as e:
|
||||
logger.error(f"商家订单管事分红失败: {e}", exc_info=True)
|
||||
return
|
||||
|
||||
try:
|
||||
from houtai.utils import update_guanshi_daily_by_action
|
||||
update_guanshi_daily_by_action(
|
||||
yonghuid=guanshi_id,
|
||||
action=3,
|
||||
amount=guanshi_fencheng,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"商家订单管事日统计更新失败: {e}")
|
||||
9292
dingdan/views.py
Normal file
9292
dingdan/views.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user