入离职

This commit is contained in:
Àî×ÚÕñ 2022-07-27 16:54:15 +08:00
parent b993f3251e
commit 9eef1571bd
6 changed files with 411 additions and 11 deletions

View File

@ -8,7 +8,7 @@ from motor.motor_asyncio import AsyncIOMotorDatabase
from utils.dingding import get_redis_alluid, send_dates from utils.dingding import get_redis_alluid, send_dates
from utils.jianli import get_resume from utils.jianli import get_resume
from utils.func import get_every_days, get_every_months from utils.func import get_every_days, get_every_weeks, get_every_months
import crud, schemas import crud, schemas
from datetime import datetime from datetime import datetime
from core.configuration import * from core.configuration import *
@ -778,11 +778,132 @@ async def year_trend_form(
res_msg[chk_date]['入职人数'] += 1 * count_num res_msg[chk_date]['入职人数'] += 1 * count_num
if chk_stage >= 8: if chk_stage >= 8:
res_msg[chk_date]['转正人数'] += 1 * count_num res_msg[chk_date]['转正人数'] += 1 * count_num
if chk_stage >= 9: if chk_stage == 9:
res_msg[chk_date]['离职人数'] += 1 * count_num res_msg[chk_date]['离职人数'] += 1 * count_num
res_msg[chk_date]['主动离职'] += 1 * count_num res_msg[chk_date]['主动离职'] += 1 * count_num
if chk_stage >= 10: if chk_stage == 10:
res_msg[chk_date]['离职人数'] += 1 * count_num res_msg[chk_date]['离职人数'] += 1 * count_num
res_msg[chk_date]['被动离职'] += 1 * count_num res_msg[chk_date]['被动离职'] += 1 * count_num
return schemas.Msg(code=200, msg='ok', data=res_msg) return schemas.Msg(code=200, msg='ok', data=res_msg)
# 年度岗位招聘数据报表
@router.post("/year_job_form")
async def year_job_form(
request: Request,
interview: InterviewDo = Depends(InterviewDo),
ck_db: CKDrive = Depends(get_ck_db),
db: AsyncIOMotorDatabase = Depends(get_database)
) -> schemas.Msg:
""" 岗位招聘数据分析报表 """
await interview.init()
res = interview.year_job_form_sql()
sql = res['sql']
data = await ck_db.execute(sql)
if not data:
return schemas.Msg(code=-9, msg='无数据', data=None)
# 取出job和部门
job_ids = set([j_data['job_id'] for j_data in data.values()])
job_ids = list(job_ids)
job_datas = await crud.jobs.find_job_some(db, job_ids)
job_dict = {job['job_id']: {'name': job['job_name'], 'sector': job['job_sector']} for job in job_datas}
sdate = res['sdate']
edate = res['edate']
chk_type = res['chk_type']
if chk_type == 'day':
months = get_every_days(sdate, edate)
elif chk_type == 'week':
months = get_every_weeks(sdate, edate)
else:
months = get_every_months(sdate, edate)
res_msg = {}
for i in months:
res_msg[str(i)] = {}
for job_id in job_ids:
res_msg[str(i)][job_id] = {
'简历推荐数': 0,
'有效简历数': 0,
'到场面试数': 0,
'面试通过': 0,
'offer发出数': 0,
'入职人数': 0,
'离职人数': 0
}
for chk_data in data.values():
if chk_type == 'month':
chk_date = datetime.strftime(chk_data['date'], '%Y-%m')
else:
chk_date = datetime.strftime(chk_data['date'], '%Y-%m-%d')
if chk_date not in res_msg:
continue
chk_stage = chk_data['interview_stage']
count_num = chk_data['value']
chk_job_id = chk_data['job_id']
if chk_stage >= 1:
res_msg[chk_date][chk_job_id]['简历推荐数'] += 1 * count_num
if chk_stage >= 2:
res_msg[chk_date][chk_job_id]['有效简历数'] += 1 * count_num
if chk_stage >= 3:
res_msg[chk_date][chk_job_id]['到场面试数'] += 1 * count_num
if chk_stage >= 4:
res_msg[chk_date][chk_job_id]['面试通过'] += 1 * count_num
if chk_stage >= 5:
res_msg[chk_date][chk_job_id]['offer发出数'] += 1 * count_num
if chk_stage >= 7:
res_msg[chk_date][chk_job_id]['入职人数'] += 1 * count_num
if chk_stage >= 9:
res_msg[chk_date][chk_job_id]['离职人数'] += 1 * count_num
res_data = {
'res_msg': res_msg,
'job_data': job_dict
}
return schemas.Msg(code=200, msg='ok', data=res_data)
# 年度入离职数据报表
@router.post("/year_in_out")
async def year_in_out(
request: Request,
interview: InterviewDo = Depends(InterviewDo),
ck_db: CKDrive = Depends(get_ck_db)
) -> schemas.Msg:
""" 年度入离职数据报表 """
await interview.init()
res = interview.year_in_out_sql()
sql_in = res['sql_in']
sql_out = res['sql_out']
data_in = await ck_db.execute(sql_in)
data_out = await ck_db.execute(sql_out)
if not data_in and data_out:
return schemas.Msg(code=-9, msg='无数据', data=None)
sdate = res['sdate']
edate = res['edate']
months = get_every_months(sdate, edate)
res_msg = {
'入职': {},
'离职': {}
}
for i in months:
res_msg['入职'][str(i)] = 0
res_msg['离职'][str(i)] = 0
# 入职数据处理
for in_data in data_in.values():
in_date = datetime.strftime(in_data['date'], '%Y-%m')
if in_date not in res_msg['入职']:
continue
value = in_data['value']
res_msg['入职'][in_date] += value
# 离职数据处理
for out_data in data_out.values():
out_date = datetime.strftime(out_data['date'], '%Y-%m')
if out_date not in res_msg['离职']:
continue
value = out_data['value']
res_msg['离职'][out_date] += value
return schemas.Msg(code=200, msg='ok', data=res_msg)

View File

@ -51,8 +51,8 @@ class CRUDJobs(CRUDBase):
# 获取对应job_id的名字,以及部门, 招聘数量 # 获取对应job_id的名字,以及部门, 招聘数量
async def find_job_some(self, db: AsyncIOMotorDatabase, job_ids): async def find_job_some(self, db: AsyncIOMotorDatabase, job_ids):
return await self.find_many(db, {'job_id': {"$in": job_ids}}, return await self.find_many(db, {'job_id': {"$in": job_ids}},
{'_id': 0, 'job_name': 1, 'job_sector': 1, 'job_num': 1, 'job_id': 1, {'_id': 0, 'job_name': 1, 'job_sector': 1, 'job_num': 1, 'job_id': 1,
'principal': 1}) 'principal': 1})
jobs = CRUDJobs('jobs') jobs = CRUDJobs('jobs')

View File

@ -609,11 +609,11 @@ class InterviewDo:
sql += f" where" sql += f" where"
if start_time: if start_time:
if whereStr: if whereStr:
sql += f" and date >= '{start_time}'" sql += f" and toDate(addHours(`event_time`, 0)) >= '{start_time}'"
else: else:
sql += f" date >= '{start_time}'" sql += f" toDate(addHours(`event_time`, 0)) >= '{start_time}'"
if end_time: if end_time:
sql += f" and date <= '{end_time}'" sql += f" and toDate(addHours(`event_time`, 0)) <= '{end_time}'"
# 没有日期条件 # 没有日期条件
else: else:
if whereStr: if whereStr:
@ -704,11 +704,11 @@ class InterviewDo:
sql += f" where" sql += f" where"
if start_time: if start_time:
if whereStr: if whereStr:
sql += f" and date >= '{start_time}'" sql += f" and toDate(addHours(`event_time`, 0)) >= '{start_time}'"
else: else:
sql += f" date >= '{start_time}'" sql += f" toDate(addHours(`event_time`, 0)) >= '{start_time}'"
if end_time: if end_time:
sql += f" and date <= '{end_time}'" sql += f" and toDate(addHours(`event_time`, 0)) <= '{end_time}'"
# 没有日期条件 # 没有日期条件
else: else:
if whereStr: if whereStr:
@ -723,6 +723,108 @@ class InterviewDo:
'edate': end_time, 'edate': end_time,
} }
# 年度招聘数据sql
def year_job_form_sql(self):
whereStr = ''
is_date = 0
if self.where:
for key, value in self.where.items():
if key in ['start_time', 'end_time', 'chk_type']:
is_date = 1
continue
if isinstance(value, str):
whereStr += str(key) + ' = ' + "'" + value + "'" + ' '
continue
whereStr += str(key) + ' = ' + str(value) + ' '
whereStr = whereStr.strip()
# 有日期条件
start_time = self.where.get('start_time', '')
end_time = self.where.get('end_time', '')
chk_type = self.where.get('chk_type', 'day')
if chk_type == 'day':
select_str = f"toDate(addHours(`event_time`, 0))"
if chk_type == 'week':
select_str = f"toStartOfWeek(addHours(`event_time`, 0))"
if chk_type == 'month':
select_str = f"toStartOfMonth(addHours(`event_time`, 0))"
if is_date:
if whereStr:
sql = f"select {select_str} as date,interview_stage, job_id, count() as value from HR.resumes where {whereStr}"
else:
sql = f"select {select_str} as date,interview_stage, job_id, count() as value from HR.resumes"
if start_time or end_time:
sql += f" where"
if start_time:
if whereStr:
sql += f" and toDate(addHours(`event_time`, 0)) >= '{start_time}'"
else:
sql += f" toDate(addHours(`event_time`, 0)) >= '{start_time}'"
if end_time:
sql += f" and toDate(addHours(`event_time`, 0)) <= '{end_time}'"
# 没有日期条件
else:
if whereStr:
sql = f"select {select_str} as date,interview_stage, job_id, count() as value from HR.resumes where {whereStr}"
else:
sql = f"select {select_str} as date,interview_stage, job_id, count() as value from HR.resumes"
sql += f" group by date, interview_stage, job_id"
print(sql)
return {
'sql': sql,
'sdate': start_time,
'edate': end_time,
'chk_type': chk_type,
}
# 年度入离值数据sql
def year_in_out_sql(self):
whereStr = ''
if self.where:
for key, value in self.where.items():
if key in ['start_time', 'end_time']:
continue
if isinstance(value, str):
whereStr += str(key) + ' = ' + "'" + value + "'" + ' '
continue
whereStr += str(key) + ' = ' + str(value) + ' '
whereStr = whereStr.strip()
# 有日期条件
start_time = self.where.get('start_time', '')
end_time = self.where.get('end_time', '')
select_in_str = f"toStartOfMonth(addHours(`in_time`, 0))"
select_out_str = f"toStartOfMonth(addHours(`out_time`, 0))"
if whereStr:
sql_in = f"select {select_in_str} as date, count() as value from HR.resumes where {whereStr}"
sql_out = f"select {select_out_str} as date, count() as value from HR.resumes where {whereStr}"
else:
sql_in = f"select {select_in_str} as date, count() as value from HR.resumes"
sql_out = f"select {select_out_str} as date, count() as value from HR.resumes"
if start_time or end_time:
sql_in += f" where"
sql_out += f" where"
if start_time:
if whereStr:
sql_in += f" and toDate(addHours(`in_time`, 0)) >= '{start_time}'"
sql_out += f" and toDate(addHours(`out_time`, 0)) >= '{start_time}'"
else:
sql_in += f" toDate(addHours(`in_time`, 0)) >= '{start_time}'"
sql_out += f" toDate(addHours(`out_time`, 0)) >= '{start_time}'"
if end_time:
sql_in += f" and toDate(addHours(`in_time`, 0)) <= '{end_time}'"
sql_out += f" and toDate(addHours(`out_time`, 0)) <= '{end_time}'"
sql_in += f" group by date"
sql_out += f" group by date"
print(sql_in, sql_out)
return {
'sql_in': sql_in,
'sql_out': sql_out,
'sdate': start_time,
'edate': end_time,
}
if __name__ == '__main__': if __name__ == '__main__':
col = 'max_interview_stage' col = 'max_interview_stage'

View File

@ -1,6 +1,7 @@
import random import random
import time import time
import datetime import datetime
from math import ceil
import pandas as pd import pandas as pd
import smtplib import smtplib
from email.mime.text import MIMEText from email.mime.text import MIMEText
@ -307,5 +308,32 @@ def get_every_months(sdate, edate):
return month_range return month_range
# 获取两个日期之间所有的周日日期
def get_every_weeks(sdate, edate):
start_date = datetime.datetime.strptime(sdate, '%Y-%m-%d')
end_date = datetime.datetime.strptime(edate, '%Y-%m-%d')
different_day = end_date - start_date
day_num = different_day.days
weeks = int(ceil(day_num / 7))
week_days = []
# 当前周的周末的日期
start_day = get_current_week(start_date)
for i in range(weeks + 1):
day = start_day + timedelta(days=i * 7)
true_day = datetime.datetime.strftime(day, '%Y-%m-%d')
week_days.append(true_day)
return week_days
# 获取当前日期的周日日期
def get_current_week(s_date):
sunday = s_date
one_day = datetime.timedelta(days=1)
while sunday.weekday() != 6:
sunday += one_day
return sunday
if __name__ == '__main__': if __name__ == '__main__':
get_every_months('2022-01-01', '2022-12-31') get_every_months('2022-01-01', '2022-12-31')

View File

@ -0,0 +1,110 @@
路由: /api/v1/forms/year_job_form
参数:
{
"data_in": "string", # 传''
"interview_query": { # 查询条件
"start_time":"2022-07-10", # 查询区间开始时间 格式固定年-月-日字符串
"end_time":"2022-07-27",
"chk_type":"week" # 'day'表示按天, 'week'表示按周, 'month'表示按月 不传值默认按月
},
"find_column": [ # 传[]
"string"
]
}
返回值:
{
"code": 200,
"msg": "ok",
"data": {
"res_msg": { # 解析数据
"2022-07-10": { # 对应条件下的分组日期
"123": { # job_id
"简历推荐数": 1, # 对应job_id对应的分析数据
"有效简历数": 1,
"到场面试数": 1,
"面试通过": 1,
"offer发出数": 1,
"入职人数": 0,
"离职人数": 0
},
"123456": {
"简历推荐数": 15,
"有效简历数": 14,
"到场面试数": 14,
"面试通过": 13,
"offer发出数": 13,
"入职人数": 2,
"离职人数": 1
}
},
"2022-07-17": {
"123": {
"简历推荐数": 0,
"有效简历数": 0,
"到场面试数": 0,
"面试通过": 0,
"offer发出数": 0,
"入职人数": 0,
"离职人数": 0
},
"123456": {
"简历推荐数": 3,
"有效简历数": 3,
"到场面试数": 3,
"面试通过": 3,
"offer发出数": 3,
"入职人数": 2,
"离职人数": 2
}
},
"2022-07-24": {
"123": {
"简历推荐数": 0,
"有效简历数": 0,
"到场面试数": 0,
"面试通过": 0,
"offer发出数": 0,
"入职人数": 0,
"离职人数": 0
},
"123456": {
"简历推荐数": 0,
"有效简历数": 0,
"到场面试数": 0,
"面试通过": 0,
"offer发出数": 0,
"入职人数": 0,
"离职人数": 0
}
},
"2022-07-31": {
"123": {
"简历推荐数": 0,
"有效简历数": 0,
"到场面试数": 0,
"面试通过": 0,
"offer发出数": 0,
"入职人数": 0,
"离职人数": 0
},
"123456": {
"简历推荐数": 0,
"有效简历数": 0,
"到场面试数": 0,
"面试通过": 0,
"offer发出数": 0,
"入职人数": 0,
"离职人数": 0
}
}
},
"job_data": { # job_id对应的名字,所属部门信息
"123": {
"name": "高级游戏测试工程师",
"sector": "研发部"
}
}
}
}

View File

@ -0,0 +1,39 @@
路由: /api/v1/forms/year_in_out
参数:
{
"data_in": "string", # 传''
"interview_query": { # 查询条件
"start_time":"2022-01-01", # 查询区间开始时间 格式固定年-月-日字符串
"end_time":"2022-07-27",
},
"find_column": [ # 传[]
"string"
]
}
返回值:
{
"code": 200,
"msg": "ok",
"data": {
"入职": { # 入职对应数据
"2022-01": 0, # 月份对应人数
"2022-02": 2,
"2022-03": 1,
"2022-04": 1,
"2022-05": 1,
"2022-06": 1,
"2022-07": 0
},
"离职": {
"2022-01": 0,
"2022-02": 0,
"2022-03": 1,
"2022-04": 0,
"2022-05": 1,
"2022-06": 2,
"2022-07": 2
}
}
}