| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064 | # -*- encoding: utf-8 -*-"""@File    : AgentCustomerController.py@Time    : 2024/3/7 16:56@Author  : stephen@Email   : zhangdongming@asj6.wecom.work@Software: PyCharm"""import reimport timeimport jsonfrom decimal import Decimalfrom django.db.models import Sum, F, Qfrom django.http import QueryDictfrom django.views import Viewfrom django.core.paginator import Paginatorfrom datetime import datetime, timedeltafrom Ansjer.config import CONFIG_CN, LOGGER, CONFIG_INFOfrom AgentModel.models import AgentCustomerInfo, AgentCustomerCard, AgentCustomerPackage, AgentCloudServicePackage, \    AgentDeviceOrder, AgentAccountWithdraw, AgentDevice, AgentAccount, ApplyAgent, AgentDeviceOrderInstallmentfrom Model.models import UnicomCombo, Store_Meal, Device_User, CouponCombofrom Object.ResponseObject import ResponseObjectfrom Object.TokenObject import TokenObjectclass 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, 2) 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, '申请已提交')
 |