Commit 7ab2f372 authored by zhengjinlei's avatar zhengjinlei

报表提供下载功能

parent 8a1a71fa
......@@ -2,3 +2,4 @@
# from .user import UserApi
from .toolapi import ToolsApi
from .tasksapi import TasksApi
from .dataapi import DataApi
# coding: utf-8
from django.db.models import Count, Sum, Avg
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.request import Request
from inspect_report.models import Tasks, CheckSession, RulesStat, SeatStat, ScoreStat, Round
import json
from datetime import datetime, timedelta
from config.config import TABLE_PRE
from django.http import HttpResponse
import logging
from pypinyin import Style, pinyin
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
import csv
import codecs
from django.utils.http import urlquote
logger = logging.getLogger(__name__)
class DataApi(viewsets.ViewSet):
authentication_classes = ()
permission_classes = ()
@action(['get'], detail=False)
def static_score_export(self, req: Request):
"""
概览-地市得分统计-导出
:param req:
:return:
"""
task_id = req.GET.get('task', '')
sort = req.GET.get('sort', '-avg_score')
start_date = req.GET.get('start_date', (datetime.now() + timedelta(days=-1)).strftime('%Y-%m-%d'))
end_date = req.GET.get('end_date', datetime.now().strftime('%Y-%m-%d'))
q_start_date = datetime.strptime(start_date, '%Y-%m-%d').date()
q_end_date = (datetime.strptime(end_date, '%Y-%m-%d') + + timedelta(days=1)).date()
task_condition = {'create_date__gte': q_start_date, 'create_date__lt': q_end_date}
if task_id:
task_condition['task'] = task_id
rules = ScoreStat.objects.filter(**task_condition).extra(select={'area': "task"}) \
.values('area').annotate(avg_score_svc=Round(Avg('service_score'), 2),
avg_score_bus=Round(Avg('business_score'), 2),
avg_score=Round(Avg('score'), 2), total_session=Sum('total_session'),
validate_num=Sum('validate_num'), validate_zero=Sum('validate_zero')) \
.order_by(sort)
response = HttpResponse(content_type='text/csv')
file_name = '组长概览_' + datetime.now().strftime('%Y%m%d%H%M%S') + '.csv'
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="{0}"'.format(urlquote(file_name))
# 设置编码,放置中文乱码
response.write(codecs.BOM_UTF8)
writer = csv.writer(response)
# 设置表头
header = ['地市', '全部会话数', '触发违规项次数', '服务类平均分', '业务类平均分', '总平均分(包含0分项)', '触发0分项次数']
writer.writerow(header)
# 设置表数据
for r in rules:
row = [r['area'], r['total_session'], r['validate_num'], r['avg_score_svc'], r['avg_score_bus'],
r['avg_score'], r['validate_zero']]
writer.writerow(row)
return response
@action(['get'], detail=False)
def static_rule_export(self, req: Request):
"""
违规项统计-导出
:param req:
:return:
"""
task_id = req.GET.get('task', '')
start_date = req.GET.get('start_date', (datetime.now() + timedelta(days=-1)).strftime('%Y-%m-%d'))
end_date = req.GET.get('end_date', datetime.now().strftime('%Y-%m-%d'))
task_condition = {'hasCheck': 1, 'createdAt__gte': start_date, 'createdAt__lt': end_date + ' 23:59:59'}
if task_id:
task_condition['name__startswith'] = task_id
tasks = Tasks.objects.filter(**task_condition).values('id', 'sessionCollectionId')
task_dict = {}
for t in tasks:
if t['sessionCollectionId'] in task_dict.keys():
task_dict[t['sessionCollectionId']].append(t['id'])
else:
task_dict[t['sessionCollectionId']] = [t['id'], ]
return_data = {}
call_count = 0
for k, v in task_dict.items():
table_name = TABLE_PRE + k
tn = CheckSession.set_table(table_name)
session_condition = {'taskId__in': v, 'violationRuleCount__gt': 0}
validate_all = tn.objects.filter(**session_condition).aggregate(Count("id"))
call_count += validate_all['id__count']
q_start_date = datetime.strptime(start_date, '%Y-%m-%d').date()
q_end_date = (datetime.strptime(end_date, '%Y-%m-%d') + + timedelta(days=1)).date()
task_condition = {'create_date__gte': q_start_date, 'create_date__lt': q_end_date}
if task_id:
task_condition['task'] = task_id
tasks = RulesStat.objects.all().filter(**task_condition) \
.extra(select={'rule': "rule", 'sessionCollectionId': 'sessionCollectionId'}) \
.values('rule', 'sessionCollectionId').annotate(rule_num=Count('id')).order_by('-rule_num')
for t in tasks:
name = t['rule']
if name in return_data.keys():
return_data[name]['count'] += int(t['rule_num'])
else:
return_data[name] = {'count': int(t['rule_num']), 'tables': []}
if t['sessionCollectionId'] not in return_data[name]['tables']:
return_data[name]['tables'].append(t['sessionCollectionId'])
data_sort = []
for k, v in return_data.items():
v['rule'] = k
v['ratio'] = round(v['count'] / call_count, 2) if call_count else 0
v['ratio'] = '{0}%'.format(int(v['ratio'] * 100))
v['call_count'] = call_count
data_sort.append(v)
response = HttpResponse(content_type='text/csv')
file_name = '违规项分析_' + datetime.now().strftime('%Y%m%d%H%M%S') + '.csv'
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="{0}"'.format(urlquote(file_name))
# 设置编码,放置中文乱码
response.write(codecs.BOM_UTF8)
writer = csv.writer(response)
# 设置表头
header = ['违规项', '违规次数', '通话次数', '违规占比']
writer.writerow(header)
# 设置表数据
for r in data_sort:
row = [r['rule'], r['count'], r['call_count'], r['ratio']]
writer.writerow(row)
return response
@action(['get'], detail=False)
def seat_rule_export(self, req: Request):
"""
坐席违规分析-按照得分-导出
:param req:
:return:
"""
task_id = req.data.get('task', '')
agent_name = req.data.get('agentName', '')
sort = req.data.get('sort', 'des')
start_date = req.data.get('start_date', (datetime.now()+timedelta(days=-1)).strftime('%Y-%m-%d'))
end_date = req.data.get('end_date', datetime.now().strftime('%Y-%m-%d'))
q_start_date = datetime.strptime(start_date, '%Y-%m-%d').date()
q_end_date = (datetime.strptime(end_date, '%Y-%m-%d') + + timedelta(days=1)).date()
task_condition = {'create_date__gte': q_start_date, 'create_date__lt': q_end_date}
if task_id:
task_condition['task'] = task_id
if agent_name:
task_condition['agentName'] = agent_name
if sort == 'des':
seats = SeatStat.objects.filter(**task_condition).extra(select={'agentName': 'agentName'}) \
.values('agentName').annotate(remainTime=Sum('remainTime'), validate_session=Sum('validate_session'),
total_session=Sum('total_session')).order_by('-validate_session')
else:
seats = SeatStat.objects.filter(**task_condition).extra(select={'agentName': 'agentName'}) \
.values('agentName').annotate(remainTime=Sum('remainTime'), validate_session=Sum('validate_session'),
total_session=Sum('total_session')).order_by('validate_session')
return_data = []
for s in seats:
detail = {'agentName': s['agentName'], 'validate_session': s['validate_session'],
'remainTime': s['remainTime'], 'total_session': s['total_session'],
'ratio': round(s['validate_session']/s['total_session'], 2)}
return_data.append(detail)
if sort == 'asc':
data_sort = sorted(return_data, key=lambda x: x['ratio'])
for i in range(len(data_sort)):
data_sort[i]['ratio'] = '{0}%'.format(int(data_sort[i]['ratio'] * 100))
else:
data_sort = sorted(return_data, key=lambda x: x['ratio'], reverse=True)
for i in range(len(data_sort)):
data_sort[i]['ratio'] = '{0}%'.format(int(data_sort[i]['ratio'] * 100))
response = HttpResponse(content_type='text/csv')
file_name = '坐席违规_' + datetime.now().strftime('%Y%m%d%H%M%S') + '.csv'
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="{0}"'.format(urlquote(file_name))
# 设置编码,放置中文乱码
response.write(codecs.BOM_UTF8)
writer = csv.writer(response)
# 设置表头
header = ['坐席', '全部会话数', '违规会话数', '违规占比']
writer.writerow(header)
# 设置表数据
for r in data_sort:
row = [r['agentName'], r['validate_session'], r['total_session'], r['ratio']]
writer.writerow(row)
return response
@action(['get'], detail=False)
def seat_area_export(self, req: Request):
"""
地市坐席成绩分析-导出
:param req:
:return:
"""
task_id = req.GET.get('task', '')
agent_name = req.GET.get('agentName', '')
sort = req.GET.get('sort', '-avg_score')
start_date = req.GET.get('start_date', (datetime.now() + timedelta(days=-1)).strftime('%Y-%m-%d'))
end_date = req.GET.get('end_date', datetime.now().strftime('%Y-%m-%d'))
q_start_date = datetime.strptime(start_date, '%Y-%m-%d').date()
q_end_date = (datetime.strptime(end_date, '%Y-%m-%d') + + timedelta(days=1)).date()
task_condition = {'create_date__gte': q_start_date, 'create_date__lt': q_end_date}
if task_id:
task_condition['task'] = task_id
if agent_name:
task_condition['agentName'] = agent_name
# , 'total_session', 'validate_num', 'validate_session', 'validate_zero'
rules = ScoreStat.objects.filter(**task_condition).extra(select={'area': "task", 'agentName': 'agentName'}) \
.values('area', 'agentName').annotate(avg_score_svc=Round(Avg('service_score'), 2),
avg_score_bus=Round(Avg('business_score'), 2),
avg_score=Round(Avg('score'), 2), total_session=Sum('total_session'),
validate_num=Sum('validate_num'), validate_zero=Sum('validate_zero')) \
.order_by(sort)
response = HttpResponse(content_type='text/csv')
file_name = '坐席成绩_' + datetime.now().strftime('%Y%m%d%H%M%S') + '.csv'
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="{0}"'.format(urlquote(file_name))
# 设置编码,放置中文乱码
response.write(codecs.BOM_UTF8)
writer = csv.writer(response)
# 设置表头
header = ['地市', '坐席工号', '全部会话数', '触发违规项次数', '服务类平均分', '业务类平均分', '平均分', '触发0分项次数']
writer.writerow(header)
# 设置表数据
for r in rules:
row = [r['area'], r['agentName'], r['total_session'], r['validate_num'], r['avg_score_svc'],
r['avg_score_bus'], r['avg_score'], r['validate_zero']]
writer.writerow(row)
return response
@action(['get'], detail=False)
def seat_check_export(self, req: Request):
"""
坐席绩效考核汇总-导出
:param req:
:return:
"""
task_id = req.GET.get('task', '')
agent_name = req.GET.get('agentName', '')
start_date = req.GET.get('start_date', (datetime.now() + timedelta(days=-1)).strftime('%Y-%m-%d'))
end_date = req.GET.get('end_date', datetime.now().strftime('%Y-%m-%d'))
task_condition = {'hasCheck': 1, 'createdAt__gte': start_date, 'createdAt__lt': end_date + ' 23:59:59'}
if task_id:
task_condition['name__startswith'] = task_id
tasks = Tasks.objects.filter(**task_condition).values('id', 'name', 'sessionCollectionId')
task_dict = {}
task_name_dict = {}
for t in tasks:
task_name_dict[t['id']] = t['name']
if t['sessionCollectionId'] in task_dict.keys():
task_dict[t['sessionCollectionId']].append(t['id'])
else:
task_dict[t['sessionCollectionId']] = [t['id'], ]
return_data = []
for k, v in task_dict.items():
table_name = TABLE_PRE + k
tn = CheckSession.set_table(table_name)
session_condition = {'taskId__in': v}
if agent_name:
session_condition['agentName'] = agent_name
checks = tn.objects.filter(**session_condition).values('id', 'createdAt', 'agentName', 'extra', 'taskId',
'remainTime', 'scoreItemRecord', 'sessionId')
for check in checks:
result = check['scoreItemRecord']
t_name = task_name_dict[check['taskId']]
total_score = 100
extra = json.loads(check['extra'])
f_name = extra['filename'] if extra and 'filename' in extra.keys() else ''
detail = {'id': check['id'], 'sessionId': check['sessionId'], 'createdAt': check['createdAt'],
'area': t_name.split('_')[0], 'agentName': check['agentName'], 'filename': f_name,
'remainTime': check['remainTime'], 'sessionCollectionId': k, 'taskId': check['taskId']}
rule_detail = {'fwyy': 10, 'kcb': 10, 'jsy': 5, 'fwtd': 10, 'yssb': 5, 'jysb': 5, 'yycl': 10,
'ywcc': 15, 'yyjlz': 15, 'fwjs': 5, 'wtgbj': 5, 'wzyhfljs': 5, 'wgzlf': 100, 'mgc': 100}
if result:
data = json.loads(result)
for d in data:
if 'scoreItemName' in d.keys() and 'score' in d.keys():
item_score = 0 if d['score'] and d['score'] > 0 else 1
name_py = pinyin(d['scoreItemName'], style=Style.FIRST_LETTER, strict=False)
item_name = ''.join([x[0] for x in name_py])
# detail[item_name] = {d['scoreItemName']: item_score}
if item_name in rule_detail.keys():
if item_score == 0:
total_score -= rule_detail[item_name]
rule_detail[item_name] = item_score
for kk, vv in rule_detail.items():
if vv > 1:
rule_detail[kk] = 1
if rule_detail['wgzlf'] == 0 or rule_detail['mgc'] == 0:
total_score = 0
detail.update(rule_detail)
detail['total_score'] = total_score
return_data.append(detail)
response = HttpResponse(content_type='text/csv')
file_name = '质检绩效考核_' + datetime.now().strftime('%Y%m%d%H%M%S') + '.csv'
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="{0}"'.format(urlquote(file_name))
# 设置编码,放置中文乱码
response.write(codecs.BOM_UTF8)
writer = csv.writer(response)
# 设置表头
header = ['时间', '坐席工号', '文件名', '通话时长(s)', '服务用语(10%)', '开场白(10%)', '结束语(5%)', '服务态度(10%)',
'语速识别(5%)', '静音识别(5%)', '异议处理(10%)', '业务促成(15%)', '预约及流转(15%)', '服务介绍(5%)',
'为提供报价(5%)', '未做优惠费率介绍(5%)', '违规则0分(100%)', '敏感词(100%)', '得分']
writer.writerow(header)
# 设置表数据
for r in return_data:
row = [r['createdAt'], r['agentName'], r['filename'], r['remainTime'], r['fwyy'], r['kcb'], r['jsy'],
r['fwtd'], r['yssb'], r['jysb'], r['yycl'], r['ywcc'], r['yyjlz'], r['fwjs'], r['wtgbj'],
r['wzyhfljs'], r['wgzlf'], r['mgc'], r['total_score']]
writer.writerow(row)
return response
......@@ -199,11 +199,14 @@ class TasksApi(viewsets.ViewSet):
if agent_name:
task_condition['agentName'] = agent_name
if sort == 'des':
seats = SeatStat.objects.filter(**task_condition).values('agentName', 'validate_session', 'total_session')\
.order_by('-validate_session')
seats = SeatStat.objects.filter(**task_condition).extra(select={'agentName': 'agentName'}) \
.values('agentName').annotate(remainTime=Sum('remainTime'), validate_session=Sum('validate_session'),
total_session=Sum('total_session')).order_by('-validate_session')
else:
seats = SeatStat.objects.filter(**task_condition).values('agentName', 'validate_session', 'total_session') \
.order_by('validate_session')
seats = SeatStat.objects.filter(**task_condition).extra(select={'agentName': 'agentName'}) \
.values('agentName').annotate(remainTime=Sum('remainTime'), validate_session=Sum('validate_session'),
total_session=Sum('total_session')).order_by('validate_session')
paginator = Paginator(seats, page_size)
total_count = paginator.count
try:
......@@ -215,7 +218,8 @@ class TasksApi(viewsets.ViewSet):
return_data = []
for s in seats:
detail = {'agentName': s['agentName'], 'validate_session': s['validate_session'],
'total_session': s['total_session'], 'ratio': round(s['validate_session']/s['total_session'], 2)}
'remainTime': s['remainTime'], 'total_session': s['total_session'],
'ratio': round(s['validate_session']/s['total_session'], 2)}
return_data.append(detail)
if sort == 'asc':
data_sort = sorted(return_data, key=lambda x: x['ratio'])
......
......@@ -78,7 +78,8 @@ def seat_stat(start_date=None, end_date=None):
table_name = TABLE_PRE + t['sessionCollectionId']
tn = CheckSession.set_table(table_name)
session_condition = {'taskId': t['id']}
checks = tn.objects.filter(**session_condition).values('id', 'agentName', 'taskId', 'violationRuleCount')
checks = tn.objects.filter(**session_condition).values('id', 'agentName', 'remainTime', 'taskId',
'violationRuleCount')
seat_dict = {}
seat_list = []
for check in checks:
......@@ -86,12 +87,14 @@ def seat_stat(start_date=None, end_date=None):
if check['agentName'] in seat_dict.keys():
seat = seat_dict.get(check['agentName'])
seat['total_session'] += 1
seat['remainTime'] = check['remainTime']
seat['validate_session'] += 1 if check['violationRuleCount'] > 0 else 0
else:
seat_dict[check['agentName']] = {'create_date': start_date, 'agentName': check['agentName'],
'taskId': check['taskId'], 'task': t['name'].split('_')[0],
'sessionCollectionId': t['sessionCollectionId'], 'total_session': 1}
seat_dict[check['agentName']]['validate_session'] = 1 if check['violationRuleCount'] > 0 else 0
seat_dict[check['agentName']]['remainTime'] = check['remainTime']
for k, v in seat_dict.items():
seat_obj = {'agentName': k}
seat_obj.update(v)
......
......@@ -22,6 +22,7 @@ from . import api
router = routers.DefaultRouter()
router.register(r'tools', api.ToolsApi, base_name='tools')
router.register(r'tasks', api.TasksApi, base_name='tasks')
router.register(r'data', api.DataApi, base_name='data')
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment