第一次提交:阿龙电竞 Django 后端最新版本
This commit is contained in:
0
yonghu/__init__.py
Normal file
0
yonghu/__init__.py
Normal file
3
yonghu/admin.py
Normal file
3
yonghu/admin.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
5
yonghu/apps.py
Normal file
5
yonghu/apps.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class YonghuConfig(AppConfig):
|
||||
name = "yonghu"
|
||||
168
yonghu/fadan_fenhong_utils.py
Normal file
168
yonghu/fadan_fenhong_utils.py
Normal file
@@ -0,0 +1,168 @@
|
||||
# yonghu/fadan_fenhong_utils.py
|
||||
# 罚款缴纳分红处理公共方法(支持更新罚单中的申请人分红金额)
|
||||
|
||||
import decimal
|
||||
import logging
|
||||
from decimal import Decimal
|
||||
from django.db import transaction
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
from dingdan.models import Fadan, FadanFenhong, FadanFenhongLilv
|
||||
from yonghu.models import UserShangjia
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# 身份映射字典
|
||||
IDENTITY_MAP = {
|
||||
1: {'fenhong': 2, 'lilv': 1}, # 客服
|
||||
2: {'fenhong': 5, 'lilv': 2}, # 售后
|
||||
3: {'fenhong': 3, 'lilv': 3}, # 管理员
|
||||
4: {'fenhong': 4, 'lilv': 4}, # 店铺
|
||||
5: {'fenhong': 1, 'lilv': 5}, # 商家
|
||||
}
|
||||
|
||||
|
||||
def process_fadan_fenhong(fadan_id):
|
||||
"""
|
||||
罚款缴纳后的分红处理(在回调中调用)
|
||||
参数:
|
||||
fadan_id: 罚单 ID
|
||||
返回:
|
||||
(success, message)
|
||||
"""
|
||||
try:
|
||||
# 1. 获取罚单对象(必须是已缴纳状态)
|
||||
try:
|
||||
fadan = Fadan.objects.get(id=fadan_id, zhuangtai=2)
|
||||
except Fadan.DoesNotExist:
|
||||
logger.error(f"罚单 {fadan_id} 不存在或状态不是已缴纳")
|
||||
return False, "罚单不存在或状态异常"
|
||||
|
||||
# 2. 获取申请处罚者ID和身份(源身份数字)
|
||||
shenqing_chufa = fadan.shenqing_chufa
|
||||
src_shenfen = fadan.shenqingren_shenfen
|
||||
|
||||
if not shenqing_chufa:
|
||||
logger.info(f"罚单 {fadan_id} 无申请处罚者,不进行分红")
|
||||
# 即使无申请者,也可将分红金额字段设为0(默认已是0)
|
||||
return True, "无申请处罚者,无需分红"
|
||||
|
||||
# 3. 映射身份数字
|
||||
if src_shenfen not in IDENTITY_MAP:
|
||||
logger.error(f"未知的申请处罚者身份: {src_shenfen},罚单 {fadan_id}")
|
||||
return False, f"未知身份 {src_shenfen}"
|
||||
|
||||
mapped = IDENTITY_MAP[src_shenfen]
|
||||
fenhong_shenfen = mapped['fenhong'] # 用于 FadanFenhong.shenfen
|
||||
lilv_shenfen = mapped['lilv'] # 用于 FadanFenhongLilv.shenfen
|
||||
|
||||
# 4. 获取罚款金额
|
||||
fakuan_jine = fadan.fakuanjine
|
||||
if fakuan_jine <= 0:
|
||||
logger.info(f"罚单 {fadan_id} 罚款金额为0,不产生分红")
|
||||
fadan.shenqingren_fenhong_jine = Decimal('0.00')
|
||||
fadan.save(update_fields=['shenqingren_fenhong_jine'])
|
||||
return True, "罚款金额为0,无分红"
|
||||
|
||||
# 5. 确定分红利率
|
||||
rate = _get_fenhong_rate(shenqing_chufa, fenhong_shenfen, lilv_shenfen)
|
||||
if rate is None:
|
||||
logger.warning(f"未找到身份 {src_shenfen} (映射后 fenhong_shenfen={fenhong_shenfen}, lilv_shenfen={lilv_shenfen}) 的分红利率,罚单 {fadan_id} 不进行分红")
|
||||
fadan.shenqingren_fenhong_jine = Decimal('0.00')
|
||||
fadan.save(update_fields=['shenqingren_fenhong_jine'])
|
||||
return True, "未配置分红利率,无分红"
|
||||
|
||||
# 6. 计算分红金额
|
||||
fenhong_jine = (Decimal(str(fakuan_jine)) * Decimal(str(rate))).quantize(Decimal('0.01'))
|
||||
if fenhong_jine <= 0:
|
||||
logger.info(f"罚单 {fadan_id} 计算分红金额为0,无需处理")
|
||||
fadan.shenqingren_fenhong_jine = Decimal('0.00')
|
||||
fadan.save(update_fields=['shenqingren_fenhong_jine'])
|
||||
return True, "分红金额为0"
|
||||
|
||||
# 7. 根据申请处罚者身份执行不同的分红逻辑
|
||||
# src_shenfen == 5 代表商家(源身份)
|
||||
if src_shenfen == 5:
|
||||
# 商家特殊处理:只记录总额,可提现分红永远为0,直接加到商家余额
|
||||
with transaction.atomic():
|
||||
fenhong_record, created = FadanFenhong.objects.get_or_create(
|
||||
fenhongzhe_id=shenqing_chufa,
|
||||
shenfen=fenhong_shenfen,
|
||||
defaults={
|
||||
'zonge': Decimal('0.00'),
|
||||
'ketixian_fenhong': Decimal('0.00'),
|
||||
'fenhong_cishu': 0,
|
||||
'yingde_lilv': rate,
|
||||
'is_individual_rate': False
|
||||
}
|
||||
)
|
||||
fenhong_record.zonge += fenhong_jine
|
||||
# 可提现分红不累加,保持0
|
||||
fenhong_record.fenhong_cishu += 1
|
||||
fenhong_record.save()
|
||||
|
||||
# 直接增加商家余额(UserShangjia.yue)
|
||||
try:
|
||||
shangjia = UserShangjia.objects.get(user__yonghuid=shenqing_chufa)
|
||||
shangjia.yue += fenhong_jine
|
||||
shangjia.save(update_fields=['yue'])
|
||||
logger.info(f"商家 {shenqing_chufa} 余额增加 {fenhong_jine} 元")
|
||||
except UserShangjia.DoesNotExist:
|
||||
logger.error(f"商家 {shenqing_chufa} 扩展表不存在,无法增加余额")
|
||||
raise Exception(f"商家 {shenqing_chufa} 扩展表不存在,无法增加余额")
|
||||
|
||||
# 更新罚单中的申请人分红金额
|
||||
fadan.shenqingren_fenhong_jine = fenhong_jine
|
||||
fadan.save(update_fields=['shenqingren_fenhong_jine'])
|
||||
|
||||
else:
|
||||
# 其他身份(客服、售后、管理员、店铺):同时增加总额和可提现分红
|
||||
with transaction.atomic():
|
||||
fenhong_record, created = FadanFenhong.objects.get_or_create(
|
||||
fenhongzhe_id=shenqing_chufa,
|
||||
shenfen=fenhong_shenfen,
|
||||
defaults={
|
||||
'zonge': Decimal('0.00'),
|
||||
'ketixian_fenhong': Decimal('0.00'),
|
||||
'fenhong_cishu': 0,
|
||||
'yingde_lilv': rate,
|
||||
'is_individual_rate': False
|
||||
}
|
||||
)
|
||||
fenhong_record.zonge += fenhong_jine
|
||||
fenhong_record.ketixian_fenhong += fenhong_jine
|
||||
fenhong_record.fenhong_cishu += 1
|
||||
fenhong_record.save()
|
||||
|
||||
# 更新罚单中的申请人分红金额
|
||||
fadan.shenqingren_fenhong_jine = fenhong_jine
|
||||
fadan.save(update_fields=['shenqingren_fenhong_jine'])
|
||||
|
||||
logger.info(f"罚单 {fadan_id} 分红处理成功: 申请者 {shenqing_chufa}, 分红金额 {fenhong_jine} 元, 源身份 {src_shenfen}, 映射后分红身份 {fenhong_shenfen}")
|
||||
return True, "分红处理成功"
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"罚单 {fadan_id} 分红处理异常: {str(e)}", exc_info=True)
|
||||
return False, f"分红处理异常: {str(e)}"
|
||||
|
||||
|
||||
def _get_fenhong_rate(fenhongzhe_id, fenhong_shenfen, lilv_shenfen):
|
||||
"""
|
||||
获取分红利率(优先使用个人单独配置,否则使用全局身份配置)
|
||||
"""
|
||||
try:
|
||||
individual = FadanFenhong.objects.get(
|
||||
fenhongzhe_id=fenhongzhe_id,
|
||||
shenfen=fenhong_shenfen,
|
||||
is_individual_rate=True
|
||||
)
|
||||
return individual.yingde_lilv
|
||||
except FadanFenhong.DoesNotExist:
|
||||
pass
|
||||
|
||||
try:
|
||||
global_rate = FadanFenhongLilv.objects.get(shenfen=lilv_shenfen)
|
||||
return global_rate.lilv
|
||||
except FadanFenhongLilv.DoesNotExist:
|
||||
return None
|
||||
833
yonghu/migrations/0001_initial.py
Normal file
833
yonghu/migrations/0001_initial.py
Normal file
@@ -0,0 +1,833 @@
|
||||
# Generated by Django 4.2.27 on 2026-01-23 19:32
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="UserMain",
|
||||
fields=[
|
||||
(
|
||||
"last_login",
|
||||
models.DateTimeField(
|
||||
blank=True, null=True, verbose_name="last login"
|
||||
),
|
||||
),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
primary_key=True, serialize=False, verbose_name="主键ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"yonghuid",
|
||||
models.CharField(
|
||||
db_index=True, max_length=7, unique=True, verbose_name="用户ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"openid",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=64,
|
||||
unique=True,
|
||||
verbose_name="微信OpenID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"avatar",
|
||||
models.CharField(
|
||||
blank=True, max_length=500, null=True, verbose_name="头像"
|
||||
),
|
||||
),
|
||||
(
|
||||
"phone",
|
||||
models.CharField(
|
||||
blank=True, max_length=11, null=True, verbose_name="手机号"
|
||||
),
|
||||
),
|
||||
(
|
||||
"password",
|
||||
models.CharField(
|
||||
blank=True, max_length=200, null=True, verbose_name="密码"
|
||||
),
|
||||
),
|
||||
(
|
||||
"zhifu",
|
||||
models.CharField(
|
||||
blank=True, max_length=500, null=True, verbose_name="收款码图片"
|
||||
),
|
||||
),
|
||||
(
|
||||
"skzhanghao",
|
||||
models.CharField(
|
||||
blank=True, max_length=11, null=True, verbose_name="收款账号"
|
||||
),
|
||||
),
|
||||
(
|
||||
"ip",
|
||||
models.CharField(
|
||||
blank=True, max_length=50, null=True, verbose_name="来访用户ip"
|
||||
),
|
||||
),
|
||||
(
|
||||
"last_login_time",
|
||||
models.DateTimeField(
|
||||
blank=True, null=True, verbose_name="最后登录时间"
|
||||
),
|
||||
),
|
||||
(
|
||||
"user_type",
|
||||
models.CharField(
|
||||
choices=[
|
||||
("normal", "普通用户"),
|
||||
("dashou", "打手"),
|
||||
("shop", "商家"),
|
||||
("guanshi", "管事"),
|
||||
("admin", "管理员"),
|
||||
],
|
||||
default="normal",
|
||||
max_length=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": "user_main",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Xiugaijilu",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
primary_key=True, serialize=False, verbose_name="记录ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"yonghuid",
|
||||
models.CharField(max_length=7, verbose_name="被修改用户ID"),
|
||||
),
|
||||
(
|
||||
"xiugaiid",
|
||||
models.CharField(max_length=30, verbose_name="修改人账号ID"),
|
||||
),
|
||||
("leixing", models.IntegerField(verbose_name="被修改用户类型")),
|
||||
(
|
||||
"xiugaitijiao",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="修改后的打手提现金额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"xiugaitijiaoq",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="修改前的打手提现金额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"jifen",
|
||||
models.IntegerField(default=0, verbose_name="修改后的打手积分"),
|
||||
),
|
||||
(
|
||||
"yjifen",
|
||||
models.IntegerField(default=0, verbose_name="修改前的打手积分"),
|
||||
),
|
||||
(
|
||||
"yajin",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="修改后的打手押金",
|
||||
),
|
||||
),
|
||||
(
|
||||
"yyajin",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="修改前的打手押金",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shangjiayue",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="修改后的商家余额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shangjiayueq",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="修改前的商家余额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"guanshiyue",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="修改后的管事余额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"guanshiyueq",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="修改前的管事余额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"huiyuants",
|
||||
models.IntegerField(default=0, verbose_name="添加会员天数"),
|
||||
),
|
||||
(
|
||||
"huiyuan_id",
|
||||
models.CharField(
|
||||
blank=True, max_length=6, null=True, verbose_name="会员ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"qitashuoming",
|
||||
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": "xiugaijilu",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="UserShangjia",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"nicheng",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=50,
|
||||
unique=True,
|
||||
verbose_name="商家昵称",
|
||||
),
|
||||
),
|
||||
(
|
||||
"zhuangtai",
|
||||
models.IntegerField(
|
||||
choices=[(0, "待审核"), (1, "正常"), (2, "禁用")],
|
||||
default=1,
|
||||
verbose_name="商家状态",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dianhua",
|
||||
models.CharField(max_length=20, null=True, verbose_name="商家电话"),
|
||||
),
|
||||
(
|
||||
"wechat",
|
||||
models.CharField(
|
||||
max_length=50, null=True, verbose_name="商家微信号"
|
||||
),
|
||||
),
|
||||
("fabu", models.IntegerField(default=0, verbose_name="发布订单总数量")),
|
||||
(
|
||||
"tuikuan",
|
||||
models.IntegerField(default=0, verbose_name="退款订单总量"),
|
||||
),
|
||||
(
|
||||
"yue",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="商家余额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"chengjiao",
|
||||
models.IntegerField(default=0, verbose_name="商家成交订单总量"),
|
||||
),
|
||||
(
|
||||
"jinridingdan",
|
||||
models.IntegerField(default=0, verbose_name="商家今日订单总量"),
|
||||
),
|
||||
(
|
||||
"jinriliushui",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="商家今日流水",
|
||||
),
|
||||
),
|
||||
(
|
||||
"jinyuedingdan",
|
||||
models.IntegerField(default=0, verbose_name="商家今月订单总量"),
|
||||
),
|
||||
(
|
||||
"jinyueliushui",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="商家今月流水",
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="shop_profile",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="关联用户",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "商家扩展表",
|
||||
"verbose_name_plural": "商家扩展表",
|
||||
"db_table": "user_shangjia",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="UserGuanshi",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"yaoqingma",
|
||||
models.CharField(
|
||||
db_index=True, max_length=20, null=True, verbose_name="邀请码"
|
||||
),
|
||||
),
|
||||
(
|
||||
"dianhua",
|
||||
models.CharField(max_length=20, null=True, verbose_name="管事电话"),
|
||||
),
|
||||
(
|
||||
"wechat",
|
||||
models.CharField(
|
||||
max_length=50, null=True, verbose_name="管事微信号"
|
||||
),
|
||||
),
|
||||
(
|
||||
"yaogingshuliang",
|
||||
models.IntegerField(default=0, verbose_name="邀请打手总数"),
|
||||
),
|
||||
(
|
||||
"zhuangtai",
|
||||
models.IntegerField(
|
||||
choices=[(0, "禁用"), (1, "正常")],
|
||||
default=1,
|
||||
verbose_name="管事状态",
|
||||
),
|
||||
),
|
||||
(
|
||||
"jinrichongzhi",
|
||||
models.IntegerField(default=0, verbose_name="今日充值打手数量"),
|
||||
),
|
||||
(
|
||||
"jinyuechongzhi",
|
||||
models.IntegerField(default=0, verbose_name="今月充值打手数量"),
|
||||
),
|
||||
(
|
||||
"chongzhifenrun",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="充值分佣总额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"yue",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="可提现余额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="guanshi_profile",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="关联用户",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "管事扩展表",
|
||||
"verbose_name_plural": "管事扩展表",
|
||||
"db_table": "user_guanshi",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="UserDashou",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"nicheng",
|
||||
models.CharField(max_length=50, null=True, verbose_name="打手昵称"),
|
||||
),
|
||||
(
|
||||
"chenghao",
|
||||
models.CharField(max_length=50, null=True, verbose_name="打手称号"),
|
||||
),
|
||||
("zhuangtai", models.IntegerField(default=1, verbose_name="打手状态")),
|
||||
(
|
||||
"zaixianzhuangtai",
|
||||
models.IntegerField(default=1, verbose_name="打手在线状态"),
|
||||
),
|
||||
(
|
||||
"zhanghaozhuangtai",
|
||||
models.IntegerField(default=1, verbose_name="打手账号状态"),
|
||||
),
|
||||
("jieshao", models.TextField(null=True, verbose_name="打手介绍")),
|
||||
(
|
||||
"jiedanzongliang",
|
||||
models.IntegerField(default=0, verbose_name="接单总量"),
|
||||
),
|
||||
(
|
||||
"chengjiaozongliang",
|
||||
models.IntegerField(default=0, verbose_name="成交单总量"),
|
||||
),
|
||||
(
|
||||
"tuikuanliang",
|
||||
models.IntegerField(default=0, verbose_name="退款订单总量"),
|
||||
),
|
||||
(
|
||||
"yue",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="可提现余额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"zonge",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="打单赚取总额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"dianhua",
|
||||
models.CharField(max_length=20, null=True, verbose_name="打手电话"),
|
||||
),
|
||||
(
|
||||
"wechat",
|
||||
models.CharField(
|
||||
max_length=50, null=True, verbose_name="打手微信号"
|
||||
),
|
||||
),
|
||||
(
|
||||
"yaoqingren",
|
||||
models.CharField(
|
||||
db_index=True, max_length=7, null=True, verbose_name="邀请人ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"jinrijiedan",
|
||||
models.IntegerField(default=0, verbose_name="今日接单数量"),
|
||||
),
|
||||
(
|
||||
"jinrishouyi",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="今日收益金额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"jinyuejiedan",
|
||||
models.IntegerField(default=0, verbose_name="今月接单数量"),
|
||||
),
|
||||
(
|
||||
"jinyueshouyi",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="今月收益金额",
|
||||
),
|
||||
),
|
||||
("jifen", models.IntegerField(default=0, verbose_name="打手积分")),
|
||||
(
|
||||
"yajin",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="打手押金",
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="dashou_profile",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="关联用户",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "打手扩展表",
|
||||
"verbose_name_plural": "打手扩展表",
|
||||
"db_table": "user_dashou",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="UserBoss",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("nickname", models.CharField(max_length=50, verbose_name="老板昵称")),
|
||||
(
|
||||
"zonge",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="消费总额",
|
||||
),
|
||||
),
|
||||
("alldingdan", models.IntegerField(default=0, verbose_name="订单总数")),
|
||||
("alltui", models.IntegerField(default=0, verbose_name="退款总数")),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="boss_profile",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="关联用户",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "老板扩展表",
|
||||
"verbose_name_plural": "老板扩展表",
|
||||
"db_table": "user_boss",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Tixianjilu",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
primary_key=True, serialize=False, verbose_name="提现记录ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"yonghuid",
|
||||
models.CharField(
|
||||
db_index=True, max_length=7, verbose_name="提现用户ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"avatar",
|
||||
models.CharField(
|
||||
blank=True, max_length=500, null=True, verbose_name="头像"
|
||||
),
|
||||
),
|
||||
(
|
||||
"phone",
|
||||
models.CharField(
|
||||
blank=True, max_length=11, null=True, verbose_name="手机号"
|
||||
),
|
||||
),
|
||||
(
|
||||
"nicheng",
|
||||
models.CharField(max_length=50, null=True, verbose_name="打手昵称"),
|
||||
),
|
||||
(
|
||||
"leixing",
|
||||
models.PositiveIntegerField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name="提现类型1:打手佣金2:管事分红",
|
||||
),
|
||||
),
|
||||
(
|
||||
"zhifu",
|
||||
models.CharField(
|
||||
blank=True, max_length=500, null=True, verbose_name="收款码图片"
|
||||
),
|
||||
),
|
||||
(
|
||||
"skzhanghao",
|
||||
models.CharField(
|
||||
blank=True, max_length=11, null=True, verbose_name="收款账号"
|
||||
),
|
||||
),
|
||||
(
|
||||
"jine",
|
||||
models.DecimalField(
|
||||
blank=True,
|
||||
decimal_places=2,
|
||||
max_digits=10,
|
||||
null=True,
|
||||
verbose_name="提现金额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"zhuangtai",
|
||||
models.IntegerField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
default=1,
|
||||
null=True,
|
||||
verbose_name="提现状态1:审核2:成功3:失败",
|
||||
),
|
||||
),
|
||||
(
|
||||
"fangshi",
|
||||
models.IntegerField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
null=True,
|
||||
verbose_name="收款方式1:微信2:支付宝",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shenheid",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=7,
|
||||
null=True,
|
||||
verbose_name="审核用户ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"bhliyou",
|
||||
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": "tixianjilu",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["yonghuid"], name="tixianjilu_yonghui_8083bb_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["zhuangtai"], name="tixianjilu_zhuangt_839d8e_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["shenheid"], name="tixianjilu_shenhei_470e0c_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["fangshi"], name="tixianjilu_fangshi_a1e0bc_idx"
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="AdminProfile",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("password", models.CharField(max_length=255, verbose_name="密码")),
|
||||
(
|
||||
"wechat",
|
||||
models.CharField(
|
||||
blank=True, max_length=50, verbose_name="管理员微信"
|
||||
),
|
||||
),
|
||||
(
|
||||
"yaoqingma",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=20,
|
||||
null=True,
|
||||
verbose_name="管理员邀请码",
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="admin_profile",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="关联用户",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "管理员扩展表",
|
||||
"verbose_name_plural": "管理员扩展表",
|
||||
"db_table": "admin_profile",
|
||||
},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="usermain",
|
||||
index=models.Index(
|
||||
fields=["yonghuid"], name="user_main_yonghui_b8b2fe_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="usermain",
|
||||
index=models.Index(fields=["openid"], name="user_main_openid_c9edbe_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="usermain",
|
||||
index=models.Index(
|
||||
fields=["user_type"], name="user_main_user_ty_8515fd_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="usershangjia",
|
||||
index=models.Index(fields=["user"], name="user_shangj_user_id_823c5c_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="usershangjia",
|
||||
index=models.Index(
|
||||
fields=["nicheng"], name="user_shangj_nicheng_6967bc_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="userguanshi",
|
||||
index=models.Index(fields=["user"], name="user_guansh_user_id_cbadac_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="userguanshi",
|
||||
index=models.Index(
|
||||
fields=["yaoqingma"], name="user_guansh_yaoqing_21d1d4_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="userdashou",
|
||||
index=models.Index(fields=["user"], name="user_dashou_user_id_cf0410_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="userdashou",
|
||||
index=models.Index(
|
||||
fields=["yaoqingren"], name="user_dashou_yaoqing_894658_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="userboss",
|
||||
index=models.Index(fields=["user"], name="user_boss_user_id_4e81a4_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="adminprofile",
|
||||
index=models.Index(fields=["user"], name="admin_profi_user_id_7d067d_idx"),
|
||||
),
|
||||
]
|
||||
90
yonghu/migrations/0002_rankingrecord.py
Normal file
90
yonghu/migrations/0002_rankingrecord.py
Normal file
@@ -0,0 +1,90 @@
|
||||
# Generated by Django 4.2.27 on 2026-01-24 22:53
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="RankingRecord",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
primary_key=True, serialize=False, verbose_name="ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"zhouqi",
|
||||
models.IntegerField(
|
||||
choices=[(1, "日榜"), (2, "月榜")], verbose_name="周期类型"
|
||||
),
|
||||
),
|
||||
(
|
||||
"tongji_date",
|
||||
models.DateField(db_index=True, verbose_name="统计日期"),
|
||||
),
|
||||
(
|
||||
"shenfen",
|
||||
models.IntegerField(
|
||||
choices=[(2, "打手"), (3, "管事"), (4, "商家")],
|
||||
verbose_name="用户身份",
|
||||
),
|
||||
),
|
||||
(
|
||||
"yonghuid",
|
||||
models.CharField(
|
||||
db_index=True, max_length=7, verbose_name="用户ID"
|
||||
),
|
||||
),
|
||||
("paiming", models.IntegerField(verbose_name="排名")),
|
||||
(
|
||||
"zhizhi",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="指标值",
|
||||
),
|
||||
),
|
||||
(
|
||||
"nicheng",
|
||||
models.CharField(max_length=50, null=True, verbose_name="用户昵称"),
|
||||
),
|
||||
(
|
||||
"avatar",
|
||||
models.CharField(
|
||||
blank=True, max_length=500, null=True, verbose_name="头像"
|
||||
),
|
||||
),
|
||||
(
|
||||
"chuangjian_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "排行榜记录",
|
||||
"verbose_name_plural": "排行榜记录",
|
||||
"db_table": "ranking_record",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["zhouqi", "tongji_date", "shenfen", "paiming"],
|
||||
name="ranking_rec_zhouqi_fc9f4d_idx",
|
||||
),
|
||||
models.Index(
|
||||
fields=["yonghuid", "zhouqi"],
|
||||
name="ranking_rec_yonghui_e5be77_idx",
|
||||
),
|
||||
models.Index(
|
||||
fields=["tongji_date"], name="ranking_rec_tongji__820158_idx"
|
||||
),
|
||||
],
|
||||
"unique_together": {("zhouqi", "tongji_date", "shenfen", "paiming")},
|
||||
},
|
||||
),
|
||||
]
|
||||
24
yonghu/migrations/0003_alter_usermain_avatar.py
Normal file
24
yonghu/migrations/0003_alter_usermain_avatar.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 4.2.27 on 2026-01-24 23:49
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0002_rankingrecord"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="usermain",
|
||||
name="avatar",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
default="a_long/morentouxiang.jpg",
|
||||
max_length=500,
|
||||
null=True,
|
||||
verbose_name="头像",
|
||||
),
|
||||
),
|
||||
]
|
||||
63
yonghu/migrations/0004_officialaccountuser.py
Normal file
63
yonghu/migrations/0004_officialaccountuser.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-09 18:09
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0003_alter_usermain_avatar"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="OfficialAccountUser",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"unionid",
|
||||
models.CharField(
|
||||
db_index=True, max_length=64, verbose_name="UnionID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"official_openid",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=64,
|
||||
unique=True,
|
||||
verbose_name="服务号OpenID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"subscribe_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="关注时间"),
|
||||
),
|
||||
(
|
||||
"is_subscribed",
|
||||
models.BooleanField(default=True, verbose_name="是否关注"),
|
||||
),
|
||||
(
|
||||
"created_at",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"updated_at",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "服务号用户",
|
||||
"verbose_name_plural": "服务号用户",
|
||||
"db_table": "official_account_user",
|
||||
},
|
||||
),
|
||||
]
|
||||
24
yonghu/migrations/0005_usermain_unionid.py
Normal file
24
yonghu/migrations/0005_usermain_unionid.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-09 19:17
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0004_officialaccountuser"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="usermain",
|
||||
name="unionid",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=64,
|
||||
null=True,
|
||||
verbose_name="微信UnionID",
|
||||
),
|
||||
),
|
||||
]
|
||||
20
yonghu/migrations/0006_alter_officialaccountuser_unionid.py
Normal file
20
yonghu/migrations/0006_alter_officialaccountuser_unionid.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-09 19:21
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0005_usermain_unionid"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="officialaccountuser",
|
||||
name="unionid",
|
||||
field=models.CharField(
|
||||
db_index=True, max_length=64, null=True, verbose_name="UnionID"
|
||||
),
|
||||
),
|
||||
]
|
||||
79
yonghu/migrations/0007_userkefu.py
Normal file
79
yonghu/migrations/0007_userkefu.py
Normal file
@@ -0,0 +1,79 @@
|
||||
# Generated by Django 4.2.27 on 2026-02-22 01:00
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0006_alter_officialaccountuser_unionid"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="UserKefu",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("nicheng", models.CharField(max_length=50, verbose_name="客服昵称")),
|
||||
("erjimima", models.CharField(max_length=128, verbose_name="二级密码")),
|
||||
(
|
||||
"zhuangtai",
|
||||
models.IntegerField(
|
||||
choices=[(0, "禁用"), (1, "正常")],
|
||||
default=1,
|
||||
verbose_name="客服状态",
|
||||
),
|
||||
),
|
||||
(
|
||||
"jinrichuli",
|
||||
models.IntegerField(default=0, verbose_name="今日处理订单数"),
|
||||
),
|
||||
(
|
||||
"jinyuechuli",
|
||||
models.IntegerField(default=0, verbose_name="本月处理订单数"),
|
||||
),
|
||||
(
|
||||
"zongchuli",
|
||||
models.IntegerField(default=0, verbose_name="累计处理订单数"),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="kefu_profile",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="关联用户",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "客服扩展表",
|
||||
"verbose_name_plural": "客服扩展表",
|
||||
"db_table": "user_kefu",
|
||||
"indexes": [
|
||||
models.Index(fields=["user"], name="user_kefu_user_id_5fe3a1_idx"),
|
||||
models.Index(
|
||||
fields=["zhuangtai"], name="user_kefu_zhuangt_317491_idx"
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,176 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-04 23:27
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0007_userkefu"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="userdashou",
|
||||
name="ewai_xiane",
|
||||
field=models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="额外提现限额(元)",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="userdashou",
|
||||
name="jinritixian_jine",
|
||||
field=models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="今日已提现金额",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="userdashou",
|
||||
name="kaioi_ewai_xiane",
|
||||
field=models.BooleanField(
|
||||
default=False, verbose_name="是否开启额外提现限额"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="userdashou",
|
||||
name="last_tixian_date",
|
||||
field=models.DateField(blank=True, null=True, verbose_name="最近提现日期"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="usershangjia",
|
||||
name="ewai_xiane",
|
||||
field=models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="额外提现限额(元)",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="usershangjia",
|
||||
name="jinritixian_jine",
|
||||
field=models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="今日已提现金额",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="usershangjia",
|
||||
name="kaioi_ewai_xiane",
|
||||
field=models.BooleanField(
|
||||
default=False, verbose_name="是否开启额外提现限额"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="usershangjia",
|
||||
name="last_tixian_date",
|
||||
field=models.DateField(blank=True, null=True, verbose_name="最近提现日期"),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="TixianAutoRecord",
|
||||
fields=[
|
||||
("id", models.BigAutoField(primary_key=True, serialize=False)),
|
||||
(
|
||||
"tixian_id",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
unique=True,
|
||||
verbose_name="提现订单号(自定义)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"yonghuid",
|
||||
models.CharField(
|
||||
db_index=True, max_length=7, verbose_name="用户ID"
|
||||
),
|
||||
),
|
||||
("leixing", models.IntegerField(verbose_name="提现类型 1打手 2管事")),
|
||||
(
|
||||
"jine",
|
||||
models.DecimalField(
|
||||
decimal_places=2, max_digits=10, verbose_name="申请提现金额"
|
||||
),
|
||||
),
|
||||
(
|
||||
"shouxufei",
|
||||
models.DecimalField(
|
||||
decimal_places=2, max_digits=10, verbose_name="手续费"
|
||||
),
|
||||
),
|
||||
(
|
||||
"shijidaozhang",
|
||||
models.DecimalField(
|
||||
decimal_places=2, max_digits=10, verbose_name="实际到账金额"
|
||||
),
|
||||
),
|
||||
(
|
||||
"feilv",
|
||||
models.DecimalField(
|
||||
decimal_places=4, max_digits=5, verbose_name="费率"
|
||||
),
|
||||
),
|
||||
(
|
||||
"zhuangtai",
|
||||
models.IntegerField(
|
||||
choices=[(0, "处理中"), (1, "成功"), (2, "失败")],
|
||||
default=0,
|
||||
verbose_name="状态",
|
||||
),
|
||||
),
|
||||
(
|
||||
"wechat_transfer_no",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
max_length=64,
|
||||
null=True,
|
||||
verbose_name="微信转账单号",
|
||||
),
|
||||
),
|
||||
(
|
||||
"wechat_package",
|
||||
models.TextField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name="微信返回的package_info(JSON)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"fail_reason",
|
||||
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": "tixian_auto_record",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["tixian_id"], name="tixian_auto_tixian__273dac_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["yonghuid"], name="tixian_auto_yonghui_61c5b6_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["zhuangtai"], name="tixian_auto_zhuangt_24d9fa_idx"
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,61 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-05 16:11
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0008_userdashou_ewai_xiane_userdashou_jinritixian_jine_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name="usershangjia",
|
||||
name="ewai_xiane",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="usershangjia",
|
||||
name="jinritixian_jine",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="usershangjia",
|
||||
name="kaioi_ewai_xiane",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="usershangjia",
|
||||
name="last_tixian_date",
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="userguanshi",
|
||||
name="ewai_xiane",
|
||||
field=models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="额外提现限额(元)",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="userguanshi",
|
||||
name="jinritixian_jine",
|
||||
field=models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="今日已提现金额",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="userguanshi",
|
||||
name="kaioi_ewai_xiane",
|
||||
field=models.BooleanField(
|
||||
default=False, verbose_name="是否开启额外提现限额"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="userguanshi",
|
||||
name="last_tixian_date",
|
||||
field=models.DateField(blank=True, null=True, verbose_name="最近提现日期"),
|
||||
),
|
||||
]
|
||||
20
yonghu/migrations/0010_alter_tixianjilu_shenheid.py
Normal file
20
yonghu/migrations/0010_alter_tixianjilu_shenheid.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-06 21:46
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0009_remove_usershangjia_ewai_xiane_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="tixianjilu",
|
||||
name="shenheid",
|
||||
field=models.CharField(
|
||||
db_index=True, max_length=11, null=True, verbose_name="审核用户ID"
|
||||
),
|
||||
),
|
||||
]
|
||||
23
yonghu/migrations/0011_userguanshi_invite_qrcode_url.py
Normal file
23
yonghu/migrations/0011_userguanshi_invite_qrcode_url.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-10 21:32
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0010_alter_tixianjilu_shenheid"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="userguanshi",
|
||||
name="invite_qrcode_url",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
max_length=500,
|
||||
null=True,
|
||||
verbose_name="邀请码二维码图片URL",
|
||||
),
|
||||
),
|
||||
]
|
||||
181
yonghu/migrations/0012_userguanshi_fenghong_erci_and_more.py
Normal file
181
yonghu/migrations/0012_userguanshi_fenghong_erci_and_more.py
Normal file
@@ -0,0 +1,181 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-19 15:28
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0011_userguanshi_invite_qrcode_url"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="userguanshi",
|
||||
name="fenghong_erci",
|
||||
field=models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="二次分红金额",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="userguanshi",
|
||||
name="fenghong_erci_enabled",
|
||||
field=models.BooleanField(default=False, verbose_name="开启二次分红"),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="UserZuzhang",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"yaoqingma",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=20,
|
||||
unique=True,
|
||||
verbose_name="组长邀请码",
|
||||
),
|
||||
),
|
||||
(
|
||||
"fenyong_zonge",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="分佣总额(元)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"ketixian_jine",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="可提现金额(元)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"yaoqing_zongshu",
|
||||
models.IntegerField(default=0, verbose_name="邀请总数"),
|
||||
),
|
||||
(
|
||||
"jinri_fenyong",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="今日分佣(元)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"jinyue_fenyong",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="今月分佣(元)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"zhuangtai",
|
||||
models.IntegerField(
|
||||
choices=[(0, "禁用"), (1, "正常")],
|
||||
default=1,
|
||||
verbose_name="账号状态",
|
||||
),
|
||||
),
|
||||
(
|
||||
"haibao_url",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
max_length=500,
|
||||
null=True,
|
||||
verbose_name="推广海报相对URL",
|
||||
),
|
||||
),
|
||||
(
|
||||
"jinri_tixian",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="今日提现金额(元)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"last_tixian_time",
|
||||
models.DateTimeField(
|
||||
blank=True, null=True, verbose_name="最后提现时间"
|
||||
),
|
||||
),
|
||||
(
|
||||
"ewai_tixian_xiane",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=10,
|
||||
verbose_name="额外提现限额(元)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"kaioi_ewai_tixian",
|
||||
models.BooleanField(default=False, verbose_name="开启额外提现"),
|
||||
),
|
||||
(
|
||||
"kaioi_ewai_fenhong",
|
||||
models.BooleanField(default=False, verbose_name="开启额外分红"),
|
||||
),
|
||||
(
|
||||
"ewai_fenhong_jine",
|
||||
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="更新时间"),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="zuzhang_profile",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="关联用户",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "组长扩展表",
|
||||
"verbose_name_plural": "组长扩展表",
|
||||
"db_table": "user_zuzhang",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["user"], name="user_zuzhan_user_id_8064f2_idx"
|
||||
),
|
||||
models.Index(
|
||||
fields=["yaoqingma"], name="user_zuzhan_yaoqing_cba91d_idx"
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
]
|
||||
20
yonghu/migrations/0013_userguanshi_yaoqingren.py
Normal file
20
yonghu/migrations/0013_userguanshi_yaoqingren.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 4.2.27 on 2026-03-19 16:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0012_userguanshi_fenghong_erci_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="userguanshi",
|
||||
name="yaoqingren",
|
||||
field=models.CharField(
|
||||
db_index=True, max_length=7, null=True, verbose_name="邀请人ID"
|
||||
),
|
||||
),
|
||||
]
|
||||
20
yonghu/migrations/0014_usermain_session_key.py
Normal file
20
yonghu/migrations/0014_usermain_session_key.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-03 12:28
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0013_userguanshi_yaoqingren"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="usermain",
|
||||
name="session_key",
|
||||
field=models.CharField(
|
||||
blank=True, max_length=100, null=True, verbose_name="微信虚拟支付"
|
||||
),
|
||||
),
|
||||
]
|
||||
18
yonghu/migrations/0015_usermain_shoujihao_renzheng.py
Normal file
18
yonghu/migrations/0015_usermain_shoujihao_renzheng.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-13 08:51
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0014_usermain_session_key"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="usermain",
|
||||
name="shoujihao_renzheng",
|
||||
field=models.BooleanField(default=False, verbose_name="手机号是否已认证"),
|
||||
),
|
||||
]
|
||||
100
yonghu/migrations/0016_usershenheguan.py
Normal file
100
yonghu/migrations/0016_usershenheguan.py
Normal file
@@ -0,0 +1,100 @@
|
||||
# Generated by Django 4.2.27 on 2026-05-19 17:30
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0015_usermain_shoujihao_renzheng"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="UserShenheguan",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"zhuangtai",
|
||||
models.IntegerField(
|
||||
choices=[(0, "禁用"), (1, "正常")],
|
||||
default=1,
|
||||
verbose_name="账号状态",
|
||||
),
|
||||
),
|
||||
(
|
||||
"is_renzheng",
|
||||
models.BooleanField(default=False, verbose_name="是否认证"),
|
||||
),
|
||||
(
|
||||
"shenhe_zhuangtai",
|
||||
models.IntegerField(
|
||||
choices=[(0, "空闲"), (1, "审核中")],
|
||||
default=0,
|
||||
verbose_name="审核官状态",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shenhe_zongshu",
|
||||
models.IntegerField(default=0, verbose_name="审核总数"),
|
||||
),
|
||||
(
|
||||
"tongguo_zongshu",
|
||||
models.IntegerField(default=0, verbose_name="通过总数"),
|
||||
),
|
||||
(
|
||||
"yue",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="可提现余额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"zonge",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0.0,
|
||||
max_digits=12,
|
||||
verbose_name="赚取总额",
|
||||
),
|
||||
),
|
||||
(
|
||||
"create_time",
|
||||
models.DateTimeField(auto_now_add=True, verbose_name="创建时间"),
|
||||
),
|
||||
(
|
||||
"update_time",
|
||||
models.DateTimeField(auto_now=True, verbose_name="更新时间"),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.OneToOneField(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="shenheguan_profile",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="关联用户",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "审核官扩展表",
|
||||
"verbose_name_plural": "审核官扩展表",
|
||||
"db_table": "user_shenheguan",
|
||||
"indexes": [
|
||||
models.Index(fields=["user"], name="user_shenhe_user_id_624f19_idx")
|
||||
],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,197 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-08 17:30
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0016_usershenheguan"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="tixianautorecord",
|
||||
name="shenhe_danhao",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
null=True,
|
||||
verbose_name="关联审核单号",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="tixianjilu",
|
||||
name="shenhe_danhao",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
null=True,
|
||||
verbose_name="关联提现审核单号",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="tixianjilu",
|
||||
name="shenhe_jilu_id",
|
||||
field=models.IntegerField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
null=True,
|
||||
verbose_name="关联提现审核记录ID(TixianShenheJilu.id)",
|
||||
),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="TixianShenheJilu",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shenhe_danhao",
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
unique=True,
|
||||
verbose_name="审核单号",
|
||||
),
|
||||
),
|
||||
(
|
||||
"yonghuid",
|
||||
models.CharField(
|
||||
db_index=True, max_length=7, verbose_name="用户ID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"leixing",
|
||||
models.PositiveSmallIntegerField(
|
||||
db_index=True, verbose_name="提现类型"
|
||||
),
|
||||
),
|
||||
(
|
||||
"zhuangtai",
|
||||
models.IntegerField(
|
||||
db_index=True,
|
||||
default=1,
|
||||
verbose_name="审核状态(1审核中2提现成功3提现失败4审核成功5审核失败6待收款)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shenqing_jine",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
max_digits=10,
|
||||
verbose_name="申请提现金额(扣款额)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shouxufei",
|
||||
models.DecimalField(
|
||||
decimal_places=2,
|
||||
default=0,
|
||||
max_digits=10,
|
||||
verbose_name="手续费",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shijidaozhang",
|
||||
models.DecimalField(
|
||||
decimal_places=2, max_digits=10, verbose_name="实际到账金额"
|
||||
),
|
||||
),
|
||||
(
|
||||
"feilv",
|
||||
models.DecimalField(
|
||||
decimal_places=4,
|
||||
default=0,
|
||||
max_digits=5,
|
||||
verbose_name="手续费率",
|
||||
),
|
||||
),
|
||||
(
|
||||
"bhliyou",
|
||||
models.TextField(
|
||||
blank=True, null=True, verbose_name="驳回/失败原因"
|
||||
),
|
||||
),
|
||||
(
|
||||
"bo_hui_ren_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=11,
|
||||
null=True,
|
||||
verbose_name="驳回人用户ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"shenhe_ren_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=11,
|
||||
null=True,
|
||||
verbose_name="审核通过操作人ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"tixianjilu_id",
|
||||
models.IntegerField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
null=True,
|
||||
verbose_name="关联Tixianjilu.id",
|
||||
),
|
||||
),
|
||||
(
|
||||
"tixian_auto_id",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
max_length=32,
|
||||
null=True,
|
||||
verbose_name="最近一次打款单号(非唯一,重试收款会更新)",
|
||||
),
|
||||
),
|
||||
(
|
||||
"fail_reason",
|
||||
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": "tixian_shenhe_jilu",
|
||||
"indexes": [
|
||||
models.Index(
|
||||
fields=["yonghuid", "zhuangtai"],
|
||||
name="tixian_shen_yonghui_a782e9_idx",
|
||||
),
|
||||
models.Index(
|
||||
fields=["yonghuid", "leixing"],
|
||||
name="tixian_shen_yonghui_bb44eb_idx",
|
||||
),
|
||||
models.Index(
|
||||
fields=["shenhe_danhao"], name="tixian_shen_shenhe__4a1ca7_idx"
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
]
|
||||
20
yonghu/migrations/0018_tixianjilu_dakuan_mode.py
Normal file
20
yonghu/migrations/0018_tixianjilu_dakuan_mode.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 4.2.27 on 2026-06-08 18:23
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("yonghu", "0017_tixianautorecord_shenhe_danhao_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="tixianjilu",
|
||||
name="dakuan_mode",
|
||||
field=models.PositiveSmallIntegerField(
|
||||
db_index=True, default=1, verbose_name="打款方式(1手动2自动)"
|
||||
),
|
||||
),
|
||||
]
|
||||
0
yonghu/migrations/__init__.py
Normal file
0
yonghu/migrations/__init__.py
Normal file
596
yonghu/models.py
Normal file
596
yonghu/models.py
Normal file
@@ -0,0 +1,596 @@
|
||||
# models.py
|
||||
from django.db import models
|
||||
import random
|
||||
import string
|
||||
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
|
||||
|
||||
# ==================== 用户主表 ====================
|
||||
class UserMain(AbstractBaseUser):
|
||||
# ID字段
|
||||
id = models.AutoField(primary_key=True, verbose_name='主键ID')
|
||||
yonghuid = models.CharField(max_length=7, unique=True, db_index=True, verbose_name='用户ID')
|
||||
|
||||
# 微信相关字段
|
||||
openid = models.CharField(max_length=64, unique=True, db_index=True, verbose_name='微信OpenID')
|
||||
unionid = models.CharField(max_length=64, null=True, blank=True, db_index=True, verbose_name='微信UnionID')
|
||||
session_key = models.CharField(max_length=100, blank=True, null=True,verbose_name='微信虚拟支付')
|
||||
|
||||
# 基础信息字段
|
||||
#tupian_url = models.CharField(max_length=500, null=True, blank=True, verbose_name='商品图片URL') # 用CharField
|
||||
avatar = models.CharField(max_length=500, null=True, blank=True, default='a_long/morentouxiang.jpg', verbose_name='头像') # 用CharField
|
||||
phone = models.CharField(max_length=11, blank=True, null=True, verbose_name='手机号')
|
||||
shoujihao_renzheng = models.BooleanField(default=False, verbose_name='手机号是否已认证')
|
||||
password = models.CharField(max_length=200, null=True, blank=True, verbose_name='密码')
|
||||
zhifu = models.CharField(max_length=500, null=True, blank=True, verbose_name='收款码图片') # 用CharField
|
||||
skzhanghao = models.CharField(max_length=11, blank=True, null=True, verbose_name='收款账号')
|
||||
ip = models.CharField(max_length=50, blank=True, null=True, verbose_name='来访用户ip')
|
||||
last_login_time = models.DateTimeField(null=True, blank=True, verbose_name='最后登录时间')
|
||||
|
||||
|
||||
# 用户类型字段
|
||||
user_type = models.CharField(
|
||||
max_length=10,
|
||||
choices=[
|
||||
('normal', '普通用户'),
|
||||
('dashou', '打手'),
|
||||
('shop', '商家'),
|
||||
('guanshi', '管事'),
|
||||
('admin', '管理员')
|
||||
],
|
||||
default='normal',
|
||||
verbose_name='用户类型'
|
||||
)
|
||||
|
||||
# 状态和时间字段
|
||||
#is_active = models.BooleanField(default=True, verbose_name='是否激活')
|
||||
#last_login = models.DateTimeField(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='更新时间')
|
||||
|
||||
# 邀请码字段
|
||||
#yaoqingma = models.CharField(max_length=20, blank=True, null=True, verbose_name='邀请码')
|
||||
|
||||
# 只需要添加这3行
|
||||
USERNAME_FIELD = 'openid' # 用openid作为用户名
|
||||
REQUIRED_FIELDS = ['yonghuid'] # 必填字段
|
||||
|
||||
class Meta:
|
||||
db_table = 'user_main'
|
||||
verbose_name = '用户主表'
|
||||
verbose_name_plural = verbose_name
|
||||
indexes = [
|
||||
models.Index(fields=['yonghuid']),
|
||||
models.Index(fields=['openid']),
|
||||
#models.Index(fields=['phone']),
|
||||
models.Index(fields=['user_type']),
|
||||
#models.Index(fields=['create_time']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.yonghuid}'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 新增服务号用户表
|
||||
class OfficialAccountUser(models.Model):
|
||||
unionid = models.CharField(max_length=64, null =True,db_index=True, verbose_name='UnionID')
|
||||
official_openid = models.CharField(max_length=64, db_index=True, unique=True, verbose_name='服务号OpenID')
|
||||
subscribe_time = models.DateTimeField(auto_now_add=True, verbose_name='关注时间')
|
||||
is_subscribed = models.BooleanField(default=True, verbose_name='是否关注')
|
||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
|
||||
|
||||
class Meta:
|
||||
db_table = 'official_account_user'
|
||||
verbose_name = '服务号用户'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.unionid[:8]}... (关注: {self.is_subscribed})"
|
||||
|
||||
|
||||
|
||||
# ==================== 老板扩展表 ====================
|
||||
class UserBoss(models.Model):
|
||||
user = models.OneToOneField(UserMain, on_delete=models.CASCADE, related_name='boss_profile',
|
||||
verbose_name='关联用户')
|
||||
nickname = models.CharField(max_length=50, verbose_name='老板昵称')
|
||||
zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='消费总额')
|
||||
alldingdan = models.IntegerField(default=0, verbose_name='订单总数')
|
||||
alltui = models.IntegerField(default=0, verbose_name='退款总数')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
|
||||
class Meta:
|
||||
db_table = 'user_boss'
|
||||
verbose_name = '老板扩展表'
|
||||
verbose_name_plural = verbose_name
|
||||
indexes = [models.Index(fields=['user']), ]
|
||||
|
||||
|
||||
# ==================== 打手扩展表 ====================
|
||||
class UserDashou(models.Model):
|
||||
user = models.OneToOneField(UserMain, on_delete=models.CASCADE, related_name='dashou_profile',
|
||||
verbose_name='关联用户')
|
||||
nicheng = models.CharField(max_length=50, null=True, verbose_name='打手昵称')
|
||||
chenghao = models.CharField(max_length=50, null=True,verbose_name='打手称号')
|
||||
zhuangtai = models.IntegerField(default=1, verbose_name='打手状态')
|
||||
zaixianzhuangtai = models.IntegerField(default=1, verbose_name='打手在线状态')
|
||||
zhanghaozhuangtai = models.IntegerField(default=1, verbose_name='打手账号状态')
|
||||
jieshao = models.TextField(null=True, verbose_name='打手介绍')
|
||||
jiedanzongliang = models.IntegerField(default=0, verbose_name='接单总量')
|
||||
chengjiaozongliang = models.IntegerField(default=0, verbose_name='成交单总量')
|
||||
tuikuanliang = models.IntegerField(default=0, verbose_name='退款订单总量')
|
||||
yue = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='可提现余额')
|
||||
zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='打单赚取总额')
|
||||
dianhua = models.CharField(max_length=20, null=True, verbose_name='打手电话')
|
||||
wechat = models.CharField(max_length=50,null=True, verbose_name='打手微信号')
|
||||
yaoqingren = models.CharField(max_length=7,null=True, db_index=True, verbose_name='邀请人ID')
|
||||
jinrijiedan = models.IntegerField(default=0, verbose_name='今日接单数量')
|
||||
jinrishouyi = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='今日收益金额')
|
||||
jinyuejiedan = models.IntegerField(default=0, verbose_name='今月接单数量')
|
||||
jinyueshouyi = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='今月收益金额')
|
||||
jifen = models.IntegerField(default=0, verbose_name='打手积分')
|
||||
yajin= models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='打手押金')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
|
||||
last_tixian_date = models.DateField(null=True, blank=True, verbose_name='最近提现日期') # 用于重置今日提现金额
|
||||
jinritixian_jine = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='今日已提现金额')
|
||||
kaioi_ewai_xiane = models.BooleanField(default=False, verbose_name='是否开启额外提现限额') # True=开启额外限额
|
||||
ewai_xiane = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='额外提现限额(元)')
|
||||
|
||||
class Meta:
|
||||
db_table = 'user_dashou'
|
||||
verbose_name = '打手扩展表'
|
||||
verbose_name_plural = verbose_name
|
||||
indexes = [
|
||||
models.Index(fields=['user']),
|
||||
#models.Index(fields=['zhuangtai']),
|
||||
models.Index(fields=['yaoqingren']),
|
||||
#models.Index(fields=['nicheng']),
|
||||
|
||||
]
|
||||
|
||||
|
||||
# ==================== 商家扩展表 ====================
|
||||
class UserShangjia(models.Model):
|
||||
user = models.OneToOneField(UserMain, on_delete=models.CASCADE, related_name='shop_profile',
|
||||
verbose_name='关联用户')
|
||||
nicheng = models.CharField(max_length=50, unique=True, db_index=True, verbose_name='商家昵称')
|
||||
zhuangtai = models.IntegerField(choices=[(0, '待审核'), (1, '正常'), (2, '禁用')], default=1,
|
||||
verbose_name='商家状态')
|
||||
dianhua = models.CharField(max_length=20,null=True,verbose_name='商家电话')
|
||||
wechat = models.CharField(max_length=50, null=True, verbose_name='商家微信号')
|
||||
fabu = models.IntegerField(default=0, verbose_name='发布订单总数量')
|
||||
tuikuan = models.IntegerField(default=0, verbose_name='退款订单总量')
|
||||
yue = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='商家余额')
|
||||
chengjiao = models.IntegerField(default=0, verbose_name='商家成交订单总量')
|
||||
jinridingdan = models.IntegerField(default=0, verbose_name='商家今日订单总量')
|
||||
jinriliushui = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='商家今日流水')
|
||||
jinyuedingdan = models.IntegerField(default=0, verbose_name='商家今月订单总量')
|
||||
jinyueliushui = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='商家今月流水')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Meta:
|
||||
db_table = 'user_shangjia'
|
||||
verbose_name = '商家扩展表'
|
||||
verbose_name_plural = verbose_name
|
||||
indexes = [
|
||||
models.Index(fields=['user']),
|
||||
models.Index(fields=['nicheng']),
|
||||
]
|
||||
|
||||
|
||||
# ==================== 管事扩展表 ====================
|
||||
class UserGuanshi(models.Model):
|
||||
user = models.OneToOneField(UserMain, on_delete=models.CASCADE, related_name='guanshi_profile',
|
||||
verbose_name='关联用户')
|
||||
yaoqingren = models.CharField(max_length=7, null=True, db_index=True, verbose_name='邀请人ID')
|
||||
|
||||
yaoqingma = models.CharField(max_length=20,null=True,db_index=True, verbose_name='邀请码')
|
||||
invite_qrcode_url = models.CharField(max_length=500, null=True, blank=True, verbose_name='邀请码二维码图片URL')
|
||||
dianhua = models.CharField(max_length=20,null=True, verbose_name='管事电话')
|
||||
wechat = models.CharField(max_length=50,null=True, verbose_name='管事微信号')
|
||||
yaogingshuliang = models.IntegerField(default=0, verbose_name='邀请打手总数')
|
||||
zhuangtai = models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='管事状态')
|
||||
jinrichongzhi = models.IntegerField(default=0, verbose_name='今日充值打手数量')
|
||||
jinyuechongzhi = models.IntegerField(default=0, verbose_name='今月充值打手数量')
|
||||
chongzhifenrun = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='充值分佣总额')
|
||||
yue = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='可提现余额')
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
|
||||
# 新增:二次分红开关
|
||||
fenghong_erci_enabled = models.BooleanField(default=False,verbose_name='开启二次分红')
|
||||
|
||||
# 新增:二次分红金额
|
||||
fenghong_erci = models.DecimalField(max_digits=10,decimal_places=2,default=0.00,verbose_name='二次分红金额')
|
||||
|
||||
|
||||
last_tixian_date = models.DateField(null=True, blank=True, verbose_name='最近提现日期')
|
||||
jinritixian_jine = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='今日已提现金额')
|
||||
kaioi_ewai_xiane = models.BooleanField(default=False, verbose_name='是否开启额外提现限额')
|
||||
ewai_xiane = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='额外提现限额(元)')
|
||||
|
||||
class Meta:
|
||||
db_table = 'user_guanshi'
|
||||
verbose_name = '管事扩展表'
|
||||
verbose_name_plural = verbose_name
|
||||
indexes = [models.Index(fields=['user']),
|
||||
models.Index(fields=['yaoqingma']),
|
||||
]
|
||||
|
||||
|
||||
class UserZuzhang(models.Model):
|
||||
"""组长扩展表(与UserMain一对一关联)"""
|
||||
user = models.OneToOneField(
|
||||
UserMain,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='zuzhang_profile',
|
||||
verbose_name='关联用户',
|
||||
db_index=True
|
||||
)
|
||||
# 组长邀请码
|
||||
yaoqingma = models.CharField(max_length=20, unique=True, db_index=True, verbose_name='组长邀请码')
|
||||
# 分佣总额
|
||||
fenyong_zonge = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='分佣总额(元)')
|
||||
# 可提现金额
|
||||
ketixian_jine = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='可提现金额(元)')
|
||||
# 邀请总数
|
||||
yaoqing_zongshu = models.IntegerField(default=0, verbose_name='邀请总数')
|
||||
# 今日分佣
|
||||
jinri_fenyong = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='今日分佣(元)')
|
||||
# 今月分佣
|
||||
jinyue_fenyong = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='今月分佣(元)')
|
||||
# 账号状态
|
||||
zhuangtai = models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='账号状态')
|
||||
# 推广海报相对URL
|
||||
haibao_url = models.CharField(max_length=500, null=True, blank=True, verbose_name='推广海报相对URL')
|
||||
# 今日提现
|
||||
jinri_tixian = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='今日提现金额(元)')
|
||||
# 最后提现时间
|
||||
last_tixian_time = models.DateTimeField(null=True, blank=True, verbose_name='最后提现时间')
|
||||
# 额外提现限额
|
||||
ewai_tixian_xiane = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name='额外提现限额(元)')
|
||||
# 是否开启额外提现
|
||||
kaioi_ewai_tixian = models.BooleanField(default=False, verbose_name='开启额外提现')
|
||||
# 是否开启额外分红
|
||||
kaioi_ewai_fenhong = models.BooleanField(default=False, verbose_name='开启额外分红')
|
||||
# 额外分红金额
|
||||
ewai_fenhong_jine = 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 = 'user_zuzhang'
|
||||
verbose_name = '组长扩展表'
|
||||
verbose_name_plural = verbose_name
|
||||
indexes = [
|
||||
models.Index(fields=['user']),
|
||||
models.Index(fields=['yaoqingma']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"组长 {self.user.yonghuid}"
|
||||
|
||||
|
||||
# ==================== 管理员扩展表 ====================
|
||||
class AdminProfile(models.Model):
|
||||
user = models.OneToOneField(UserMain, on_delete=models.CASCADE, related_name='admin_profile',
|
||||
verbose_name='关联用户')
|
||||
password = models.CharField(max_length=255, verbose_name='密码')
|
||||
wechat = models.CharField(max_length=50, blank=True, verbose_name='管理员微信')
|
||||
yaoqingma = models.CharField(max_length=20, null=True, db_index=True,verbose_name='管理员邀请码') # 🟢 新增字段
|
||||
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
|
||||
class Meta:
|
||||
db_table = 'admin_profile'
|
||||
verbose_name = '管理员扩展表'
|
||||
verbose_name_plural = verbose_name
|
||||
indexes = [models.Index(fields=['user']), ]
|
||||
|
||||
|
||||
class UserKefu(models.Model):
|
||||
user = models.OneToOneField(UserMain, on_delete=models.CASCADE, related_name='kefu_profile', verbose_name='关联用户')
|
||||
nicheng = models.CharField(max_length=50, verbose_name='客服昵称')
|
||||
erjimima = models.CharField(max_length=128, verbose_name='二级密码')
|
||||
zhuangtai = models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='客服状态')
|
||||
jinrichuli = models.IntegerField(default=0, verbose_name='今日处理订单数')
|
||||
jinyuechuli = models.IntegerField(default=0, verbose_name='本月处理订单数')
|
||||
zongchuli = models.IntegerField(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 = 'user_kefu'
|
||||
verbose_name = '客服扩展表'
|
||||
verbose_name_plural = verbose_name
|
||||
indexes = [
|
||||
models.Index(fields=['user']),
|
||||
models.Index(fields=['zhuangtai']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.nicheng} ({self.user.yonghuid})"
|
||||
|
||||
|
||||
|
||||
class UserShenheguan(models.Model):
|
||||
"""审核官扩展表(与UserMain一对一关联)"""
|
||||
user = models.OneToOneField(UserMain, on_delete=models.CASCADE, related_name='shenheguan_profile', verbose_name='关联用户', db_index=True)
|
||||
zhuangtai = models.IntegerField(choices=[(0, '禁用'), (1, '正常')], default=1, verbose_name='账号状态')
|
||||
is_renzheng = models.BooleanField(default=False, verbose_name='是否认证')
|
||||
shenhe_zhuangtai = models.IntegerField(choices=[(0, '空闲'), (1, '审核中')], default=0, verbose_name='审核官状态')
|
||||
shenhe_zongshu = models.IntegerField(default=0, verbose_name='审核总数')
|
||||
tongguo_zongshu = models.IntegerField(default=0, verbose_name='通过总数')
|
||||
yue = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='可提现余额')
|
||||
zonge = models.DecimalField(max_digits=12, 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 = 'user_shenheguan'
|
||||
verbose_name = '审核官扩展表'
|
||||
verbose_name_plural = verbose_name
|
||||
indexes = [models.Index(fields=['user'])]
|
||||
|
||||
|
||||
|
||||
|
||||
class Tixianjilu(models.Model):
|
||||
id = models.AutoField(primary_key=True, verbose_name='提现记录ID')
|
||||
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='提现用户ID')
|
||||
avatar = models.CharField(max_length=500, null=True, blank=True, verbose_name='头像') # 用CharField
|
||||
phone = models.CharField(max_length=11, blank=True, null=True, verbose_name='手机号')
|
||||
nicheng = models.CharField(max_length=50, null=True, verbose_name='打手昵称')
|
||||
leixing = models.PositiveIntegerField(null=True, blank=True, verbose_name='提现类型1:打手佣金2:管事分红')
|
||||
zhifu = models.CharField(max_length=500, null=True, blank=True, verbose_name='收款码图片') # 用CharField
|
||||
skzhanghao = models.CharField(max_length=11, blank=True, null=True, verbose_name='收款账号')
|
||||
jine = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='提现金额')
|
||||
# 状态与平台:用整数表示,具体含义由业务逻辑定义
|
||||
zhuangtai = models.IntegerField(default=1, null=True, blank=True, db_index=True, verbose_name='提现状态1:审核2:成功3:失败')
|
||||
fangshi = models.IntegerField(null=True, blank=True,db_index=True, verbose_name='收款方式1:微信2:支付宝')
|
||||
dakuan_mode = models.PositiveSmallIntegerField(
|
||||
default=1, db_index=True, verbose_name='打款方式(1手动2自动)'
|
||||
)
|
||||
shenheid = models.CharField(max_length=11, null=True, db_index=True, verbose_name='审核用户ID')
|
||||
bhliyou = models.TextField(null=True, blank=True, verbose_name='驳回理由')
|
||||
# ---------- 自动提现审核新流程关联字段(旧数据为空,兼容历史记录) ----------
|
||||
shenhe_jilu_id = models.IntegerField(
|
||||
null=True, blank=True, db_index=True,
|
||||
verbose_name='关联提现审核记录ID(TixianShenheJilu.id)'
|
||||
)
|
||||
shenhe_danhao = models.CharField(
|
||||
max_length=32, null=True, blank=True, db_index=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 = 'tixianjilu'
|
||||
verbose_name = '提现记录表'
|
||||
verbose_name_plural = verbose_name
|
||||
indexes = [models.Index(fields=['yonghuid']),
|
||||
models.Index(fields=['zhuangtai']),
|
||||
models.Index(fields=['shenheid']),
|
||||
models.Index(fields=['fangshi']),
|
||||
]
|
||||
|
||||
|
||||
|
||||
class TixianShenheJilu(models.Model):
|
||||
"""
|
||||
提现审核记录表(自动打款新流程)
|
||||
状态码与前端 TX_STATUS / Tixianjilu.zhuangtai 完全对标:
|
||||
1=审核中 2=提现成功(已收款) 3=提现失败 4=审核成功 5=审核失败 6=待收款
|
||||
"""
|
||||
# 审核单号(唯一,前端字段 shenhe_danhao)
|
||||
shenhe_danhao = models.CharField(
|
||||
max_length=32, unique=True, db_index=True, verbose_name='审核单号'
|
||||
)
|
||||
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
|
||||
# 提现类型:1打手佣金 2管事分红 3组长分红 4考核官分佣 5打手押金 6商家余额
|
||||
leixing = models.PositiveSmallIntegerField(db_index=True, verbose_name='提现类型')
|
||||
zhuangtai = models.IntegerField(
|
||||
default=1, db_index=True,
|
||||
verbose_name='审核状态(1审核中2提现成功3提现失败4审核成功5审核失败6待收款)'
|
||||
)
|
||||
# 金额:shenqing_jine=申请扣款金额;shijidaozhang=实际打款到账金额
|
||||
shenqing_jine = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='申请提现金额(扣款额)')
|
||||
shouxufei = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name='手续费')
|
||||
shijidaozhang = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='实际到账金额')
|
||||
feilv = models.DecimalField(max_digits=5, decimal_places=4, default=0, verbose_name='手续费率')
|
||||
# 审核/驳回
|
||||
bhliyou = models.TextField(null=True, blank=True, verbose_name='驳回/失败原因')
|
||||
bo_hui_ren_id = models.CharField(
|
||||
max_length=11, null=True, blank=True, db_index=True, verbose_name='驳回人用户ID'
|
||||
)
|
||||
shenhe_ren_id = models.CharField(
|
||||
max_length=11, null=True, blank=True, db_index=True, verbose_name='审核通过操作人ID'
|
||||
)
|
||||
# 关联提现记录表主键
|
||||
tixianjilu_id = models.IntegerField(null=True, blank=True, db_index=True, verbose_name='关联Tixianjilu.id')
|
||||
# 最近一次打款单号(仅作记录,不唯一;同一审核单可多次收款产生多条打款记录)
|
||||
tixian_auto_id = models.CharField(
|
||||
max_length=32, null=True, blank=True, db_index=True,
|
||||
verbose_name='最近一次打款单号(非唯一,重试收款会更新)'
|
||||
)
|
||||
fail_reason = models.TextField(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 = 'tixian_shenhe_jilu'
|
||||
verbose_name = '提现审核记录'
|
||||
verbose_name_plural = verbose_name
|
||||
indexes = [
|
||||
models.Index(fields=['yonghuid', 'zhuangtai']),
|
||||
models.Index(fields=['yonghuid', 'leixing']),
|
||||
models.Index(fields=['shenhe_danhao']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.shenhe_danhao}({self.yonghuid})'
|
||||
|
||||
|
||||
|
||||
class TixianAutoRecord(models.Model):
|
||||
"""
|
||||
自动提现记录表(微信自动打款)
|
||||
"""
|
||||
id = models.BigAutoField(primary_key=True)
|
||||
tixian_id = models.CharField(
|
||||
max_length=32,
|
||||
unique=True,
|
||||
db_index=True,
|
||||
verbose_name='提现订单号(自定义)'
|
||||
)
|
||||
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
|
||||
leixing = models.IntegerField(verbose_name='提现类型 1打手 2管事')
|
||||
jine = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='申请提现金额')
|
||||
shouxufei = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='手续费')
|
||||
shijidaozhang = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='实际到账金额')
|
||||
feilv = models.DecimalField(max_digits=5, decimal_places=4, verbose_name='费率')
|
||||
zhuangtai = models.IntegerField(
|
||||
default=0,
|
||||
choices=[(0, '处理中'), (1, '成功'), (2, '失败')],
|
||||
verbose_name='状态'
|
||||
)
|
||||
wechat_transfer_no = models.CharField(
|
||||
max_length=64,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name='微信转账单号'
|
||||
)
|
||||
wechat_package = models.TextField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name='微信返回的package_info(JSON)'
|
||||
)
|
||||
fail_reason = models.TextField(null=True, blank=True, verbose_name='失败原因')
|
||||
# 关联提现审核单号(新流程必填,旧数据为空)
|
||||
shenhe_danhao = models.CharField(
|
||||
max_length=32, null=True, blank=True, db_index=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 = 'tixian_auto_record'
|
||||
verbose_name = '自动提现记录'
|
||||
verbose_name_plural = verbose_name
|
||||
indexes = [
|
||||
models.Index(fields=['tixian_id']),
|
||||
models.Index(fields=['yonghuid']),
|
||||
models.Index(fields=['zhuangtai']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.tixian_id} - {self.get_zhuangtai_display()}"
|
||||
|
||||
|
||||
# yonghu/models.py
|
||||
class Xiugaijilu(models.Model):
|
||||
id = models.AutoField(primary_key=True, verbose_name='记录ID')
|
||||
yonghuid = models.CharField(max_length=7, verbose_name='被修改用户ID')
|
||||
xiugaiid = models.CharField(max_length=30, verbose_name='修改人账号ID')
|
||||
leixing = models.IntegerField(verbose_name='被修改用户类型')
|
||||
|
||||
# 打手相关金钱字段
|
||||
xiugaitijiao = models.DecimalField(max_digits=12, decimal_places=2, default=0.00,
|
||||
verbose_name='修改后的打手提现金额')
|
||||
xiugaitijiaoq = models.DecimalField(max_digits=12, decimal_places=2, default=0.00,
|
||||
verbose_name='修改前的打手提现金额')
|
||||
|
||||
# 打手积分
|
||||
jifen = models.IntegerField(default=0, verbose_name='修改后的打手积分')
|
||||
yjifen = models.IntegerField(default=0, verbose_name='修改前的打手积分')
|
||||
|
||||
# 打手押金
|
||||
yajin = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='修改后的打手押金')
|
||||
yyajin = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='修改前的打手押金')
|
||||
|
||||
# 商家余额
|
||||
shangjiayue = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='修改后的商家余额')
|
||||
shangjiayueq = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='修改前的商家余额')
|
||||
|
||||
# 管事余额
|
||||
guanshiyue = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='修改后的管事余额')
|
||||
guanshiyueq = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='修改前的管事余额')
|
||||
|
||||
# 会员相关
|
||||
huiyuants = models.IntegerField(default=0, verbose_name='添加会员天数')
|
||||
huiyuan_id = models.CharField(max_length=6, null=True, blank=True, verbose_name='会员ID')
|
||||
|
||||
# 其他字段
|
||||
qitashuoming = models.TextField(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 = 'xiugaijilu'
|
||||
verbose_name = '修改记录表'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return f"修改记录-用户{self.yonghuid}"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# yonghu/models.py - 新增排行榜模型
|
||||
class RankingRecord(models.Model):
|
||||
# id: 主键ID
|
||||
id = models.AutoField(primary_key=True, verbose_name='ID')
|
||||
|
||||
# zhouqi: 周期类型,1=日榜,2=月榜
|
||||
zhouqi = models.IntegerField(choices=[(1, '日榜'), (2, '月榜')], verbose_name='周期类型')
|
||||
|
||||
# tongji_date: 统计日期(日榜存具体日期,月榜存月份第一天)
|
||||
tongji_date = models.DateField(db_index=True, verbose_name='统计日期')
|
||||
|
||||
# shenfen: 用户身份,2=打手,3=管事,4=商家(1=普通用户不统计)
|
||||
shenfen = models.IntegerField(choices=[(2, '打手'), (3, '管事'), (4, '商家')], verbose_name='用户身份')
|
||||
|
||||
# yonghuid: 用户ID(冗余存储,避免连表查询)
|
||||
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
|
||||
|
||||
# paiming: 排名(从1开始)
|
||||
paiming = models.IntegerField(verbose_name='排名')
|
||||
|
||||
# zhizhi: 指标数值(打手:收益金额,管事:充值人数,商家:流水金额)
|
||||
zhizhi = models.DecimalField(max_digits=12, decimal_places=2, default=0.00, verbose_name='指标值')
|
||||
|
||||
# nicheng: 用户昵称
|
||||
nicheng = models.CharField(max_length=50, null=True,verbose_name='用户昵称')
|
||||
|
||||
# avatar: 用户头像URL
|
||||
avatar = models.CharField(max_length=500, blank=True, null=True, verbose_name='头像')
|
||||
|
||||
# chuangjian_time: 记录创建时间
|
||||
chuangjian_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||
|
||||
class Meta:
|
||||
db_table = 'ranking_record'
|
||||
verbose_name = '排行榜记录'
|
||||
verbose_name_plural = verbose_name
|
||||
indexes = [
|
||||
models.Index(fields=['zhouqi', 'tongji_date', 'shenfen', 'paiming']),
|
||||
models.Index(fields=['yonghuid', 'zhouqi']),
|
||||
models.Index(fields=['tongji_date']),
|
||||
]
|
||||
unique_together = [['zhouqi', 'tongji_date', 'shenfen', 'paiming']]
|
||||
|
||||
def __str__(self):
|
||||
zhouqi_str = '日' if self.zhouqi == 1 else '月'
|
||||
shenfen_map = {2: '打手', 3: '管事', 4: '商家'}
|
||||
return f"{self.tongji_date} {zhouqi_str}榜 {shenfen_map.get(self.shenfen)} 第{self.paiming}名"
|
||||
280
yonghu/ranking_tasks.py
Normal file
280
yonghu/ranking_tasks.py
Normal file
@@ -0,0 +1,280 @@
|
||||
# yonghu/ranking_tasks.py
|
||||
"""
|
||||
排行榜数据转移任务 - 生产环境专用
|
||||
在清空前将数据转移到排行榜表
|
||||
"""
|
||||
|
||||
from celery import shared_task
|
||||
from django.db import transaction
|
||||
from django.utils import timezone
|
||||
from datetime import datetime, timedelta
|
||||
import logging
|
||||
from decimal import Decimal
|
||||
|
||||
from yonghu.models import (
|
||||
UserMain, UserDashou, UserShangjia, UserGuanshi, UserBoss,
|
||||
RankingRecord
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def get_user_nicheng(user, shenfen):
|
||||
"""
|
||||
获取用户昵称
|
||||
规则:打手用打手nicheng,其他用老板nickname
|
||||
"""
|
||||
try:
|
||||
if shenfen == 2: # 打手
|
||||
dashou_profile = getattr(user, 'dashou_profile', None)
|
||||
if dashou_profile and dashou_profile.nicheng:
|
||||
return dashou_profile.nicheng
|
||||
else: # 管事或商家
|
||||
boss_profile = getattr(user, 'boss_profile', None)
|
||||
if boss_profile and boss_profile.nickname:
|
||||
return boss_profile.nickname
|
||||
|
||||
# 默认返回用户ID
|
||||
return f"用户{user.yonghuid}"
|
||||
except Exception:
|
||||
return f"用户{user.yonghuid}"
|
||||
|
||||
@shared_task
|
||||
def zhuanyi_ribang():
|
||||
"""
|
||||
转移日榜数据 - 每天23:55执行
|
||||
在清零前将今日数据转移到排行榜表
|
||||
"""
|
||||
try:
|
||||
# 统计日期(今天)
|
||||
today = timezone.now().date()
|
||||
logger.info(f"开始转移日榜数据,日期: {today}")
|
||||
|
||||
records_to_create = []
|
||||
|
||||
# 1. 转移打手日榜(今日收益 > 0)
|
||||
dashou_list = UserDashou.objects.filter(
|
||||
jinrishouyi__gt=0 # 只转移收益大于0的
|
||||
).select_related('user').order_by('-jinrishouyi')
|
||||
|
||||
for i, dashou in enumerate(dashou_list, start=1):
|
||||
if i > 100: # 最多100条
|
||||
break
|
||||
|
||||
user = dashou.user
|
||||
record = RankingRecord(
|
||||
zhouqi=1, # 日榜
|
||||
tongji_date=today,
|
||||
shenfen=2, # 打手
|
||||
yonghuid=user.yonghuid,
|
||||
paiming=i,
|
||||
zhizhi=dashou.jinrishouyi,
|
||||
nicheng=get_user_nicheng(user, 2),
|
||||
avatar=user.avatar or ''
|
||||
)
|
||||
records_to_create.append(record)
|
||||
|
||||
# 2. 转移商家日榜(今日流水 > 0)
|
||||
shangjia_list = UserShangjia.objects.filter(
|
||||
jinriliushui__gt=0 # 只转移流水大于0的
|
||||
).select_related('user').order_by('-jinriliushui')
|
||||
|
||||
for i, shangjia in enumerate(shangjia_list, start=1):
|
||||
if i > 100: # 最多100条
|
||||
break
|
||||
|
||||
user = shangjia.user
|
||||
record = RankingRecord(
|
||||
zhouqi=1,
|
||||
tongji_date=today,
|
||||
shenfen=4, # 商家
|
||||
yonghuid=user.yonghuid,
|
||||
paiming=i,
|
||||
zhizhi=shangjia.jinriliushui,
|
||||
nicheng=get_user_nicheng(user, 4),
|
||||
avatar=user.avatar or ''
|
||||
)
|
||||
records_to_create.append(record)
|
||||
|
||||
# 3. 转移管事日榜(今日充值人数 > 0)
|
||||
guanshi_list = UserGuanshi.objects.filter(
|
||||
jinrichongzhi__gt=0 # 只转移充值人数大于0的
|
||||
).select_related('user').order_by('-jinrichongzhi')
|
||||
|
||||
for i, guanshi in enumerate(guanshi_list, start=1):
|
||||
if i > 100: # 最多100条
|
||||
break
|
||||
|
||||
user = guanshi.user
|
||||
record = RankingRecord(
|
||||
zhouqi=1,
|
||||
tongji_date=today,
|
||||
shenfen=3, # 管事
|
||||
yonghuid=user.yonghuid,
|
||||
paiming=i,
|
||||
zhizhi=Decimal(guanshi.jinrichongzhi),
|
||||
nicheng=get_user_nicheng(user, 3),
|
||||
avatar=user.avatar or ''
|
||||
)
|
||||
records_to_create.append(record)
|
||||
|
||||
# 批量保存
|
||||
if records_to_create:
|
||||
with transaction.atomic():
|
||||
RankingRecord.objects.bulk_create(records_to_create)
|
||||
logger.info(f"日榜数据转移完成,保存{len(records_to_create)}条记录")
|
||||
|
||||
result = {
|
||||
'success': True,
|
||||
'date': today.strftime('%Y-%m-%d'),
|
||||
'total_count': len(records_to_create),
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"日榜数据转移失败: {str(e)}", exc_info=True)
|
||||
raise
|
||||
|
||||
@shared_task
|
||||
def zhuanyi_yuebang():
|
||||
"""
|
||||
转移月榜数据 - 每月最后一天23:50执行
|
||||
在清零前将本月数据转移到排行榜表
|
||||
"""
|
||||
try:
|
||||
# 🔥 获取当前时间
|
||||
now = timezone.now()
|
||||
today = now.date()
|
||||
|
||||
# 🔥 判断今天是否是当月的最后一天
|
||||
# 方法:计算明天的日期,如果明天的月份和今天不同,那么今天就是最后一天
|
||||
tomorrow = today + timedelta(days=1)
|
||||
if tomorrow.month == today.month:
|
||||
# 今天不是最后一天,直接返回
|
||||
logger.info(f"今天不是当月最后一天({today}),跳过月榜转移")
|
||||
return {
|
||||
'success': True,
|
||||
'message': f'今天不是当月最后一天,跳过执行',
|
||||
'is_last_day': False,
|
||||
'today': today.strftime('%Y-%m-%d'),
|
||||
}
|
||||
|
||||
logger.info(f"今天是当月最后一天({today}),开始转移月榜数据")
|
||||
|
||||
# 🔥 统计日期为当月第一天(如2024-01-01)
|
||||
tongji_date = datetime(today.year, today.month, 1).date()
|
||||
|
||||
records_to_create = []
|
||||
|
||||
# 1. 转移打手月榜(今月收益 > 0)
|
||||
dashou_list = UserDashou.objects.filter(
|
||||
jinyueshouyi__gt=0 # 只转移收益大于0的
|
||||
).select_related('user').order_by('-jinyueshouyi')
|
||||
|
||||
for i, dashou in enumerate(dashou_list, start=1):
|
||||
if i > 100: # 最多100条
|
||||
break
|
||||
|
||||
user = dashou.user
|
||||
record = RankingRecord(
|
||||
zhouqi=2, # 月榜
|
||||
tongji_date=tongji_date,
|
||||
shenfen=2, # 打手
|
||||
yonghuid=user.yonghuid,
|
||||
paiming=i,
|
||||
zhizhi=dashou.jinyueshouyi,
|
||||
nicheng=get_user_nicheng(user, 2),
|
||||
avatar=user.avatar or ''
|
||||
)
|
||||
records_to_create.append(record)
|
||||
|
||||
# 2. 转移商家月榜(今月流水 > 0)
|
||||
shangjia_list = UserShangjia.objects.filter(
|
||||
jinyueliushui__gt=0 # 只转移流水大于0的
|
||||
).select_related('user').order_by('-jinyueliushui')
|
||||
|
||||
for i, shangjia in enumerate(shangjia_list, start=1):
|
||||
if i > 100: # 最多100条
|
||||
break
|
||||
|
||||
user = shangjia.user
|
||||
record = RankingRecord(
|
||||
zhouqi=2,
|
||||
tongji_date=tongji_date,
|
||||
shenfen=4, # 商家
|
||||
yonghuid=user.yonghuid,
|
||||
paiming=i,
|
||||
zhizhi=shangjia.jinyueliushui,
|
||||
nicheng=get_user_nicheng(user, 4),
|
||||
avatar=user.avatar or ''
|
||||
)
|
||||
records_to_create.append(record)
|
||||
|
||||
# 3. 转移管事月榜(今月充值人数 > 0)
|
||||
guanshi_list = UserGuanshi.objects.filter(
|
||||
jinyuechongzhi__gt=0 # 只转移充值人数大于0的
|
||||
).select_related('user').order_by('-jinyuechongzhi')
|
||||
|
||||
for i, guanshi in enumerate(guanshi_list, start=1):
|
||||
if i > 100: # 最多100条
|
||||
break
|
||||
|
||||
user = guanshi.user
|
||||
record = RankingRecord(
|
||||
zhouqi=2,
|
||||
tongji_date=tongji_date,
|
||||
shenfen=3, # 管事
|
||||
yonghuid=user.yonghuid,
|
||||
paiming=i,
|
||||
zhizhi=Decimal(guanshi.jinyuechongzhi),
|
||||
nicheng=get_user_nicheng(user, 3),
|
||||
avatar=user.avatar or ''
|
||||
)
|
||||
records_to_create.append(record)
|
||||
|
||||
# 批量保存
|
||||
if records_to_create:
|
||||
with transaction.atomic():
|
||||
RankingRecord.objects.bulk_create(records_to_create)
|
||||
logger.info(f"月榜数据转移完成,保存{len(records_to_create)}条记录")
|
||||
|
||||
result = {
|
||||
'success': True,
|
||||
'month': tongji_date.strftime('%Y-%m'),
|
||||
'total_count': len(records_to_create),
|
||||
'is_last_day': True,
|
||||
'today': today.strftime('%Y-%m-%d'),
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"月榜数据转移失败: {str(e)}", exc_info=True)
|
||||
raise
|
||||
|
||||
@shared_task
|
||||
def qingli_jiulishuju():
|
||||
"""
|
||||
清理旧历史数据 - 每月1号凌晨1点执行
|
||||
清理3个月前的排行榜数据,保留最近3个月的数据
|
||||
"""
|
||||
try:
|
||||
# 计算3个月前的日期
|
||||
three_months_ago = timezone.now().date() - timedelta(days=90)
|
||||
|
||||
# 删除旧数据
|
||||
deleted_count, _ = RankingRecord.objects.filter(
|
||||
tongji_date__lt=three_months_ago
|
||||
).delete()
|
||||
|
||||
logger.info(f"清理旧历史数据完成,删除{deleted_count}条记录")
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'deleted_count': deleted_count,
|
||||
'before_date': three_months_ago.strftime('%Y-%m-%d')
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"清理旧历史数据失败: {str(e)}")
|
||||
raise
|
||||
176
yonghu/tasks.py
Normal file
176
yonghu/tasks.py
Normal file
@@ -0,0 +1,176 @@
|
||||
"""
|
||||
阿龙电竞 - 用户定时任务
|
||||
处理每日/每月清零等用户相关定时任务
|
||||
完整版本,包含所有异常处理
|
||||
"""
|
||||
|
||||
from celery import shared_task
|
||||
from django.db import transaction
|
||||
from django.db.models import F, Q
|
||||
from django.utils import timezone
|
||||
from datetime import datetime
|
||||
import logging
|
||||
|
||||
# 导入模型
|
||||
from yonghu.models import UserDashou, UserShangjia, UserGuanshi
|
||||
from utils.celery_utils import log_task_execution, rollback_on_failure
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@shared_task
|
||||
@rollback_on_failure("每日清零任务")
|
||||
def daily_reset_task():
|
||||
"""
|
||||
每日清零任务 - 每天凌晨0点执行
|
||||
清零打手、商家、管事的今日相关字段
|
||||
"""
|
||||
try:
|
||||
with transaction.atomic():
|
||||
start_time = timezone.now()
|
||||
today = datetime.now().strftime('%Y-%m-%d')
|
||||
|
||||
logger.info(f"开始执行每日清零任务,日期: {today}")
|
||||
|
||||
# 1. 清零打手今日数据
|
||||
dashou_updated = UserDashou.objects.filter(
|
||||
Q(jinrijiedan__gt=0) | Q(jinrishouyi__gt=0)
|
||||
).update(
|
||||
jinrijiedan=0,
|
||||
jinrishouyi=0
|
||||
)
|
||||
|
||||
logger.info(f"打手今日数据清零完成,影响记录: {dashou_updated}条")
|
||||
|
||||
# 2. 清零商家今日数据
|
||||
shangjia_updated = UserShangjia.objects.filter(
|
||||
Q(jinridingdan__gt=0) | Q(jinriliushui__gt=0)
|
||||
).update(
|
||||
jinridingdan=0,
|
||||
jinriliushui=0
|
||||
)
|
||||
|
||||
logger.info(f"商家今日数据清零完成,影响记录: {shangjia_updated}条")
|
||||
|
||||
# 3. 清零管事今日数据
|
||||
guanshi_updated = UserGuanshi.objects.filter(
|
||||
jinrichongzhi__gt=0
|
||||
).update(
|
||||
jinrichongzhi=0
|
||||
)
|
||||
|
||||
logger.info(f"管事今日数据清零完成,影响记录: {guanshi_updated}条")
|
||||
|
||||
end_time = timezone.now()
|
||||
duration = (end_time - start_time).total_seconds()
|
||||
|
||||
# 记录执行结果
|
||||
result_msg = (
|
||||
f"每日清零完成 - 日期: {today}, "
|
||||
f"打手: {dashou_updated}条, "
|
||||
f"商家: {shangjia_updated}条, "
|
||||
f"管事: {guanshi_updated}条, "
|
||||
f"耗时: {duration:.2f}秒"
|
||||
)
|
||||
|
||||
log_task_execution("每日清零任务", True, result_msg)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"date": today,
|
||||
"updated_dashou": dashou_updated,
|
||||
"updated_shangjia": shangjia_updated,
|
||||
"updated_guanshi": guanshi_updated,
|
||||
"duration_seconds": duration,
|
||||
"message": result_msg
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"每日清零任务失败: {str(e)}"
|
||||
logger.error(error_msg)
|
||||
log_task_execution("每日清零任务", False, error_msg)
|
||||
|
||||
return {
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"date": datetime.now().strftime('%Y-%m-%d'),
|
||||
"message": error_msg
|
||||
}
|
||||
|
||||
@shared_task
|
||||
@rollback_on_failure("每月清零任务")
|
||||
def monthly_reset_task():
|
||||
"""
|
||||
每月清零任务 - 每月1日凌晨0点执行
|
||||
清零打手、商家、管事的本月相关字段
|
||||
"""
|
||||
try:
|
||||
with transaction.atomic():
|
||||
start_time = timezone.now()
|
||||
current_month = datetime.now().strftime('%Y-%m')
|
||||
|
||||
logger.info(f"开始执行每月清零任务,月份: {current_month}")
|
||||
|
||||
# 1. 清零打手本月数据
|
||||
dashou_updated = UserDashou.objects.filter(
|
||||
Q(jinyuejiedan__gt=0) | Q(jinyueshouyi__gt=0)
|
||||
).update(
|
||||
jinyuejiedan=0,
|
||||
jinyueshouyi=0
|
||||
)
|
||||
|
||||
logger.info(f"打手本月数据清零完成,影响记录: {dashou_updated}条")
|
||||
|
||||
# 2. 清零商家本月数据
|
||||
shangjia_updated = UserShangjia.objects.filter(
|
||||
Q(jinyuedingdan__gt=0) | Q(jinyueliushui__gt=0)
|
||||
).update(
|
||||
jinyuedingdan=0,
|
||||
jinyueliushui=0
|
||||
)
|
||||
|
||||
logger.info(f"商家本月数据清零完成,影响记录: {shangjia_updated}条")
|
||||
|
||||
# 3. 清零管事本月数据
|
||||
guanshi_updated = UserGuanshi.objects.filter(
|
||||
jinyuechongzhi__gt=0
|
||||
).update(
|
||||
jinyuechongzhi=0
|
||||
)
|
||||
|
||||
logger.info(f"管事本月数据清零完成,影响记录: {guanshi_updated}条")
|
||||
|
||||
end_time = timezone.now()
|
||||
duration = (end_time - start_time).total_seconds()
|
||||
|
||||
# 记录执行结果
|
||||
result_msg = (
|
||||
f"每月清零完成 - 月份: {current_month}, "
|
||||
f"打手: {dashou_updated}条, "
|
||||
f"商家: {shangjia_updated}条, "
|
||||
f"管事: {guanshi_updated}条, "
|
||||
f"耗时: {duration:.2f}秒"
|
||||
)
|
||||
|
||||
log_task_execution("每月清零任务", True, result_msg)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"month": current_month,
|
||||
"updated_dashou": dashou_updated,
|
||||
"updated_shangjia": shangjia_updated,
|
||||
"updated_guanshi": guanshi_updated,
|
||||
"duration_seconds": duration,
|
||||
"message": result_msg
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"每月清零任务失败: {str(e)}"
|
||||
logger.error(error_msg)
|
||||
log_task_execution("每月清零任务", False, error_msg)
|
||||
|
||||
return {
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"month": datetime.now().strftime('%Y-%m'),
|
||||
"message": error_msg
|
||||
}
|
||||
3
yonghu/tests.py
Normal file
3
yonghu/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
1337
yonghu/tixian_shenhe_services.py
Normal file
1337
yonghu/tixian_shenhe_services.py
Normal file
File diff suppressed because it is too large
Load Diff
383
yonghu/tixian_shenhe_views.py
Normal file
383
yonghu/tixian_shenhe_views.py
Normal file
@@ -0,0 +1,383 @@
|
||||
# yonghu/tixian_shenhe_collect_b.py
|
||||
"""
|
||||
自动提现审核 — 用户侧接口:
|
||||
① TixianZddkshApplyView → POST /yonghu/zddksh 提交审核(扣款)
|
||||
② process_audit_collect → POST /yonghu/tixiansq 收款(P0:一单到底,先查微信再决定是否新建)
|
||||
"""
|
||||
import decimal
|
||||
import json
|
||||
import logging
|
||||
import random
|
||||
import string
|
||||
import time
|
||||
|
||||
import requests
|
||||
from django.conf import settings
|
||||
from django.db import transaction
|
||||
from django.utils import timezone
|
||||
from rest_framework import permissions
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from .models import TixianAutoRecord, TixianShenheJilu
|
||||
from .tixian_shenhe_services import (
|
||||
RECONCILE_ALLOW_NEW,
|
||||
RECONCILE_COMPLETED,
|
||||
RECONCILE_PENDING,
|
||||
RECONCILE_WAIT_CONFIRM,
|
||||
check_collect_quota_limits,
|
||||
create_audit_application,
|
||||
get_audit_for_collect,
|
||||
handle_post_transfer_failure,
|
||||
reconcile_shenhe_wechat_bills,
|
||||
release_collect_quota_for_record,
|
||||
reserve_collect_quota_limits,
|
||||
resolve_collect_context,
|
||||
validate_collect_eligibility,
|
||||
)
|
||||
|
||||
logger = logging.getLogger('yonghu.tixian_shenhe')
|
||||
|
||||
|
||||
def generate_tixian_id():
|
||||
"""生成唯一微信商户打款单号:TX + 时间戳(13位) + 4位随机数"""
|
||||
timestamp = str(int(time.time() * 1000))
|
||||
rand = ''.join(random.choices(string.digits, k=4))
|
||||
return f'TX{timestamp}{rand}'
|
||||
|
||||
|
||||
def _build_collect_success_response(payload):
|
||||
return Response({
|
||||
'code': 0,
|
||||
'msg': '请确认收款',
|
||||
'data': payload,
|
||||
})
|
||||
|
||||
|
||||
def _is_wx_balance_insufficient(err_code='', err_msg=''):
|
||||
blob = f'{err_code} {err_msg}'.upper()
|
||||
return any(k in blob for k in ('NOT_ENOUGH', 'INSUFFICIENT', '余额不足', '资金不足'))
|
||||
|
||||
|
||||
def _verify_collect_quota_or_response(user_main, audit, shenhe_danhao):
|
||||
"""收款限额校验;不通过时直接返回 Response"""
|
||||
ok, msg, limit_kind = check_collect_quota_limits(
|
||||
user_main,
|
||||
audit.leixing,
|
||||
audit.shenqing_jine,
|
||||
audit.shijidaozhang,
|
||||
shenhe_danhao,
|
||||
)
|
||||
if not ok:
|
||||
limit_code = 33 if limit_kind == 'platform' else 400
|
||||
logger.warning(
|
||||
'收款限额校验未通过 yonghuid=%s shenhe_danhao=%s leixing=%s kind=%s msg=%s',
|
||||
user_main.yonghuid, shenhe_danhao, audit.leixing, limit_kind, msg,
|
||||
)
|
||||
return Response({'code': limit_code, 'msg': msg})
|
||||
return None
|
||||
|
||||
|
||||
def _mark_auto_record_failed(tixian_id, fail_reason):
|
||||
"""微信明确失败时标记打款记录终态,避免后续一直被当成「处理中」"""
|
||||
TixianAutoRecord.objects.filter(tixian_id=tixian_id, zhuangtai=0).update(
|
||||
zhuangtai=2,
|
||||
fail_reason=(fail_reason or '打款失败')[:500],
|
||||
update_time=timezone.now(),
|
||||
)
|
||||
|
||||
|
||||
def _build_wx_transfer_body(wx_cfg, tixian_id, openid, yonghuid, leixing, shijidaozhang):
|
||||
transfer_scene_id = wx_cfg['TRANSFER_SCENE_ID']
|
||||
role_map = {1: '打手', 2: '管事', 3: '组长', 4: '考核官', 5: '打手', 6: '商家'}
|
||||
desc_map = {1: '佣金提现', 2: '分红提现', 3: '分红提现', 4: '分佣提现', 5: '押金提现', 6: '余额提现'}
|
||||
transfer_scene_report_infos = []
|
||||
if transfer_scene_id == '1005':
|
||||
transfer_scene_report_infos = [
|
||||
{'info_type': '岗位类型', 'info_content': role_map.get(leixing, '用户')},
|
||||
{'info_type': '报酬说明', 'info_content': desc_map.get(leixing, '提现')},
|
||||
]
|
||||
elif transfer_scene_id == '1009':
|
||||
transfer_scene_report_infos = [
|
||||
{'info_type': '采购商品名称', 'info_content': '平台服务'},
|
||||
]
|
||||
return {
|
||||
'appid': wx_cfg['APPID'],
|
||||
'out_bill_no': tixian_id,
|
||||
'transfer_scene_id': transfer_scene_id,
|
||||
'openid': openid,
|
||||
'transfer_amount': int(shijidaozhang * 100),
|
||||
'transfer_remark': f'兄弟们 收款前记得录屏发快手',
|
||||
'transfer_scene_report_infos': transfer_scene_report_infos,
|
||||
}
|
||||
|
||||
|
||||
def _call_wechat_transfer(body, wx_cfg):
|
||||
from utils.wechat_v3 import build_authorization
|
||||
|
||||
url = 'https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills'
|
||||
body_json = json.dumps(body, separators=(',', ':'))
|
||||
auth = build_authorization('POST', url, body_json)
|
||||
headers = {
|
||||
'Authorization': auth,
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'User-Agent': 'Mozilla/5.0',
|
||||
}
|
||||
resp = requests.post(url, data=body_json, headers=headers, timeout=15)
|
||||
try:
|
||||
wx_result = resp.json()
|
||||
except ValueError:
|
||||
wx_result = {}
|
||||
return resp, wx_result
|
||||
|
||||
|
||||
class TixianZddkshApplyView(APIView):
|
||||
"""POST /yonghu/zddksh 提交审核申请(扣款,不创建 TixianAutoRecord)"""
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
def post(self, request):
|
||||
from utils.redis_lock import acquire_lock, release_lock
|
||||
|
||||
user_main = request.user
|
||||
lock_key = f'tixian_audit_apply:{user_main.yonghuid}'
|
||||
if not acquire_lock(lock_key, timeout=10):
|
||||
return Response({'code': 429, 'msg': '操作频繁,请稍后重试'})
|
||||
|
||||
try:
|
||||
leixing = request.data.get('leixing')
|
||||
jine_str = request.data.get('jine')
|
||||
if leixing is None or jine_str is None:
|
||||
return Response({'code': 1, 'msg': '缺少参数: leixing 或 jine'})
|
||||
|
||||
try:
|
||||
leixing = int(leixing)
|
||||
jine = decimal.Decimal(str(jine_str))
|
||||
except (ValueError, decimal.InvalidOperation):
|
||||
return Response({'code': 2, 'msg': '参数格式错误'})
|
||||
|
||||
if leixing not in [1, 2, 3, 4, 5, 6]:
|
||||
return Response({'code': 3, 'msg': '提现类型无效'})
|
||||
if jine <= decimal.Decimal('0.1'):
|
||||
return Response({'code': 4, 'msg': '提现金额必须大于0.1'})
|
||||
|
||||
try:
|
||||
data = create_audit_application(user_main, leixing, jine)
|
||||
except ValueError as e:
|
||||
return Response({'code': 400, 'msg': str(e)})
|
||||
except Exception as e:
|
||||
logger.error(f'提现审核申请异常: {e}', exc_info=True)
|
||||
return Response({'code': 99, 'msg': '提现申请失败,请稍后重试'})
|
||||
|
||||
return Response({'code': 0, 'msg': '提现申请已提交,请等待审核', 'data': data})
|
||||
|
||||
finally:
|
||||
release_lock(lock_key)
|
||||
|
||||
|
||||
def process_audit_collect(request):
|
||||
"""
|
||||
POST /yonghu/tixiansq 用户收款(P0 防多提)
|
||||
|
||||
主路径:tixianjilu_id → Tixianjilu → TixianShenheJilu(状态6)
|
||||
若 TixianAutoRecord 已有 tixian_id → 只问微信,非终态绝不新建
|
||||
仅微信 FAIL/CANCELLED 终态后才允许新建打款记录
|
||||
"""
|
||||
from utils.redis_lock import acquire_lock, release_lock
|
||||
|
||||
user_main = request.user
|
||||
yonghuid = user_main.yonghuid
|
||||
tixianjilu_id = request.data.get('tixianjilu_id') or request.data.get('id')
|
||||
shenhe_danhao = (request.data.get('shenhe_danhao') or '').strip()
|
||||
shenhe_jilu_id = request.data.get('shenhe_jilu_id')
|
||||
|
||||
logger.info(
|
||||
'收款请求 yonghuid=%s tixianjilu_id=%s shenhe_jilu_id=%s shenhe_danhao=%s',
|
||||
yonghuid, tixianjilu_id, shenhe_jilu_id, shenhe_danhao,
|
||||
)
|
||||
|
||||
try:
|
||||
if not user_main.openid:
|
||||
return Response({'code': 10, 'msg': '用户未绑定微信,无法收款'})
|
||||
|
||||
wx_cfg = settings.WECHAT_PAY_V3_CONFIG
|
||||
if not wx_cfg.get('APPID') or not wx_cfg.get('MCHID') or not wx_cfg.get('TRANSFER_SCENE_ID'):
|
||||
logger.error('微信打款配置不完整 APPID=%s MCHID=%s', wx_cfg.get('APPID'), wx_cfg.get('MCHID'))
|
||||
return Response({'code': 11, 'msg': '系统配置异常,请联系客服'})
|
||||
|
||||
ctx, err = resolve_collect_context(
|
||||
yonghuid,
|
||||
tixianjilu_id=tixianjilu_id,
|
||||
shenhe_danhao=shenhe_danhao,
|
||||
shenhe_jilu_id=shenhe_jilu_id,
|
||||
)
|
||||
if not ctx:
|
||||
return Response({'code': 400, 'msg': err})
|
||||
|
||||
audit = ctx['audit']
|
||||
shenhe_danhao = ctx['shenhe_danhao']
|
||||
tixianjilu_id_val = ctx['jilu'].id if ctx.get('jilu') else audit.tixianjilu_id
|
||||
leixing = audit.leixing
|
||||
|
||||
# 二次资格校验:不通过仅返回错误,审核单保持待收款(6),不退款,用户补齐资质后可再点收款
|
||||
collect_ok, collect_msg = validate_collect_eligibility(user_main, leixing)
|
||||
if not collect_ok:
|
||||
logger.warning(
|
||||
'收款校验未通过 yonghuid=%s shenhe_danhao=%s leixing=%s msg=%s',
|
||||
yonghuid, shenhe_danhao, leixing, collect_msg,
|
||||
)
|
||||
return Response({'code': 400, 'msg': collect_msg})
|
||||
|
||||
quota_resp = _verify_collect_quota_or_response(user_main, audit, shenhe_danhao)
|
||||
if quota_resp:
|
||||
return quota_resp
|
||||
|
||||
lock_key = f'tixian_collect:{shenhe_danhao}'
|
||||
if not acquire_lock(lock_key, timeout=15):
|
||||
return Response({'code': 429, 'msg': '操作频繁,请稍后重试'})
|
||||
|
||||
tixian_id = None
|
||||
quota_reserved = False
|
||||
try:
|
||||
action, payload = reconcile_shenhe_wechat_bills(shenhe_danhao)
|
||||
if action == RECONCILE_COMPLETED:
|
||||
return Response({'code': 8, 'msg': payload.get('msg', '该提现已完成,请勿重复操作')})
|
||||
if action == RECONCILE_WAIT_CONFIRM:
|
||||
quota_resp = _verify_collect_quota_or_response(user_main, audit, shenhe_danhao)
|
||||
if quota_resp:
|
||||
return quota_resp
|
||||
return _build_collect_success_response(payload)
|
||||
if action == RECONCILE_PENDING:
|
||||
msg = payload.get('msg') if isinstance(payload, dict) else payload
|
||||
return Response({'code': 12, 'msg': msg or '有收款处理中,请稍后再试'})
|
||||
|
||||
if action != RECONCILE_ALLOW_NEW:
|
||||
return Response({'code': 12, 'msg': '收款处理中,请稍后再试'})
|
||||
|
||||
with transaction.atomic():
|
||||
audit, err = get_audit_for_collect(
|
||||
shenhe_danhao, yonghuid, audit.id,
|
||||
)
|
||||
if not audit:
|
||||
return Response({'code': 400, 'msg': err})
|
||||
|
||||
# 金额一律用审核表已落库数据(申请时扣款+算费),收款不再重算
|
||||
jine = audit.shenqing_jine
|
||||
shouxufei = audit.shouxufei
|
||||
shijidaozhang = audit.shijidaozhang
|
||||
feilv = audit.feilv
|
||||
|
||||
ok, msg, limit_kind = reserve_collect_quota_limits(
|
||||
user_main, leixing, jine, shijidaozhang, shenhe_danhao,
|
||||
)
|
||||
if not ok:
|
||||
limit_code = 33 if limit_kind == 'platform' else 400
|
||||
return Response({'code': limit_code, 'msg': msg})
|
||||
|
||||
quota_reserved = True
|
||||
|
||||
tixian_id = generate_tixian_id()
|
||||
TixianAutoRecord.objects.create(
|
||||
tixian_id=tixian_id,
|
||||
yonghuid=yonghuid,
|
||||
leixing=leixing,
|
||||
jine=jine,
|
||||
shouxufei=shouxufei,
|
||||
shijidaozhang=shijidaozhang,
|
||||
feilv=feilv,
|
||||
zhuangtai=0,
|
||||
shenhe_danhao=shenhe_danhao,
|
||||
)
|
||||
audit.tixian_auto_id = tixian_id
|
||||
audit.save(update_fields=['tixian_auto_id', 'update_time'])
|
||||
|
||||
body = _build_wx_transfer_body(
|
||||
wx_cfg, tixian_id, user_main.openid, yonghuid, leixing, shijidaozhang,
|
||||
)
|
||||
|
||||
try:
|
||||
resp, wx_result = _call_wechat_transfer(body, wx_cfg)
|
||||
|
||||
if resp.status_code == 200 and wx_result.get('state') == 'WAIT_USER_CONFIRM':
|
||||
package_info = wx_result.get('package_info')
|
||||
auto_record = TixianAutoRecord.objects.get(tixian_id=tixian_id)
|
||||
auto_record.wechat_package = json.dumps(package_info, ensure_ascii=False)
|
||||
auto_record.save(update_fields=['wechat_package'])
|
||||
|
||||
return _build_collect_success_response({
|
||||
'tixian_id': tixian_id,
|
||||
'package_info': package_info,
|
||||
'shouxufei': str(shouxufei),
|
||||
'shijidaozhang': str(shijidaozhang),
|
||||
'current_rate': str(feilv),
|
||||
'mch_id': wx_cfg['MCHID'],
|
||||
'shenhe_danhao': shenhe_danhao,
|
||||
'tixianjilu_id': tixianjilu_id_val,
|
||||
})
|
||||
|
||||
err_code = wx_result.get('code', '')
|
||||
err_msg = wx_result.get('message', wx_result.get('detail', '微信接口调用失败'))
|
||||
logger.error(
|
||||
'微信发起转账未进入待确认: bill=%s code=%s msg=%s HTTP%s',
|
||||
tixian_id, err_code, err_msg, resp.status_code,
|
||||
)
|
||||
|
||||
is_balance_issue = _is_wx_balance_insufficient(err_code, err_msg)
|
||||
if is_balance_issue:
|
||||
_mark_auto_record_failed(tixian_id, err_msg)
|
||||
if quota_reserved:
|
||||
release_collect_quota_for_record(
|
||||
TixianAutoRecord.objects.get(tixian_id=tixian_id),
|
||||
)
|
||||
quota_reserved = False
|
||||
return Response({
|
||||
'code': 99,
|
||||
'msg': '运营账户资金不足,需等管理员充值后才能提现',
|
||||
})
|
||||
|
||||
post_action, post_payload = handle_post_transfer_failure(
|
||||
tixian_id, shenhe_danhao, err_code, err_msg,
|
||||
)
|
||||
if post_action == RECONCILE_WAIT_CONFIRM:
|
||||
quota_resp = _verify_collect_quota_or_response(user_main, audit, shenhe_danhao)
|
||||
if quota_resp:
|
||||
return quota_resp
|
||||
return _build_collect_success_response(post_payload)
|
||||
if post_action == RECONCILE_COMPLETED:
|
||||
return Response({'code': 8, 'msg': '该提现已完成,请勿重复操作'})
|
||||
if post_action == RECONCILE_PENDING:
|
||||
pending_msg = (
|
||||
post_payload.get('msg', post_payload)
|
||||
if isinstance(post_payload, dict) else post_payload
|
||||
)
|
||||
return Response({'code': 12, 'msg': pending_msg or '有收款处理中,请稍后再试'})
|
||||
|
||||
user_msg = err_msg or '微信收款发起失败,请稍后重试'
|
||||
_mark_auto_record_failed(tixian_id, user_msg)
|
||||
if quota_reserved:
|
||||
release_collect_quota_for_record(
|
||||
TixianAutoRecord.objects.get(tixian_id=tixian_id),
|
||||
)
|
||||
quota_reserved = False
|
||||
return Response({'code': 99, 'msg': user_msg})
|
||||
|
||||
except requests.RequestException as e:
|
||||
logger.error(
|
||||
'微信打款网络异常(保持待查单): bill=%s err=%s',
|
||||
tixian_id, e, exc_info=True,
|
||||
)
|
||||
return Response({
|
||||
'code': 12,
|
||||
'msg': '收款请求已提交,系统正在核对状态,请稍后再试,切勿重复点击',
|
||||
})
|
||||
|
||||
finally:
|
||||
release_lock(lock_key)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
'收款接口未捕获异常 yonghuid=%s tixianjilu_id=%s shenhe_danhao=%s err=%s',
|
||||
yonghuid, tixianjilu_id, shenhe_danhao, e,
|
||||
exc_info=True,
|
||||
)
|
||||
return Response({'code': 99, 'msg': '系统繁忙,请稍后重试'})
|
||||
157
yonghu/urls.py
Normal file
157
yonghu/urls.py
Normal file
@@ -0,0 +1,157 @@
|
||||
from django.urls import path
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from .views import WechatMiniProgramLoginView, UserInfoUpdateView, DashouXinxiAPIView, \
|
||||
ZaixianZhuangtaiAPIView, GuanshiXinxiView, ShangJiaXinXiView, BossBiaoshiView, YaoqingmaView, \
|
||||
DashouZhuceView, GuanshiYaoqingDashouListView, TixianXinxiHuoquView, ShoukuanXinxiShangchuanView, \
|
||||
TixianShenqingView, TixianJiluHuoquViewV2, AdminLoginView, AdminFinancialDataView, AdGetDingdanList, \
|
||||
AdGetOrderTypes, AdGuanLiYongHu, AdYaoQingDaShou, CfGuanLi, AdTongYiChuFa, AdckyhxqView, AdcjxgView, AddtxshView, \
|
||||
AdtixianqkView, DashouZiliaoHuoquView, DashouGengxinView, \
|
||||
ShangjiaZhuceView,PaihangbangGuanliQueryView,PaihangbangRiqiliebiaoView,WechatLoginAndDashouRegisterView, \
|
||||
YonghuTixianShenheXiugaiView, ChufaJiluHuoquView, DashouShensuView, ShangjiaChufaJiluHuoquView,\
|
||||
WeixinOfficialCallbackView,KefuLoginView, KefuStatsView, KefuGetOrderTypesView, KefuGetOrderListView, \
|
||||
KefuGetShangjiaOrderListView, KefuGetOrderDetailView, KefuChangeDashouView, KefuRecoverOrderView, \
|
||||
KefuPlatformRefundView, KefuRejectRefundView, KefuMerchantRefundView, KefuRejectSettlementView, \
|
||||
KefuTransferHallView, KefuCancelDesignationView, KefuGetDashouListView, KefuGetDashouDetailView, \
|
||||
KefuUpdateDashouView, KefuPunishmentListView, KefuPunishmentActionView, KefuPunishmentDetailView, \
|
||||
KefuWithdrawListView, KefuWithdrawDetailView, KefuWithdrawActionView, KefuPunishView, AdKfglView, AdKftjView, \
|
||||
AdKfxgView,TixianQueRenAutoView, TixianShenqingV3View, TixianCallbackV3View, KefuForceCompleteView,\
|
||||
GuanshiRegisterView, WechatLoginAndGuanshiRegisterView, ZuzhangZhuceView, ZuzhangXinxiView,\
|
||||
DashouJianquanView, LaobanJianquanView,HuoQuYaoQingRenView,FaKuanJiFenTongJiView, DaShouFaKuanLieBiaoView, \
|
||||
FaKuanShenSuView, FaKuanPayView, FaKuanPayPollView, FaKuanPayFailView, FaKuanHuitiaoView,\
|
||||
KaohePayView,KaohePayCallbackView, KaohePayPollView, KaohePayFailView, TixianAssetView
|
||||
|
||||
from .tixian_shenhe_views import TixianZddkshApplyView
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('wechatlogin', WechatMiniProgramLoginView.as_view(), name='用户一键微信登录'),
|
||||
path('xiugai', UserInfoUpdateView.as_view(), name='用户信息修改'),
|
||||
# 打手信息接口
|
||||
path('dashouxinxi', DashouXinxiAPIView.as_view(), name='打手信息查询'),
|
||||
# 更改在线状态接口
|
||||
path('zaixianzhuangtai', ZaixianZhuangtaiAPIView.as_view(), name='打手在线状态更改'),
|
||||
path('guanshixinxi', GuanshiXinxiView.as_view(), name='获取管事信息'),
|
||||
path('shangjiaxinxi', ShangJiaXinXiView.as_view(), name='获取商家信息'),
|
||||
path('bossbiaoshi', BossBiaoshiView.as_view(), name='获取老板标识'),
|
||||
path('yaoqingma', YaoqingmaView.as_view(), name='管事生成邀请码'),
|
||||
path('dashouzhuce',DashouZhuceView.as_view(), name='打手邀请码注册'),
|
||||
path('gshqyqds', GuanshiYaoqingDashouListView.as_view(), name='管事获取邀请打手'),
|
||||
path('tixianhq', TixianXinxiHuoquView.as_view(), name='获取体现缓存信息'), # 获取提现信息
|
||||
path('sksc', ShoukuanXinxiShangchuanView.as_view(), name='上传提现相关数据或收款码'), # 上传收款信息
|
||||
path('tixian', TixianShenqingView.as_view(), name='提现申请'), # 提交提现申请
|
||||
path('tixianjiluhq', TixianJiluHuoquViewV2.as_view(), name='打手提现记录查询'),
|
||||
path('adlog', AdminLoginView.as_view(), name='管理元登录'),
|
||||
path('adhq', AdminFinancialDataView.as_view(), name='管理元获取收支记录'),
|
||||
path('adgetordertypes', AdGetOrderTypes.as_view(), name='管理员获取订单类型'),
|
||||
|
||||
# 订单列表获取接口
|
||||
path('adddhq', AdGetDingdanList.as_view(), name='管理员获取订单列表'),
|
||||
path('adyqds', AdYaoQingDaShou.as_view(), name='管理员获取邀请码'),
|
||||
|
||||
# 用户管理列表接口
|
||||
path('adgl', AdGuanLiYongHu.as_view(), name='管理员获取用户'),
|
||||
path('cfgl', CfGuanLi.as_view(), name='处罚记录获取'),
|
||||
path('adtycf', AdTongYiChuFa.as_view(), name='同意或拒绝处罚'),
|
||||
path('adckyhxq', AdckyhxqView.as_view(), name='管理员获取用户具体数据'),
|
||||
|
||||
# 修改用户信息接口
|
||||
path('adcjxg',AdcjxgView.as_view(), name='管理员修改用户数据'),
|
||||
path('addtxsh', AddtxshView.as_view(), name='管理员获取提现审核'),
|
||||
|
||||
# 处理提现申请接口
|
||||
path('adtixianqk', AdtixianqkView.as_view(), name='管理员提现修改'),
|
||||
# 打手资料获取
|
||||
path('dszjxxhq', DashouZiliaoHuoquView.as_view(), name='打手获取自己信息'),
|
||||
|
||||
# 打手信息更新
|
||||
path('dsgxxx', DashouGengxinView.as_view(), name='打手修改自己信息'),
|
||||
# 🔥🟢 新增商家路由
|
||||
path('shangjiahuce', ShangjiaZhuceView.as_view(), name='商家注册'),
|
||||
path('paihangbang', PaihangbangGuanliQueryView.as_view(), name='管理查询排行榜'),
|
||||
path('adhqphrq', PaihangbangRiqiliebiaoView.as_view(), name='管理原获取排行榜日期'),
|
||||
|
||||
|
||||
|
||||
|
||||
path('wdlyhdl', WechatLoginAndDashouRegisterView.as_view(), name='打手扫码注册'),
|
||||
path('yonghutxshxg', YonghuTixianShenheXiugaiView.as_view(), name='用户自己体现修改'),
|
||||
path('dshqcfjl', ChufaJiluHuoquView.as_view(), name='打手处罚记录获取'),
|
||||
|
||||
# 打手申诉接口
|
||||
path('dscfss', DashouShensuView.as_view(), name='打手处罚上诉申请'),
|
||||
path('sjcfjlhq', ShangjiaChufaJiluHuoquView.as_view(), name='商家处罚记录获取'),
|
||||
#path('officialcallback', csrf_exempt(WeixinOfficialCallbackView.as_view()), name='用户关注取关服务号回调'),
|
||||
|
||||
path('kefujinru', KefuLoginView.as_view(), name='客服登录'),
|
||||
path('kfjrhqzl', KefuStatsView.as_view(), name='客服获取数据'),
|
||||
path('kfhqptddlx', KefuGetOrderTypesView.as_view(), name='客服获取订单类型'),
|
||||
path('kfhqddlb', KefuGetOrderListView.as_view(), name='客服获取订单列表'),
|
||||
|
||||
path('kfhqsjddlb', KefuGetShangjiaOrderListView.as_view(),name='客服获取商家订单列表'),
|
||||
path('kefuhqddxq', KefuGetOrderDetailView.as_view(), name='获取订单详情页面'),
|
||||
path('kefughds', KefuChangeDashouView.as_view(), name='客服更换打手'),
|
||||
path('kefuhf', KefuRecoverOrderView.as_view(), name='客服恢复订单'),
|
||||
path('kefupttk', KefuPlatformRefundView.as_view(), name='客服给平台订单退款'),
|
||||
path('kefujjtk', KefuRejectRefundView.as_view(), name='客服拒绝商家退款'),
|
||||
path('kefusjtk', KefuMerchantRefundView.as_view(), name='客服同意商家退款'),
|
||||
path('kefujjjs', KefuRejectSettlementView.as_view(), name='客服拒绝结算'),
|
||||
path('kefuzydt', KefuTransferHallView.as_view(), name='客服订单返回大厅'),
|
||||
path('kefuqxzd', KefuCancelDesignationView.as_view(), name='客服取消指定'),
|
||||
path('kefuhqdslb', KefuGetDashouListView.as_view(), name='客服获取打手数据'),
|
||||
path('kefuhqdsxq', KefuGetDashouDetailView.as_view(), name='客服获取打手具体信息'),
|
||||
path('kefuxgds', KefuUpdateDashouView.as_view(), name='客服修改打手数据'),
|
||||
path('kefu_cfgl', KefuPunishmentListView.as_view(), name='客服获取处罚记录'),
|
||||
path('kefu_cf_detail', KefuPunishmentDetailView.as_view(), name='kefu_cf_detail'),
|
||||
path('kefu_cf_action', KefuPunishmentActionView.as_view(), name='客服处理处罚'),
|
||||
path('kefu_txsh_list', KefuWithdrawListView.as_view(), name='客服获取体现数据'),
|
||||
path('kefu_txsh_detail', KefuWithdrawDetailView.as_view(), name='客服获取体现详情数据'),
|
||||
path('kefu_txsh_action', KefuWithdrawActionView.as_view(), name='客服处理体现'),
|
||||
path('kefuchufa', KefuPunishView.as_view(), name='客服申请出发打手'),
|
||||
path('adkfgl', AdKfglView.as_view(), name='管理员获取客服数据'),
|
||||
path('adkftj', AdKftjView.as_view(), name='管理添加客服'),
|
||||
path('adkfxg', AdKfxgView.as_view(), name='管理修改客服'),
|
||||
|
||||
|
||||
path('tixiansq', TixianShenqingV3View.as_view(), name='提现申请'),
|
||||
path('tixianqr', TixianQueRenAutoView.as_view(), name='新提现确认'),
|
||||
|
||||
path('tixiancallback', csrf_exempt(TixianCallbackV3View.as_view()), name='提现回调'),
|
||||
path('kefuqiangzhijiedan', KefuForceCompleteView.as_view(), name='客服强制结单'),
|
||||
|
||||
|
||||
|
||||
|
||||
# 已登录用户注册管事
|
||||
path('guanshizhuce', GuanshiRegisterView.as_view(), name='管事注册,已经登陆'),
|
||||
# 未登录用户微信登录+管事注册
|
||||
path('wdlyqmzc', WechatLoginAndGuanshiRegisterView.as_view(), name='管事注册,没有登录'),
|
||||
path('zuzhangzhuce', ZuzhangZhuceView.as_view(), name='组长注册'),
|
||||
path('zuzhangxinxi', ZuzhangXinxiView.as_view(), name='组长刷新获取信息'),
|
||||
path('hqwdyqr', HuoQuYaoQingRenView.as_view(), name='打手联系获取管事'),
|
||||
|
||||
path('dshqltqx', DashouJianquanView.as_view(), name='前端鉴权打手是否有使用消息功能'), # 打手鉴权
|
||||
path('lbhqltqx', LaobanJianquanView.as_view(), name='鉴权老板是否有使用消息功能'), # 老板鉴权
|
||||
|
||||
path('cffktjhq', FaKuanJiFenTongJiView.as_view(), name='获取罚款 + 积分处罚综合统计'),
|
||||
|
||||
# 获取打手自己的罚款列表
|
||||
path('dsfklbhq', DaShouFaKuanLieBiaoView.as_view(), name='获取打手自己的罚款列表'),
|
||||
|
||||
# 提交罚款申诉
|
||||
path('fkss', FaKuanShenSuView.as_view(), name='提交罚款申诉'),
|
||||
|
||||
path('fkjn', FaKuanPayView.as_view(), name='提交罚款微信支付申请'), # 下单
|
||||
path('fk_huitiao', csrf_exempt(FaKuanHuitiaoView.as_view()), name='提交罚款微信支付回调'), # 回调
|
||||
path('fkzffc', FaKuanPayPollView.as_view(), name='提交罚款申微信支付成功轮询'), # 轮询
|
||||
path('fkzfsb', FaKuanPayFailView.as_view(), name='提交罚款微信支付失败'), # 失败
|
||||
|
||||
path('khzf', KaohePayView.as_view(), name='考核支付下单'),
|
||||
path('kh_huitiao', csrf_exempt(KaohePayCallbackView.as_view()), name='考核支付回调'),
|
||||
path('khzffc', KaohePayPollView.as_view(), name='考核支付复查轮询'),
|
||||
path('khzfsb', KaohePayFailView.as_view(), name='考核支付失败'),
|
||||
path('tixianzichan', TixianAssetView.as_view(), name='小程序提现数据获取'),
|
||||
path('zddksh', TixianZddkshApplyView.as_view(), name='自动提现审核申请'),
|
||||
|
||||
|
||||
|
||||
]
|
||||
17268
yonghu/views.py
Normal file
17268
yonghu/views.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user