# -*- encoding: utf-8 -*- """ @File : TelecomService.py @Time : 2024/1/24 15:12 @Author : stephen @Email : zhangdongming@asj6.wecom.work @Software: PyCharm """ import json import re import time from decimal import Decimal from Ansjer.config import LOGGER from Model.models import UnicomDeviceInfo, LogModel from Object.RedisObject import RedisObject from Object.TelecomObject import TelecomObject class TelecomService: @classmethod def query_total_usage_by_access_number(cls, iccid, key, expire=600): """ 根据接入号码查询设备总流量使用量(实现缓存) @param iccid: 20位ICCID @param key: 缓存key @param expire: 失效时间 @return: 查询流量结果 """ redis = RedisObject() sim_flow_used_total = redis.get_data(key) if sim_flow_used_total: return Decimal(sim_flow_used_total).quantize(Decimal('0.00')) else: # 查询SIM卡信息 sim_qs = UnicomDeviceInfo.objects.filter(iccid=iccid) if not sim_qs: return None sim_vo = sim_qs.first() telecom = TelecomObject() # 查询电信当月流量用量 data = telecom.query_total_usage_by_date(sim_vo.access_number) if data and data['SvcCont']['resultCode'] == '0' and 'dataCumulationTotal' in data['SvcCont']['result']: cycle_total = data['SvcCont']['result'].get('dataCumulationTotal') else: LOGGER.info(f'query_total_usage_by_access_number查询流量异常,iccid:{iccid}') return sim_vo.sim_used_flow + sim_vo.sim_cycle_used_flow cycle_total = Decimal(cycle_total).quantize(Decimal('0.00')) n_time = int(time.time()) # 判断数据库周期流量用量 是否大于API查询出来的周期用量 如果是则判定进入了下一个周期 if sim_vo.sim_cycle_used_flow != 0 and sim_vo.sim_cycle_used_flow > cycle_total: sim_used_flow = sim_vo.sim_used_flow + sim_vo.sim_cycle_used_flow sim_qs.update( sim_used_flow=sim_used_flow, sim_cycle_used_flow=cycle_total, updated_time=n_time ) # 队列用量历史总量 + 上一个周期流量 + 当前周期流量 = 总消耗流量 sim_flow_used_total = sim_used_flow + cycle_total elif cycle_total > sim_vo.sim_cycle_used_flow: # API周期用量大于当前数据库用量则更新记录 sim_qs.update(sim_cycle_used_flow=cycle_total, updated_time=n_time) # 队列用量历史总量 + 当前周期流量 = 总消耗流量 sim_flow_used_total = sim_vo.sim_used_flow + cycle_total else: sim_flow_used_total = sim_vo.sim_used_flow + sim_vo.sim_cycle_used_flow # 缓存当月流量数据 redis.CONN.setnx(key, str(sim_flow_used_total)) redis.CONN.expire(key, expire) return sim_flow_used_total @classmethod def update_access_number_network(cls, access_number, action): """ 根据接入号码修改卡网络状态 @param access_number: 11位接入号码 @param action: ADD:单独添加断网,DEL:单独恢复上网 @return: True|False """ try: result = TelecomObject().single_cut_net(access_number, action) url = 'update/access_number/network' ip = '127.0.0.1' params = {'access_number': access_number, 'action': action, 'result': result} if not result: explain = f'{access_number}单独断网或恢复异常' cls.create_operation_log(url, ip, params, explain) return None explain = f'{access_number}单独断网或恢复成功' cls.create_operation_log(url, ip, params, explain) return 'success' except Exception as e: LOGGER.info('***{} TelecomService.update_access_number_network:errLine:{}, errMsg:{}' .format(access_number, e.__traceback__.tb_lineno, repr(e))) return None @classmethod def create_operation_log(cls, url, ip, request_dict, describe): """ 创建操作日志 @param url: 请求路径 @param describe: 描述 @param ip: 当前IP @param request_dict: 请求参数 @return: True | False """ try: # 记录操作日志 content = json.loads(json.dumps(request_dict)) log = { 'ip': ip, 'user_id': 1, 'status': 200, 'time': int(time.time()), 'content': json.dumps(content), 'url': url, 'operation': describe, } LogModel.objects.create(**log) return True except Exception as e: print('日志异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))) return False @classmethod def get_access_number_network_status(cls, access_number): """ 根据access_number查询是否单独断网 @param access_number: 11位接入号码 @return: 当前网络数据 """ try: result = TelecomObject().query_product_information(access_number) if not result: return None if result and result['result_code']: # 获取产品信息 prod_infos = result["result"]["SvcCont"]["result"]["prodInfos"] # 获取 funProdInfos 列表 fun_prod_infos = prod_infos["funProdInfos"] # 遍历 funProdInfos 列表 for prod_info in fun_prod_infos: # 获取是否已单独断网信息 if isinstance(prod_info, dict) and "productName" in prod_info: is_disconnect = prod_info.get("productName") if "是否已单独断网" in is_disconnect: is_disconnect_value = re.search(r"(?<=:).+", is_disconnect).group(0) # 进行判断 if is_disconnect_value == "否": return 'disconnect' else: return 'connect' return None except Exception as e: print('***{}get_access_number_network_status,errLine:{}, errMsg:{}' .format(access_number, e.__traceback__.tb_lineno, repr(e))) return None