mirror of
https://github.com/zhtyyx/ioe.git
synced 2026-06-03 21:02:59 +08:00
752 lines
27 KiB
Python
752 lines
27 KiB
Python
from django.shortcuts import render, redirect, get_object_or_404
|
||
from django.contrib.auth.decorators import login_required
|
||
from django.contrib import messages
|
||
from django.db.models import F, Sum
|
||
from .models import Product, Category, Inventory, Sale, SaleItem, InventoryTransaction, Member, MemberLevel, RechargeRecord
|
||
from django.http import JsonResponse
|
||
from .models import OperationLog
|
||
from django.db.models import Q
|
||
from decimal import Decimal
|
||
from django.utils import timezone
|
||
import re
|
||
|
||
|
||
def product_by_barcode(request, barcode):
|
||
try:
|
||
# 先尝试精确匹配条码
|
||
product = Product.objects.get(barcode=barcode)
|
||
# 获取库存信息
|
||
try:
|
||
inventory = Inventory.objects.get(product=product)
|
||
stock = inventory.quantity
|
||
except Inventory.DoesNotExist:
|
||
stock = 0
|
||
|
||
return JsonResponse({
|
||
'success': True,
|
||
'product_id': product.id,
|
||
'name': product.name,
|
||
'price': product.price,
|
||
'stock': stock,
|
||
'category': product.category.name if product.category else '',
|
||
'specification': product.specification,
|
||
'manufacturer': product.manufacturer
|
||
})
|
||
except Product.DoesNotExist:
|
||
# 如果精确匹配失败,尝试模糊匹配条码
|
||
products = Product.objects.filter(barcode__icontains=barcode).order_by('barcode')[:5]
|
||
if products.exists():
|
||
# 返回匹配的多个商品
|
||
product_list = []
|
||
for product in products:
|
||
try:
|
||
inventory = Inventory.objects.get(product=product)
|
||
stock = inventory.quantity
|
||
except Inventory.DoesNotExist:
|
||
stock = 0
|
||
|
||
product_list.append({
|
||
'product_id': product.id,
|
||
'barcode': product.barcode,
|
||
'name': product.name,
|
||
'price': float(product.price),
|
||
'stock': stock
|
||
})
|
||
|
||
return JsonResponse({
|
||
'success': True,
|
||
'multiple_matches': True,
|
||
'products': product_list
|
||
})
|
||
else:
|
||
return JsonResponse({'success': False, 'message': '未找到商品'})
|
||
|
||
# 新增会员搜索API
|
||
def member_search_by_phone(request, phone):
|
||
"""
|
||
根据手机号搜索会员的API
|
||
支持精确匹配和模糊匹配,返回多个匹配结果
|
||
"""
|
||
try:
|
||
# 先尝试精确匹配手机号
|
||
member = Member.objects.get(phone=phone)
|
||
return JsonResponse({
|
||
'success': True,
|
||
'multiple_matches': False,
|
||
'member_id': member.id,
|
||
'member_name': member.name,
|
||
'member_level': member.level.name,
|
||
'member_balance': float(member.balance),
|
||
'member_points': member.points,
|
||
'member_gender': member.get_gender_display(),
|
||
'member_birthday': member.birthday.strftime('%Y-%m-%d') if member.birthday else '',
|
||
'member_total_spend': float(member.total_spend),
|
||
'member_purchase_count': member.purchase_count
|
||
})
|
||
except Member.DoesNotExist:
|
||
# 如果精确匹配失败,尝试模糊匹配手机号或姓名
|
||
members = Member.objects.filter(
|
||
models.Q(phone__icontains=phone) |
|
||
models.Q(name__icontains=phone)
|
||
).order_by('phone')[:5] # 限制返回数量
|
||
|
||
if members.exists():
|
||
# 如果只有一个匹配结果
|
||
if members.count() == 1:
|
||
member = members.first()
|
||
return JsonResponse({
|
||
'success': True,
|
||
'multiple_matches': False,
|
||
'member_id': member.id,
|
||
'member_name': member.name,
|
||
'member_level': member.level.name,
|
||
'member_balance': float(member.balance),
|
||
'member_points': member.points,
|
||
'member_gender': member.get_gender_display(),
|
||
'member_birthday': member.birthday.strftime('%Y-%m-%d') if member.birthday else '',
|
||
'member_total_spend': float(member.total_spend),
|
||
'member_purchase_count': member.purchase_count
|
||
})
|
||
# 如果有多个匹配结果
|
||
else:
|
||
member_list = []
|
||
for member in members:
|
||
member_list.append({
|
||
'member_id': member.id,
|
||
'member_name': member.name,
|
||
'member_phone': member.phone,
|
||
'member_level': member.level.name,
|
||
'member_balance': float(member.balance),
|
||
'member_points': member.points
|
||
})
|
||
return JsonResponse({
|
||
'success': True,
|
||
'multiple_matches': True,
|
||
'members': member_list
|
||
})
|
||
else:
|
||
return JsonResponse({'success': False, 'message': '未找到会员'})
|
||
|
||
from .forms import ProductForm, InventoryTransactionForm, SaleForm, SaleItemForm, MemberForm
|
||
|
||
@login_required
|
||
def index(request):
|
||
products = Product.objects.all()[:5] # 获取最新的5个商品
|
||
low_stock_items = Inventory.objects.filter(quantity__lte=F('warning_level'))[:5] # 获取库存预警商品
|
||
context = {
|
||
'products': products,
|
||
'low_stock_items': low_stock_items,
|
||
}
|
||
return render(request, 'inventory/index.html', context)
|
||
|
||
@login_required
|
||
def product_list(request):
|
||
products = Product.objects.all()
|
||
categories = Category.objects.all()
|
||
return render(request, 'inventory/product_list.html', {'products': products, 'categories': categories})
|
||
|
||
@login_required
|
||
def inventory_list(request):
|
||
# 获取筛选参数
|
||
category_id = request.GET.get('category', '')
|
||
color = request.GET.get('color', '')
|
||
size = request.GET.get('size', '')
|
||
search_query = request.GET.get('search', '')
|
||
|
||
# 基础查询
|
||
inventory_items = Inventory.objects.select_related('product', 'product__category').all()
|
||
|
||
# 应用筛选条件
|
||
if category_id:
|
||
inventory_items = inventory_items.filter(product__category_id=category_id)
|
||
|
||
if color:
|
||
inventory_items = inventory_items.filter(product__color=color)
|
||
|
||
if size:
|
||
inventory_items = inventory_items.filter(product__size=size)
|
||
|
||
if search_query:
|
||
inventory_items = inventory_items.filter(
|
||
Q(product__name__icontains=search_query) |
|
||
Q(product__barcode__icontains=search_query)
|
||
)
|
||
|
||
# 获取所有分类
|
||
categories = Category.objects.all()
|
||
|
||
# 获取所有可用的颜色和尺码
|
||
colors = Product.COLOR_CHOICES
|
||
sizes = Product.SIZE_CHOICES
|
||
|
||
context = {
|
||
'inventory_items': inventory_items,
|
||
'categories': categories,
|
||
'colors': colors,
|
||
'sizes': sizes,
|
||
'selected_category': category_id,
|
||
'selected_color': color,
|
||
'selected_size': size,
|
||
'search_query': search_query,
|
||
}
|
||
|
||
return render(request, 'inventory/inventory_list.html', context)
|
||
|
||
@login_required
|
||
def sale_list(request):
|
||
sales = Sale.objects.all().order_by('-created_at')
|
||
return render(request, 'inventory/sale_list.html', {'sales': sales})
|
||
|
||
@login_required
|
||
def sale_detail(request, sale_id):
|
||
"""销售单详情视图"""
|
||
sale = get_object_or_404(Sale, pk=sale_id)
|
||
items = sale.items.all()
|
||
|
||
context = {
|
||
'sale': sale,
|
||
'items': items,
|
||
}
|
||
|
||
return render(request, 'inventory/sale_detail.html', context)
|
||
|
||
@login_required
|
||
def product_create(request):
|
||
initial_data = {}
|
||
|
||
# 如果是从条码API跳转过来的,预填表单
|
||
if request.method == 'GET' and 'barcode' in request.GET:
|
||
initial_data = {
|
||
'barcode': request.GET.get('barcode', ''),
|
||
'name': request.GET.get('name', ''),
|
||
'price': request.GET.get('price', 0),
|
||
'specification': request.GET.get('specification', ''),
|
||
'manufacturer': request.GET.get('manufacturer', ''),
|
||
'description': request.GET.get('description', '')
|
||
}
|
||
|
||
if request.method == 'POST':
|
||
form = ProductForm(request.POST, request.FILES)
|
||
if form.is_valid():
|
||
product = form.save()
|
||
Inventory.objects.create(product=product)
|
||
|
||
# 记录操作日志
|
||
from django.contrib.contenttypes.models import ContentType
|
||
OperationLog.objects.create(
|
||
operator=request.user,
|
||
operation_type='INVENTORY',
|
||
details=f'添加新商品: {product.name} (条码: {product.barcode})',
|
||
related_object_id=product.id,
|
||
related_content_type=ContentType.objects.get_for_model(Product)
|
||
)
|
||
|
||
messages.success(request, '商品添加成功')
|
||
return redirect('product_list')
|
||
else:
|
||
form = ProductForm(initial=initial_data)
|
||
|
||
return render(request, 'inventory/product_form.html', {
|
||
'form': form,
|
||
'is_from_barcode_api': bool(initial_data)
|
||
})
|
||
|
||
@login_required
|
||
def product_edit(request, product_id):
|
||
"""编辑商品信息"""
|
||
product = get_object_or_404(Product, id=product_id)
|
||
|
||
if request.method == 'POST':
|
||
form = ProductForm(request.POST, request.FILES, instance=product)
|
||
if form.is_valid():
|
||
form.save()
|
||
|
||
# 记录操作日志
|
||
from django.contrib.contenttypes.models import ContentType
|
||
OperationLog.objects.create(
|
||
operator=request.user,
|
||
operation_type='INVENTORY',
|
||
details=f'编辑商品: {product.name} (条码: {product.barcode})',
|
||
related_object_id=product.id,
|
||
related_content_type=ContentType.objects.get_for_model(Product)
|
||
)
|
||
|
||
messages.success(request, '商品信息更新成功')
|
||
return redirect('product_list')
|
||
else:
|
||
form = ProductForm(instance=product)
|
||
|
||
return render(request, 'inventory/product_form.html', {
|
||
'form': form,
|
||
'product': product,
|
||
'is_edit': True
|
||
})
|
||
|
||
@login_required
|
||
def inventory_transaction_create(request):
|
||
if request.method == 'POST':
|
||
form = InventoryTransactionForm(request.POST)
|
||
if form.is_valid():
|
||
transaction = form.save(commit=False)
|
||
transaction.transaction_type = 'IN'
|
||
transaction.operator = request.user
|
||
transaction.save()
|
||
|
||
inventory = Inventory.objects.get(product=transaction.product)
|
||
inventory.quantity += transaction.quantity
|
||
inventory.save()
|
||
|
||
messages.success(request, '入库操作成功')
|
||
return redirect('inventory_list')
|
||
else:
|
||
form = InventoryTransactionForm()
|
||
return render(request, 'inventory/inventory_form.html', {'form': form})
|
||
|
||
@login_required
|
||
def sale_create(request):
|
||
if request.method == 'POST':
|
||
form = SaleForm(request.POST)
|
||
if form.is_valid():
|
||
sale = form.save(commit=False)
|
||
sale.operator = request.user
|
||
|
||
# 添加会员关联
|
||
member_id = request.POST.get('member')
|
||
if member_id:
|
||
try:
|
||
member = Member.objects.get(id=member_id)
|
||
sale.member = member
|
||
except Member.DoesNotExist:
|
||
pass
|
||
|
||
sale.save()
|
||
messages.success(request, '销售单创建成功')
|
||
return redirect('sale_item_create', sale_id=sale.id)
|
||
else:
|
||
form = SaleForm()
|
||
|
||
# 获取会员等级列表,用于添加会员模态框
|
||
member_levels = MemberLevel.objects.all()
|
||
|
||
return render(request, 'inventory/sale_form.html', {
|
||
'form': form,
|
||
'member_levels': member_levels
|
||
})
|
||
|
||
@login_required
|
||
def sale_item_create(request, sale_id):
|
||
sale = get_object_or_404(Sale, id=sale_id)
|
||
if request.method == 'POST':
|
||
form = SaleItemForm(request.POST)
|
||
if form.is_valid():
|
||
sale_item = form.save(commit=False)
|
||
sale_item.sale = sale
|
||
|
||
inventory = Inventory.objects.get(product=sale_item.product)
|
||
if inventory.quantity >= sale_item.quantity:
|
||
inventory.quantity -= sale_item.quantity
|
||
inventory.save()
|
||
|
||
sale_item.save()
|
||
sale.update_total_amount()
|
||
|
||
transaction = InventoryTransaction.objects.create(
|
||
product=sale_item.product,
|
||
transaction_type='OUT',
|
||
quantity=sale_item.quantity,
|
||
operator=request.user,
|
||
notes=f'销售单号:{sale.id}'
|
||
)
|
||
|
||
messages.success(request, '商品添加成功')
|
||
|
||
# 记录操作日志
|
||
from django.contrib.contenttypes.models import ContentType
|
||
OperationLog.objects.create(
|
||
operator=request.user,
|
||
operation_type='SALE',
|
||
details=f'销售商品 {sale_item.product.name} 数量 {sale_item.quantity}',
|
||
related_object_id=sale.id,
|
||
related_content_type=ContentType.objects.get_for_model(Sale)
|
||
)
|
||
return redirect('sale_item_create', sale_id=sale.id)
|
||
else:
|
||
messages.error(request, '库存不足')
|
||
else:
|
||
form = SaleItemForm()
|
||
|
||
sale_items = sale.items.all()
|
||
return render(request, 'inventory/sale_item_form.html', {
|
||
'form': form,
|
||
'sale': sale,
|
||
'sale_items': sale_items
|
||
})
|
||
|
||
@login_required
|
||
def member_list(request):
|
||
sort_by = request.GET.get('sort', 'name')
|
||
|
||
# 根据排序参数查询会员
|
||
if sort_by == 'total_spend':
|
||
members = Member.objects.all().order_by('-total_spend')
|
||
sort_label = '累计消费'
|
||
elif sort_by == 'purchase_count':
|
||
members = Member.objects.all().order_by('-purchase_count')
|
||
sort_label = '消费次数'
|
||
else:
|
||
members = Member.objects.all().order_by('name')
|
||
sort_by = 'name' # 防止注入
|
||
sort_label = '姓名'
|
||
|
||
member_levels = MemberLevel.objects.all()
|
||
|
||
return render(request, 'inventory/member_list.html', {
|
||
'members': members,
|
||
'member_levels': member_levels,
|
||
'sort_by': sort_by,
|
||
'sort_label': sort_label
|
||
})
|
||
|
||
@login_required
|
||
def member_create(request):
|
||
# 移除对当前用户是否已有会员记录的检查,允许管理员创建多个会员
|
||
if request.method == 'POST':
|
||
form = MemberForm(request.POST)
|
||
if form.is_valid():
|
||
member = form.save(commit=False)
|
||
# 不再将会员与当前用户关联,允许创建独立的会员记录
|
||
member.save()
|
||
messages.success(request, '会员添加成功')
|
||
return redirect('member_list')
|
||
else:
|
||
form = MemberForm()
|
||
return render(request, 'inventory/member_form.html', {'form': form})
|
||
|
||
@login_required
|
||
def member_edit(request, member_id):
|
||
member = get_object_or_404(Member, id=member_id)
|
||
if request.method == 'POST':
|
||
form = MemberForm(request.POST, instance=member)
|
||
if form.is_valid():
|
||
form.save()
|
||
messages.success(request, '会员信息更新成功')
|
||
return redirect('member_list')
|
||
else:
|
||
form = MemberForm(instance=member)
|
||
return render(request, 'inventory/member_form.html', {'form': form})
|
||
|
||
@login_required
|
||
def member_purchases(request):
|
||
"""会员消费记录查询视图"""
|
||
search_term = request.GET.get('search', '')
|
||
|
||
if search_term:
|
||
# 根据名称或手机号查询会员
|
||
member = None
|
||
sales = []
|
||
|
||
try:
|
||
# 先尝试按手机号查找
|
||
member = Member.objects.get(phone=search_term)
|
||
sales = Sale.objects.filter(member=member).order_by('-created_at')
|
||
except Member.DoesNotExist:
|
||
# 再尝试按名称模糊查找
|
||
members = Member.objects.filter(name__icontains=search_term)
|
||
if members.exists():
|
||
# 如果找到多个会员,使用第一个
|
||
member = members.first()
|
||
sales = Sale.objects.filter(member=member).order_by('-created_at')
|
||
|
||
return render(request, 'inventory/member_purchases.html', {
|
||
'search_term': search_term,
|
||
'member': member,
|
||
'sales': sales
|
||
})
|
||
|
||
return render(request, 'inventory/member_purchases.html', {
|
||
'search_term': '',
|
||
'member': None,
|
||
'sales': []
|
||
})
|
||
|
||
@login_required
|
||
def member_level_list(request):
|
||
"""会员等级列表视图"""
|
||
levels = MemberLevel.objects.all().order_by('points_threshold')
|
||
return render(request, 'inventory/member_level_list.html', {'levels': levels})
|
||
|
||
@login_required
|
||
def member_level_create(request):
|
||
"""创建会员等级视图"""
|
||
from .forms import MemberLevelForm
|
||
|
||
if request.method == 'POST':
|
||
form = MemberLevelForm(request.POST)
|
||
if form.is_valid():
|
||
form.save()
|
||
messages.success(request, '会员等级添加成功')
|
||
return redirect('member_level_list')
|
||
else:
|
||
form = MemberLevelForm()
|
||
|
||
return render(request, 'inventory/member_level_form.html', {'form': form})
|
||
|
||
@login_required
|
||
def member_level_edit(request, level_id):
|
||
"""编辑会员等级视图"""
|
||
from .forms import MemberLevelForm
|
||
|
||
level = get_object_or_404(MemberLevel, id=level_id)
|
||
if request.method == 'POST':
|
||
form = MemberLevelForm(request.POST, instance=level)
|
||
if form.is_valid():
|
||
form.save()
|
||
messages.success(request, '会员等级更新成功')
|
||
return redirect('member_level_list')
|
||
else:
|
||
form = MemberLevelForm(instance=level)
|
||
|
||
return render(request, 'inventory/member_level_form.html', {'form': form, 'level': level})
|
||
|
||
@login_required
|
||
def member_recharge(request, member_id):
|
||
"""会员充值视图"""
|
||
member = get_object_or_404(Member, id=member_id)
|
||
|
||
if request.method == 'POST':
|
||
amount = Decimal(request.POST.get('amount', '0'))
|
||
actual_amount = Decimal(request.POST.get('actual_amount', '0'))
|
||
payment_method = request.POST.get('payment_method', 'cash')
|
||
remark = request.POST.get('remark', '')
|
||
|
||
if amount <= 0:
|
||
messages.error(request, '充值金额必须大于0')
|
||
return redirect('member_recharge', member_id=member_id)
|
||
|
||
# 创建充值记录
|
||
recharge = RechargeRecord.objects.create(
|
||
member=member,
|
||
amount=amount,
|
||
actual_amount=actual_amount,
|
||
payment_method=payment_method,
|
||
operator=request.user,
|
||
remark=remark
|
||
)
|
||
|
||
# 更新会员余额和状态
|
||
member.balance += amount
|
||
member.is_recharged = True
|
||
member.save()
|
||
|
||
# 记录操作日志
|
||
from django.contrib.contenttypes.models import ContentType
|
||
OperationLog.objects.create(
|
||
operator=request.user,
|
||
operation_type='MEMBER',
|
||
details=f'为会员 {member.name} 充值 {amount} 元',
|
||
related_object_id=recharge.id,
|
||
related_content_type=ContentType.objects.get_for_model(RechargeRecord)
|
||
)
|
||
|
||
messages.success(request, f'已成功为 {member.name} 充值 {amount} 元')
|
||
return redirect('member_list')
|
||
|
||
return render(request, 'inventory/member_recharge.html', {
|
||
'member': member
|
||
})
|
||
|
||
@login_required
|
||
def member_recharge_records(request, member_id):
|
||
"""会员充值记录视图"""
|
||
member = get_object_or_404(Member, id=member_id)
|
||
recharge_records = RechargeRecord.objects.filter(member=member).order_by('-created_at')
|
||
|
||
return render(request, 'inventory/member_recharge_records.html', {
|
||
'member': member,
|
||
'recharge_records': recharge_records
|
||
})
|
||
|
||
@login_required
|
||
def birthday_members_report(request):
|
||
"""当月生日会员报表"""
|
||
# 获取当前月份
|
||
current_month = timezone.now().month
|
||
current_month_name = {
|
||
1: '一月', 2: '二月', 3: '三月', 4: '四月', 5: '五月', 6: '六月',
|
||
7: '七月', 8: '八月', 9: '九月', 10: '十月', 11: '十一月', 12: '十二月'
|
||
}[current_month]
|
||
|
||
# 获取当月生日的会员
|
||
members = Member.objects.filter(birthday__month=current_month).order_by('id')
|
||
|
||
# 统计会员等级分布
|
||
level_counts = {}
|
||
levels_data = []
|
||
|
||
for member in members:
|
||
if member.level:
|
||
level_id = member.level.id
|
||
if level_id not in level_counts:
|
||
level_counts[level_id] = {
|
||
'id': level_id,
|
||
'name': member.level.name,
|
||
'color': member.level.color,
|
||
'color_code': f'#{member.level.color}' if member.level.color.startswith('gradient-') else member.level.color,
|
||
'count': 0
|
||
}
|
||
level_counts[level_id]['count'] += 1
|
||
|
||
levels_data = list(level_counts.values())
|
||
|
||
# 统计生日日期分布 (1-31日)
|
||
days_distribution = [0] * 31
|
||
for member in members:
|
||
if member.birthday:
|
||
day = member.birthday.day
|
||
if 1 <= day <= 31:
|
||
days_distribution[day - 1] += 1
|
||
|
||
context = {
|
||
'current_month_name': current_month_name,
|
||
'members': members,
|
||
'levels': levels_data,
|
||
'days_distribution': days_distribution
|
||
}
|
||
|
||
return render(request, 'inventory/birthday_members_report.html', context)
|
||
|
||
@login_required
|
||
def member_details(request, member_id):
|
||
"""会员详细信息视图,包括消费记录和充值记录"""
|
||
member = get_object_or_404(Member, id=member_id)
|
||
|
||
# 获取会员的消费记录
|
||
sales = Sale.objects.filter(member=member).order_by('-created_at')
|
||
|
||
# 获取会员的充值记录
|
||
recharge_records = RechargeRecord.objects.filter(member=member).order_by('-created_at')
|
||
|
||
return render(request, 'inventory/member_details.html', {
|
||
'member': member,
|
||
'sales': sales,
|
||
'recharge_records': recharge_records
|
||
})
|
||
|
||
# 报表中心相关视图
|
||
@login_required
|
||
def reports_index(request):
|
||
"""报表中心首页,显示所有可用报表及其统计信息"""
|
||
# 获取当月生日会员数量
|
||
current_month = timezone.now().month
|
||
birthday_members_count = Member.objects.filter(birthday__month=current_month).count()
|
||
|
||
# 获取销售记录数量
|
||
total_sales_count = Sale.objects.count()
|
||
|
||
# 获取库存偏低的商品数量
|
||
low_stock_count = Inventory.objects.filter(quantity__lt=F('warning_level')).count() or 0
|
||
|
||
# 获取充值总金额
|
||
total_recharge_amount = RechargeRecord.objects.aggregate(total=Sum('amount'))['total'] or 0
|
||
|
||
# 获取本月销售额
|
||
current_month_start = timezone.now().replace(day=1, hour=0, minute=0, second=0, microsecond=0)
|
||
monthly_sales_amount = Sale.objects.filter(
|
||
created_at__gte=current_month_start
|
||
).aggregate(total=Sum('final_amount'))['total'] or 0
|
||
|
||
# 获取今日操作日志数量
|
||
today_start = timezone.now().replace(hour=0, minute=0, second=0, microsecond=0)
|
||
today_log_count = OperationLog.objects.filter(timestamp__gte=today_start).count()
|
||
|
||
context = {
|
||
'birthday_members_count': birthday_members_count,
|
||
'total_sales_count': total_sales_count,
|
||
'low_stock_count': low_stock_count,
|
||
'total_recharge_amount': total_recharge_amount,
|
||
'monthly_sales_amount': monthly_sales_amount,
|
||
'today_log_count': today_log_count,
|
||
}
|
||
|
||
return render(request, 'inventory/reports_index.html', context)
|
||
|
||
@login_required
|
||
def member_add_ajax(request):
|
||
"""AJAX添加会员"""
|
||
if request.method == 'POST':
|
||
try:
|
||
name = request.POST.get('name')
|
||
phone = request.POST.get('phone')
|
||
level_id = request.POST.get('level')
|
||
|
||
# 详细验证数据
|
||
errors = {}
|
||
if not name:
|
||
errors['name'] = '会员姓名不能为空'
|
||
if not phone:
|
||
errors['phone'] = '手机号不能为空'
|
||
elif not re.match(r'^\d{11}$', phone):
|
||
errors['phone'] = '请输入11位手机号码'
|
||
if not level_id:
|
||
errors['level'] = '请选择会员等级'
|
||
|
||
if errors:
|
||
return JsonResponse({
|
||
'success': False,
|
||
'message': '表单验证失败',
|
||
'errors': errors
|
||
})
|
||
|
||
# 检查手机号是否已存在
|
||
if Member.objects.filter(phone=phone).exists():
|
||
return JsonResponse({
|
||
'success': False,
|
||
'message': '该手机号已注册为会员,请使用其他手机号'
|
||
})
|
||
|
||
# 获取会员等级
|
||
try:
|
||
level = MemberLevel.objects.get(id=level_id)
|
||
except MemberLevel.DoesNotExist:
|
||
return JsonResponse({
|
||
'success': False,
|
||
'message': '所选会员等级不存在,请重新选择'
|
||
})
|
||
|
||
# 创建会员
|
||
member = Member.objects.create(
|
||
name=name,
|
||
phone=phone,
|
||
level=level,
|
||
points=0,
|
||
balance=0
|
||
)
|
||
|
||
# 记录操作日志
|
||
from django.contrib.contenttypes.models import ContentType
|
||
OperationLog.objects.create(
|
||
operator=request.user,
|
||
operation_type='MEMBER',
|
||
details=f'添加会员: {name} (手机: {phone})',
|
||
related_object_id=member.id,
|
||
related_content_type=ContentType.objects.get_for_model(Member)
|
||
)
|
||
|
||
return JsonResponse({
|
||
'success': True,
|
||
'member_id': member.id,
|
||
'member_name': member.name,
|
||
'member_phone': member.phone,
|
||
'member_level': member.level.name
|
||
})
|
||
|
||
except Exception as e:
|
||
import traceback
|
||
print(f"会员添加错误: {str(e)}")
|
||
print(traceback.format_exc())
|
||
return JsonResponse({
|
||
'success': False,
|
||
'message': f'添加会员时发生错误: {str(e)}'
|
||
})
|
||
|
||
return JsonResponse({'success': False, 'message': '不支持的请求方法'}) |