# -*- encoding: utf-8 -*- """ @File : AgentCustomerController.py @Time : 2024/3/7 16:56 @Author : stephen @Email : zhangdongming@asj6.wecom.work @Software: PyCharm """ import re import time import json from decimal import Decimal from django.db.models import Sum, F, Q from django.http import QueryDict from django.views import View from django.core.paginator import Paginator from datetime import datetime, timedelta from Ansjer.config import CONFIG_CN, LOGGER, CONFIG_INFO from AgentModel.models import AgentCustomerInfo, AgentCustomerCard, AgentCustomerPackage, AgentCloudServicePackage, \ AgentDeviceOrder, AgentAccountWithdraw, AgentDevice, AgentAccount, ApplyAgent, AgentDeviceOrderInstallment from Model.models import UnicomCombo, Store_Meal, Device_User, CouponCombo from Object.ResponseObject import ResponseObject from Object.TokenObject import TokenObject class AgentCustomerView(View): def get(self, request, *args, **kwargs): request.encoding = 'utf-8' operation = kwargs.get('operation') return self.validation(request.GET, request, operation) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' operation = kwargs.get('operation') return self.validation(request.POST, request, operation) def delete(self, request, *args, **kwargs): request.encoding = 'utf-8' operation = kwargs.get('operation') delete = QueryDict(request.body) if not delete: delete = request.GET return self.validation(delete, request, operation) def put(self, request, *args, **kwargs): request.encoding = 'utf-8' operation = kwargs.get('operation') put = QueryDict(request.body) return self.validation(put, request, operation) def validation(self, request_dict, request, operation): AgentCustomerInfo.objects.filter() language = request_dict.get('language', 'en') response = ResponseObject(language, 'pc') if operation == 'getUnicomAndIcloud': return self.get_unicom_and_icloud(request_dict, response) elif operation == 'applyAgent': return self.apply_agent(request_dict, response) else: tko = TokenObject( request.META.get('HTTP_AUTHORIZATION'), returntpye='pc') if tko.code != 0: return response.json(tko.code) response.lang = tko.lang userID = tko.userID # 代理用户界面(代理顾客个人信息) if operation == 'getAgentInfo': return self.get_agent_info(userID, response) # 代理云存套餐 elif operation == 'getAgentServicePackage': return self.get_agent_service_package(request_dict, response) elif operation == 'addAgentServicePackage': return self.add_agent_service_package(userID, request_dict, response) elif operation == 'updateAgentServicePackage': return self.update_agent_service_package(userID, request_dict, response) elif operation == 'delAgentServicePackage': return self.del_agent_service_package(request_dict, response) # 代理客户绑定套餐 elif operation == 'getCustomerList': return self.get_customer_list(request_dict, response) elif operation == 'getCustomerPackageList': return self.get_cumstomer_package_list(request_dict, response) elif operation == 'batchRebindCustomerPackage': return self.batch_rebind_customer_packages(userID, request_dict, response) elif operation == 'getAgentServicePackageList': return self.get_agent_service_package_list(response) elif operation == 'getAgentSettleOrders': return self.get_agent_settle_order(userID, request_dict, response) elif operation == 'getDataStatistics': return self.get_data_statistics(userID, response) # 代理商提现功能 elif operation == 'getAgentAccountWithdraw': return self.get_agent_account_withdraw(userID, request_dict, response) elif operation == 'getCheckBalance': return self.get_check_balance(userID, response) elif operation == 'agentApplyWithdraw': return self.agent_apply_withdraw(userID, request_dict, response) elif operation == 'getWithdrawalReview': return self.get_withdrawal_review(request_dict, response) elif operation == 'updateWithdrawalReview': return self.update_withdrawal_review(userID, request_dict, response) else: return response.json(444, 'operation') @classmethod def get_unicom_and_icloud(cls, request_dict, response): """ 查询云存储套餐和物联网卡套餐列表 @param response: 响应对象 @return: 包含套餐信息的响应 """ try: lang = request_dict.get('lang', 'cn') # 1. 优化查询 - 云存储套餐 store_meals_qs = Store_Meal.objects.filter( ~Q(pay_type__in=[10, 11]), lang__lang=lang, is_show=0 ).exclude(app_type=2) # 根据配置区分国内外套餐 if CONFIG_INFO == CONFIG_CN: store_meals_qs = store_meals_qs.filter(is_ai=0, bucket__mold=0) else: store_meals_qs = store_meals_qs.filter(bucket__mold=1) # 一次性获取所有需要的字段和关联数据 store_meals = store_meals_qs.annotate( title=F('lang__title'), content=F('lang__content'), new_title=F('lang__new_title'), discount_content=F('lang__discount_content'), store_day=F('bucket__storeDay'), bucket_name=F('bucket__bucket'), bucket_area=F('bucket__area') ).order_by('-pixel_level', '-is_ai').values( "id", "title", "content", "price", "day", "currency", "store_day", "new_title", "bucket_name", "bucket_area", "commodity_code", "commodity_type", "is_discounts", "virtual_price", "expire", "discount_price", "discount_content", "symbol", "cycle_config_id", 'pixel_level', 'is_ai', 'app_type' ) # 2. 批量处理优惠券信息 - 避免N+1查询 ios_meal_ids = [meal['id'] for meal in store_meals if meal.get('app_type') == 1] coupon_map = {} if ios_meal_ids: coupon_combos = CouponCombo.objects.filter( combo_id__in=ios_meal_ids ).values_list('combo_id', flat=True).distinct() coupon_map = {combo_id: True for combo_id in coupon_combos} # 3. 使用列表推导式构建套餐列表 store_meal_list = [] for meal in store_meals: # 构建基础名称 name_parts = [meal['title'], f'{meal.get("symbol")}{meal["price"]}', f"({str(meal['expire'])}month+", '≥4K' if meal.get('pixel_level') == 1 else '<4K'] # 添加AI标识 if meal.get('is_ai') == 1: name_parts.append('+AI') # 处理iOS套餐 if meal.get('app_type') == 1: name_parts.append('+ios') # 检查优惠券 - 使用预处理的映射 if meal['id'] in coupon_map: name_parts.append('+discount') # 添加周期订阅标识 if meal.get('cycle_config_id', 0) == 1: name_parts.append('+cycle') # 关闭括号并连接字符串 name_parts.append(')') full_name = ''.join(name_parts) store_meal_list.append({ 'id': meal['id'], 'name': full_name }) # 4. 物联网卡套餐查询 unicom_combo_list = list( UnicomCombo.objects.filter( is_show=1, is_del=False ).distinct().values('id', 'combo_name') ) # 统一字段名 for combo in unicom_combo_list: combo['name'] = combo.pop('combo_name') return response.json(0, { 'storeMeals': store_meal_list, 'unicomCombos': unicom_combo_list, }) except Exception as e: LOGGER.error(f"get_unicom_and_icloud error: {str(e)}", exc_info=True) return response.json(500, 'Server error') def get_agent_info(self, userID, response): """ 查询用户信息 @param userID: userID @param response: 响应对象 @return: """ try: # 使用userID查询AgentCustomerInfo获取基本信息 agent_info = AgentCustomerInfo.objects.filter(user_id=userID, status=1).first() if not agent_info: return response.json(444, {'error': '没有找到这个代理用户'}) # userID查询用户电话 device_user_qs = Device_User.objects.filter(userID=userID).first() # 代理客户ID(ac_id)查询AgentCustomerCard获取银行卡信息。 card_details = AgentCustomerCard.objects.filter(ac_id=agent_info.id, status=1).first() # ac_id查询AgentCustomerPackage来找到关联的云服务套餐ID(cs_id) package_ids = AgentCustomerPackage.objects.filter(ac_id=agent_info.id).values_list('cs_id', flat=True) # cs_id查询AgentCloudServicePackage获取服务套餐详情。 service_packages = AgentCloudServicePackage.objects.filter(id__in=package_ids, status=1).values() result = { 'agent_info': { 'ac_id': agent_info.id, 'company_name': agent_info.company_name, 'phone': device_user_qs.phone, 'created_time': agent_info.created_time, 'service_packages': list(service_packages), } } if card_details: # 获取银行卡号 card_no = card_details.card_no # 检查银行卡号字符串长度,如果小于等于8,则返回"null" if len(card_no) <= 8: masked_card_no = "null" else: # 保留前四位和后四位,用"*"代替中间的数字 masked_card_no = card_no[:4] + '*' * (len(card_no) - 8) + card_no[-4:] result['agent_info'].update({ 'card_name': card_details.name, 'card_no': masked_card_no, 'card_address': card_details.card_address, }) return response.json(0, result) except Exception as e: return response.json(500, {'error': str(e)}) def get_agent_service_package(self, request_dict, response): """ 查询所有代理云服务套餐 @param request_dict: 请求参数 @request_dict page: 页码 @request_dict page_size: 查询分页数 @param response: 响应对象 @return: """ page = int(request_dict.get('page', 1)) page_size = int(request_dict.get('page_size', 10)) try: # 查询所有有效的代理云服务套餐 all_packages = AgentCloudServicePackage.objects.filter(status=1).order_by('type', '-created_time') # 创建分页对象 paginator = Paginator(all_packages, page_size) # 获取请求页的数据 packages_page = paginator.page(page) # 准备响应数据,转换查询集为列表形式 agents_list = [] for agent_info in packages_page: package_name = agent_info.package_id if agent_info.type == 1: store_meals = Store_Meal.objects.filter(id=agent_info.package_id).values('bucket__bucket').first() if store_meals: package_name = store_meals['bucket__bucket'] else: unicom_combos = UnicomCombo.objects.filter(id=agent_info.package_id).first() if unicom_combos: package_name = unicom_combos.combo_name agents = { 'id': agent_info.id, 'service_name': agent_info.service_name, 'package_name': package_name, 'type': agent_info.type, 'profit_type': agent_info.profit_type, 'cost': agent_info.cost, 'profit': agent_info.profit, 'status': agent_info.status, 'created_time': agent_info.created_time } agents_list.append(agents) # 返回分页数据 return response.json(0, { 'page': page, 'page_size': page_size, 'total': paginator.count, 'num_pages': paginator.num_pages, 'list': agents_list }) except Exception as e: # 出错时返回错误信息 return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def add_agent_service_package(self, userID, request_dict, response): """ 添加代理云服务套餐 @param request_dict: 请求参数 @request_dict package_id: 代理服务id @request_dict service_name: 代理服务名称 @request_dict package_type: 套餐类型 1:云存,2:4G @response_dict profit_type: 利润分配类型 1:固定值,2:百分比 @response_dict cost: 成本 @response_dict profit: 利润值 @param response: 响应对象 @return: """ package_id = request_dict.get('package_id', None) service_name = request_dict.get('service_name', None) package_type = int(request_dict.get('package_type', 0)) # 默认为0,确保类型安全 profit_type = int(request_dict.get('profit_type', 1)) # 默认值为1 profit = request_dict.get('profit', 0) cost = request_dict.get('cost', 0) try: # 创建AgentCloudServicePackage实例并保存 if not all([package_id, service_name]): return response.json(444) if package_type == 1: query_set = Store_Meal.objects.filter(is_show=0, id=package_id) elif package_type == 2: query_set = UnicomCombo.objects.filter(is_show=1, is_del=False, id=package_id) else: return response.json(444, 'error package_type') if not query_set.exists(): return response.json(173) AgentCloudServicePackage.objects.create( service_name=service_name, package_id=package_id, type=package_type, profit_type=profit_type, profit=profit, status=1, cost=cost, created_by=userID, created_time=int(time.time()), updated_by=userID, updated_time=int(time.time()) ) return response.json(0) except Exception as e: return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def update_agent_service_package(self, userID, request_dict, response): """ 更新代理云服务套餐 @param request_dict: 请求参数 @request_dict package_id: 代理服务id @request_dict service_name: 代理服务名称 @response_dict profit_type: 利润分配类型 1:固定值,2:百分比 @response_dict cost: 成本 @response_dict profit: 利润值 @param response: 响应对象 @return: """ id = request_dict.get('id', None) service_name = request_dict.get('service_name', None) profit_type = request_dict.get('profit_type', None) cost = request_dict.get('cost', None) profit = request_dict.get('profit', None) if not all([id, service_name, profit_type, cost, profit]): return response.json(444) try: ac_service_package = AgentCloudServicePackage.objects.get(pk=id) ac_service_package.service_name = service_name ac_service_package.profit_type = profit_type ac_service_package.cost = cost ac_service_package.profit = profit ac_service_package.updated_time = int(time.time()) ac_service_package.updated_by = userID ac_service_package.save() return response.json(0) except AgentCloudServicePackage.DoesNotExist: return response.json(173) except Exception as e: return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def del_agent_service_package(self, request_dict, response): """ 删除代理云服务套餐 @param userID: 用户ID(执行删除操作的用户) @param request_dict: 请求参数 @request_dict package_id: 代理服务id @param response: 响应对象 @return: """ id = request_dict.get('id', None) if not id: return response.json(444, 'Missing package_id') try: ac_service_package = AgentCloudServicePackage.objects.get(pk=id) # 假删除,否则查利润会出问题 ac_service_package.status = 0 ac_service_package.save() return response.json(0) except AgentCloudServicePackage.DoesNotExist: return response.json(173, 'Package does not exist.') except Exception as e: return response.json(500, {'error': str(e)}) def get_customer_list(self, request_dict, response): """ 查询代理商信息,并进行分页处理 @param request_dict: 请求对象,用于接收分页参数 @param response: 响应对象 @return: """ # 接收分页参数 page = int(request_dict.get('page', 1)) page_size = int(request_dict.get('page_size', 10)) search_query = request_dict.get('search_query', '') user_id = request_dict.get('user_id', None) phone = request_dict.get('phone', None) userEmail = request_dict.get('userEmail', None) try: # 基础查询条件 agent_infos_query = AgentCustomerInfo.objects.filter(status=1) # 精确查询条件 if user_id: agent_infos_query = agent_infos_query.filter(user_id=user_id) # 获取所有符合条件的AgentCustomerInfo记录 agent_infos = agent_infos_query.values('id', 'user_id', 'company_name').order_by('id') # 对结果进行分页 paginator = Paginator(agent_infos, page_size) packages_page = paginator.page(page) # 准备最终的代理商列表 agents_list = [] for agent_info in packages_page: # 模糊查询 if search_query: card_info_query = AgentCustomerCard.objects.filter(ac_id=agent_info['id'], name__icontains=search_query) if not card_info_query.exists() and search_query not in agent_info['company_name']: continue else: card_info_query = AgentCustomerCard.objects.filter(ac_id=agent_info['id']) # 获取卡信息 card_info = card_info_query.values('name', 'card_no', 'card_address').first() # 获取用户信息,根据需要进行精确查询 user_info_query = Device_User.objects.filter(userID=agent_info['user_id']) if phone: user_info_query = user_info_query.filter(phone=phone) if userEmail: user_info_query = user_info_query.filter(userEmail=userEmail) user_info = user_info_query.values('phone', 'userEmail').first() # 组合信息 agent_record = { 'id': agent_info['id'], 'company_name': agent_info['company_name'], 'user_id': agent_info['user_id'], 'phone': user_info.get('phone') if user_info else None, 'userEmail': user_info.get('userEmail') if user_info else None, 'card_name': card_info.get('name') if card_info else None, 'card_no': card_info.get('card_no') if card_info else None, 'card_address': card_info.get('card_address') if card_info else None, } agents_list.append(agent_record) # 返回分页后的结果 return response.json(0, { 'page': page, 'page_size': page_size, 'total': paginator.count, 'num_pages': paginator.num_pages, 'list': agents_list }) except Exception as e: print(e) return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def get_cumstomer_package_list(self, request_dict, response): """ 查询代理商服务套餐列表 @param response: 响应对象 @return: """ ac_id = request_dict.get('id', None) try: if ac_id is None: return response.json(444, 'Missing ac_id') # ac_id查询AgentCustomerPackage来找到关联的云服务套餐ID(cs_id) package_ids = AgentCustomerPackage.objects.filter(ac_id=ac_id).values_list('cs_id', flat=True) # cs_id查询AgentCloudServicePackage获取服务套餐详情。 service_packages = AgentCloudServicePackage.objects.filter(id__in=package_ids, status=1).values( 'id', 'service_name', 'type' ) service_packages_list = list(service_packages) return response.json(0, {'service_packages': service_packages_list}) except Exception as e: print(e) return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def batch_rebind_customer_packages(self, userID, request_dict, response): """ 清空并重新绑定代理商服务套餐 @param userID: 操作用户的ID @param request_dict: 请求参数,包含代理商ID和新的服务套餐ID列表 @param response: 响应对象 @return: """ ac_id = request_dict.get('ac_id', None) # 代理客户ID new_cs_ids = json.loads(request_dict.get('cs_ids', '[]')) # 新的服务套餐ID列表 if not ac_id: return response.json(444, 'Missing agent customer ID.') if not new_cs_ids: return response.json(444, 'Service package IDs are required.') try: # 删除该代理客户的所有现有绑定 AgentCustomerPackage.objects.filter(ac_id=ac_id).delete() # 过滤出存在且状态为有效的套餐ID valid_new_cs_ids = AgentCloudServicePackage.objects.filter(id__in=new_cs_ids, status=1).values_list('id', flat=True) # 准备批量创建的数据 packages_to_bind = [ AgentCustomerPackage( ac_id=ac_id, cs_id=cs_id, created_by=userID, updated_by=userID, created_time=int(time.time()), updated_time=int(time.time()) ) for cs_id in valid_new_cs_ids ] # 批量创建新的绑定关系 AgentCustomerPackage.objects.bulk_create(packages_to_bind) return response.json(0) except Exception as e: print(e) return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def get_agent_service_package_list(self, response): """ 查询云服务套餐列表 id + service_name @param response: 响应对象 @return: """ try: # 查询所有有效的代理云服务套餐 all_packages = AgentCloudServicePackage.objects.filter(status=1).order_by('-created_time').values('id', 'service_name') # 转换查询集为列表形式 packages_list = list(all_packages) # 返回数据 return response.json(0, {'packages': packages_list}) except Exception as e: # 出错时返回错误信息 return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def get_agent_settle_order(self, userID, request_dict, response): """ 查询结算明细 @param userID: userID @param request_dict: 请求参数 @param request_dict status: 结算状态 @param request_dict time: 年-季度 2023-1 @param response: 响应对象 @return: """ status = request_dict.get('status', None) time_str = request_dict.get('time', None) package_type = request_dict.get('package_type', None) startTime = int(request_dict.get('start_time', 1)) endTime = int(request_dict.get('end_time', 0)) page = int(request_dict.get('page', 1)) # 默认为第一页 page_size = int(request_dict.get('page_size', 10)) # 默认每页10条记录 try: agent_customer_info = AgentCustomerInfo.objects.filter(user_id=userID).first() if agent_customer_info is None: agent_device_orders_qs = AgentDeviceOrder.objects.filter(is_del=False) else: ac_id = agent_customer_info.id agent_device_orders_qs = AgentDeviceOrder.objects.filter(ac_id=ac_id, is_del=False) if time_str: year, quarter = map(int, time_str.split('-')) start_month = 3 * (quarter - 1) + 1 end_month = start_month + 2 start_date = datetime(year, start_month, 1) end_date = datetime(year + 1, 1, 1) if end_month == 12 else datetime(year, end_month + 1, 1) start_time = int(start_date.timestamp()) end_time = int(end_date.timestamp()) - 1 agent_device_orders_qs = agent_device_orders_qs.filter(created_time__gte=start_time, created_time__lte=end_time) if startTime < endTime: agent_device_orders_qs = agent_device_orders_qs.filter(created_time__gte=startTime, created_time__lte=endTime) if package_type: csp_ids = list( AgentCloudServicePackage.objects.filter(type=int(package_type)).values_list('id', flat=True)) agent_device_orders_qs = agent_device_orders_qs.filter(csp_id__in=csp_ids) if status is None: total_profit = agent_device_orders_qs.aggregate(Sum('profit'))['profit__sum'] or 0 else: # 计算特定状态的device_orders总额 full_profit = agent_device_orders_qs.filter(status=status).aggregate(Sum('profit'))[ 'profit__sum'] or 0 # 初始化total_profit total_profit = full_profit # 对于状态1和2,计算部分结算的利润 if status in ["1", "2"]: partial_settled_profit = AgentDeviceOrderInstallment.objects.filter( ado_id__in=agent_device_orders_qs.filter(status=1).values_list('id', flat=True), status=2 ).aggregate(total=Sum('amount'))['total'] or 0 # 根据状态调整total_profit if status == "1": total_profit -= partial_settled_profit else: # 当status为"2"时,添加partial_settled_profit(根据业务逻辑,这可能需要调整) total_profit += partial_settled_profit agent_device_orders_qs = agent_device_orders_qs.filter(status=status) # 应用分页 agent_device_orders_qs = agent_device_orders_qs.order_by('-created_time') paginator = Paginator(agent_device_orders_qs, page_size) current_page = paginator.get_page(page) orders = [] for order in current_page: csp = AgentCloudServicePackage.objects.filter(id=order.csp_id).first() service_name = csp.service_name if csp else order.csp_id agent_customer_info = AgentCustomerInfo.objects.filter(id=order.ac_id).first() company_name = agent_customer_info.company_name if agent_customer_info else order.ac_id ado_id = order.id settled_profit = \ AgentDeviceOrderInstallment.objects.filter(ado_id=ado_id, status=2).aggregate(Sum('amount'))[ 'amount__sum'] or 0 orders.append({ 'id': order.id, 'company_name': company_name, 'serial_number': order.serial_number, 'status': order.status, 'service_name': service_name, 'profit_amount': order.profit_amount, 'profit': order.profit, 'settled_profit': settled_profit, 'settlement_time': order.settlement_time, 'remark': order.remark, 'created_time': order.created_time }) response_data = { 'list': orders, 'total_profit': total_profit, 'total': paginator.count, 'page': current_page.number, 'page_size': page_size, 'num_pages': paginator.num_pages, } return response.json(0, response_data) except Exception as e: return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def get_agent_account_withdraw(self, userID, request_dict, response): """ 查询提现明细 @param userID: userID @param request_dict: 请求参数 @param response: 响应对象 @return: """ agent_customer_info = AgentCustomerInfo.objects.filter(user_id=userID).first() if not agent_customer_info: return response.json(104, 'Agent customer not found') ac_id = agent_customer_info.id try: agent_account_withdraw_qs = AgentAccountWithdraw.objects.filter(ac_id=ac_id).order_by('-updated_time') page = int(request_dict.get('page', 1)) # 默认为第一页 page_size = int(request_dict.get('page_size', 10)) # 默认每页10条记录 # 应用分页 paginator = Paginator(agent_account_withdraw_qs, page_size) current_page = paginator.get_page(page) withdraw_list = [] for withdraw in current_page: agent_customer_card = AgentCustomerCard.objects.filter(ac_id=ac_id).first() card_no = agent_customer_card.card_no masked_card_no = card_no[:4] + '*' * (len(card_no) - 8) + card_no[-4:] withdraw_list.append({ 'id': withdraw.id, 'amount': withdraw.amount, 'created_time': withdraw.created_time, 'card_no': masked_card_no, 'status': withdraw.status, 'remark': withdraw.remark, 'arrival_time': withdraw.arrival_time }) response_data = { 'list': withdraw_list, 'total': paginator.count, 'page': current_page.number, 'page_size': page_size, 'num_pages': paginator.num_pages, } return response.json(0, response_data) except Exception as e: # 出错时返回错误信息 return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def get_check_balance(self, userID, response): """ 查询余额 @param userID: userID @param response: 响应对象 @return: """ agent_customer_info = AgentCustomerInfo.objects.filter(user_id=userID).first() if not agent_customer_info: return response.json(104, 'Agent customer not found') ac_id = agent_customer_info.id try: # 计算冻结金额 frozen_amount_qs = AgentAccountWithdraw.objects.filter(ac_id=ac_id, status__in=[1, 2, 3]) frozen_amount = frozen_amount_qs.aggregate(total=Sum('amount'))['total'] or Decimal('0.00') # 计算余额:已结算 - (退款+已打款) incomes_qs = AgentAccount.objects.filter(ac_id=ac_id, status=1) expense_qs = AgentAccount.objects.filter(ac_id=ac_id, status__in=[2, 3]) incomes_all = incomes_qs.aggregate(total=Sum('amount'))['total'] or Decimal('0.00') expense_all = expense_qs.aggregate(total=Sum('amount'))['total'] or Decimal('0.00') total_profit = incomes_all - expense_all # 可用余额 = 总余额 - 冻结金额 available_balance = total_profit - frozen_amount # 构造返回数据 balance_data = { 'frozen_amount': frozen_amount, # 冻结金额 'total_profit': total_profit, # 总余额 'available_balance': available_balance # 可用余额 } return response.json(0, balance_data) except Exception as e: # 出错时返回错误信息 return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def get_data_statistics(self, userID, response): """ 首页总览 @param userID: userID @param response: 响应对象 @return: """ agent_customer_info = AgentCustomerInfo.objects.filter(user_id=userID).first() if agent_customer_info is None: agent_device_orders_qs = AgentDeviceOrder.objects.filter(is_del=False) agent_device_qs = AgentDevice.objects.filter() else: ac_id = agent_customer_info.id agent_device_orders_qs = AgentDeviceOrder.objects.filter(ac_id=ac_id, is_del=False) agent_device_qs = AgentDevice.objects.filter(ac_id=ac_id) now = datetime.now() today_start = datetime(now.year, now.month, now.day) yesterday_start = today_start - timedelta(days=1) tomorrow_start = today_start + timedelta(days=1) try: # 计算AgentDeviceOrderInstallment表 结算金额 partial_settled_profit = AgentDeviceOrderInstallment.objects.filter( ado_id__in=agent_device_orders_qs.filter(status=1).values_list('id', flat=True), status=2 ).aggregate(total=Sum('amount'))['total'] or 0 # 总利润 total_profit_all = \ agent_device_orders_qs.filter(status__in=[1, 2], is_del=False).aggregate( total=Sum('profit'))[ 'total'] or Decimal('0.00') total_profit_no = \ agent_device_orders_qs.filter(status=1, is_del=False).aggregate(total=Sum('profit'))[ 'total'] or Decimal('0.00') total_profit_no = total_profit_no - partial_settled_profit total_profit_yes = \ agent_device_orders_qs.filter(status=2, is_del=False).aggregate(total=Sum('profit'))[ 'total'] or Decimal('0.00') total_profit_yes = total_profit_yes + partial_settled_profit # 总营业额 profit_amount_all = agent_device_orders_qs.filter(status__in=[1, 2], is_del=False).aggregate( total=Sum('profit_amount'))['total'] or Decimal('0.00') # 今日总营业额 profit_amount_today_all = agent_device_orders_qs.filter( status__in=[1, 2], is_del=False, created_time__gte=int(today_start.timestamp()), created_time__lt=int(tomorrow_start.timestamp()) ).aggregate(total=Sum('profit_amount'))['total'] or Decimal('0.00') # 昨日总营业额 profit_amount_yesterday_all = agent_device_orders_qs.filter( status__in=[1, 2], is_del=False, created_time__gte=int(yesterday_start.timestamp()), created_time__lt=int(today_start.timestamp()) ).aggregate(total=Sum('profit_amount'))['total'] or Decimal('0.00') # 激活设备数 active_device_count_today = agent_device_qs.filter( status=1, created_time__gte=int(today_start.timestamp()), created_time__lt=int(tomorrow_start.timestamp()) ).count() active_device_count_yesterday = agent_device_qs.filter( status=1, created_time__gte=int(yesterday_start.timestamp()), created_time__lt=int(today_start.timestamp()) ).count() # 总设备数 active_device_count = agent_device_qs.filter(status=1).count() inactive_device_count = agent_device_qs.filter(status=0).count() return response.json(0, { 'total_profit_all': total_profit_all, 'total_profit_no': total_profit_no, 'total_profit_yes': total_profit_yes, 'profit_amount_all': profit_amount_all, 'profit_amount_today_all': profit_amount_today_all, 'profit_amount_yesterday_all': profit_amount_yesterday_all, 'active_device_count_today': active_device_count_today, 'active_device_count_yesterday': active_device_count_yesterday, 'active_device_count': active_device_count, 'inactive_device_count': inactive_device_count, 'all_device_count': active_device_count + inactive_device_count }) except Exception as e: return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def agent_apply_withdraw(self, userID, request_dict, response): """ 用户提现申请 @param userID: userID @param request_dict: 请求参数 @param request_dict amount: 金额 @param response: 响应对象 @return: """ amount = Decimal(request_dict.get('amount', '0.00')) if amount == Decimal('0.00'): return response.json(444) agent_customer_info = AgentCustomerInfo.objects.filter(user_id=userID).first() if not agent_customer_info: return response.json(104, 'Agent customer not found') ac_id = agent_customer_info.id try: # 计算余额:已结算 - (退款+已打款) incomes_qs = AgentAccount.objects.filter(ac_id=ac_id, status=1) expense_qs = AgentAccount.objects.filter(ac_id=ac_id, status__in=[2, 3]) incomes_all = incomes_qs.aggregate(total=Sum('amount'))['total'] or Decimal('0.00') expense_all = expense_qs.aggregate(total=Sum('amount'))['total'] or Decimal('0.00') total_profit = incomes_all - expense_all # 冻结余额 frozen_amount_qs = AgentAccountWithdraw.objects.filter(ac_id=ac_id, status__in=[1, 2, 3]) frozen_amount = frozen_amount_qs.aggregate(total=Sum('amount'))['total'] or Decimal('0.00') # 可提现余额 = 总余额 - 冻结金额 available_balance = total_profit - frozen_amount if amount < Decimal('1000.00'): return response.json(10, '每次提现最少为1000元') if amount > available_balance: return response.json(10, '余额不足,无法提现') # 提交提现申请 acc = AgentCustomerCard.objects.filter(ac_id=ac_id).first() AgentAccountWithdraw.objects.create(ac_id=ac_id, status=1, card_id=acc.id, amount=amount, created_time=int(time.time()), updated_time=int(time.time())) return response.json(0) except Exception as e: print(e) return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def get_withdrawal_review(self, request_dict, response): """ 后台用户提现申请审核列表 @param request_dict: 请求参数 @param request_dict company_name: 公司名称 @param request_dict status: 审核状态 @param response: 响应对象 @return: """ company_name = request_dict.get('company_name', None) status = request_dict.get('status', None) page = int(request_dict.get('page', 1)) # 默认为第一页 page_size = int(request_dict.get('page_size', 10)) # 默认每页10条记录 try: agent_account_withdraw_qs = AgentAccountWithdraw.objects.filter().order_by('updated_time') if company_name: agent_customer_info = AgentCustomerInfo.objects.filter(company_name=company_name).first() ac_id = agent_customer_info.id agent_account_withdraw_qs = agent_account_withdraw_qs.filter(ac_id=ac_id) if status: agent_account_withdraw_qs = agent_account_withdraw_qs.filter(status=status) # 提现id 公司名 审核状态 提现金额 余额 paginator = Paginator(agent_account_withdraw_qs, page_size) current_page = paginator.get_page(page) review_list = [] for review in current_page: ac_id = review.ac_id agent_customer_info = AgentCustomerInfo.objects.filter(id=ac_id).first() company_name = agent_customer_info.company_name review_list.append({ "id": review.id, "company_name": company_name, "status": review.status, "amount": review.amount, "remark": review.remark, }) response_data = { 'list': review_list, 'total': paginator.count, 'page': current_page.number, 'page_size': page_size, 'num_pages': paginator.num_pages, } return response.json(0, response_data) except Exception as e: return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def update_withdrawal_review(self, userID, request_dict, response): """ 后台提现审核 @param request_dict: 请求参数 @param request_dict id: 提现单id @param request_dict status: 提现单状态 @param request_dict remark: 提现单备注 @param response: 响应对象 @return: """ id = request_dict.get('id', None) status = request_dict.get('status', None) remark = request_dict.get('remark', "") if not all([id, status]): return response.json(444) try: agent_account_withdraw = AgentAccountWithdraw.objects.get(pk=id) agent_account_withdraw.status = status agent_account_withdraw.remark = remark agent_account_withdraw.save() if int(status) == 4: AgentAccount.objects.create(ac_id=agent_account_withdraw.ac_id, amount=agent_account_withdraw.amount, status=3, created_time=int(time.time()), updated_time=int(time.time()), remark=f"{userID}修改为已提现") return response.json(0) except Exception as e: return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) def apply_agent(self, request_dict, response): """ 代理申请 @param request_dict: 请求参数 @param request_dict name: 名字 @param request_dict phone: 电话 @param request_dict regin: 地区 @param request_dict remark: 备注 @param response: 响应对象 @return: """ name = request_dict.get('name', None) phone = request_dict.get('phone', None) regin = request_dict.get('regin', None) remark = request_dict.get('remark', "") if not all([name, phone, regin]): return response.json(444) # 去除非数字字符 clean_phone = re.sub(r'\D', '', phone) if ApplyAgent.objects.filter(phone=clean_phone).exists(): return response.json(174, 'Phone number already exists') ApplyAgent.objects.create(name=name, phone=clean_phone, regin=regin, remark=remark) return response.json(0, '申请已提交')