| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 | # -*- encoding: utf-8 -*-"""@File    : AgentDeviceController.py@Time    : 2024/3/8 13:55@Author  : stephen@Email   : zhangdongming@asj6.wecom.work@Software: PyCharm"""from datetime import datetimefrom dateutil.relativedelta import relativedeltafrom collections import defaultdictfrom decimal import Decimalimport tracebackfrom django.http import QueryDictfrom django.views import Viewfrom django.core.paginator import Paginatorfrom AgentModel.models import AgentCustomerInfo, AgentDeviceOrder, AgentDevice, AgentCloudServicePackagefrom Model.models import DeviceTypeModelfrom Object.ResponseObject import ResponseObjectfrom Object.TokenObject import TokenObjectclass AgentDeviceView(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):        language = request_dict.get('language', 'en')        response = ResponseObject(language, 'pc')        # 订单结算界面        if operation == 'XXXXX':            pass        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 == 'getAgentDevice':                return self.get_agent_device(userID, request_dict, response)            elif operation == 'getAgentDeviceOrder':                return self.get_agent_device_order(userID, request_dict, response)            else:                return response.json(444, 'operation')    def get_agent_device(self, userID, request_dict, response):        """        查询设备明细        @param userID: userID        @param request_dict: 请求参数        @param request_dict ac_id: 代理商id        @param request_dict device_name: 设备名字        @param request_dict status: 设备类型        @param request_dict serial_number: 设备9位序列号        @param response: 响应对象        @return:        """        device_name = request_dict.get('device_name', None)        status = request_dict.get('status', None)        serial_number = request_dict.get('serial_number', None)        page = int(request_dict.get('page', 1))  # 默认为第一页        page_size = int(request_dict.get('page_size', 10))  # 默认每页10条记录        agent_customer_info = AgentCustomerInfo.objects.filter(user_id=userID).first()        if agent_customer_info is None:            return response.json(104, 'Agent customer not found')        ac_id = agent_customer_info.id        try:            agent_device_qs = AgentDevice.objects.filter(ac_id=ac_id)            if device_name:                # 根据device_name查询对应的type值                device_types = list(DeviceTypeModel.objects.filter(name=device_name).values_list('type', flat=True))                agent_device_qs = agent_device_qs.filter(type__in=device_types)            if status:                agent_device_qs = agent_device_qs.filter(status=status)            if serial_number:                agent_device_qs = agent_device_qs.filter(serial_number=serial_number)            # 应用分页            paginator = Paginator(agent_device_qs, page_size)            current_page = paginator.get_page(page)            # 构造返回列表            device_list = []            for device in current_page:                device_type = DeviceTypeModel.objects.filter(type=device.type).first()                device_name = device_type.name if device_type else device.type                device_list.append({                    'id': device.id,                    'ac_id': device.ac_id,                    'status': device.status,                    'serial_number': device.serial_number,                    'device_name': device_name,                    'at_time': device.at_time,                })            # 包含分页信息的响应            response_data = {                'list': device_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:            print(e)            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))    def calculate_profit_or_revenue(self, agent_device_orders, package_details, time_unit, metric_type, start_time, end_time):        """        计算利润或者营业额        @param agent_device_orders: 代理设备订单        @param package_details: 代理套餐详情        @param time_unit: 时间单位        @param metric_type: 利润或者营业额        @param start_time: 开始时间        @param end_time: 结束时间        @return:        """        summary = defaultdict(lambda: {"云存": Decimal('0.00'), "4G": Decimal('0.00'), "all": Decimal('0.00')})        time_format = {            "month": "%Y-%m",            "year": "%Y",            "quarter": lambda x: f"{x.year}年{(x.month - 1) // 3 + 1}季度"        }        for order in agent_device_orders:            package = package_details.get(order.csp_id)            if not package:                continue            # 根据利润类型计算利润或者直接使用营业额            if metric_type == 1:  # 利润                profit = order.profit            else:  # 营业额                profit = order.profit_amount            # 区分云服务 + 4G套餐并加入 summary            service_type = "云存" if package.type == 1 else "4G"            time_key = datetime.fromtimestamp(order.created_time).strftime(                time_format[time_unit]) if time_unit != "quarter" else time_format[time_unit](                datetime.fromtimestamp(order.created_time))            summary[time_key][service_type] += profit            summary[time_key]["all"] += profit        # 补全时间段内所有可能的时间单位        current_time = start_time        end_time += relativedelta(days=1)  # 包括结束日期        while current_time < end_time:            time_key = current_time.strftime(time_format[time_unit]) if time_unit != "quarter" else time_format[                time_unit](current_time)            if time_key not in summary:                summary[time_key] = {"云存": Decimal('0.00'), "4G": Decimal('0.00'), "all": Decimal('0.00')}            current_time += relativedelta(months=1) if time_unit == "month" else relativedelta(                years=1) if time_unit == "year" else relativedelta(months=3)        return [{"time": time, **data} for time, data in sorted(summary.items())]    def get_agent_device_order(self, userID, request_dict, response):        """        查询设备订单明细        @param userID: userID        @param request_dict: 请求参数        @param request_dict startTime: 开始时间        @param request_dict endTime: 结束时间        @param request_dict timeUnit: 时间单位        @param request_dict metric_type: 利润或者营业额        @param response: 响应对象        @return:        """        try:            startTime = int(request_dict.get('startTime', 1704038400))            endTime = int(request_dict.get('endTime', 1732982400))            timeUnit = request_dict.get('timeUnit', 'month')            metric_type = int(request_dict.get('metric_type', 0))            agent_customer_info = AgentCustomerInfo.objects.filter(user_id=userID).first()            if not agent_customer_info:                return response.json(104, 'Agent customer not found')            agent_device_orders = AgentDeviceOrder.objects.filter(                ac_id=agent_customer_info.id, created_time__gte=startTime, created_time__lte=endTime, status__in=[1, 2]            )                        # 获取代理套餐包id            package_ids = agent_device_orders.values_list('csp_id', flat=True).distinct()            package_details = {pkg.id: pkg for pkg in AgentCloudServicePackage.objects.filter(id__in=package_ids)}            start_time = datetime.fromtimestamp(startTime)            end_time = datetime.fromtimestamp(endTime)            result = self.calculate_profit_or_revenue(agent_device_orders, package_details, timeUnit, metric_type,                                                      start_time, end_time)            return response.json(0, {'list': result})        except Exception as e:            error_msg = f"error_line:{traceback.format_exc()}, error_msg:{str(e)}"            return response.json(500, error_msg)
 |