Files
Django/jituan/models.py

467 lines
23 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""集团多俱乐部数据模型(新建表,不修改 gvsdsdk"""
import uuid
from decimal import Decimal
from django.db import models
from gvsdsdk.model_base import QModel
class Club(QModel):
"""子公司 / 俱乐部主表。"""
club_id = models.CharField(max_length=16, primary_key=True, verbose_name='俱乐部ID')
name = models.CharField(max_length=64, verbose_name='展示名')
status = models.IntegerField(default=1, verbose_name='1启用0停用')
wx_appid = models.CharField(max_length=32, blank=True, default='')
wx_secret = models.CharField(max_length=128, blank=True, default='')
# —— 点单/会员等收款商户V2 JSAPI退款也应对齐这套——
mch_id = models.CharField(max_length=32, blank=True, default='', verbose_name='收款商户号')
pay_app_id = models.CharField(max_length=32, blank=True, default='', verbose_name='收款AppID')
mch_key = models.CharField(max_length=128, blank=True, default='', verbose_name='收款APIv2密钥')
pay_cert_path = models.CharField(
max_length=512, blank=True, default='',
verbose_name='收款商户证书路径',
help_text='apiclient_cert.pem退款/V2 证书用',
)
pay_key_path = models.CharField(
max_length=512, blank=True, default='',
verbose_name='收款商户私钥路径',
help_text='apiclient_key.pem退款/V2 证书用',
)
# —— 提现/转账商户V3可与收款商户号不同——
withdraw_mch_id = models.CharField(
max_length=32, blank=True, default='',
verbose_name='提现商户号',
help_text='空则回落收款商户号 mch_id',
)
api_v3_key = models.CharField(max_length=128, blank=True, default='', verbose_name='提现APIv3密钥')
cert_serial_no = models.CharField(max_length=64, blank=True, default='', verbose_name='提现证书序列号')
private_key_path = models.CharField(
max_length=512, blank=True, default='', verbose_name='提现商户私钥路径',
)
platform_cert_dir = models.CharField(
max_length=512, blank=True, default='', verbose_name='提现平台证书目录',
)
official_appid = models.CharField(max_length=32, blank=True, default='')
official_secret = models.CharField(max_length=128, blank=True, default='')
official_token = models.CharField(max_length=64, blank=True, default='')
encoding_aes_key = models.CharField(max_length=64, blank=True, default='')
template_id = models.CharField(max_length=64, blank=True, default='')
template_max_per_minute = models.IntegerField(default=950)
h5_domain = models.CharField(max_length=128, blank=True, default='')
oss_prefix = models.CharField(max_length=128, blank=True, default='')
goeasy_appkey = models.CharField(max_length=64, blank=True, default='')
goeasy_secret = models.CharField(max_length=128, blank=True, default='')
config_json = models.JSONField(default=dict, blank=True)
# 小程序「微信支付」入口实际走哪条通道wechat=直连商户号fubei=付呗(前端仍传 wechat
mini_pay_channel = models.CharField(
max_length=16,
blank=True,
default='wechat',
verbose_name='小程序收款通道',
help_text='wechat=微信直连fubei=付呗;默认 wechat不影响现网',
)
company_uuid = models.BinaryField(max_length=16, null=True, blank=True)
sort_order = models.IntegerField(default=0)
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club'
verbose_name = '俱乐部'
class ClubPaymentChannel(QModel):
"""俱乐部支付通道配置(可多条;同 channel 用 is_default 选主配置)。"""
CHANNEL_CHOICES = (
('wechat_jsapi', '微信直连-小程序JSAPI'),
('wechat_v3', '微信直连-V3转账/退款'),
('alipay_wap', '支付宝-手机网站'),
('fubei_wx_mini', '付呗-微信小程序'),
)
club_id = models.CharField(max_length=16, db_index=True, verbose_name='俱乐部ID')
channel = models.CharField(max_length=32, choices=CHANNEL_CHOICES, db_index=True)
name = models.CharField(max_length=64, verbose_name='配置名称', help_text='如:主付呗、备用微信')
enabled = models.IntegerField(default=1, verbose_name='1启用0停用')
is_default = models.BooleanField(default=True, verbose_name='同通道默认配置')
sort_order = models.IntegerField(default=0, verbose_name='前端展示顺序')
sandbox = models.BooleanField(default=False, verbose_name='沙箱/联调')
app_id = models.CharField(max_length=64, blank=True, default='', verbose_name='AppID/付呗ID')
mch_id = models.CharField(max_length=64, blank=True, default='', verbose_name='商户号')
api_key_enc = models.TextField(blank=True, default='', verbose_name='API密钥/付呗Secret(加密)')
private_key_enc = models.TextField(blank=True, default='', verbose_name='应用私钥(加密)')
public_key_enc = models.TextField(blank=True, default='', verbose_name='平台公钥(加密或明文)')
cert_serial_no = models.CharField(max_length=64, blank=True, default='')
private_key_path = models.CharField(max_length=255, blank=True, default='')
platform_cert_dir = models.CharField(max_length=255, blank=True, default='')
notify_url = models.CharField(max_length=512, blank=True, default='', verbose_name='异步回调URL')
return_url = models.CharField(max_length=512, blank=True, default='', verbose_name='同步返回URL')
gateway_url = models.CharField(max_length=255, blank=True, default='', verbose_name='API网关')
mini_app_id = models.CharField(
max_length=32, blank=True, default='',
verbose_name='支付用小程序AppID',
help_text='付呗/微信JSAPI空则回落 club.wx_appid',
)
extra_json = models.JSONField(blank=True, default=dict, verbose_name='扩展配置')
remark = models.CharField(max_length=255, blank=True, default='')
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club_payment_channel'
verbose_name = '俱乐部支付通道'
unique_together = [['club_id', 'channel', 'name']]
indexes = [
models.Index(fields=['club_id', 'channel', 'enabled'], name='idx_cpc_club_ch_en'),
models.Index(fields=['club_id', 'is_default'], name='idx_cpc_club_default'),
]
class PayChannelLedger(QModel):
"""下单时记录实际支付通道,供回调路由与退款选用(前端无感知)。"""
out_trade_no = models.CharField(max_length=64, unique=True, db_index=True, verbose_name='商户订单号')
club_id = models.CharField(max_length=16, db_index=True, default='')
channel = models.CharField(max_length=32, db_index=True, verbose_name='通道')
channel_config_id = models.IntegerField(null=True, blank=True)
biz_type = models.CharField(max_length=16, blank=True, default='', verbose_name='order/czjilu')
provider_order_sn = models.CharField(max_length=64, blank=True, default='', verbose_name='通道侧订单号')
amount_yuan = models.DecimalField(max_digits=12, decimal_places=2, default=0)
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'pay_channel_ledger'
verbose_name = '支付通道流水'
class UserWxOpenid(QModel):
"""微信 openid 与俱乐部用户绑定club_id + openid 唯一)。"""
club_id = models.CharField(max_length=16, db_index=True)
openid = models.CharField(max_length=64, db_index=True)
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
unionid = models.CharField(max_length=64, null=True, blank=True)
CreateTime = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'user_wx_openid'
unique_together = [['club_id', 'openid']]
class AdminAssignment(QModel):
"""管理任职:集团或子公司后台权限范围。"""
yonghuid = models.CharField(max_length=7, db_index=True)
club_id = models.CharField(max_length=16, null=True, blank=True, db_index=True,
verbose_name='NULL=集团任职')
role_code = models.CharField(max_length=50, default='CLUB_ADMIN')
data_scope = models.CharField(max_length=20, default='SINGLE_CLUB')
is_primary = models.BooleanField(default=False)
granted_by = models.CharField(max_length=7, blank=True, default='')
status = models.IntegerField(default=1, verbose_name='1有效0停用')
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'admin_assignment'
unique_together = [['yonghuid', 'club_id', 'role_code']]
class AdminAuditLog(QModel):
"""后台敏感操作审计(改余额等)。"""
club_id = models.CharField(max_length=16, null=True, blank=True, db_index=True)
operator_yonghuid = models.CharField(max_length=16, db_index=True)
operator_role_code = models.CharField(max_length=50, blank=True, default='')
target_yonghuid = models.CharField(max_length=7, null=True, blank=True)
action = models.CharField(max_length=64, db_index=True)
resource_type = models.CharField(max_length=32, blank=True, default='')
resource_id = models.CharField(max_length=64, blank=True, default='')
field_name = models.CharField(max_length=64, blank=True, default='')
value_before = models.TextField(null=True, blank=True)
value_after = models.TextField(null=True, blank=True)
request_ip = models.CharField(max_length=64, blank=True, default='')
remark = models.CharField(max_length=500, blank=True, default='')
CreateTime = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'admin_audit_log'
indexes = [models.Index(fields=['club_id', '-CreateTime'])]
class ClubHuiyuanPrice(QModel):
"""各俱乐部会员售价/分成(全局 huiyuan_id 定义不变)。"""
club_id = models.CharField(max_length=16, db_index=True)
huiyuan_id = models.CharField(max_length=6, db_index=True)
jiage = models.DecimalField(max_digits=10, decimal_places=2, default=Decimal('0.00'))
guanshifc = models.DecimalField(max_digits=10, decimal_places=2, default=Decimal('0.00'))
zuzhangfc = models.DecimalField(max_digits=10, decimal_places=2, default=Decimal('0.00'))
formal_days = models.PositiveIntegerField(default=30, verbose_name='正式会员有效天数')
trial_enabled = models.BooleanField(default=False, verbose_name='是否开启体验会员')
trial_price = models.DecimalField(
max_digits=10, decimal_places=2, default=Decimal('0.00'), verbose_name='体验会员价格',
)
trial_days = models.PositiveIntegerField(default=0, verbose_name='体验会员有效天数')
trial_guanshifc = models.DecimalField(
max_digits=10, decimal_places=2, default=Decimal('0.00'), verbose_name='体验管事分成',
)
trial_zuzhangfc = models.DecimalField(
max_digits=10, decimal_places=2, default=Decimal('0.00'), verbose_name='体验组长分成',
)
card_image = models.CharField(
max_length=500, blank=True, default='', verbose_name='充值页会员卡片装饰图(相对URL)',
)
card_bg = models.CharField(
max_length=500, blank=True, default='', verbose_name='充值页会员卡片背景图(相对URL,可选)',
)
is_enabled = models.BooleanField(default=True)
bankuai_id = models.IntegerField(null=True, blank=True)
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club_huiyuan_price'
unique_together = [['club_id', 'huiyuan_id']]
class ClubHuiyuanBundleInclude(QModel):
"""俱乐部总会员包含的子会员类型(仅 is_bundle 会员使用)。"""
club_id = models.CharField(max_length=16, db_index=True)
bundle_huiyuan_id = models.CharField(max_length=6, db_index=True, verbose_name='总会员ID')
included_huiyuan_id = models.CharField(max_length=6, db_index=True, verbose_name='包含的子会员ID')
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club_huiyuan_bundle_include'
unique_together = [['club_id', 'bundle_huiyuan_id', 'included_huiyuan_id']]
class ClubShangpinLeixingConfig(QModel):
"""各俱乐部小程序商品类型上架与图标(全局 ShangpinLeixing 由集团定义)。"""
club_id = models.CharField(max_length=16, db_index=True)
leixing_id = models.IntegerField(db_index=True, verbose_name='全局商品类型ID')
is_enabled = models.BooleanField(default=True, verbose_name='是否上架')
tupian_url = models.CharField(max_length=500, blank=True, default='', verbose_name='俱乐部专属图标')
paixu = models.IntegerField(default=0, verbose_name='排序权重')
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club_shangpin_leixing_config'
unique_together = [['club_id', 'leixing_id']]
class ClubKaoheChenghaoConfig(QModel):
"""各俱乐部抢单池标签筛选区上架配置(全局 Chenghao 由集团定义)。"""
club_id = models.CharField(max_length=16, db_index=True)
chenghao_id = models.IntegerField(db_index=True, verbose_name='全局称号ID')
is_enabled = models.BooleanField(default=True, verbose_name='是否在抢单池筛选区展示')
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club_kaohe_chenghao_config'
unique_together = [['club_id', 'chenghao_id']]
class ClubLilubiao(QModel):
"""各俱乐部分红/手续费配置(对应 lilubiao.fadanpingtai"""
club_id = models.CharField(max_length=16, db_index=True)
config_type = models.IntegerField(db_index=True, verbose_name='同 lilubiao.fadanpingtai')
lilv = models.DecimalField(max_digits=10, decimal_places=4, default=Decimal('0.0000'))
remark = models.CharField(max_length=255, blank=True, default='')
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club_lilubiao'
unique_together = [['club_id', 'config_type']]
class ClubWithdrawConfig(QModel):
club_id = models.CharField(max_length=16, primary_key=True)
mode = models.IntegerField(default=1, verbose_name='1自动2手动')
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club_withdraw_config'
class ClubTixianQuota(QModel):
club_id = models.CharField(max_length=16, db_index=True)
leixing = models.IntegerField(db_index=True)
daily_limit = models.DecimalField(max_digits=12, decimal_places=2, default=Decimal('0.00'))
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club_tixian_quota'
unique_together = [['club_id', 'leixing']]
class ClubFadanFenhongLilv(QModel):
club_id = models.CharField(max_length=16, db_index=True)
shenfen = models.IntegerField(db_index=True)
lilv = models.DecimalField(max_digits=10, decimal_places=4, default=Decimal('0.0000'))
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club_fadan_fenhong_lilv'
unique_together = [['club_id', 'shenfen']]
class IdentityTag(QModel):
"""身份装饰标签定义(与考核称号、订单需求标签分离)。"""
club_id = models.CharField(max_length=16, db_index=True)
name = models.CharField(max_length=64, verbose_name='标签名')
color = models.CharField(max_length=32, default='#000000', verbose_name='主色')
flash_enabled = models.BooleanField(default=False, verbose_name='闪光特效')
texiao_json = models.TextField(blank=True, default='', verbose_name='特效JSON')
sort_order = models.IntegerField(default=0)
status = models.IntegerField(default=1, verbose_name='1启用0停用')
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'identity_tag'
ordering = ['sort_order', 'id']
class IdentityTagBind(QModel):
"""用户身份与装饰标签绑定。"""
club_id = models.CharField(max_length=16, db_index=True)
yonghuid = models.CharField(max_length=7, db_index=True)
shenfen = models.IntegerField(verbose_name='1打手2管事3商家4组长')
tag = models.ForeignKey(IdentityTag, on_delete=models.CASCADE, related_name='binds')
CreateTime = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'identity_tag_bind'
unique_together = [['club_id', 'yonghuid', 'shenfen', 'tag']]
indexes = [
models.Index(fields=['club_id', 'yonghuid', 'shenfen']),
]
class ClubDashouExamConfig(QModel):
"""各俱乐部打手抢单前考试配置(互不影响)。"""
club_id = models.CharField(max_length=16, primary_key=True)
is_enabled = models.BooleanField(default=False, verbose_name='是否开启考试')
draw_count = models.PositiveIntegerField(default=10, verbose_name='每次抽题数量')
pass_count = models.PositiveIntegerField(default=10, verbose_name='至少答对题数')
require_member = models.BooleanField(default=True, verbose_name='须开通会员方可考试')
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club_dashou_exam_config'
class ClubDashouExamQuestion(QModel):
"""俱乐部考试题库(题干+最多6选项"""
club_id = models.CharField(max_length=16, db_index=True)
stem = models.TextField(verbose_name='题干文字')
question_type = models.IntegerField(default=1, verbose_name='1单选2多选')
option_1 = models.CharField(max_length=500, blank=True, default='')
option_2 = models.CharField(max_length=500, blank=True, default='')
option_3 = models.CharField(max_length=500, blank=True, default='')
option_4 = models.CharField(max_length=500, blank=True, default='')
option_5 = models.CharField(max_length=500, blank=True, default='')
option_6 = models.CharField(max_length=500, blank=True, default='')
correct_1 = models.BooleanField(default=False)
correct_2 = models.BooleanField(default=False)
correct_3 = models.BooleanField(default=False)
correct_4 = models.BooleanField(default=False)
correct_5 = models.BooleanField(default=False)
correct_6 = models.BooleanField(default=False)
explanation = models.TextField(blank=True, default='', verbose_name='错题解析')
is_enabled = models.BooleanField(default=True, verbose_name='是否上架')
sort_order = models.IntegerField(default=0)
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club_dashou_exam_question'
indexes = [models.Index(fields=['club_id', 'is_enabled'])]
class ClubDashouExamQuestionImage(QModel):
"""题目配图(题干下方,可多张)。"""
club_id = models.CharField(max_length=16, db_index=True)
question_id = models.IntegerField(db_index=True)
image_url = models.CharField(max_length=500)
sort_order = models.IntegerField(default=0)
CreateTime = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'club_dashou_exam_question_image'
indexes = [models.Index(fields=['club_id', 'question_id'])]
class ClubDashouExamPass(QModel):
"""打手在本俱乐部是否已通过考试。"""
club_id = models.CharField(max_length=16, db_index=True)
yonghuid = models.CharField(max_length=7, db_index=True)
passed_at = models.DateTimeField(auto_now_add=True)
CreateTime = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'club_dashou_exam_pass'
unique_together = [['club_id', 'yonghuid']]
class ClubRechargePageCopy(QModel):
"""会员充值页 / 履约金页按俱乐部可配置的文案与图标。"""
club_id = models.CharField(max_length=16, db_index=True, verbose_name='俱乐部ID')
page_key = models.CharField(max_length=16, db_index=True, verbose_name='huiyuan|yajin')
region_key = models.CharField(max_length=32, db_index=True, verbose_name='rules|benefits|advantages')
title = models.CharField(max_length=64, blank=True, default='', verbose_name='区域标题')
items_json = models.JSONField(default=list, blank=True, verbose_name='条目列表JSON')
enabled = models.BooleanField(default=True, verbose_name='是否启用该区域')
sort_order = models.IntegerField(default=0)
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club_recharge_page_copy'
unique_together = [['club_id', 'page_key', 'region_key']]
verbose_name = '充值页文案配置'
class KefuMenuPage(QModel):
"""客服后台左侧菜单页(固定 page_id与前端路由对应"""
page_id = models.CharField(max_length=64, primary_key=True, verbose_name='页面ID')
name = models.CharField(max_length=64, verbose_name='展示名')
path = models.CharField(max_length=128, blank=True, default='', verbose_name='路由路径,分组为空')
parent_id = models.CharField(max_length=64, blank=True, default='', db_index=True)
sort_order = models.IntegerField(default=0)
perm_codes = models.JSONField(default=list, blank=True, verbose_name='拥有任一权限即可见')
require_super = models.BooleanField(default=False, verbose_name='仅超级管理000001')
require_group_manage = models.BooleanField(default=False, verbose_name='仅集团超管任职')
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'kefu_menu_page'
ordering = ['sort_order', 'page_id']
class ClubOrderGrabLink(QModel):
"""
俱乐部订单单向互通抢单。
grabber_club_id 的打手可抢 order_club_id 的待接单;反向需另建一条。
关停:删除记录即可(两字段,无开关列)。
"""
grabber_club_id = models.CharField(max_length=16, db_index=True, verbose_name='抢单方俱乐部')
order_club_id = models.CharField(max_length=16, db_index=True, verbose_name='被抢订单所属俱乐部')
CreateTime = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'club_order_grab_link'
verbose_name = '俱乐部订单互通抢单'
unique_together = [['grabber_club_id', 'order_club_id']]
indexes = [
models.Index(fields=['grabber_club_id'], name='idx_cogl_grabber'),
models.Index(fields=['order_club_id'], name='idx_cogl_order'),
]