渠道质量,阶段数据

This commit is contained in:
Àî×ÚÕñ 2022-07-21 17:06:39 +08:00
parent bd1523b5c4
commit db6dcc91de
6 changed files with 324 additions and 13 deletions

View File

@ -2,6 +2,7 @@ import operator
import os import os
import re import re
import pandas as pd import pandas as pd
from copy import deepcopy
from fastapi import APIRouter, Depends, Request, File, UploadFile from fastapi import APIRouter, Depends, Request, File, UploadFile
from motor.motor_asyncio import AsyncIOMotorDatabase from motor.motor_asyncio import AsyncIOMotorDatabase
@ -21,12 +22,12 @@ router = APIRouter()
# 候选人质量报表 # 候选人质量报表
@router.post("/man_mass_form") @router.post("/man_mass_form")
async def interview_find( async def man_mass_form(
request: Request, request: Request,
interview: InterviewDo = Depends(InterviewDo), interview: InterviewDo = Depends(InterviewDo),
db: CKDrive = Depends(get_ck_db), db: CKDrive = Depends(get_ck_db),
) -> schemas.Msg: ) -> schemas.Msg:
""" interview面试数据查询 """ """ 候选人质量报表 """
await interview.init() await interview.init()
res = interview.get_man_mass_form_sql() res = interview.get_man_mass_form_sql()
sql = res['sql'] sql = res['sql']
@ -171,7 +172,7 @@ async def interview_find(
else: else:
work_exp['20-40'].append(i_name) work_exp['20-40'].append(i_name)
i_job_name = interview_data.get('job_name', '') i_job_name = interview_data.get('job_names', '')
if i_job_name: if i_job_name:
if i_job_name in account: if i_job_name in account:
job_name[i_job_name].append(i_name) job_name[i_job_name].append(i_name)
@ -210,3 +211,122 @@ async def interview_find(
return schemas.Msg(code=200, msg='ok', data=res_msg) return schemas.Msg(code=200, msg='ok', data=res_msg)
# 职位阶段数据报表
@router.post("/get_every_stage_form")
async def owner_form(
request: Request,
interview: InterviewDo = Depends(InterviewDo),
ck_db: CKDrive = Depends(get_ck_db),
db: AsyncIOMotorDatabase = Depends(get_database)
) -> schemas.Msg:
""" 职位阶段数据报表 """
all_jobs = await crud.jobs.all_some_field(db)
res_msg = {}
job_id_to_name = {}
job_ids = []
for job_data in all_jobs:
job_id = job_data['job_id']
job_ids.append(job_id)
job_name = job_data['job_name']
job_id_to_name[job_id] = job_name
res_job_data = deepcopy({k: v for k, v in job_data.items() if k != 'job_id'})
res_job_data.update({
'初筛': 0,
'复筛': 0,
'面试': 0,
'offer': 0,
'待入职': 0,
'已入职': job_data['now_job_num'],
})
res_msg[job_name] = res_job_data
await interview.init()
res = interview.get_every_stage_form_sql(job_ids)
sql = res['sql']
data = await ck_db.execute(sql)
for ck_data in data.values():
# 职位id不存在跳过
if ck_data['job_id'] not in job_id_to_name:
continue
ck_job_name = job_id_to_name[ck_data['job_id']]
stage = ck_data['interview_stage']
if stage == 1:
res_msg[ck_job_name]['初筛'] += 1
elif stage == 2:
res_msg[ck_job_name]['复筛'] += 1
elif stage == 3:
res_msg[ck_job_name]['面试'] += 1
elif stage == 4:
res_msg[ck_job_name]['offer'] += 1
elif stage == 5:
res_msg[ck_job_name]['待入职'] += 1
return schemas.Msg(code=200, msg='ok', data=res_msg)
# 每个阶段报表
@router.post("/get_owner_form")
async def owner_form(
request: Request,
interview: InterviewDo = Depends(InterviewDo),
db: CKDrive = Depends(get_ck_db),
) -> schemas.Msg:
""" 渠道质量报表 """
await interview.init()
res = interview.get_owner_form_sql()
sql = res['sql']
data = await db.execute(sql)
# 简历渠道
owner_dict = {1: '前程无忧', 2: '人才库', 3: '智联招聘', 4: 'Boss直聘', 5: '58同城'}
chk_data = {
'前程无忧': [],
'人才库': [],
'智联招聘': [],
'Boss直聘': [],
'58同城': [],
}
for i in data.values():
owner_name = owner_dict[i['owner_name']]
i_data = deepcopy(i)
chk_data[owner_name].append(i_data)
res_msg = {
'前程无忧': {
'count': 0
},
'人才库': {
'count': 0
},
'智联招聘': {
'count': 0
},
'Boss直聘': {
'count': 0
},
'58同城': {
'count': 0
},
}
for key, data_list in chk_data.items():
count_num = len(data_list)
offer_num = len([1 for i in data_list if i['interview_stage'] >= 5])
work_num = len([1 for i in data_list if i['interview_stage'] >= 7])
if offer_num:
offer_chance = round(offer_num / count_num, 2)
else:
offer_chance = 0
if work_num:
work_chance = round(work_num / count_num, 2)
else:
work_chance = 0
res_msg[key]['count'] = count_num
res_msg[key]['offer_num'] = offer_num
res_msg[key]['work_num'] = work_num
res_msg[key]['offer_chance'] = offer_chance
res_msg[key]['work_chance'] = work_chance
return schemas.Msg(code=200, msg='ok', data=res_msg)

View File

@ -8,7 +8,12 @@ __all__ = 'jobs',
class CRUDJobs(CRUDBase): class CRUDJobs(CRUDBase):
# 获取所有对应职位字段的数据 # 获取所有对应职位字段的数据
async def all_field(self, db: AsyncIOMotorDatabase): async def all_field(self, db: AsyncIOMotorDatabase):
return await self.find_many(db, {}) return await self.find_many(db, {}, {'_id': 0})
# 获取所有对应职位指定字段的数据
async def all_some_field(self, db: AsyncIOMotorDatabase):
return await self.find_many(db, {}, {'_id': 0, 'job_id': 1, 'job_sector': 1, 'principal': 1, 'job_num': 1,
'start_time': 1, 'now_job_num': 1, 'job_name': 1})
# 获取所有对应条件职位字段的数据 # 获取所有对应条件职位字段的数据
async def all_fields(self, db: AsyncIOMotorDatabase, data_in: schemas.Jobs): async def all_fields(self, db: AsyncIOMotorDatabase, data_in: schemas.Jobs):

View File

@ -424,6 +424,94 @@ class InterviewDo:
'sql': sql 'sql': sql
} }
# 渠道质量sql
def get_owner_form_sql(self):
findStr = ''
whereStr = ''
# 查询字段
self.find_column = ["name", "owner_name", "interview_stage"]
for fstr in self.find_column:
findStr += fstr + ', '
is_date = 0
if self.where:
for key, value in self.where.items():
if key in ['start_time', 'end_time']:
is_date = 1
continue
if isinstance(value, str):
whereStr += str(key) + ' = ' + "'" + value + "'" + ' '
continue
whereStr += str(key) + ' = ' + str(value) + ' '
whereStr = whereStr.strip()
findStr = findStr.strip().strip(',')
# 有日期条件
if is_date:
start_time = self.where.get('start_time', '')
end_time = self.where.get('end_time', '')
if whereStr:
sql = f"select {findStr} from HR.resumes where {whereStr}"
else:
sql = f"select {findStr} from HR.resumes where '1'"
if start_time:
sql += f" and toDate(event_time) >= `{start_time}`"
if end_time:
sql += f" and toDate(event_time) <= `{end_time}`"
# 没有日期条件
else:
if whereStr:
sql = f"select {findStr} from HR.resumes where {whereStr}"
else:
sql = f"select {findStr} from HR.resumes"
print(sql)
return {
'sql': sql
}
# 渠道质量sql
def get_every_stage_form_sql(self, job_ids):
findStr = ''
whereStr = ''
# 查询字段
self.find_column = ["name", "interview_stage", "job_id"]
for fstr in self.find_column:
findStr += fstr + ', '
is_date = 0
if self.where:
for key, value in self.where.items():
if key in ['start_time', 'end_time']:
is_date = 1
continue
if isinstance(value, str):
whereStr += str(key) + ' = ' + "'" + value + "'" + ' '
continue
whereStr += str(key) + ' = ' + str(value) + ' '
whereStr = whereStr.strip()
findStr = findStr.strip().strip(',')
# 有日期条件
if is_date:
start_time = self.where.get('start_time', '')
end_time = self.where.get('end_time', '')
if whereStr:
sql = f"select {findStr} from HR.resumes where {whereStr} and job_id in {job_ids}"
else:
sql = f"select {findStr} from HR.resumes where job_id in {job_ids}"
if start_time:
sql += f" and toDate(event_time) >= `{start_time}`"
if end_time:
sql += f" and toDate(event_time) <= `{end_time}`"
# 没有日期条件
else:
if whereStr:
sql = f"select {findStr} from HR.resumes where {whereStr} and job_id in {job_ids}"
else:
sql = f"select {findStr} from HR.resumes where job_id in {job_ids}"
print(sql)
return {
'sql': sql
}
if __name__ == '__main__': if __name__ == '__main__':
find = re.search(r"\d+\.?\d*", "18岁") find = re.search(r"\d+\.?\d*", "18岁")

View File

@ -2,10 +2,9 @@
参数: 参数:
{ {
"data_in": "string", "data_in": "",
"interview_query": {"hr_name":"Îâ²Ù"}, "interview_query": {"hr_name":"吴操"}, # 对应hr的名字
"find_column": [ "find_column": [
"string"
] ]
} }

View File

@ -0,0 +1,53 @@
路由: /api/v1/forms/get_owner_form
参数:
{
"data_in": "", # 参数可都为空
"interview_query": {},
"find_column": [
]
}
返回值:
{
"code": 200,
"msg": "ok",
"data": {
"前程无忧": {
"count": 0, # 渠道简历总数
"offer_num": 0, # 进入offer阶段数量 # 下同
"work_num": 0, # 进入入职阶段数量
"offer_chance": 0, # offer率
"work_chance": 0 # 入职率
},
"人才库": {
"count": 2,
"offer_num": 2,
"work_num": 1,
"offer_chance": 1,
"work_chance": 0.5
},
"智联招聘": {
"count": 0,
"offer_num": 0,
"work_num": 0,
"offer_chance": 0,
"work_chance": 0
},
"Boss直聘": {
"count": 0,
"offer_num": 0,
"work_num": 0,
"offer_chance": 0,
"work_chance": 0
},
"58同城": {
"count": 0,
"offer_num": 0,
"work_num": 0,
"offer_chance": 0,
"work_chance": 0
}
}
}

View File

@ -0,0 +1,46 @@
路由: /api/v1/forms/get_owner_form
参数:
{
"data_in": "", # 参数可都为空
"interview_query": {},
"find_column": [
]
}
返回值:
{
"code": 200,
"msg": "ok",
"data": {
"高级游戏测试工程师": { # 职位对应的数据
"job_name": "高级游戏测试工程师", # 职位名
"job_sector": "研发部", # 部门
"principal": "a负责人", # 负责人
"start_time": "2021-08-23T11:41:54.563000", # 招聘开始时间
"job_num": 3, # 招聘人数
"now_job_num": 14, # 已入职人数
"初筛": 0,
"复筛": 0,
"面试": 0,
"offer": 0,
"待入职": 0,
"已入职": 14
},
"python开发": {
"job_name": "python开发",
"job_sector": "平台部",
"principal": "李",
"start_time": "2022-06-06T10:51:44.223000",
"job_num": 6,
"now_job_num": 0,
"初筛": 0,
"复筛": 0,
"面试": 0,
"offer": 0,
"待入职": 0,
"已入职": 0
}
}
}