完成后台多俱乐部数据隔离:订单/会员/财务/板块,并添加星之界初始化命令

This commit is contained in:
XingQue
2026-06-24 22:59:08 +08:00
parent 8154b2639d
commit 65613af195
7 changed files with 273 additions and 184 deletions

View File

@@ -3,6 +3,7 @@ from datetime import date, datetime, timedelta
from django.db.models import Sum
from jituan.constants import DATA_SCOPE_ALL
from jituan.services.club_context import (
filter_club_char_field,
filter_queryset_by_club,

View File

@@ -0,0 +1,144 @@
"""后台会员管理:全局 Huiyuan 定义 + 各俱乐部 ClubHuiyuanPrice 售价/分成。"""
import random
import string
from decimal import Decimal
from django.db import transaction
from jituan.constants import CLUB_ID_DEFAULT, DATA_SCOPE_ALL
from jituan.models import ClubHuiyuanPrice
from jituan.services.club_context import club_id_for_write, resolve_club_id_from_request, resolve_club_scope
from jituan.services.club_user_access import list_response_meta
from products.models import Huiyuan
def _format_member(m, price_row=None):
item = {
'huiyuan_id': m.huiyuan_id,
'jieshao': m.jieshao,
'jtjieshao': m.jtjieshao,
'jiage': str(m.jiage),
'guanshifc': str(m.guanshifc),
'zuzhangfc': str(m.zuzhangfc),
'goumai_cishu': m.goumai_cishu,
'CreateTime': m.CreateTime.isoformat() if m.CreateTime else None,
'UpdateTime': m.UpdateTime.isoformat() if m.UpdateTime else None,
'bankuai_id': m.bankuai_id,
'club_enabled': True,
}
if price_row is not None:
item['jiage'] = str(price_row.jiage)
item['guanshifc'] = str(price_row.guanshifc)
item['zuzhangfc'] = str(price_row.zuzhangfc)
item['club_enabled'] = bool(price_row.is_enabled)
return item
def build_member_list_payload(request):
scope = resolve_club_scope(request)
club_id = resolve_club_id_from_request(request)
members = Huiyuan.query.all().order_by('-CreateTime')
member_list = []
if scope == DATA_SCOPE_ALL:
for m in members:
member_list.append(_format_member(m))
else:
price_map = {
r.huiyuan_id: r
for r in ClubHuiyuanPrice.query.filter(club_id=club_id)
}
for m in members:
row = price_map.get(m.huiyuan_id)
if row is None and club_id != CLUB_ID_DEFAULT:
continue
if row is not None and not row.is_enabled:
continue
member_list.append(_format_member(m, row))
return {
'list': member_list,
'club_id': club_id,
'scope': scope,
**list_response_meta(request),
}
def update_member_for_club(request, huiyuan_id, jieshao, jiage, guanshifc, zuzhangfc, jtjieshao):
if resolve_club_scope(request) == DATA_SCOPE_ALL:
return None, '集团汇总视图下不可修改,请切换到具体俱乐部'
club_id = club_id_for_write(request)
with transaction.atomic():
try:
member = Huiyuan.objects.select_for_update().get(huiyuan_id=huiyuan_id)
except Huiyuan.DoesNotExist:
return None, '会员不存在'
member.jieshao = jieshao
member.jtjieshao = jtjieshao
member.save(update_fields=['jieshao', 'jtjieshao', 'UpdateTime'])
row, created = ClubHuiyuanPrice.query.get_or_create(
club_id=club_id,
huiyuan_id=huiyuan_id,
defaults={
'jiage': jiage,
'guanshifc': guanshifc,
'zuzhangfc': zuzhangfc,
'is_enabled': True,
'bankuai_id': member.bankuai_id,
},
)
if not created:
row.jiage = jiage
row.guanshifc = guanshifc
row.zuzhangfc = zuzhangfc
row.is_enabled = True
row.save()
if club_id == CLUB_ID_DEFAULT:
member.jiage = jiage
member.guanshifc = guanshifc
member.zuzhangfc = zuzhangfc
member.save(update_fields=['jiage', 'guanshifc', 'zuzhangfc', 'UpdateTime'])
return {'huiyuan_id': huiyuan_id}, None
def add_member_for_club(request, jieshao, jiage, guanshifc, zuzhangfc, jtjieshao, bankuai_id=None):
if resolve_club_scope(request) == DATA_SCOPE_ALL:
return None, '集团汇总视图下不可添加,请切换到具体俱乐部'
club_id = club_id_for_write(request)
def generate_huiyuan_id():
while True:
new_id = ''.join(random.choices(string.ascii_uppercase + string.digits, k=6))
if not Huiyuan.query.filter(huiyuan_id=new_id).exists():
return new_id
with transaction.atomic():
new_id = generate_huiyuan_id()
member = Huiyuan.query.create(
huiyuan_id=new_id,
jieshao=jieshao,
jiage=jiage,
guanshifc=guanshifc,
zuzhangfc=zuzhangfc,
jtjieshao=jtjieshao,
goumai_cishu=0,
bankuai_id=bankuai_id,
)
ClubHuiyuanPrice.query.create(
club_id=club_id,
huiyuan_id=new_id,
jiage=jiage,
guanshifc=guanshifc,
zuzhangfc=zuzhangfc,
is_enabled=True,
bankuai_id=bankuai_id,
)
return {'huiyuan_id': member.huiyuan_id}, None

View File

@@ -1,7 +1,7 @@
"""后台按俱乐部校验用户是否在当前数据范围内。"""
"""后台按俱乐部校验用户/订单是否在当前数据范围内。"""
from rest_framework.response import Response
from jituan.constants import DATA_SCOPE_ALL
from jituan.constants import CLUB_ID_DEFAULT, DATA_SCOPE_ALL
from jituan.services.club_context import resolve_club_id_from_request, resolve_club_scope
@@ -25,3 +25,19 @@ def list_response_meta(request):
'club_id': resolve_club_id_from_request(request),
'scope': resolve_club_scope(request),
}
def order_belongs_to_request(order, request):
if resolve_club_scope(request) == DATA_SCOPE_ALL:
return True
club_id = resolve_club_id_from_request(request)
order_club = (getattr(order, 'ClubID', None) or '').strip()
if club_id == CLUB_ID_DEFAULT:
return order_club in (club_id, '', None) or not order_club
return order_club == club_id
def forbid_if_order_out_of_scope(request, order):
if order_belongs_to_request(order, request):
return None
return Response({'code': 403, 'msg': '该订单不属于当前俱乐部数据范围'})