Merge remote-tracking branch 'origin/master'

This commit is contained in:
李伟 2022-07-26 11:02:53 +08:00
commit 56f8b39d43
10 changed files with 316 additions and 18 deletions

View File

@ -11,6 +11,7 @@ from .endpoints import query
from .endpoints import xquery from .endpoints import xquery
from .endpoints import interview from .endpoints import interview
from .endpoints import forms from .endpoints import forms
from .endpoints import worker_info
from .endpoints import data_auth from .endpoints import data_auth
from .endpoints import event_mana from .endpoints import event_mana
from .endpoints import test from .endpoints import test
@ -43,4 +44,5 @@ api_router.include_router(user_label.router, tags=["用户标签"], prefix='/use
api_router.include_router(interview.router, tags=["面试数据管理"], prefix='/itr') api_router.include_router(interview.router, tags=["面试数据管理"], prefix='/itr')
api_router.include_router(forms.router, tags=["hr报表模板管理"], prefix='/forms') api_router.include_router(forms.router, tags=["hr报表模板管理"], prefix='/forms')
api_router.include_router(worker_info.router, tags=["入职人员信息管理"], prefix='/worker')

View File

@ -8,6 +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
import crud, schemas import crud, schemas
from datetime import datetime from datetime import datetime
from core.configuration import * from core.configuration import *
@ -271,6 +272,8 @@ async def every_stage_form(
res = interview.get_every_stage_form_sql(job_ids) res = interview.get_every_stage_form_sql(job_ids)
sql = res['sql'] sql = res['sql']
data = await ck_db.execute(sql) data = await ck_db.execute(sql)
if not data:
return schemas.Msg(code=-9, msg='无数据', data=None)
for ck_data in data.values(): for ck_data in data.values():
# 职位id不存在跳过 # 职位id不存在跳过
if ck_data['job_id'] not in job_id_to_name: if ck_data['job_id'] not in job_id_to_name:
@ -304,6 +307,8 @@ async def hr_works_form(
res = interview.get_hr_works_form_sql() res = interview.get_hr_works_form_sql()
sql = res['sql'] sql = res['sql']
data = await ck_db.execute(sql) data = await ck_db.execute(sql)
if not data:
return schemas.Msg(code=-9, msg='无数据', data=None)
res_msg = {} res_msg = {}
job_name_sector = {} job_name_sector = {}
hr_names = [] # 查询面试数据 hr_names = [] # 查询面试数据
@ -437,6 +442,8 @@ async def stage_success_form(
res = interview.get_every_stage_form_sql(job_ids) res = interview.get_every_stage_form_sql(job_ids)
sql = res['sql'] sql = res['sql']
data = await ck_db.execute(sql) data = await ck_db.execute(sql)
if not data:
return schemas.Msg(code=-9, msg='无数据', data=None)
for ck_data in data.values(): for ck_data in data.values():
# 职位id不存在跳过 # 职位id不存在跳过
if ck_data['job_id'] not in job_id_to_name: if ck_data['job_id'] not in job_id_to_name:
@ -505,6 +512,8 @@ async def interview_funnel_form(
res = interview.get_hr_works_form_sql() res = interview.get_hr_works_form_sql()
sql = res['sql'] sql = res['sql']
data = await ck_db.execute(sql) data = await ck_db.execute(sql)
if not data:
return schemas.Msg(code=-9, msg='无数据', data=None)
res_msg = { res_msg = {
'初筛': 0, '初筛': 0,
'复筛': 0, '复筛': 0,
@ -543,6 +552,8 @@ async def owner_form(
res = interview.get_owner_form_sql() res = interview.get_owner_form_sql()
sql = res['sql'] sql = res['sql']
data = await db.execute(sql) data = await db.execute(sql)
if not data:
return schemas.Msg(code=-9, msg='无数据', data=None)
# 简历渠道 # 简历渠道
owner_dict = {1: '前程无忧', 2: '人才库', 3: '智联招聘', 4: 'Boss直聘', 5: '58同城'} owner_dict = {1: '前程无忧', 2: '人才库', 3: '智联招聘', 4: 'Boss直聘', 5: '58同城'}
chk_data = { chk_data = {
@ -597,3 +608,42 @@ async def owner_form(
return schemas.Msg(code=200, msg='ok', data=res_msg) return schemas.Msg(code=200, msg='ok', data=res_msg)
# 招聘趋势分析报表
@router.post("/interview_trend_form")
async def interview_trend_form(
request: Request,
interview: InterviewDo = Depends(InterviewDo),
ck_db: CKDrive = Depends(get_ck_db)
) -> schemas.Msg:
""" 招聘趋势分析报表 """
await interview.init()
res = interview.get_trend_form_sql()
sql = res['sql']
data = await ck_db.execute(sql)
if not data:
return schemas.Msg(code=-9, msg='无数据', data=None)
sdate = res['sdate']
edate = res['edate']
days = get_every_days(sdate, edate)
res_msg = {}
for i in days:
res_msg[str(i)] = {
'初筛简历数': 0,
'初筛': 0,
'创建面试的申请数': 0
}
for chk_data in data.values():
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']
if chk_stage >= 1:
res_msg[chk_date]['初筛简历数'] += 1 * count_num
if chk_stage >= 2:
res_msg[chk_date]['初筛'] += 1 * count_num
if chk_stage >= 3:
res_msg[chk_date]['创建面试的申请数'] += 1 * count_num
return schemas.Msg(code=200, msg='ok', data=res_msg)

View File

@ -0,0 +1,64 @@
import operator
import os
import re
import pandas as pd
from copy import deepcopy
from fastapi import APIRouter, Depends, Request, File, UploadFile
from motor.motor_asyncio import AsyncIOMotorDatabase
from utils.dingding import get_redis_alluid, send_dates
from utils.jianli import get_resume
import crud, schemas
from datetime import datetime
from core.configuration import *
from db import get_database
from db.ckdb import get_ck_db, CKDrive
from models.interview_zsgc import InterviewDo
from utils import get_time, qujian_time, Download_xlsx, send_str_mail
router = APIRouter()
# 增加入职人员
@router.post("/add_worker")
async def add_worker(
request: Request,
data_in: schemas.WorkerQuery,
db: AsyncIOMotorDatabase = Depends(get_database)
) -> schemas.Msg:
""" 增加入职人员信息 """
data = await crud.worker_info.insert_worker(db, data_in.data_in)
return schemas.Msg(code=200, msg='ok', data=data)
# 查询入职人员信息
@router.post("/find_worker")
async def add_worker(
request: Request,
data_in: schemas.WorkerQuery,
db: AsyncIOMotorDatabase = Depends(get_database)
) -> schemas.Msg:
""" 查询入职人员信息 """
data = await crud.worker_info.find_worker_some(db, findlist=data_in.find_filed)
return schemas.Msg(code=200, msg='ok', data=data)
# 修改入职人员信息
@router.post("/update_worker")
async def add_worker(
request: Request,
data_in: schemas.WorkerQuery,
db: AsyncIOMotorDatabase = Depends(get_database)
) -> schemas.Msg:
""" 修改入职人员信息 """
data = await crud.worker_info.update_worker(db, data_in.worker_query, data_in.data_in)
return schemas.Msg(code=200, msg='ok', data=data)

View File

@ -27,3 +27,4 @@ from .crud_interview_modes import api_interview_modes
from .crud_email_record import email_record from .crud_email_record import email_record
from .crud_operate_log import operate_log from .crud_operate_log import operate_log
from .crud_interview_record import interview_record from .crud_interview_record import interview_record
from .crud_worker_info import worker_info

34
crud/crud_worker_info.py Normal file
View File

@ -0,0 +1,34 @@
from motor.motor_asyncio import AsyncIOMotorDatabase
import schemas
from crud.base import CRUDBase
__all__ = 'worker_info',
class CRUDWorkerInfo(CRUDBase):
# 获取所有入职人员信息
async def all_worker(self, db: AsyncIOMotorDatabase):
return await self.find_many(db, {}, {'_id': 0})
# 获取指定字段
async def find_worker_some(self, db: AsyncIOMotorDatabase, findlist=[]):
findWhere = {'_id': 0}
if findlist:
for key in findlist:
findWhere.update({
key: 1
})
return await self.find_many(db, {}, findWhere)
# 更新一条入职人员信息
async def update_worker(self, db: AsyncIOMotorDatabase, where, updatedata):
await self.update_one(db, where, {'$set': updatedata})
# 插入一条新的面试数据数据
async def insert_worker(self, db: AsyncIOMotorDatabase, insertdata):
await self.insert_one(db, insertdata)
worker_info = CRUDWorkerInfo('worker_info')

View File

@ -412,9 +412,12 @@ class InterviewDo:
end_time = self.where.get('end_time', '') end_time = self.where.get('end_time', '')
sql = f"select {findStr} from HR.resumes where {whereStr}" sql = f"select {findStr} from HR.resumes where {whereStr}"
if start_time: if start_time:
sql += f" and toDate(event_time) >= {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: if end_time:
sql += f" and toDate(event_time) <= {end_time}" sql += f" and toDate(addHours(`event_time`, 0)) <= '{end_time}'"
# 没有日期条件 # 没有日期条件
else: else:
sql = f"select {findStr} from HR.resumes where {whereStr}" sql = f"select {findStr} from HR.resumes where {whereStr}"
@ -453,10 +456,15 @@ class InterviewDo:
sql = f"select {findStr} from HR.resumes where {whereStr}" sql = f"select {findStr} from HR.resumes where {whereStr}"
else: else:
sql = f"select {findStr} from HR.resumes" sql = f"select {findStr} from HR.resumes"
if start_time or end_time:
sql += f" where"
if start_time: if start_time:
sql += f" and toDate(event_time) >= {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: if end_time:
sql += f" and toDate(event_time) <= {end_time}" sql += f" and toDate(addHours(`event_time`, 0)) <= '{end_time}'"
# 没有日期条件 # 没有日期条件
else: else:
if whereStr: if whereStr:
@ -498,10 +506,15 @@ class InterviewDo:
sql = f"select {findStr} from HR.resumes where {whereStr}" sql = f"select {findStr} from HR.resumes where {whereStr}"
else: else:
sql = f"select {findStr} from HR.resumes where '1'" sql = f"select {findStr} from HR.resumes where '1'"
if start_time or end_time:
sql += f" where"
if start_time: if start_time:
sql += f" and toDate(event_time) >= {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: if end_time:
sql += f" and toDate(event_time) <= {end_time}" sql += f" and toDate(addHours(`event_time`, 0)) <= '{end_time}'"
# 没有日期条件 # 没有日期条件
else: else:
if whereStr: if whereStr:
@ -542,10 +555,15 @@ class InterviewDo:
sql = f"select {findStr} from HR.resumes where {whereStr} and job_id in {job_ids}" sql = f"select {findStr} from HR.resumes where {whereStr} and job_id in {job_ids}"
else: else:
sql = f"select {findStr} from HR.resumes where job_id in {job_ids}" sql = f"select {findStr} from HR.resumes where job_id in {job_ids}"
if start_time or end_time:
sql += f" where"
if start_time: if start_time:
sql += f" and toDate(event_time) >= {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: if end_time:
sql += f" and toDate(event_time) <= {end_time}" sql += f" and toDate(addHours(`event_time`, 0)) <= '{end_time}'"
# 没有日期条件 # 没有日期条件
else: else:
if whereStr: if whereStr:
@ -586,10 +604,15 @@ class InterviewDo:
sql = f"select {findStr} from HR.resumes where {whereStr}" sql = f"select {findStr} from HR.resumes where {whereStr}"
else: else:
sql = f"select {findStr} from HR.resumes" sql = f"select {findStr} from HR.resumes"
if start_time or end_time:
sql += f" where"
if start_time: if start_time:
sql += f" and toDate(event_time) >= {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: if end_time:
sql += f" and toDate(event_time) <= {end_time}" sql += f" and toDate(addHours(`event_time`, 0)) <= '{end_time}'"
# 没有日期条件 # 没有日期条件
else: else:
if whereStr: if whereStr:
@ -601,6 +624,52 @@ class InterviewDo:
'sql': sql 'sql': sql
} }
# 招聘趋势分析sql
def get_trend_form_sql(self):
whereStr = ''
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()
# 有日期条件
start_time = self.where.get('start_time', '')
end_time = self.where.get('end_time', '')
if is_date:
if whereStr:
sql = f"select toDate(addHours(`event_time`, 0)) as date,interview_stage, count() as value from HR.resumes where {whereStr}"
else:
sql = f"select toDate(addHours(`event_time`, 0)) as date,interview_stage, count() as value from HR.resumes"
if start_time or end_time:
sql += f" where"
if start_time:
if whereStr:
sql += f" and date >= '{start_time}'"
else:
sql += f" date >= '{start_time}'"
if end_time:
sql += f" and date <= '{end_time}'"
# 没有日期条件
else:
if whereStr:
sql = f"select toDate(addHours(`event_time`, 0)) as date,interview_stage, count() as value from HR.resumes where {whereStr}"
else:
sql = f"select toDate(addHours(`event_time`, 0)) as date,interview_stage, count() as value from HR.resumes"
sql += f" group by date, interview_stage"
print(sql)
return {
'sql': sql,
'sdate': start_time,
'edate': end_time,
}
if __name__ == '__main__': if __name__ == '__main__':
find = re.search(r"\d+\.?\d*", "18岁") find = re.search(r"\d+\.?\d*", "18岁")

View File

@ -33,3 +33,4 @@ from .email_record import *
from .operate_log import * from .operate_log import *
from .interview_modes import * from .interview_modes import *
from .interview_record import * from .interview_record import *
from .worker import *

14
schemas/worker.py Normal file
View File

@ -0,0 +1,14 @@
from typing import Dict, List, Union, Any
from pydantic import BaseModel
# 面试数据包含字段样式
class WorkerModel(BaseModel):
pass
# 面试查询格式
class WorkerQuery(BaseModel):
data_in: Any
worker_query: dict = dict() # 查询删选条件
find_filed: List[str] = None # 显示列名

View File

@ -280,3 +280,17 @@ def start_end_month(time):
this_month_end = datetime.datetime(now.year, now.month, calendar.monthrange(now.year, now.month)[1]) this_month_end = datetime.datetime(now.year, now.month, calendar.monthrange(now.year, now.month)[1])
this_month_end1 = this_month_end + timedelta(hours=23, minutes=59, seconds=59) this_month_end1 = this_month_end + timedelta(hours=23, minutes=59, seconds=59)
return this_month_start, this_month_end1 return this_month_start, this_month_end1
# 获取两个日期之间的所有天数
def get_every_days(sdate, edate):
days = []
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
for i in range(day_num + 1):
day = start_date + timedelta(days=i)
true_day = datetime.datetime.strftime(day, '%Y-%m-%d')
days.append(true_day)
return days

View File

@ -0,0 +1,49 @@
路由: /api/v1/itr/interview_trend_form
参数:
{
"data_in": "string", 可为空字符串 ""
"interview_query": {"start_time":"2022-07-10", "end_time":"2022-07-15"}, 条件查询区间 开始结束时间 "年-月-日"格式字符串
"find_column": [ 可为空列表[]
"string"
]
}
返回值:
{
"code": 200,
"msg": "ok",
"data": { 日期对应的数据
"2022-07-10": {
"初筛简历数": 0,
"初筛": 0,
"创建面试的申请数": 0
},
"2022-07-11": {
"初筛简历数": 0,
"初筛": 0,
"创建面试的申请数": 0
},
"2022-07-12": {
"初筛简历数": 2,
"初筛": 2,
"创建面试的申请数": 2
},
"2022-07-13": {
"初筛简历数": 0,
"初筛": 0,
"创建面试的申请数": 0
},
"2022-07-14": {
"初筛简历数": 0,
"初筛": 0,
"创建面试的申请数": 0
},
"2022-07-15": {
"初筛简历数": 0,
"初筛": 0,
"创建面试的申请数": 0
}
}
}