# -*- coding: utf-8 -*- # !/usr/bin/env python import datetime import time from collections import Counter from typing import TYPE_CHECKING, Dict, Union from apilib.monetary import RMB, VirtualCoin, Percent from apilib.utils_datetime import to_datetime from apps.common.utils import get_start_and_end_by_year from apps.web.agent.models import Agent from apps.web.common.proxy import DealerDailyStatsModelProxy from apps.web.constant import MONTH_DATE_KEY from apps.web.dealer.models import Dealer from apps.web.device.models import Device, FeedBack from apps.web.user.models import ServiceProgress, MyUser, RechargeRecord, ConsumeRecord if TYPE_CHECKING: from bson.objectid import ObjectId from apps.web.report.models import DealerDailyStat def get_dealerMap_by_managerId(managerId, agentId = None, dealerId = None): # type:(Union[ObjectId,str], str, str)->Dict[str, dict] if not dealerId: if not agentId: agentMap = {str(_['_id']): str(_['nickname']) for _ in Agent.get_collection().find({'managerId': str(managerId)})} else: agent = Agent.objects(id = agentId).get() # type: Agent agentMap = {agentId: agent.nickname} dealerMap = {str(_['_id']): {'nickname': str(_['nickname']), 'agentName': agentMap[_['agentId']]} for _ in Dealer.get_collection().find({'agentId': {'$in': agentMap.keys()}})} else: dealer = Dealer.objects(id = dealerId).get() # type: Dealer agent = Agent.objects(id = dealer.agentId).get() # type: Agent dealerMap = {dealerId: {'nickname': dealer.nickname, 'agentName': agent.nickname}} return dealerMap def query_device_income(dealerIds): now_time = datetime.datetime.now() statsDict = DealerDailyStatsModelProxy.get_stats_as_day( dealerIds = dealerIds, startDay = (now_time - datetime.timedelta(days = 30)), endDay = now_time, project = ('daily.totalIncome', 'daily.consumption.coin'), aggregateMap = {'payIncome': {'$sum': '$daily.totalIncome'}, 'lineCoins': {'$sum': '$daily.consumption.coin'}}) dataList = [] for _day, _stat in statsDict.iteritems(): # type: DealerDailyStat dataList.append({ 'dateStr': _day, 'payIncome': RMB(_stat.get('payIncome', 0)), 'lineCoins': VirtualCoin(_stat.get('lineCoins', 0)) }) return dataList def query_device_consumption(dealerIds): now = datetime.datetime.now() endDate = MONTH_DATE_KEY.format(year = now.year, month = now.month) def get_start_day(date, var): year = int(date.split('-')[0]) month = int(date.split('-')[-1]) year = year if month > var else year - 1 month = month - var if month > var else month + 12 - var return '{year:d}-{month:02d}-01'.format(year = year, month = month) endDay = datetime.datetime.now() startDay = get_start_day(MONTH_DATE_KEY.format(year = endDay.year, month = endDay.month), 5) rv = DealerDailyStatsModelProxy.get_consume_as_month( dealerIds = dealerIds, startDay = startDay, endDay = endDay, sources = ['elec', 'coin']) dataList = [] for monthStr, value in rv.iteritems(): dataList.append({ 'consumptionList': [ {'name': '电量', 'value': Percent(value.get('elec', 0)), 'unit': '度'}, {'name': '金币', 'value': VirtualCoin(value.get('coin', 0)), 'unit': '个'} ], 'dateStr': monthStr }) return dataList def get_user_stats(dealerIds): devGroupIdList = [_['groupId'] for _ in list(Device.get_collection().find( {'ownerId': {'$in': dealerIds}}, {'devNo': 1, 'groupId': 1, '_id': 0} ))] myUserList = list(MyUser.get_collection().find( {'groupId': {'$in': devGroupIdList}}, {'nickname': 1, 'sex': 1, 'openId': 1, '_id': 0} )) myUserNameList = list(set([_.get('nickname', '') for _ in myUserList])) myUserOpenIdList = list(set([_['openId'] for _ in myUserList])) femaleCount = 0 maleCount = 0 for _ in myUserList: if _['sex'] == 2: femaleCount += 1 else: maleCount += 1 temp = int(((femaleCount + maleCount) - len(myUserNameList)) / 2) startDateTime = to_datetime(datetime.datetime.now().strftime('%Y-%m-%d') + ' 00:00:00') endDateTime = to_datetime(datetime.datetime.now().strftime('%Y-%m-%d') + ' 23:59:59') # 过滤重复的openId,找到今天的活跃用户 rcdList = list(RechargeRecord.get_collection().find( {'dateTimeAdded': {'$gte': startDateTime, '$lte': endDateTime}, 'openId': {'$in': myUserOpenIdList}}, {'openId': 1, '_id': 0} )) todayActiveUsers = list(set([_['openId'] for _ in rcdList])) return { "userCount": len(myUserNameList), "femaleCount": femaleCount - temp, "maleCount": maleCount - temp, "todayActiveUsers": len(todayActiveUsers) } def get_feed_back_stats(dealerIds): now_time = datetime.datetime.now() start_day = now_time.strftime('%Y-%m-%d %H:%M:%S') end_day = (now_time - datetime.timedelta(days = 90)).strftime('%Y-%m-%d %H:%M:%S') feedBacks = list(FeedBack.get_collection().find( {'ownerId': {'$in': dealerIds}, 'createTime': {'$gte': start_day, '$lte': end_day}}, {'_id': 0, 'feedType': 1, 'status': 1} )) fault = [_['status'] for _ in feedBacks if _['feedType'] == 'fault'] faultProcessed = [_ for _ in fault if _ == 1] offlineFeed = [_['status'] for _ in feedBacks if _['feedType'] in ['upper', 'refund', 'ic', 'putCoin']] offlineProcessed = [_ for _ in offlineFeed if _ == 1] netpayFeed = [_['status'] for _ in feedBacks if _['feedType'] == 'netpay'] netpayProcessed = [_ for _ in netpayFeed if _ == 1] return { "faultCount": len(fault), "faultProcessedCount": len(faultProcessed), "offlineFeedCount": len(offlineFeed), "offlineFeedProcessedCount": len(offlineProcessed), "netpayFeedCount": len(netpayFeed), "netpayFeedProcessedCount": len(netpayProcessed) } def query_total_dealer_income_top(dealerDict): startDay, endDay = get_start_and_end_by_year(datetime.date.today().strftime("%Y")) total_income_dict = DealerDailyStatsModelProxy.get_total_income_as_dealer( dealerIds = dealerDict.keys(), startDay = startDay, endDay = endDay) dic = {} for dealerId, nickname in dealerDict.iteritems(): item = total_income_dict.get(dealerId, {'totalIncome': 0}) dic.update({nickname: RMB(item.get('totalIncome'))}) data = Counter(dic).most_common()[0:5] # 返回一个列表,按照dict的value从大到小排序, 取前5位 return [{'name': _[0], 'payIncomeTotal': _[1]} for _ in data] def query_user_consume_frequency(dealerIds): # 查找出所有已注册的设备 devGroupIdList = [_['groupId'] for _ in list(Device.get_collection().find( {'ownerId': {'$in': dealerIds}}, {'devNo': 1, 'groupId': 1, '_id': 0} ))] myUserList = list(MyUser.get_collection().find( {'groupId': {'$in': devGroupIdList}}, {'nickname': 1, 'sex': 1, 'openId': 1, '_id': 0} )) myUserOpenIdList = list(set([_['openId'] for _ in myUserList])) aMonthAgo = time.mktime((datetime.date.today() - datetime.timedelta(days = 30)).timetuple()) rcdOpenIdList = [_['openId'] for _ in list(ConsumeRecord.get_collection().find( {'openId': {'$in': myUserOpenIdList}, 'dateTimeAdded': {'$gte': aMonthAgo}}, {'openId': 1, '_id': 0} ))] rcdCountDict = dict(Counter(rcdOpenIdList)) rcdCountPctDict = dict(Counter([_ for _ in rcdCountDict.values()])) totalCount = 0 for _ in rcdCountPctDict.values(): totalCount += _ dataList = [ { "name": "1次", "percent": 0 }, { "name": "2-5次", "percent": 0 }, { "name": "5-10次", "percent": 0 }, { "name": "10-20次", "percent": 0 }, { "name": "20+次", "percent": 0 } ] for k, v in rcdCountPctDict.items(): if k == 1: dataList[0]['percent'] += v elif 2 <= k <= 5: dataList[1]['percent'] += v elif 6 <= k <= 10: dataList[2]['percent'] += v elif 11 <= k <= 20: dataList[3]['percent'] += v else: dataList[4]['percent'] += v for _ in dataList: if float(totalCount) == 0: _['percent'] = 0 continue _['percent'] = Percent((float(_['percent']) / float(totalCount)) * 100) return dataList def get_device_being_used_trend(dealerIds): devList = list(Device.get_collection().find( {'ownerId': {'$in': dealerIds}, 'groupId': {'$ne': ''}}, {'devNo': 1, 'groupId': 1, '_id': 0} )) devNoList = [_['devNo'] for _ in devList] # 找前一天的数据 def get_hours_time(hoursStr): return time.mktime(to_datetime( (datetime.date.today() - datetime.timedelta(days = 1)).strftime('%Y-%m-%d') + hoursStr).timetuple()) yesterdayBegin = get_hours_time(' 00:00:00') yesterdayEnd = get_hours_time(' 23:59:59') serviceProgress = list(ServiceProgress.get_collection().find( {'device_imei': {'$in': devNoList}, 'start_time': {'$gte': int(yesterdayBegin), '$lte': int(yesterdayEnd)}}, {'_id': 0, 'start_time': 1} )) dataList = [] for _ in range(24): if _ < 9: timeStr = '0' + str(_ + 1) + '时' else: timeStr = str(_ + 1) + '时' dataList.append({ 'time': timeStr, 'devBeingUsed': 0 }) for svs in serviceProgress: for _ in range(24): if _ < 10: timeStr = ' ' + '0' + str(_) else: timeStr = ' ' + str(_) begin = timeStr + ':00:00' end = timeStr + ':59:59' if get_hours_time(begin) <= svs['start_time'] <= get_hours_time(end): dataList[_]['devBeingUsed'] += 1 return dataList