入离职
This commit is contained in:
parent
b993f3251e
commit
9eef1571bd
@ -8,7 +8,7 @@ from motor.motor_asyncio import AsyncIOMotorDatabase
|
||||
|
||||
from utils.dingding import get_redis_alluid, send_dates
|
||||
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
|
||||
from datetime import datetime
|
||||
from core.configuration import *
|
||||
@ -778,11 +778,132 @@ async def year_trend_form(
|
||||
res_msg[chk_date]['入职人数'] += 1 * count_num
|
||||
if chk_stage >= 8:
|
||||
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
|
||||
if chk_stage >= 10:
|
||||
if chk_stage == 10:
|
||||
res_msg[chk_date]['离职人数'] += 1 * count_num
|
||||
res_msg[chk_date]['被动离职'] += 1 * count_num
|
||||
|
||||
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)
|
||||
|
@ -51,8 +51,8 @@ class CRUDJobs(CRUDBase):
|
||||
# 获取对应job_id的名字,以及部门, 招聘数量
|
||||
async def find_job_some(self, db: AsyncIOMotorDatabase, 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,
|
||||
'principal': 1})
|
||||
{'_id': 0, 'job_name': 1, 'job_sector': 1, 'job_num': 1, 'job_id': 1,
|
||||
'principal': 1})
|
||||
|
||||
|
||||
jobs = CRUDJobs('jobs')
|
||||
|
@ -609,11 +609,11 @@ class InterviewDo:
|
||||
sql += f" where"
|
||||
if start_time:
|
||||
if whereStr:
|
||||
sql += f" and date >= '{start_time}'"
|
||||
sql += f" and toDate(addHours(`event_time`, 0)) >= '{start_time}'"
|
||||
else:
|
||||
sql += f" date >= '{start_time}'"
|
||||
sql += f" toDate(addHours(`event_time`, 0)) >= '{start_time}'"
|
||||
if end_time:
|
||||
sql += f" and date <= '{end_time}'"
|
||||
sql += f" and toDate(addHours(`event_time`, 0)) <= '{end_time}'"
|
||||
# 没有日期条件
|
||||
else:
|
||||
if whereStr:
|
||||
@ -704,11 +704,11 @@ class InterviewDo:
|
||||
sql += f" where"
|
||||
if start_time:
|
||||
if whereStr:
|
||||
sql += f" and date >= '{start_time}'"
|
||||
sql += f" and toDate(addHours(`event_time`, 0)) >= '{start_time}'"
|
||||
else:
|
||||
sql += f" date >= '{start_time}'"
|
||||
sql += f" toDate(addHours(`event_time`, 0)) >= '{start_time}'"
|
||||
if end_time:
|
||||
sql += f" and date <= '{end_time}'"
|
||||
sql += f" and toDate(addHours(`event_time`, 0)) <= '{end_time}'"
|
||||
# 没有日期条件
|
||||
else:
|
||||
if whereStr:
|
||||
@ -723,6 +723,108 @@ class InterviewDo:
|
||||
'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__':
|
||||
col = 'max_interview_stage'
|
||||
|
@ -1,6 +1,7 @@
|
||||
import random
|
||||
import time
|
||||
import datetime
|
||||
from math import ceil
|
||||
import pandas as pd
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText
|
||||
@ -307,5 +308,32 @@ def get_every_months(sdate, edate):
|
||||
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__':
|
||||
get_every_months('2022-01-01', '2022-12-31')
|
||||
|
110
接口文档/各岗位招聘数据接口文档.txt
Normal file
110
接口文档/各岗位招聘数据接口文档.txt
Normal 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": "研发部"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
39
接口文档/年度入离职数据接口文档.txt
Normal file
39
接口文档/年度入离职数据接口文档.txt
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user