().Where(x => x.TableName == id.ObjToString()).ToListAsync();
var statements = await _ghrh_ResumeStatementServices.QueryDto(x => x.ResumeId != null && x.ResumeId == id);//证件
Data.Statement = statements.ToDictionary(person => person.StatementCode, person => person.TrueOrFalse);
obj.Data = Data;
#endregion
#region Guide
Guide.Title = "应聘信息登记表填写说明";
Guide.CompanyName = "乔邦 Tiobon";
Guide.GuideText = @"亲爱的小伙伴:
感谢你对公司的认可。
填写公司岗位应聘表时,请确保信息准确无误。
请依次填写个人信息(如姓名、联系方式等)、教育青景、工作经验(从最近到最远列出,包括公司名称、职位和主要职责)等。
强调与职位相关的经历和技能,保持内容简洁明了。
";
obj.Guide = Guide;
#endregion
#region 承诺
var promiseList = new List
{
"本人诚实告知未思有各类传染性疾病,若经体检后发现有不符合本公司要求的项目,本人愿意放弃此次应征机会!",
"本人正式入职之前,已不与任何单位存在劳动关系,并承诺在工作中不使用曾经服务过的工作单位的技术和商业秘密,如有违背,由此引起的法律纠纷及经济责任由本人承担。"
};
obj.Promise = promiseList;
#endregion
dynamic StatementRemark = new ExpandoObject();
StatementRemark.Top = "员工本人声明(本人填写、提供的资料,是真实的、可靠的。如有虚假,则所签订的劳动合同将自动作废,由此产生的一切后果由本人负责。)";
StatementRemark.CenterPart1 = "根据本人实际情况,在下列";
StatementRemark.CenterPart2 = "中打“√”选择符合项目:";
obj.StatementRemark = StatementRemark;
return ServiceResult.OprateSuccess("查询成功", obj);
}
public async Task> QueryResumeFormColumn(long resumeTemplateID)
{
var sql = @$"DECLARE @ResumeTemplateID BIGINT = {resumeTemplateID}
SELECT A.ColumnName, A.ResumeInfoColumnName ColumnNameDesc, D.GroupType
FROM Ghrh_ResumeInfoColumn A
LEFT JOIN Ghrh_ResumeTemplateInfoGroupColumn B
ON B.ResumeInfoColumnID = A.ID
AND B.IsDisplay = 1
AND B.IsEnable = 1
AND A.IsEnable = 1
JOIN Ghrh_ResumeTemplateInfoGroup C
ON B.ResumeTemplateInfoGroupID = C.Id
JOIN Ghrh_ResumeInfoGroup D
ON C.ResumeInfoGroupId = D.ID AND D.IsEnable = 1
WHERE C.ResumeTemplateID = @ResumeTemplateID
-- AND D.GroupType = 'Base'
ORDER BY D.GroupType, b.SortNo";
return await Db.Ado.SqlQueryAsync(sql);
}
#endregion
#region 简历提交接口
public async Task Submit(long id, string status, ResumeFormColumnSubmit resume)
{
resume.Base.ApplicationStatus = status;
resume.Base.ApplicationTime = DateTime.Now;
if (status == "Submit")
resume.Base.Status = DIC_INTERVIEW_ORDER_STATUS.WaitRecommended;
resume.Base.ApplyStatus = resume.Base.ApplyStatus ?? "Dimission";
var entity = await base.QueryById(id);
if (entity != null)
{
if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.WaitRecommended)
resume.Base.Status = entity.Status;
resume.Base.Tags = entity.Tags;
}
if (resume.Base.Status.IsNullOrEmpty())
resume.Base.Status = DIC_INTERVIEW_ORDER_STATUS.WaitRecommended;
if (resume.Base.PhotoUrls != null && resume.Base.PhotoUrls.Any())
resume.Base.PhotoUrl = resume.Base.PhotoUrls[0].RelativePath;
#region 计算年龄
if (resume.Base.Birthday != null && resume.Base.Birthday > DateTime.MinValue)
{
DateTime birthdate = (DateTime)resume.Base.Birthday;
DateTime now = DateTime.Now;
int age = now.Year - birthdate.Year;
if (now.Month < birthdate.Month || (now.Month == birthdate.Month && now.Day < birthdate.Day))
age--;
resume.Base.Age = age;
}
#endregion
await base.Update(id, resume.Base);
await _ghrh_ResumeHomeServices.Delete(x => x.ResumeId != null && x.ResumeId == id);//家庭关系
await _ghrh_ResumeEduBGServices.Delete(x => x.ResumeId != null && x.ResumeId == id);//教育背景
await _ghrh_ResumeWorkExpServices.Delete(x => x.ResumeId != null && x.ResumeId == id);//工作经历
await _ghrh_ResumeLicenceServices.Delete(x => x.ResumeId != null && x.ResumeId == id);//简历培训记录
await _ghrh_ResumeTrainingServices.Delete(x => x.ResumeId != null && x.ResumeId == id);//证件
await _ghrh_ResumeStatementServices.Delete(x => x.ResumeId != null && x.ResumeId == id);//证件
//await Db.Queryable().Where(x => x.TableName == id.ObjToString()).ToListAsync();
if (resume.Family != null && resume.Family.Any())
{
resume.Family.ForEach(x => x.ResumeId = id);
await _ghrh_ResumeHomeServices.Add(resume.Family);
}
if (resume.Education != null && resume.Education.Any())
{
resume.Education.ForEach(x => x.ResumeId = id);
await _ghrh_ResumeEduBGServices.Add(resume.Education);
}
if (resume.WorkExp != null && resume.WorkExp.Any())
{
resume.WorkExp.ForEach(x => x.ResumeId = id);
await _ghrh_ResumeWorkExpServices.Add(resume.WorkExp);
}
if (resume.Licence != null && resume.Licence.Any())
{
resume.Licence.ForEach(x => x.ResumeId = id);
await _ghrh_ResumeLicenceServices.Add(resume.Licence);
}
if (resume.Training != null && resume.Training.Any())
{
resume.Training.ForEach(x => x.ResumeId = id);
await _ghrh_ResumeTrainingServices.Add(resume.Training);
}
if (resume.Statement != null && resume.Statement.Any())
{
var inserts = new List();
foreach (var item in resume.Statement)
{
inserts.Add(new InsertGhrh_ResumeStatementInput()
{
ResumeId = id,
StatementCode = item.Key,
TrueOrFalse = item.Value
});
}
await _ghrh_ResumeStatementServices.Add(inserts);
}
await Db.Updateable()
.SetColumns(it => new Ghrs_Attachment() { TableName = null })
.Where(it => it.TableName == id.ToString())
.ExecuteCommandAsync();
if (resume.Attachment != null && resume.Attachment.Any())
{
for (int i = 0; i < resume.Attachment.Count; i++)
{
await Db.Updateable()
.SetColumns(it => new Ghrs_Attachment()
{
TableName = id.ToString(),
RemarkSz = resume.Attachment[i].RemarkSz
})
.Where(it => it.RelativePath == resume.Attachment[i].RelativePath)
.ExecuteCommandAsync();
}
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 查询招聘表单信息提交结果接口
public async Task> QueryResult(long id, int langId)
{
dynamic Data = new ExpandoObject();
var entity = await QueryById(id);
if (entity is null) throw new Exception("无效的ID!");
decimal completionDegree = 0;
var groups = await Db.Ado.SqlQueryAsync("select GroupName tabName, GroupType type from Ghrh_ResumeInfoGroup where IsEnable=1 and GroupType !='Photo' and GroupType !='Attachment'");
int count = groups.Count;
#region 基础数据
var notNUllCount = 0;
var formColumns = await QueryResumeFormColumn(1);
var columnNames = formColumns.Where(x => x.GroupType == "Base").Select(x => x.ColumnName).ToList();
columnNames = columnNames.Distinct().ToList();
columnNames.ForEach(x =>
{
var value = entity.GetPropertyValue(x);
if (value != null)
notNUllCount++;
});
var basePercent = (decimal)notNUllCount / columnNames.Count * 100;
completionDegree += basePercent;
#endregion
#region 家庭关系
decimal familyPercent = 0;
var familys = await _ghrh_ResumeHomeServices.QueryDto(x => x.ResumeId != null && x.ResumeId == id);
if (familys.Any())
{
notNUllCount = 0;
columnNames = formColumns.Where(x => x.GroupType == "Family").Select(x => x.ColumnName).ToList();
columnNames = columnNames.Distinct().ToList();
columnNames.ForEach(x =>
{
var value = entity.GetPropertyValue(x);
if (value != null)
notNUllCount++;
});
familyPercent = (decimal)notNUllCount / (columnNames.Count * familys.Count) * 100;
completionDegree += familyPercent;
}
#endregion
#region 教育背景
decimal educationPercent = 0;
var educations = await _ghrh_ResumeEduBGServices.QueryDto(x => x.ResumeId != null && x.ResumeId == id);
if (educations.Any())
{
notNUllCount = 0;
columnNames = formColumns.Where(x => x.GroupType == "Education").Select(x => x.ColumnName).ToList();
columnNames = columnNames.Distinct().ToList();
columnNames.ForEach(x =>
{
var value = entity.GetPropertyValue(x);
if (value != null)
notNUllCount++;
});
educationPercent = (decimal)notNUllCount / (columnNames.Count * educations.Count) * 100;
completionDegree += educationPercent;
}
#endregion
#region 工作经历
decimal workExpPercent = 0;
var workExps = await _ghrh_ResumeWorkExpServices.QueryDto(x => x.ResumeId != null && x.ResumeId == id);
if (workExps.Any())
{
notNUllCount = 0;
columnNames = formColumns.Where(x => x.GroupType == "WorkExp").Select(x => x.ColumnName).ToList();
columnNames = columnNames.Distinct().ToList();
columnNames.ForEach(x =>
{
var value = entity.GetPropertyValue(x);
if (value != null)
notNUllCount++;
});
workExpPercent = (decimal)notNUllCount / (columnNames.Count * workExps.Count) * 100;
completionDegree += workExpPercent;
}
#endregion
#region 证件
decimal licencePercent = 0;
var licences = await _ghrh_ResumeLicenceServices.QueryDto(x => x.ResumeId != null && x.ResumeId == id);
if (licences.Any())
{
notNUllCount = 0;
columnNames = formColumns.Where(x => x.GroupType == "Licence").Select(x => x.ColumnName).ToList();
columnNames = columnNames.Distinct().ToList();
columnNames.ForEach(x =>
{
var value = entity.GetPropertyValue(x);
if (value != null)
notNUllCount++;
});
licencePercent = (decimal)notNUllCount / (columnNames.Count * licences.Count) * 100;
completionDegree += licencePercent;
}
#endregion
#region 培训
decimal trainingPercent = 0;
var trainings = await _ghrh_ResumeTrainingServices.QueryDto(x => x.ResumeId != null && x.ResumeId == id);
if (trainings.Any())
{
notNUllCount = 0;
columnNames = formColumns.Where(x => x.GroupType == "Training").Select(x => x.ColumnName).ToList();
columnNames = columnNames.Distinct().ToList();
columnNames.ForEach(x =>
{
var value = entity.GetPropertyValue(x);
if (value != null)
notNUllCount++;
});
trainingPercent = (decimal)notNUllCount / (columnNames.Count * trainings.Count) * 100;
completionDegree += trainingPercent;
}
#endregion
#region 声明
decimal statementPercent = 0;
var statements = await _ghrh_ResumeStatementServices.QueryDto(x => x.ResumeId != null && x.ResumeId == id);//证件
if (statements.Any())
{
notNUllCount = statements.Count;
statementPercent = (decimal)notNUllCount / columnNames.Count * 100;
completionDegree += statementPercent;
}
#endregion
completionDegree = completionDegree / count;
Dictionary dics = new()
{
{ "Base", Convert.ToInt32(StringHelper.TrimDecimalString(StringHelper.TrimDecimalString(basePercent, 0))) },
{ "Family", Convert.ToInt32(StringHelper.TrimDecimalString(StringHelper.TrimDecimalString(familyPercent, 0))) },
{ "Education", Convert.ToInt32(StringHelper.TrimDecimalString(StringHelper.TrimDecimalString(educationPercent, 0))) },
{ "WorkExp", Convert.ToInt32(StringHelper.TrimDecimalString(StringHelper.TrimDecimalString(workExpPercent, 0))) },
{ "Licence", Convert.ToInt32(StringHelper.TrimDecimalString(StringHelper.TrimDecimalString(licencePercent, 0))) },
{ "Training", Convert.ToInt32(StringHelper.TrimDecimalString(StringHelper.TrimDecimalString(trainingPercent, 0))) },
{ "Statement", Convert.ToInt32(StringHelper.TrimDecimalString(StringHelper.TrimDecimalString(statementPercent, 0))) }
};
var seriesData = new List();
var xAxisData = new List();
groups.ForEach(x =>
{
if (dics.ContainsKey(x.type))
{
seriesData.Add(dics[x.type]);
xAxisData.Add(x.tabName);
}
});
Data.CompletionDegree = StringHelper.TrimDecimalString(StringHelper.TrimDecimalString(completionDegree, 2));
Data.SeriesData = seriesData;
Data.XAxisData = xAxisData;
Data.StaffName = entity.StaffName;
Data.PhotoUrl = entity.PhotoUrl;
return ServiceResult.OprateSuccess("查询成功", Data);
}
#endregion
#region 导出Excel
public async Task> Export(QueryBody filter, string condition, bool? IsEnable = true)
{
filter.pageNum = 1;
filter.pageSize = 100000;
var data = await QueryFilterPage(filter, condition, IsEnable);
var formColumns = await QueryResumeFormColumn(1);
formColumns.ForEach(x =>
{
if (x.GroupType == "Base")
{
if (x.ColumnName == "TitleId")
x.ColumnName = "TitleName";
else if (x.ColumnName == "Gender")
x.ColumnName = "GenderLabel";
else if (x.ColumnName == "Education")
x.ColumnName = "EducationLabel";
else if (x.ColumnName == "Nation")
x.ColumnName = "NationLabel";
else if (x.ColumnName == "MaritalStatus")
x.ColumnName = "MaritalStatusLabel";
else if (x.ColumnName == "PoliticStatus")
x.ColumnName = "PoliticStatusLabel";
else if (x.ColumnName == "UrgentRelation")
x.ColumnName = "UrgentRelationLabel";
else if (x.ColumnName == "CertificateType")
x.ColumnName = "CertificateTypeLabel";
else if (x.ColumnName == "RegisteredType")
x.ColumnName = "RegisteredTypeLabel";
}
});
var menuName = string.Empty;
string sql = "select QueryProcedure, EditProcedure, IUDProcedure, MenuName from Ghrs_Menu where MenuNo='{0}'";
sql = string.Format(sql, filter.menuName);
var dt = await Db.Ado.GetDataTableAsync(sql);
if (dt.Rows.Count > 0)
{
menuName = dt.Rows[0]["MenuName"].ToString();
}
var dic = formColumns.Where(x => x.GroupType == "Base").ToDictionary(item => item.ColumnNameDesc, item => item.ColumnName);
var name = menuName + "_" + DateTimeHelper.ConvertToSecondString1(DateTime.Now);
var physicsPath1 = await ReportHelper.SendFile(data.result.DT_TableDataT1.AsQueryable(), name, null, dic, null, null, menuName);
var result = ServiceResult.OprateSuccess(name + ".xlsx", physicsPath1);
return result;
}
#endregion
#region 简历推荐
public async Task Recommend(ResumeRecommendForm recommend)
{
//if (recommend.RequestId.IsNullOrEmpty())
// throw new Exception("请先选择用人申请单!");
if (recommend.RequestId.IsNullOrEmpty())
{
if (recommend.DeptId.IsNullOrEmpty() || recommend.TitleId.IsNullOrEmpty())
return ServiceResult.OprateFailed("请先选择部门或岗位!");
}
if (recommend.InterviewStaffs.IsNullOrEmpty())
return ServiceResult.OprateFailed("请先选择面试者!");
recommend.InterviewStaffs = recommend.InterviewStaffs.Where(x => x.StaffId != null).ToList();
if (!recommend.InterviewStaffs.Any())
return ServiceResult.OprateFailed("请先选择面试者!");
if (recommend.RequestId.IsNotEmptyOrNull())
{
var request = await _ghrh_HumanRequestServices.QueryById(recommend.RequestId);
recommend.DeptId = request.BelongDeptId;
recommend.TitleId = request.TitleId;
}
string deptName = string.Empty;
string titleName = string.Empty;
if (recommend.DeptId.IsNotEmptyOrNull() && recommend.TitleId.IsNotEmptyOrNull())
{
deptName = (await Db.Queryable().Where(x => x.DeptID == recommend.DeptId).FirstAsync())?.DeptName;
titleName = (await Db.Queryable().Where(x => x.TitleID == recommend.TitleId).FirstAsync())?.TitleName;
}
for (int m = 0; m < recommend.ids.Count; m++)
{
var id = recommend.ids[m];
if (await AnyAsync(x => x.Id == id && (x.Status == DIC_INTERVIEW_ORDER_STATUS.HasRecommended ||
x.Status == DIC_INTERVIEW_ORDER_STATUS.HasRecommended ||
x.Status == DIC_INTERVIEW_ORDER_STATUS.WaitAppointment ||
x.Status == DIC_INTERVIEW_ORDER_STATUS.WaitInterview ||
x.Status == DIC_INTERVIEW_ORDER_STATUS.WaitSendOffer ||
x.Status == DIC_INTERVIEW_ORDER_STATUS.HasSendOffer ||
x.Status == DIC_INTERVIEW_ORDER_STATUS.HasOffer ||
x.Status == DIC_INTERVIEW_ORDER_STATUS.HasInterview)))
continue;
await Db.Updateable()
.SetColumns(it => it.IsEnable == 0)
.Where(it => it.ResumeId == id)
.ExecuteCommandAsync();
var interviewIds = recommend.InterviewStaffs
.Where(o => o.StaffId != null)
.Select(o => o.StaffId.Value).ToList();
var interviewer = await Db.Queryable().Where(o => interviewIds.Contains(o.StaffID)).ToListAsync();
var orderId = await _ghrh_InterviewOrderServices.Add(new InsertGhrh_InterviewOrderInput()
{
ResumeId = id,
RequestId = recommend.RequestId,
RecommendTime = DateTime.Now,
RecommendId = App.User.ID,
HireDeptId = recommend.DeptId,
HireTitleId = recommend.TitleId,
HireDeptName = deptName,
HireTitleName = titleName,
Round = 1,
OrderNo = await GenerateContinuousSequence("Ghrh_InterviewOrder", "OrderNo", "V"),
Status = DIC_INTERVIEW_ORDER_STATUS.HasRecommended,
RecommendRemark = recommend.RecommendRemark,
InterviewIds = JsonHelper.ObjToJson(interviewIds),
Interviewer = string.Join(",", interviewer.Select(o => o.StaffName))
});
for (int i = 0; i < recommend.InterviewStaffs.Count; i++)
await _ghrh_InterviewRecordServices.Add(new InsertGhrh_InterviewRecordInput()
{
OrderId = orderId,
Round = 1,
Status = DIC_INTERVIEW_ORDER_STATUS.HasRecommended,
StaffId = recommend.InterviewStaffs[i].StaffId,
});
var entity = await base.QueryById(id);
entity.Status = DIC_INTERVIEW_ORDER_STATUS.HasRecommended;
await Update(entity, ["Status"]);
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 已推荐提醒
public async Task RemindHasRecommend(List ids)
{
for (int m = 0; m < ids.Count; m++)
{
var id = ids[0];
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed("无效的简历ID!");
if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.HasRecommended)
return ServiceResult.OprateFailed("非【已推荐】状态下简历不可发送提醒!");
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
if (order != null)
{
var records = await _ghrh_InterviewRecordServices.Query(x => x.Round == order.Round && x.OrderId == order.Id);
//if (record.FirstViewTime.IsNotEmptyOrNull())
// return ServiceResult.OprateFailed("面试官已查看简历,暂不可发送提醒!");
for (int i = 0; i < records.Count; i++)
{
if (records[i].FirstViewTime.IsNotEmptyOrNull())
await SendMessage([records[i].StaffId.Value], "简历提醒", "您有个简历推荐,请及时查看!");
}
await LogRecord(order.Id, $"发送简历推荐提醒");
}
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 面试官约面
public async Task SubscribeInterview(long id, ResumeSubscribeInterviewForm form)
{
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed("无效的简历ID!");
if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.HasRecommended)
return ServiceResult.OprateFailed("【已推荐】状态下才能约面!");
form.Times.ForEach(x =>
{
if (x.IndexOf("~") < 0)
throw new Exception($"传入时间【{x}】无效,请检查格式!");
var array = x.Split('~');
try
{
Convert.ToDateTime(array[0]);
Convert.ToDateTime(array[1]);
}
catch (Exception)
{
throw new Exception($"传入时间【{x}】无效,请检查格式!");
}
});
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
if (order != null)
{
bool isChangeInterviewTime = false;
var records = await _ghrh_InterviewRecordServices.Query(x => x.Round == order.Round && x.OrderId == order.Id);
records.ForEach(record =>
{
record.Status = DIC_INTERVIEW_ORDER_STATUS.WaitAppointment;
record.RemarkSz = form.Remark;
if (record.PlanInterviewTime1.IsNotEmptyOrNull() || record.PlanInterviewTime2.IsNotEmptyOrNull() || record.PlanInterviewTime3.IsNotEmptyOrNull())
isChangeInterviewTime = true;
if (isChangeInterviewTime)
record.WaitInterviewStatus = "HasChangeInterviewTime";
});
for (int i = 0; i < form.Times.Count; i++)
{
if (i == 0)
records.ForEach(record => record.PlanInterviewTime1 = form.Times[i]);
else if (i == 1)
records.ForEach(record => record.PlanInterviewTime2 = form.Times[i]);
else if (i == 2)
records.ForEach(record => record.PlanInterviewTime3 = form.Times[i]);
}
if (isChangeInterviewTime)
order.WaitInterviewStatus = "HasChangeInterviewTime";
order.Status = DIC_INTERVIEW_ORDER_STATUS.WaitAppointment;
order.AppointmentFeedback = form.Remark;
await _ghrh_InterviewOrderServices.Update(order, ["Status", "AppointmentFeedback"]);
await _ghrh_InterviewRecordServices.Update(records[0], ["PlanInterviewTime1", "PlanInterviewTime2", "PlanInterviewTime3", "Status"]);
await LogRecord(order.Id, $"预约面试,面试时间:{string.Join("、", form.Times)}");
await UpdateResumeStatus(entity, DIC_INTERVIEW_ORDER_STATUS.WaitAppointment);
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 安排面试
public async Task ScheduleInterview(long id, ResumeScheduleInterviewForm body)
{
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed("无效的简历ID!");
if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.WaitAppointment)
return ServiceResult.OprateFailed("【待预约】状态下才能安排面试!");
if (body.Time.IndexOf("~") < 0)
throw new Exception($"传入时间【{body.Time}】无效,请检查格式!");
var array = body.Time.Split('~');
try
{
Convert.ToDateTime(array[0]);
Convert.ToDateTime(array[1]);
}
catch (Exception)
{
throw new Exception($"传入时间【{body.Time}】无效,请检查格式!");
}
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
if (order != null)
{
var records = await _ghrh_InterviewRecordServices.Query(x => x.Round == order.Round && x.OrderId == order.Id);
records.ForEach(record =>
{
record.InterviewTime = body.Time;
record.InterviewBeginTime = Convert.ToDateTime(array[0]);
record.InterviewEndTime = Convert.ToDateTime(array[1]);
record.Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview;
record.RemarkSz = body.Remark;
record.InterviewAddress = body.InterviewAddress;
});
await _ghrh_InterviewRecordServices.Update(records, ["InterviewTime", "InterviewBeginTime", "InterviewEndTime", "Status"]);
await LogRecord(order.Id, $"安排面试,面试时间:{body.Time}");
entity.Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview;
await Update(entity, ["Status"]);
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 变更面试时间
public async Task ModifyInterviewTime(long id, string time)
{
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed("无效的简历ID!");
if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.WaitInterview)
return ServiceResult.OprateFailed("【待面试】状态下才能变更面试时间!");
if (time.IndexOf("~") < 0)
throw new Exception($"传入时间【{time}】无效,请检查格式!");
var array = time.Split('~');
try
{
Convert.ToDateTime(array[0]);
Convert.ToDateTime(array[1]);
}
catch (Exception)
{
throw new Exception($"传入时间【{time}】无效,请检查格式!");
}
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
if (order != null)
{
var records = await _ghrh_InterviewRecordServices.Query(x => x.Round == order.Round && x.OrderId == order.Id);
records.ForEach(record =>
{
record.InterviewTime = time;
record.InterviewBeginTime = Convert.ToDateTime(array[0]);
record.InterviewEndTime = Convert.ToDateTime(array[1]);
record.Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview;
});
await _ghrh_InterviewRecordServices.Update(records, ["InterviewTime", "InterviewBeginTime", "InterviewEndTime", "Status"]);
//if (record.ReceiverIds.IsNotEmptyOrNull())
//{
// var staffs = JsonHelper.JsonToObj>(record.ReceiverIds);
// await SendMessage(staffs.Select(x => x.StaffId).ToList(), "简历提醒", "您有个简历【待面试】,请及时查看面试时间!");
//}
await LogRecord(order.Id, $"变更面试时间,面试时间:{time}");
entity.Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview;
await Update(entity, ["Status"]);
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 待面试提醒
public async Task RemindWaitInterview(List ids)
{
for (int m = 0; m < ids.Count; m++)
{
var id = ids[m];
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed("无效的简历ID!");
if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.WaitInterview)
return ServiceResult.OprateFailed("非【待面试】状态下简历不可发送提醒!");
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
if (order != null)
{
var records = await _ghrh_InterviewRecordServices.Query(x => x.Round == order.Round && x.OrderId == order.Id);
for (int i = 0; i < records.Count; i++)
{
if (records[i].FirstViewTime.IsNotEmptyOrNull())
await SendMessage([records[i].StaffId.Value], "简历提醒", "您有个简历【待面试】,请及时查看面试时间!");
}
await LogRecord(order.Id, $"发送待面试提醒");
}
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 重新安排面试
public async Task RescheduleInterview(long id, ResumeRescheduleInterviewForm input, string type)
{
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed("无效的简历ID!");
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
if (type == "Reschedule")
{
//if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.WaitInterview)
// return ServiceResult.OprateFailed("【待】状态下才能安排面试!");
if (input.Time.IndexOf("~") < 0)
throw new Exception($"传入时间【{input.Time}】无效,请检查格式!");
var array = input.Time.Split('~');
try
{
Convert.ToDateTime(array[0]);
Convert.ToDateTime(array[1]);
}
catch (Exception)
{
throw new Exception($"传入时间【{input.Time}】无效,请检查格式!");
}
if (order != null)
{
order.Round++;
order.Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview;
await _ghrh_InterviewOrderServices.Update(order, ["Status", "Round"]);
for (int i = 0; i < input.InterviewStaffs.Count; i++)
{
await _ghrh_InterviewRecordServices.Add(new InsertGhrh_InterviewRecordInput()
{
OrderId = order.Id,
Round = order.Round,
StaffId = input.InterviewStaffs[i].StaffId,
InterviewTime = input.Time,
PlanInterviewTime1 = input.Time,
InterviewBeginTime = Convert.ToDateTime(array[0]),
InterviewEndTime = Convert.ToDateTime(array[1]),
Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview
});
}
await LogRecord(order.Id, $"发起一个新的面试,面试时间:{input.Time}");
entity.Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview;
await Update(entity, ["Status"]);
if (input.InterviewStaffs.IsNotEmptyOrNull())
await SendMessage(input.InterviewStaffs.Select(x => x.StaffId.Value).ToList(), "简历提醒", "您有个新的邀约面试,请及时查看!");
}
}
else
{
if (order != null)
{
order.Round++;
order.Status = DIC_INTERVIEW_ORDER_STATUS.HasRecommended;
await _ghrh_InterviewOrderServices.Update(order, ["Status", "Round"]);
entity.Status = DIC_INTERVIEW_ORDER_STATUS.HasRecommended;
await Update(entity, ["Status"]);
for (int i = 0; i < input.InterviewStaffs.Count; i++)
await _ghrh_InterviewRecordServices.Add(new InsertGhrh_InterviewRecordInput()
{
OrderId = order.Id,
Round = order.Round,
Status = DIC_INTERVIEW_ORDER_STATUS.HasRecommended,
StaffId = input.InterviewStaffs[i].StaffId,
});
if (input.InterviewStaffs.IsNotEmptyOrNull())
await SendMessage(input.InterviewStaffs.Select(x => x.StaffId.Value).ToList(), "简历提醒", "您有个新的推荐简历,请及时查看!");
}
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 面试评估
public async Task AssessInterview(long id, ResumeAssessInterviewForm input)
{
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed("无效的简历ID!");
string Status = string.Empty;
if (input.IsPass == false)
Status = DIC_INTERVIEW_ORDER_STATUS.InterviewFail;
else
Status = DIC_INTERVIEW_ORDER_STATUS.HasInterview;
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
order.Status = Status;
order.IsPass = input.IsPass;
order.InterviewResult = input.Content;
await _ghrh_InterviewOrderServices.Update(order, ["Status", "IsPass", "InterviewResult"]);
var record = await _ghrh_InterviewRecordServices.QuerySingle(x => x.Round == order.Round && x.OrderId == order.Id && x.StaffId == GetStaffId());
record.InterviewResult = input.Content;
record.IsPass = input.IsPass;
record.AssessTime = DateTime.Now;
record.Status = Status;
await _ghrh_InterviewRecordServices.Update(record, ["AssessTime", "Status", "IsPass", "InterviewResult"]);
await UpdateResumeStatus(entity, Status);
await LogRecord(order.Id, $"填写了面试评估,轮数:{order.Round},是否通过:{(input.IsPass == true ? "通过" : "不通过")},内容:{input.Content}!");
return ServiceResult.OprateSuccess();
}
#endregion
#region 变更面试官
public async Task ModifyInterviewer(long id, List InterviewStaffs)
{
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed("无效的简历ID!");
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
var record = await _ghrh_InterviewRecordServices.QuerySingle(x => x.Round == order.Round && x.OrderId == order.Id);
var insertRecord = Mapper.Map(record).ToANew();
await _ghrh_InterviewRecordServices.Delete(x => x.Round == order.Round && x.OrderId == order.Id);
for (int i = 0; i < InterviewStaffs.Count; i++)
{
insertRecord.StaffId = InterviewStaffs[i].StaffId;
await _ghrh_InterviewRecordServices.Add(insertRecord);
}
await LogRecord(order.Id, "变更状态为:变更面试官!");
return ServiceResult.OprateSuccess();
}
#endregion
#region 发offer
public async Task SendOffer(List ids)
{
for (int i = 0; i < ids.Count; i++)
{
var id = ids[i];
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed("无效的简历ID!");
await UpdateResumeStatus(entity, DIC_INTERVIEW_ORDER_STATUS.HasSendOffer);
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
await UpdateInterviewOrderStatus(order, DIC_INTERVIEW_ORDER_STATUS.HasSendOffer);
await UpdateInterviewRecordStatus(order, DIC_INTERVIEW_ORDER_STATUS.HasSendOffer);
await LogRecord(order.Id, "变更状态为:已发offer!");
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 已发offer提醒
public async Task RemindHasOffer(List ids)
{
for (int i = 0; i < ids.Count; i++)
{
var id = ids[i];
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed("无效的简历ID!");
if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.HasSendOffer)
return ServiceResult.OprateFailed("非【已发offer】状态下简历不可发送提醒!");
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
if (order != null)
{
//var record = await _ghrh_InterviewRecordServices.QuerySingle(x => x.Round == order.Round && x.OrderId == order.Id);
//if (record.ReceiverIds.IsNotEmptyOrNull())
//{
// var staffs = JsonHelper.JsonToObj>(record.ReceiverIds);
// await SendMessage(staffs.Select(x => x.StaffId).ToList(), "简历提醒", "您有个简历【待面试】,请及时查看面试时间!");
//}
await LogRecord(order.Id, "发送待已发offer提醒!");
}
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 变更是否报道
public async Task ModifyIsOffer(List ids, bool isOffer)
{
for (int i = 0; i < ids.Count; i++)
{
var id = ids[i];
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed("无效的简历ID!");
//if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.HasSendOffer)
// return ServiceResult.OprateFailed("非【已发offer】状态下简历不可发送提醒!");
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
if (order != null)
{
var records = await _ghrh_InterviewRecordServices.Query(x => x.Round == order.Round && x.OrderId == order.Id);
if (isOffer)
{
entity.Status = DIC_INTERVIEW_ORDER_STATUS.HasOffer;
order.Status = DIC_INTERVIEW_ORDER_STATUS.HasOffer;
records.ForEach(record => record.Status = DIC_INTERVIEW_ORDER_STATUS.HasOffer);
}
await Update(entity, ["Status"]);
await _ghrh_InterviewOrderServices.Update(order, ["Status"]);
await _ghrh_InterviewRecordServices.Update(records, ["Status"]);
await LogRecord(order.Id, "变更是否报道!");
}
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 不合适
public async Task Fail(ResumeFailInterviewForm input)
{
for (int i = 0; i < input.Ids.Count; i++)
{
var id = input.Ids[i];
var entity = await base.QueryById(id);
if (entity == null)
continue;
await UpdateResumeStatus(entity, DIC_INTERVIEW_ORDER_STATUS.Fail);
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
order.Status = DIC_INTERVIEW_ORDER_STATUS.Fail;
order.InterviewResult = "不合适";
order.FilterFeedback = input.Content;
await _ghrh_InterviewOrderServices.Update(order, ["Status", "InterviewResult", "InterviewResultRemark"]);
var records = await _ghrh_InterviewRecordServices.Query(x => x.Round == order.Round && x.OrderId == order.Id);
records.ForEach(record =>
{
record.Status = DIC_INTERVIEW_ORDER_STATUS.Fail;
record.InterviewResult = "不合适";
record.FilterFeedback = input.Content;
});
await _ghrh_InterviewRecordServices.Update(records, ["Status", "InterviewResult", "InterviewResultRemark"]);
await LogRecord(order.Id, "变更状态为:不合适!");
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 取消面试
public async Task CancelInterview(long id, ResumeCancelInterviewForm input)
{
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed("无效的简历ID!");
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
var record = await _ghrh_InterviewRecordServices.QuerySingle(x => x.Round == order.Round && x.OrderId == order.Id && x.StaffId == GetStaffId());
record.WaitInterviewStatus = "Cancel";
record.CancelReason = input.CancelReason;
await LogRecord(order.Id, "取消面试!");
return ServiceResult.OprateSuccess();
}
#endregion
#region 发起录用审批
public async Task ApplyOfferApproval(List ids)
{
for (int i = 0; i < ids.Count; i++)
{
var id = ids[i];
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed("无效的简历ID!");
if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.HasInterview)
return ServiceResult.OprateFailed("暂不可发起录用审批!");
await UpdateResumeStatus(entity, DIC_INTERVIEW_ORDER_STATUS.WaitSendOffer);
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
await UpdateInterviewOrderStatus(order, DIC_INTERVIEW_ORDER_STATUS.WaitSendOffer);
await UpdateInterviewRecordStatus(order, DIC_INTERVIEW_ORDER_STATUS.WaitSendOffer);
await LogRecord(order.Id, "发起录用审批!");
}
return ServiceResult.OprateSuccess();
}
#endregion
#region ESS端查询简历记录
public async Task> QueryESS(QueryBody filter, string condition)
{
int? staffId = GetStaffId();
RefAsync totalCount = 0;
var dt = DateTime.Now.Date;
string sql = @$"SELECT C.Id,
A.Id ResumeId,
A.CreateBy,
C.CreateTime,
A.CreateProg,
A.CreateIP,
A.UpdateBy,
A.UpdateTime,
A.UpdateProg,
A.UpdateIP,
A.OperateLogID,
A.StaffName,
A.StaffEname,
A.PhotoUrl,
A.Nation,
A.Birthday,
A.NativePlace,
A.Gender,
A.Age,
A.Education,
A.School,
A.GraduateDate,
A.ApplyStatus,
A.TitleId,
A.MaritalStatus,
A.PoliticStatus,
A.Mobile,
A.Email,
A.Indate,
A.UrgentRelation,
A.UrgentContact,
A.UrgentContactTel,
A.UrgentContactAddress,
A.Urgent2Relation,
A.Urgent2Contact,
A.Urgent2ContactTel,
A.Urgent2ContactAddress,
A.PreJobSeniority,
A.EduDegree,
A.CertificateType,
A.IdCardNo,
A.IDCardBegin,
A.IDCardEnd,
A.RegisteredType,
A.IDCardOrg,
A.RegisteredAddress,
A.NowAddress,
A.Introducer,
A.NationNo,
A.FundAccountID,
A.FundBase,
A.InInsureAccountNo,
A.InsureAccountID,
A.InsureBase,
A.IsInsure,
A.IsFund,
A.IsRecommend,
A.IsStay,
A.CarNo,
A.Tags,
A.Status,
A.WorkYears,
A.SalaryPeriod,
A.ApplicationStatus,
A.ApplicationTime,
A.TitleType,
A.StaffType1,
-- A.InterviewResult,
A.FailInterviewReason,
A.RemarkSz,
A.IsDefault,
A.IsEnable,
A.Reverse1,
A.Reverse2,
A.Reverse3,
A.Reverse4,
A.Reverse5,
A.Reverse6,
A.Reverse7,
A.Reverse8,
A.Reverse9,
A.Reverse10,
A.ReverseI1,
A.ReverseI2,
B.OrderNo,
B.RecommendTime,
B.[Round],
B.IsPass,
B.InterviewResult,
C.Status OrderStatus,
C.StaffId,
C.CancelReason,
CONVERT
(BIT, CASE B.[Round] WHEN C.[Round] THEN 'true' ELSE 'false' END) AS IsAllowAssess
FROM Ghrh_Resume A
JOIN Ghrh_InterviewOrder B ON A.ID = B.ResumeId
JOIN Ghrh_InterviewRecord C
ON B.ID = C.OrderId
-- AND B.[Round] = C.[Round]
WHERE A.IsEnable = 1 AND C.IsEnable = 1";
if (string.IsNullOrWhiteSpace(filter.orderBy))
filter.orderBy = "CreateTime ASC";
sql += $" AND C.StaffId={staffId}";
#region 处理查询条件
//Expression> whereExpression = new Expression>();
var whereExpression = Expressionable.Create();
foreach (JProperty jProperty in filter.jsonParam.Properties())
{
var name = jProperty.Name;
var value = jProperty.Value.ToString();
if (name == "page" || name == "pageSize")
continue;
if (value.IsNotEmptyOrNull())
{
var jsonParam = JsonHelper.JsonToObj(value);
switch (name)
{
case "WaitRecommend":
if (jsonParam.columnValue.ObjToInt() == 1)
sql += $" AND C.Status = '{DIC_INTERVIEW_ORDER_STATUS.WaitRecommended}'";
break;
case "HasRecommended":
if (jsonParam.columnValue.ObjToInt() == 1)
sql += $" AND C.Status = '{DIC_INTERVIEW_ORDER_STATUS.HasRecommended}'";
break;
case "WaitAppointment":
if (jsonParam.columnValue.ObjToInt() == 1)
sql += $" AND C.Status = '{DIC_INTERVIEW_ORDER_STATUS.WaitAppointment}'";
break;
case "WaitInterview":
if (jsonParam.columnValue.ObjToInt() == 1)
sql += $" AND C.Status = '{DIC_INTERVIEW_ORDER_STATUS.WaitInterview}'";
break;
case "HasInterview":
if (jsonParam.columnValue.ObjToInt() == 1)
sql += $" AND (C.Status = '{DIC_INTERVIEW_ORDER_STATUS.HasInterview}' OR C.Status = '{DIC_INTERVIEW_ORDER_STATUS.InterviewFail}')";
break;
case "WaitSendOffer":
if (jsonParam.columnValue.ObjToInt() == 1)
sql += $" AND C.Status = '{DIC_INTERVIEW_ORDER_STATUS.WaitSendOffer}'";
break;
case "HasSendOffer":
if (jsonParam.columnValue.ObjToInt() == 1)
sql += $" AND C.Status = '{DIC_INTERVIEW_ORDER_STATUS.HasSendOffer}'";
break;
case "HasOffer":
if (jsonParam.columnValue.ObjToInt() == 1)
sql += $" AND C.Status = '{DIC_INTERVIEW_ORDER_STATUS.HasOffer}'";
break;
case "Fail":
if (jsonParam.columnValue.ObjToInt() == 1)
sql += $" AND C.Status = '{DIC_INTERVIEW_ORDER_STATUS.Fail}'";
break;
case "SalaryPeriod":
case "Education":
case "ApplyStatus":
case "Gender":
//if (jsonParam.columnValue.IsNotEmptyOrNull())
//{
// var ids1 = JsonHelper.JsonToObj>(jsonParam.columnValue.ToString());
// if (!ids1.Any(x => x == "NoFliter"))
// whereExpression.And(x => ids1.Contains(x.Education));
//}
if (jsonParam.columnValue != null)
{
var ids1 = JsonHelper.JsonToObj>(jsonParam.columnValue.ToString());
if (!ids1.Any(x => x == "NoFliter"))
condition += $" AND {name} IN ({string.Join(",", ids1.Select(id => "'" + id + "'"))})";
}
break;
case "WorkYears":
case "Age":
if (jsonParam.columnValue.IsNotEmptyOrNull())
{
var ids1 = JsonHelper.JsonToObj>(jsonParam.columnValue.ToString());
if (!ids1.Any(x => x == "NoFliter"))
{
var i = 0;
condition += " AND (";
ids1.ForEach(x =>
{
var arr = x.Split(['-']);
if (i == 0)
condition += $"({name} >= {arr[0]} AND {name} <={arr[1]})";
else
condition += $" OR ({name} >= {arr[0]} AND {name} <={arr[1]})";
i++;
});
condition += ")";
}
}
break;
case "Tags":
if (jsonParam.columnValue.IsNotEmptyOrNull())
{
var ids1 = JsonHelper.JsonToObj>(jsonParam.columnValue.ToString());
if (!ids1.Any(x => x == "NoFliter"))
{
var i = 0;
condition += " AND (";
ids1.ForEach(x =>
{
var arr = x.Split(['-']);
if (i == 0)
condition += $"({name} like '%{x}%')";
else
condition += $" OR ({name} like '%{x}%')";
i++;
});
condition += ")";
}
}
break;
case "Keywords":
if (jsonParam.columnValue.IsNotEmptyOrNull())
whereExpression.And(x => (x.StaffName.Contains(jsonParam.columnValue.ToString()) ||
x.StaffEname.Contains(jsonParam.columnValue.ToString()) ||
x.Tags.Contains(jsonParam.columnValue.ToString()) ||
x.RemarkSz.Contains(jsonParam.columnValue.ToString()) ||
x.School.Contains(jsonParam.columnValue.ToString())));
break;
default:
break;
}
}
}
#endregion
sql += " AND " + condition;
if (filter.pageSize == 0)
filter.pageSize = 10000;
var sql1 = GetQueryString(sql, filter.pageNum, filter.pageSize, filter.orderBy);
totalCount = await Db.Ado.GetIntAsync("select count(0) from ( " + sql + ") A");
var list = DbAccess.QueryList(sql);
//var data = await Db.SqlQueryable