Commit 5b3c99d0 authored by zhengjinlei's avatar zhengjinlei

重新统计报表

parent 73c876ad
# coding: utf-8 # coding: utf-8
from django.forms import model_to_dict
from django.shortcuts import render from django.shortcuts import render
from django.db.models import Sum, Avg from django.db.models import Sum, Avg
from rest_framework import viewsets from rest_framework import viewsets
...@@ -10,12 +11,13 @@ from before_request import before_request ...@@ -10,12 +11,13 @@ from before_request import before_request
from inspect_report.agency import get_team_names from inspect_report.agency import get_team_names
from inspect_report.dbhelper import db_static_score, db_seat_rule, db_seat_check, db_seat_area, db_static_rule, \ from inspect_report.dbhelper import db_static_score, db_seat_rule, db_seat_check, db_seat_area, db_static_rule, \
set_city_country_by_team_name set_city_country_by_team_name
from inspect_report.models import RulesStat, SeatStat, ScoreStat, Round, Seat from inspect_report.models import RulesStat, SeatStat, ScoreStat, Round, Seat, Tasks
import json import json
from django.views.decorators.clickjacking import xframe_options_exempt from django.views.decorators.clickjacking import xframe_options_exempt
import logging import logging
from inspect_report.pagehelper import page_with_seat_name from inspect_report.pagehelper import page_with_seat_name
from inspect_report.utils.report_utils import delete_stat_by_task, re_stat_by_task
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -37,6 +39,24 @@ class TasksApi(viewsets.ViewSet): ...@@ -37,6 +39,24 @@ class TasksApi(viewsets.ViewSet):
# # return render(req, 'inspect/index.html', {'tasks': tasks}) # # return render(req, 'inspect/index.html', {'tasks': tasks})
# return Response({'code': 0, 'msg': 'success', 'data': tasks}) # return Response({'code': 0, 'msg': 'success', 'data': tasks})
@action(['get'], detail=False)
def stat_report(self, req: Request):
task_id = req.GET.get('task_id')
if not task_id:
logger.error('[re_stat_report_data]---invalid params')
return Response({'code': -1, 'msg': 'invalid params'})
try:
task = Tasks.objects.get(pk=task_id)
except Exception as e:
print(e)
logger.error('[re_stat_report_data]---no task exists')
return Response({'code': -2, 'msg': 'no task exists'})
# 删除与task_id相关的统计
delete_stat_by_task(task)
# 重新统计
re_stat_by_task(model_to_dict(task))
return Response({'code': 0, 'msg': 're-stat success'})
@action(['get'], detail=False) @action(['get'], detail=False)
@before_request @before_request
def seat(self, req: Request): def seat(self, req: Request):
......
...@@ -6,31 +6,13 @@ import logging ...@@ -6,31 +6,13 @@ import logging
import kronos import kronos
from datetime import datetime, timedelta from datetime import datetime, timedelta
from inspect_report.utils.report_utils import single_rules_stat, single_seat_stat, single_score_stat
"""定时任务 """定时任务
参考:https://github.com/jgorset/django-kronos 参考:https://github.com/jgorset/django-kronos
""" """
logger = logging.getLogger('app_file') logger = logging.getLogger('app_file')
score_item_zero = {'违规则零分': 100, '敏感词': 100}
score_item_service = {'服务用语': 15, '开场白': 5, '结束语': 3, '服务态度': 5, '语速识别': 5, '静音识别': 5}
score_item_business = {'异议处理': 10, '业务促成': 10, '预约及流转': 10, '服务介绍': 10, '未提供报价': 2, '成功件信息核实': 20}
def get_remain(check):
remain = 0
if check['startTime'] and check['closeTime']:
start = datetime.strptime(check['startTime'], '%Y-%m-%d %H:%M:%S').timestamp()
close = datetime.strptime(check['closeTime'], '%Y-%m-%d %H:%M:%S').timestamp()
remain = int(close - start)
return remain
def team_seat():
teams = Team.objects.values_list('id', 'name')
team_id_name = {team[0]: team[1] for team in teams}
seats = Seat.objects.values_list('code', 'team_id')
seat_code_team_name = {seat[0]: team_id_name[seat[1]] for seat in seats}
return seat_code_team_name
@kronos.register('30 6 * * *') @kronos.register('30 6 * * *')
...@@ -43,7 +25,6 @@ def rule_stat(date_str=None): ...@@ -43,7 +25,6 @@ def rule_stat(date_str=None):
所以start_date为utc时间减去三小时足够了,至于报表的存储时间,存储当天时间即可,毕竟是当天的质检任务统计的报表 所以start_date为utc时间减去三小时足够了,至于报表的存储时间,存储当天时间即可,毕竟是当天的质检任务统计的报表
:return: :return:
""" """
seat_code_team_name = team_seat()
if not date_str: if not date_str:
# 数据库中为utc时间 # 数据库中为utc时间
date_str = datetime.now().strftime('%Y-%m-%d') date_str = datetime.now().strftime('%Y-%m-%d')
...@@ -53,36 +34,7 @@ def rule_stat(date_str=None): ...@@ -53,36 +34,7 @@ def rule_stat(date_str=None):
tasks = Tasks.objects.filter(**task_condition).values('id', 'name', 'sessionCollectionId') tasks = Tasks.objects.filter(**task_condition).values('id', 'name', 'sessionCollectionId')
stat_count = 0 stat_count = 0
for t in tasks: for t in tasks:
if RulesStat.objects.filter(taskId=t['id']).exists(): single_rules_stat(t, create_date, stat_count)
continue
table_name = TABLE_PRE + t['sessionCollectionId']
tn = CheckSession.set_table(table_name)
session_condition = {'taskId': t['id'], 'violationRuleCount__gt': 0}
checks = tn.objects.filter(**session_condition).values('id', 'checkResult', 'agentName', 'customName', 'score',
'remainTime', 'startTime', 'closeTime', 'taskId',
'sessionId')
for check in checks:
result = check['checkResult']
if result:
rules_list = []
data = json.loads(result)
for d in data:
remain = get_remain(check)
if 'isViolation' in d.keys() and d['isViolation'] and 'rule' in d.keys() and 'name' in d[
'rule'].keys():
name = d['rule']['name']
rule_obj = {'create_date': create_date, 'sessionCollectionId': t['sessionCollectionId'],
'rule': name, 'rule_num': 1,
'task': seat_code_team_name.get(check['agentName'], '未找到团队'),
'agentName': check['agentName'], 'customName': check['customName'],
'score': check['score'], 'remainTime': remain,
'taskId': check['taskId'], 'sessionId': check['sessionId'],
'session_table_id': check['id']}
rules_list.append(RulesStat(**rule_obj))
stat_count += 1
logger.info('rule stat num: [%s]', stat_count)
RulesStat.objects.bulk_create(rules_list)
logger.info('[rule_stat]rule stat num: [%s]', stat_count) logger.info('[rule_stat]rule stat num: [%s]', stat_count)
logger.info('[rule_stat]rule stat end.') logger.info('[rule_stat]rule stat end.')
...@@ -93,7 +45,6 @@ def seat_stat(date_str=None): ...@@ -93,7 +45,6 @@ def seat_stat(date_str=None):
首页概述-违规坐席统计 首页概述-违规坐席统计
:return: :return:
""" """
seat_code_team_name = team_seat()
if not date_str: if not date_str:
date_str = datetime.now().strftime('%Y-%m-%d') date_str = datetime.now().strftime('%Y-%m-%d')
create_date = date_str create_date = date_str
...@@ -102,35 +53,7 @@ def seat_stat(date_str=None): ...@@ -102,35 +53,7 @@ def seat_stat(date_str=None):
tasks = Tasks.objects.filter(**task_condition).values('id', 'name', 'sessionCollectionId') tasks = Tasks.objects.filter(**task_condition).values('id', 'name', 'sessionCollectionId')
stat_count = 0 stat_count = 0
for t in tasks: for t in tasks:
if SeatStat.objects.filter(taskId=t['id']).exists(): single_seat_stat(t, create_date, stat_count)
continue
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', 'remainTime', 'startTime',
'closeTime', 'taskId', 'violationRuleCount')
seat_dict = {}
seat_list = []
for check in checks:
stat_count += 1
remain = get_remain(check)
if check['agentName'] in seat_dict.keys():
seat = seat_dict.get(check['agentName'])
seat['total_session'] += 1
seat['remainTime'] += remain
seat['validate_session'] += 1 if check['violationRuleCount'] > 0 else 0
else:
seat_dict[check['agentName']] = {'create_date': create_date, 'agentName': check['agentName'],
'taskId': check['taskId'],
'task': seat_code_team_name.get(check['agentName'], '未找到团队'),
'sessionCollectionId': t['sessionCollectionId'], 'total_session': 1}
seat_dict[check['agentName']]['validate_session'] = 1 if check['violationRuleCount'] > 0 else 0
seat_dict[check['agentName']]['remainTime'] = remain
for k, v in seat_dict.items():
seat_obj = {'agentName': k}
seat_obj.update(v)
seat_list.append(SeatStat(**seat_obj))
SeatStat.objects.bulk_create(seat_list)
logger.info('[seat_stat]violate seat count: [%s]', stat_count) logger.info('[seat_stat]violate seat count: [%s]', stat_count)
logger.info('[seat_stat]violate seat stat end.') logger.info('[seat_stat]violate seat stat end.')
...@@ -141,7 +64,6 @@ def score_stat(date_str=None): ...@@ -141,7 +64,6 @@ def score_stat(date_str=None):
坐席得分统计 坐席得分统计
:return: :return:
""" """
seat_code_team_name = team_seat()
if not date_str: if not date_str:
date_str = datetime.now().strftime('%Y-%m-%d') date_str = datetime.now().strftime('%Y-%m-%d')
create_date = date_str create_date = date_str
...@@ -150,55 +72,7 @@ def score_stat(date_str=None): ...@@ -150,55 +72,7 @@ def score_stat(date_str=None):
tasks = Tasks.objects.filter(**task_condition).values('id', 'name', 'sessionCollectionId') tasks = Tasks.objects.filter(**task_condition).values('id', 'name', 'sessionCollectionId')
stat_count = 0 stat_count = 0
for t in tasks: for t in tasks:
if ScoreStat.objects.filter(taskId=t['id']).exists(): single_score_stat(t, create_date, stat_count)
continue
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',
'startTime', 'score', 'scoreItemRecord')
seat_dict = {}
seat_list = []
for check in checks:
stat_count += 1
score_item = json.loads(check['scoreItemRecord'])
service_score = 38
business_score = 62
validate_zero = 0
for m in score_item:
if m['scoreItemName'] in score_item_service.keys():
service_score -= m['score']
if m['scoreItemName'] in score_item_business.keys():
business_score -= m['score']
if m['scoreItemName'] in score_item_zero.keys():
validate_zero += 1
if validate_zero > 0:
score = 0
else:
score = service_score + business_score
if check['agentName'] in seat_dict.keys():
seat = seat_dict.get(check['agentName'])
seat['total_session'] += 1
seat['validate_session'] += 1 if check['violationRuleCount'] > 0 else 0
seat['validate_num'] += len(score_item)
seat['score'] = round((seat['score'] + score) / 2, 2)
seat['service_score'] = round((seat['service_score'] + service_score) / 2, 2)
seat['business_score'] = round((seat['business_score'] + business_score) / 2, 2)
else:
seat_dict[check['agentName']] = {'create_date': create_date, 'agentName': check['agentName'],
'taskId': check['taskId'],
'task': seat_code_team_name.get(check['agentName'], '未找到团队'),
'sessionCollectionId': t['sessionCollectionId'], 'total_session': 1,
'score': score, 'service_score': service_score,
'business_score': business_score, 'validate_zero': validate_zero}
seat_dict[check['agentName']]['validate_session'] = 1 if check['violationRuleCount'] > 0 else 0
seat_dict[check['agentName']]['validate_num'] = len(score_item)
for k, v in seat_dict.items():
seat_obj = {'agentName': k}
seat_obj.update(v)
seat_list.append(ScoreStat(**seat_obj))
ScoreStat.objects.bulk_create(seat_list)
logger.info('[score_stat]seat count: [%s]', stat_count) logger.info('[score_stat]seat count: [%s]', stat_count)
logger.info('[score_stat]seat score stat end.') logger.info('[score_stat]seat score stat end.')
......
...@@ -5,7 +5,7 @@ from pypinyin import pinyin, Style ...@@ -5,7 +5,7 @@ from pypinyin import pinyin, Style
from config.config import TABLE_PRE from config.config import TABLE_PRE
from inspect_report.agency import get_team_names, get_agent_name from inspect_report.agency import get_team_names, get_agent_name
from inspect_report.cron import get_remain from inspect_report.utils.report_utils import get_remain
from inspect_report.models import ScoreStat, Round, SeatStat, Seat, Country, Tasks, CheckSession, RulesStat, Team from inspect_report.models import ScoreStat, Round, SeatStat, Seat, Country, Tasks, CheckSession, RulesStat, Team
from inspect_report.pagehelper import page_with_seat_name from inspect_report.pagehelper import page_with_seat_name
......
...@@ -206,6 +206,46 @@ class Seat(models.Model): ...@@ -206,6 +206,46 @@ class Seat(models.Model):
db_table = 'seat' db_table = 'seat'
class ScoreItems(models.Model):
id = models.IntegerField('主键', primary_key=True)
name = models.CharField('评分项名称', max_length=190)
desc = models.CharField('描述', max_length=1000)
ruleTypeId = models.CharField('评分项在评分模板下的分类id', max_length=190)
status = models.IntegerField('评分项软删除标志位')
templateId = models.IntegerField('评分模板id')
rules = models.CharField('评分项的规则id', max_length=1000)
score = models.FloatField('评分项得分')
scoreType = models.IntegerField('评分项是加分项还是减分项', choices=[(0, '加分项'), (1, '减分项')], default=1)
conditions = models.TextField('规则的条件组合')
rawConditions = models.CharField('原始数据,可用于还原', max_length=5120)
createdAt = models.DateTimeField('创建时间')
updatedAt = models.DateTimeField('更新时间')
def __str__(self):
return self.name
class Meta:
db_table = 'score_items'
class ScoreTemplate(models.Model):
id = models.IntegerField('主键', primary_key=True)
name = models.CharField('类别名称', max_length=190)
basicScore = models.FloatField('基本分')
minScore = models.FloatField('基本分')
maxScore = models.FloatField('最高分')
status = models.IntegerField('评分模板软删除标志位')
rules = models.CharField('此评分模板的规则', max_length=5000)
createdAt = models.DateTimeField('创建时间')
updatedAt = models.DateTimeField('更新时间')
def __str__(self):
return self.name
class Meta:
db_table = 'score_template'
class Round(Func): class Round(Func):
function = 'ROUND' function = 'ROUND'
arity = 2 arity = 2
# -*- coding: utf-8 -*-
# @Time : 2020-06-08 09:28
# @Author : zhengjinlei
# @File : report_utils.py
import json
import logging
from datetime import datetime
from django.db.models import Sum
from inspect_report.models import RulesStat, CheckSession, Team, Seat, SeatStat, ScoreStat, ScoreTemplate, ScoreItems
from config.config import TABLE_PRE
logger = logging.getLogger('app_file')
def get_inspect_rule(task):
"""
获取质检规则
:param task:
:return:
"""
service_score, business_score, validate_zero = 0, 0, 0
score_item_service, score_item_business, score_item_zero = {}, {}, {}
extra = json.loads(task['extra']) if task['extra'] else {}
template_id = extra['templateId']
score_item_ids = extra['scoreItemIds']
try:
template = ScoreTemplate.objects.get(pk=template_id)
except Exception as e:
logger.error('obtain score template fail!, error: %s', e)
return 0, 0, 0, {}, {}, {}
rules = json.loads(template.rules)
for rule in rules:
if rule['type'] == '服务类':
service_score = ScoreItems.objects.filter(id__in=rule['scoreItemIds']).aggregate(ss=Sum('score'))['ss']
service_items = list(set(rule['scoreItemIds']).intersection(set(score_item_ids)))
items = ScoreItems.objects.filter(id__in=service_items).values('name', 'score', 'scoreType')
for item in items:
score_item_service[item['name']] = item['score'] if item['scoreType'] == 1 else -item['score']
elif rule['type'] == '业务类':
business_score = ScoreItems.objects.filter(id__in=rule['scoreItemIds']).aggregate(ss=Sum('score'))['ss']
business_items = list(set(rule['scoreItemIds']).intersection(set(score_item_ids)))
items = ScoreItems.objects.filter(id__in=business_items).values('name', 'score', 'scoreType')
for item in items:
score_item_business[item['name']] = item['score'] if item['scoreType'] == 1 else -item['score']
elif rule['type'] == '0分项':
zero_items = list(set(rule['scoreItemIds']).intersection(set(score_item_ids)))
items = ScoreItems.objects.filter(id__in=zero_items).values('name', 'score', 'scoreType')
for item in items:
score_item_zero[item['name']] = item['score'] if item['scoreType'] == 1 else -item['score']
return service_score, business_score, validate_zero, score_item_service, score_item_business, score_item_zero
def get_remain(check):
remain = 0
if check['startTime'] and check['closeTime']:
start = datetime.strptime(check['startTime'], '%Y-%m-%d %H:%M:%S').timestamp()
close = datetime.strptime(check['closeTime'], '%Y-%m-%d %H:%M:%S').timestamp()
remain = int(close - start)
return remain
def team_seat():
teams = Team.objects.values_list('id', 'name')
team_id_name = {team[0]: team[1] for team in teams}
seats = Seat.objects.values_list('code', 'team_id')
seat_code_team_name = {seat[0]: team_id_name[seat[1]] for seat in seats}
return seat_code_team_name
def single_rules_stat(t, create_date, stat_count=0):
if not RulesStat.objects.filter(taskId=t['id']).exists():
table_name = TABLE_PRE + t['sessionCollectionId']
tn = CheckSession.set_table(table_name)
session_condition = {'taskId': t['id'], 'violationRuleCount__gt': 0}
checks = tn.objects.filter(**session_condition).values('id', 'checkResult', 'agentName', 'customName', 'score',
'remainTime', 'startTime', 'closeTime', 'taskId',
'sessionId')
for check in checks:
result = check['checkResult']
if result:
rules_list = []
data = json.loads(result)
for d in data:
remain = get_remain(check)
if 'isViolation' in d.keys() and d['isViolation'] and 'rule' in d.keys() and 'name' in d['rule'].keys():
name = d['rule']['name']
rule_obj = {'create_date': create_date, 'sessionCollectionId': t['sessionCollectionId'],
'rule': name, 'rule_num': 1,
'task': team_seat().get(check['agentName'], '未找到团队'),
'agentName': check['agentName'], 'customName': check['customName'],
'score': check['score'], 'remainTime': remain,
'taskId': check['taskId'], 'sessionId': check['sessionId'],
'session_table_id': check['id']}
rules_list.append(RulesStat(**rule_obj))
stat_count += 1
logger.info('rule stat num: [%s]', stat_count)
RulesStat.objects.bulk_create(rules_list)
def single_seat_stat(t, create_date, stat_count=0):
if not SeatStat.objects.filter(taskId=t['id']).exists():
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', 'remainTime', 'startTime',
'closeTime', 'taskId', 'violationRuleCount')
seat_dict = {}
seat_list = []
for check in checks:
stat_count += 1
remain = get_remain(check)
if check['agentName'] in seat_dict.keys():
seat = seat_dict.get(check['agentName'])
seat['total_session'] += 1
seat['remainTime'] += remain
seat['validate_session'] += 1 if check['violationRuleCount'] > 0 else 0
else:
seat_dict[check['agentName']] = {'create_date': create_date, 'agentName': check['agentName'],
'taskId': check['taskId'],
'task': team_seat().get(check['agentName'], '未找到团队'),
'sessionCollectionId': t['sessionCollectionId'], 'total_session': 1}
seat_dict[check['agentName']]['validate_session'] = 1 if check['violationRuleCount'] > 0 else 0
seat_dict[check['agentName']]['remainTime'] = remain
for k, v in seat_dict.items():
seat_obj = {'agentName': k}
seat_obj.update(v)
seat_list.append(SeatStat(**seat_obj))
SeatStat.objects.bulk_create(seat_list)
def single_score_stat(t, create_date, stat_count=0):
if not ScoreStat.objects.filter(taskId=t['id']).exists():
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',
'startTime', 'score', 'scoreItemRecord')
seat_dict = {}
seat_list = []
service_s, business_s, vz, score_item_service, score_item_business, score_item_zero = get_inspect_rule(t)
for check in checks:
stat_count += 1
score_item = json.loads(check['scoreItemRecord'])
service_score = service_s
business_score = business_s
validate_zero = 0
for m in score_item:
if m['scoreItemName'] in score_item_service.keys():
service_score -= m['score']
if m['scoreItemName'] in score_item_business.keys():
business_score -= m['score']
if m['scoreItemName'] in score_item_zero.keys():
validate_zero += 1
if validate_zero > 0:
score = 0
else:
score = service_score + business_score
if check['agentName'] in seat_dict.keys():
seat = seat_dict.get(check['agentName'])
seat['total_session'] += 1
seat['validate_session'] += 1 if check['violationRuleCount'] > 0 else 0
seat['validate_num'] += len(score_item)
seat['score'] = round((seat['score'] + score) / 2, 2)
seat['service_score'] = round((seat['service_score'] + service_score) / 2, 2)
seat['business_score'] = round((seat['business_score'] + business_score) / 2, 2)
else:
seat_dict[check['agentName']] = {'create_date': create_date, 'agentName': check['agentName'],
'taskId': check['taskId'],
'task': team_seat().get(check['agentName'], '未找到团队'),
'sessionCollectionId': t['sessionCollectionId'], 'total_session': 1,
'score': score, 'service_score': service_score,
'business_score': business_score, 'validate_zero': validate_zero}
seat_dict[check['agentName']]['validate_session'] = 1 if check['violationRuleCount'] > 0 else 0
seat_dict[check['agentName']]['validate_num'] = len(score_item)
for k, v in seat_dict.items():
seat_obj = {'agentName': k}
seat_obj.update(v)
seat_list.append(ScoreStat(**seat_obj))
ScoreStat.objects.bulk_create(seat_list)
def re_stat_by_task(task):
single_rules_stat(task, task['updatedAt'], 0)
single_seat_stat(task, task['updatedAt'], 0)
single_score_stat(task, task['updatedAt'], 0)
def delete_stat_by_task(task):
RulesStat.objects.filter(taskId=task.id).delete()
SeatStat.objects.filter(taskId=task.id).delete()
ScoreStat.objects.filter(taskId=task.id).delete()
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