();
statements.ForEach(statement =>
{
if (!StatementDic.ContainsKey(statement.StatementCode))
StatementDic.Add(statement.StatementCode, statement.TrueOrFalse);
});
Data.Statement = StatementDic;
//Data.Statement = statements.ToDictionary(person => person.StatementCode, person => person.TrueOrFalse);
obj.Data = Data;
#endregion
#region Guide
var companyName = await Db.Ado.GetStringAsync("select top 1 CompanyName from Ghro_Company");
if (langId != 1)
companyName = await Db.Ado.GetStringAsync("select top 1 CompanyEname from Ghro_Company");
Guide.Title = "应聘信息登记表填写说明";
Guide.CompanyName = companyName;
Guide.GuideText = @"亲爱的小伙伴:
感谢你对公司的认可。
填写公司岗位应聘表时,请确保信息准确无误。
请依次填写个人信息(如姓名、联系方式等)、教育背景、工作经验(从最近到最远列出,包括公司名称、职位和主要职责)等。
强调与职位相关的经历和技能,保持内容简洁明了。
";
obj.Guide = Guide;
#endregion
#region 承诺
var promiseList = new List
{
"本人诚实告知未思有各类传染性疾病,若经体检后发现有不符合本公司要求的项目,本人愿意放弃此次应征机会!",
"本人正式入职之前,已不与任何单位存在劳动关系,并承诺在工作中不使用曾经服务过的工作单位的技术和商业秘密,如有违背,由此引起的法律纠纷及经济责任由本人承担。"
};
obj.Promise = promiseList;
#endregion
dynamic StatementRemark = new ExpandoObject();
StatementRemark.Top = "员工本人声明(本人填写、提供的资料,是真实的、可靠的。如有虚假,则所签订的劳动合同将自动作废,由此产生的一切后果由本人负责。)";
if (statementRemark.IsNotEmptyOrNull())
StatementRemark.Top = statementRemark;
StatementRemark.CenterPart1 = "根据本人实际情况,在下列";
StatementRemark.CenterPart2 = "中打“√”选择符合项目:";
obj.StatementRemark = StatementRemark;
return ServiceResult.OprateSuccess("查询成功", obj);
}
public async Task> QueryResumeFormColumn(long resumeTemplateID = 0)
{
resumeTemplateID = await Db.Ado.GetLongAsync("select top 1 Id from Ghrh_ResumeTemplate where IsEnable=1 and IsPublish=1");
var sql = @$"DECLARE @ResumeTemplateID BIGINT = {resumeTemplateID}
SELECT A.ColumnName,
A.ResumeInfoColumnName
ColumnNameDesc,
D.GroupType,
A.MapTableName,
A.MapColumnName,
A.DataType,
A.ColumnType,
A.IsRequired,
A.DataSourceType,
A.DataSource DataSource1,
dbo.FS_GetdataSourceBySet (NULL, A.DataSourceType, A.DataSource) DataSource,
A.DataSourceID,
b.SortNo
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)
{
if (resume.Base.IdCardNo.IsNotEmptyOrNull())
if (await base.AnyAsync(x => x.Id != id && x.IdCardNo == resume.Base.IdCardNo))
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0148", "证件号码【{0}】已在系统中存在,请确认填写是否正确!", resume.Base.IdCardNo));
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
resume.Base.Education = resume.Base.EduDegree;
#region 计算工作年限
var days = 0;
if (resume.WorkExp != null && resume.WorkExp.Any())
{
resume.WorkExp.ForEach(x =>
{
if (x.BeginDate != null && x.EndDate != null && x.EndDate > x.BeginDate)
{
var difference = x.EndDate.Value - x.BeginDate.Value;
days += difference.TotalDays.ObjToInt();
}
});
}
resume.Base.WorkYears = days / 365;
#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(await QueryLangValue("F_ResumeMaintenance_0149", langId, "无效的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();
familys.ForEach(family =>
{
columnNames.ForEach(x =>
{
var value = family.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();
educations.ForEach(education =>
{
columnNames.ForEach(x =>
{
var value = education.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();
workExps.ForEach(workExp =>
{
columnNames.ForEach(x =>
{
var value = workExp.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();
licences.ForEach(licence =>
{
columnNames.ForEach(x =>
{
var value = licence.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();
trainings.ForEach(training =>
{
columnNames.ForEach(x =>
{
var value = training.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(await QueryLangValue("F_ResumeMaintenance_0150", "请先选择部门或岗位!"));
}
if (recommend.InterviewStaffs.IsNullOrEmpty())
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0151", "请先选择面试者!"));
recommend.InterviewStaffs = recommend.InterviewStaffs.Where(x => x.StaffId != null).ToList();
if (!recommend.InterviewStaffs.Any())
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0152", "至少选择一名面试者!"));
recommend.InterviewStaffs = recommend.InterviewStaffs.Where(x => x.StaffId != null).Distinct().ToList();
var recommendCount = 0;
if (recommend.RequestId.IsNotEmptyOrNull())
{
var request = await _ghrh_HumanRequestServices.QueryById(recommend.RequestId);
recommend.DeptId = request?.DeptId;
recommend.TitleId = request?.TitleId;
recommendCount = (request?.RecommendCount ?? 0) + recommend.ids.Count;
}
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)))
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,
Email = recommend.InterviewStaffs[i].Email,
IsPrimary = i == 0 ? true : false,
});
await SendMessage(recommend.InterviewStaffs.Select(x => x.StaffId.Value).ToList(), await QueryLangValue("F_ResumeMaintenance_0153", "简历提醒"), await QueryLangValue("F_ResumeMaintenance_0154", "您有个简历推荐,请及时查看!"), "/M_ESS_Recruit/F_ESS_Candidate");
var entity = await base.QueryById(id);
entity.Status = DIC_INTERVIEW_ORDER_STATUS.HasRecommended;
await Update(entity, ["Status"]);
#region 日志
string content = await QueryLangValue("F_ResumeMaintenance_0155", "向【{0}】推荐了简历,推荐理由:{1}", string.Join("、", interviewer.Select(o => o.StaffName)), recommend.RecommendRemark ?? "无");
await LogRecord(orderId, content, id, null, "Recommended", true);
#endregion
#region 处理附件
if (recommend.Attachments != null && recommend.Attachments.Any())
for (int i = 0; i < recommend.Attachments.Count; i++)
{
await Db.Updateable()
.SetColumns(it => new Ghrs_Attachment()
{
TableName = orderId.ObjToString(),
UpdateTime = DateTime.Now
})
.Where(it => it.RelativePath == recommend.Attachments[i].RelativePath)
.ExecuteCommandAsync();
}
#endregion
}
#region 回写需求单推荐人数
if (recommend.RequestId.IsNotEmptyOrNull())
{
await Db.Updateable()
.SetColumns(it => new Ghrh_HumanRequest() { RecommendCount = recommendCount }, true)
.Where(it => it.Id == recommend.RequestId)
.ExecuteCommandAsync();
}
#endregion
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(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历ID!"));
if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.HasRecommended)
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0156", "非【已推荐】状态下简历不可发送提醒!"));
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("面试官已查看简历,暂不可发送提醒!");
var interviewIds = records.Select(x => x.StaffId).ToList();
var interviewer = await Db.Queryable().Where(o => interviewIds.Contains(o.StaffID)).ToListAsync();
for (int i = 0; i < records.Count; i++)
{
if (records[i].FirstViewTime.IsNullOrEmpty())
await SendMessage([records[i].StaffId.Value], await QueryLangValue("F_ResumeMaintenance_0153", "简历提醒"), await QueryLangValue("F_ResumeMaintenance_0154", "您有个简历推荐,请及时查看!"), "/M_ESS_Recruit/F_ESS_Candidate");
}
#region 日志
string content = await QueryLangValue("F_ResumeMaintenance_0157", "向【{0}】发送简历推荐提醒!", string.Join("、", interviewer.Select(o => o.StaffName)));
await LogRecord(order.Id, content, id, null, "RemindHasRecommend");
#endregion
}
}
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(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历ID!"));
//if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.HasRecommended)
// return ServiceResult.OprateFailed("【已推荐】状态下才能约面!");
string content = await QueryLangValue("F_ResumeMaintenance_0158", "传入时间【{0}】无效,请检查格式!");
form.Times.ForEach(x =>
{
if (x.IndexOf("~") < 0)
throw new Exception(string.Format(content, x));
var array = x.Split('~');
try
{
Convert.ToDateTime(array[0]);
Convert.ToDateTime(array[1]);
}
catch (Exception)
{
throw new Exception(string.Format(content, 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.Status = DIC_INTERVIEW_ORDER_STATUS.HasChangeDate;
});
for (int i = 0; i < form.Times.Count; i++)
{
var time = form.Times[i];
if (time.IsNotEmptyOrNull())
{
var time1 = time.Split('~');
time = DateTimeHelper.ConvertToMiniuteString(time1[0]) + "~" + DateTimeHelper.ConvertToOnlyHourMinuteString(time1[1]);
}
form.Times[i] = time;
if (i == 0)
records.ForEach(record => record.PlanInterviewTime1 = time);
else if (i == 1)
records.ForEach(record => record.PlanInterviewTime2 = time);
else if (i == 2)
records.ForEach(record => record.PlanInterviewTime3 = time);
}
order.Status = DIC_INTERVIEW_ORDER_STATUS.WaitAppointment;
if (isChangeInterviewTime)
order.Status = DIC_INTERVIEW_ORDER_STATUS.HasChangeDate;
order.AppointmentFeedback = form.Remark;
await _ghrh_InterviewOrderServices.Update(order, ["Status", "AppointmentFeedback"]);
await _ghrh_InterviewRecordServices.Update(records[0], ["PlanInterviewTime1", "PlanInterviewTime2", "PlanInterviewTime3", "Status"]);
#region 日志
if (!isChangeInterviewTime)
{
string content1 = await QueryLangValue("F_ResumeMaintenance_0159", "预约面试,面试时间:{0},约面反馈:{1}", string.Join("、", form.Times), order.AppointmentFeedback ?? "无");
await LogRecord(order.Id, content1, id, null, "SubscribeInterview");
}
else
{
string content1 = await QueryLangValue("F_ResumeMaintenance_0160", "修改面试时间,面试时间:{0},备注:{1}", string.Join("、", form.Times), form.Remark ?? "无");
await LogRecord(order.Id, content1, id, null, "ChangeInterviewDate");
}
#endregion
if (!isChangeInterviewTime)
await UpdateResumeStatus(entity, DIC_INTERVIEW_ORDER_STATUS.WaitAppointment);
else
await UpdateResumeStatus(entity, DIC_INTERVIEW_ORDER_STATUS.HasChangeDate);
}
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(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历ID!"));
//if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.WaitAppointment)
// return ServiceResult.OprateFailed("【待预约】状态下才能安排面试!");
string content = await QueryLangValue("F_ResumeMaintenance_0158", "传入时间【{0}】无效,请检查格式!");
if (body.Time.IndexOf("~") < 0)
throw new Exception(string.Format(content, body.Time));
var array = body.Time.Split('~');
try
{
Convert.ToDateTime(array[0]);
Convert.ToDateTime(array[1]);
}
catch (Exception)
{
throw new Exception(string.Format(content, 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);
order.InterviewStepName = body.InterviewStepName;
order.Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview;
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.InterviewStepName = body.InterviewStepName;
record.RemarkSz = body.Remark;
record.InterviewAddress = body.InterviewAddress;
});
await _ghrh_InterviewRecordServices.Update(records, ["InterviewTime", "InterviewBeginTime", "InterviewEndTime", "Status", "InterviewStepName", "RemarkSz", "InterviewAddress", "UpdateTime", "UpdateBy"]);
await _ghrh_InterviewOrderServices.Update(order, ["InterviewStepName", "UpdateTime", "UpdateBy"]);
string content1 = await QueryLangValue("F_ResumeMaintenance_0161", "安排面试,面试时间:{0},面试地点:{1},面试备注:{2}", body.Time, body.InterviewAddress, body.Remark ?? "无");
await LogRecord(order.Id, content1, id, records[0].Id, "ScheduleInterview", true);
entity.Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview;
await Update(entity, ["Status", "UpdateTime", "UpdateBy"]);
content1 = await QueryLangValue("F_ResumeMaintenance_0163", "您有个简历待面试,面试时间:{0},请及时查看!", body.Time);
for (int i = 0; i < records.Count; i++)
{
await SendMessage([records[i].StaffId.Value], await QueryLangValue("F_ResumeMaintenance_0162", "面试提醒"), content1, "/M_ESS_Recruit/F_ESS_Interview");
}
#region 处理附件
if (body.Attachments != null && body.Attachments.Any())
for (int i = 0; i < body.Attachments.Count; i++)
{
await Db.Updateable()
.SetColumns(it => new Ghrs_Attachment()
{
TableName = records[0].Id.ObjToString(),
UpdateTime = DateTime.Now
})
.Where(it => it.RelativePath == body.Attachments[i].RelativePath)
.ExecuteCommandAsync();
}
#endregion
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 改期
public async Task ChangeSubscribeInterview(long id, ResumeSubscribeInterviewForm form)
{
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历ID!"));
if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.HasRecommended)
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0164", "【已推荐】状态下才能约面!"));
string content = await QueryLangValue("F_ResumeMaintenance_0158", "传入时间【{0}】无效,请检查格式!");
form.Times.ForEach(x =>
{
if (x.IndexOf("~") < 0)
throw new Exception(string.Format(content, x));
var array = x.Split('~');
try
{
Convert.ToDateTime(array[0]);
Convert.ToDateTime(array[1]);
}
catch (Exception)
{
throw new Exception(string.Format(content, 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.HasChangeDate;
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++)
{
var time = form.Times[i];
if (time.IsNotEmptyOrNull())
{
var time1 = time.Split('~');
time = DateTimeHelper.ConvertToMiniuteString(time1[0]) + "~" + DateTimeHelper.ConvertToOnlyHourMinuteString(time1[1]);
}
if (i == 0)
records.ForEach(record => record.PlanInterviewTime1 = time);
else if (i == 1)
records.ForEach(record => record.PlanInterviewTime2 = time);
else if (i == 2)
records.ForEach(record => record.PlanInterviewTime3 = time);
}
if (isChangeInterviewTime)
order.WaitInterviewStatus = "HasChangeInterviewTime";
order.Status = DIC_INTERVIEW_ORDER_STATUS.HasChangeDate;
order.AppointmentFeedback = form.Remark;
await _ghrh_InterviewOrderServices.Update(order, ["Status", "AppointmentFeedback"]);
await _ghrh_InterviewRecordServices.Update(records[0], ["PlanInterviewTime1", "PlanInterviewTime2", "PlanInterviewTime3", "Status"]);
string content1 = await QueryLangValue("F_ResumeMaintenance_0165", "修改面试时间,面试时间:{0},备注:{1}", string.Join("、", form.Times), form.Remark ?? "无");
await LogRecord(order.Id, content1);
await UpdateResumeStatus(entity, DIC_INTERVIEW_ORDER_STATUS.HasChangeDate);
}
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(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历ID!"));
if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.WaitInterview)
{
string content1 = await QueryLangValue("F_ResumeMaintenance_0166", "【待面试】状态下才能变更面试时间!");
return ServiceResult.OprateFailed("");
}
string content = await QueryLangValue("F_ResumeMaintenance_0158", "传入时间【{0}】无效,请检查格式!");
if (time.IndexOf("~") < 0)
throw new Exception(string.Format(content, time));
var array = time.Split('~');
try
{
Convert.ToDateTime(array[0]);
Convert.ToDateTime(array[1]);
}
catch (Exception)
{
throw new Exception(string.Format(content, 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 QueryLangValue("F_ResumeMaintenance_0153", "简历提醒"), "您有个简历【待面试】,请及时查看面试时间!");
//}
string content1 = await QueryLangValue("F_ResumeMaintenance_0167", "变更面试时间,面试时间:{0}", time);
await LogRecord(order.Id, content1);
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(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历ID!"));
if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.WaitInterview)
{
string content1 = await QueryLangValue("F_ResumeMaintenance_0168", "非【待面试】状态下简历不可发送提醒!");
return ServiceResult.OprateFailed(content1);
}
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);
string content1 = await QueryLangValue("F_ResumeMaintenance_0169", "您有个简历【待面试】,请及时查看面试时间!");
for (int i = 0; i < records.Count; i++)
{
if (records[i].FirstViewTime.IsNotEmptyOrNull())
await SendMessage([records[i].StaffId.Value], await QueryLangValue("F_ResumeMaintenance_0153", "简历提醒"), content1, "/M_ESS_Recruit/F_ESS_Interview");
}
content1 = await QueryLangValue("F_ResumeMaintenance_0170", "发送待面试提醒");
await LogRecord(order.Id, $"", id, null, "RemindWaitInterview");
}
}
return ServiceResult.OprateSuccess();
}
#endregion
#region 重新安排面试
public async Task RescheduleInterview(long id, ResumeRescheduleInterviewForm input, string type)
{
if (input.InterviewStaffs is null)
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0152", "至少选择一名面试者!"));
input.InterviewStaffs = input.InterviewStaffs.Where(x => x.StaffId != null).Distinct().ToList();
if (!input.InterviewStaffs.Any())
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0152", "至少选择一名面试者!"));
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历ID!"));
if (type == "Reschedule")
{
//if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.WaitInterview)
// return ServiceResult.OprateFailed("【待】状态下才能安排面试!");
string content = await QueryLangValue("F_ResumeMaintenance_0158", "传入时间【{0}】无效,请检查格式!");
if (input.Time.IndexOf("~") < 0)
throw new Exception(string.Format(content, input.Time));
var array = input.Time.Split('~');
try
{
Convert.ToDateTime(array[0]);
Convert.ToDateTime(array[1]);
input.Time = DateTimeHelper.ConvertToMiniuteString(array[0]) + "~" + DateTimeHelper.ConvertToOnlyHourMinuteString(array[1]);
}
catch (Exception)
{
throw new Exception(string.Format(content, input.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 && x.Status == DIC_INTERVIEW_ORDER_STATUS.WaitInterview);
if (records != null && records.Any())
{
for (int j = 0; j < records.Count; j++)
{
records[j].Status = DIC_INTERVIEW_ORDER_STATUS.HasInterview;
var staff = await Db.Queryable().Where(x => x.StaffID == records[j].StaffId).FirstAsync();
content = await QueryLangValue("F_ResumeMaintenance_0171", "因发起一个新面试,【{0}】未及时提交评估,自动转入【已面试】!", $"{staff?.StaffName}({staff?.StaffNo})");
await LogRecord(order.Id, content, id, records[j].Id, "TransferWaitSendOffer");
}
await _ghrh_InterviewRecordServices.Update(records, ["Status", "UpdateTime", "UpdateBy"]);
}
await Db.Updateable()
.SetColumns(it => it.IsEnable == 0)
.Where(it => it.ResumeId == id)
.ExecuteCommandAsync();
}
var interviewIds = input.InterviewStaffs.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,
RecommendTime = DateTime.Now,
RecommendId = App.User.ID,
Round = 1,
OrderNo = await GenerateContinuousSequence("Ghrh_InterviewOrder", "OrderNo", "V"),
Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview,
RecommendRemark = null,
InterviewIds = JsonHelper.ObjToJson(interviewIds),
Interviewer = string.Join(",", interviewer.Select(o => o.StaffName))
});
//await Db.Updateable()
// .SetColumns(it => new Ghrh_InterviewRecord()
// {
// Status = DIC_INTERVIEW_ORDER_STATUS.SystemCancelInterview,
// UpdateTime = DateTime.Now
// })
// .Where(it => it.Status == DIC_INTERVIEW_ORDER_STATUS.WaitInterview && it.OrderId == order.Id)
// .ExecuteCommandAsync();
for (int i = 0; i < input.InterviewStaffs.Count; i++)
{
await _ghrh_InterviewRecordServices.Add(new InsertGhrh_InterviewRecordInput()
{
OrderId = orderId,
Round = 1,
StaffId = input.InterviewStaffs[i].StaffId,
Email = input.InterviewStaffs[i].Email,
InterviewTime = input.Time,
PlanInterviewTime1 = input.Time,
InterviewBeginTime = Convert.ToDateTime(array[0]),
InterviewEndTime = Convert.ToDateTime(array[1]),
Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview,
IsPrimary = i == 0 ? true : false
});
}
content = await QueryLangValue("F_ResumeMaintenance_0172", "向【{0}】发起一个新的面试,面试时间:{0}", string.Join("、", interviewer.Select(o => o.StaffName + $"({o.StaffNo})")), input.Time);
await LogRecord(orderId, content, id, null, "ReRecommended");
entity.Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview;
await Update(entity, ["Status", "UpdateTime", "UpdateBy"]);
if (input.InterviewStaffs.IsNotEmptyOrNull())
await SendMessage(input.InterviewStaffs.Select(x => x.StaffId.Value).ToList(), await QueryLangValue("F_ResumeMaintenance_0153", "简历提醒"), await QueryLangValue("F_ResumeMaintenance_0173", "您有个新的邀约面试,请及时查看!"), "/M_ESS_Recruit/F_ESS_Interview");
}
else
{
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 && x.Status == DIC_INTERVIEW_ORDER_STATUS.WaitInterview);
if (records != null && records.Any())
{
for (int j = 0; j < records.Count; j++)
{
records[j].Status = DIC_INTERVIEW_ORDER_STATUS.HasInterview;
var staff = await Db.Queryable().Where(x => x.StaffID == records[j].StaffId).FirstAsync();
var content = await QueryLangValue("F_ResumeMaintenance_0171", "因发起一个新一轮面试,【{staff?.StaffName}({staff?.StaffNo})】未及时提交评估,自动转入【已面试】!", $"{staff?.StaffName}({staff?.StaffNo})");
await LogRecord(order.Id, content, id, records[j].Id, "TransferWaitSendOffer");
}
await _ghrh_InterviewRecordServices.Update(records, ["Status", "UpdateTime", "UpdateBy"]);
}
order.Round++;
order.Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview;
await _ghrh_InterviewOrderServices.Update(order, ["Status", "Round"]);
entity.Status = DIC_INTERVIEW_ORDER_STATUS.WaitInterview;
await Update(entity, ["Status", "UpdateTime", "UpdateBy"]);
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.WaitInterview,
Email = input.InterviewStaffs[i].Email,
StaffId = input.InterviewStaffs[i].StaffId,
IsPrimary = i == 0 ? true : false
});
var interviewIds = input.InterviewStaffs.Select(o => o.StaffId.Value).ToList();
var interviewer = await Db.Queryable().Where(o => interviewIds.Contains(o.StaffID)).ToListAsync();
var content1 = await QueryLangValue("F_ResumeMaintenance_0174", "向【{0}】发起一个新一轮面试,面试时间:{1}", string.Join("、", interviewer.Select(o => o.StaffName + $"({o.StaffNo})")), input.Time);
await LogRecord(order.Id, content1, id, null, "ReScheduleInterview");
if (input.InterviewStaffs.IsNotEmptyOrNull())
await SendMessage(input.InterviewStaffs.Select(x => x.StaffId.Value).ToList(), await QueryLangValue("F_ResumeMaintenance_0153", "简历提醒"), await QueryLangValue("F_ResumeMaintenance_0175", "您有个新的推荐简历,请及时查看!"), "/M_ESS_Recruit/F_ESS_Candidate");
}
}
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(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历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, await QueryLangValue("F_ResumeMaintenance_0176", "变更面试官!"));
return ServiceResult.OprateSuccess();
}
#endregion
#region 转入已发Offer
public async Task TransferHasSendOffer(long id, long templateId, Dictionary extFields)
{
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历ID!"));
var content = (await _ghrh_TemplateServices.Preview(id, templateId, extFields)).Data;
var offerFileUrl = await GenerateOffer(entity, content);
await UpdateResumeStatus(entity, DIC_INTERVIEW_ORDER_STATUS.HasSendOffer);
var content1 = await QueryLangValue("F_ResumeMaintenance_0177", "变更状态为:已发offer!");
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
if (order != null)
{
await UpdateInterviewOrderStatus(order, DIC_INTERVIEW_ORDER_STATUS.HasSendOffer);
//await UpdateInterviewRecordStatus(order, DIC_INTERVIEW_ORDER_STATUS.HasSendOffer);
await _ghrh_InterviewLogServices.Add(new InsertGhrh_InterviewLogInput()
{
InterviewOrderId = order.Id,
ResumeId = id,
StaffId = App.User.StaffId,
StaffName = App.User.StaffName + "(" + App.User.StaffNo + ")",
Source = "TransferHasSendOffer",
Reverse1 = offerFileUrl,
UserId = App.User.ID,
UserName = App.User.Name,
RemarkSz = content1
});
}
else
await _ghrh_InterviewLogServices.Add(new InsertGhrh_InterviewLogInput()
{
InterviewOrderId = null,
ResumeId = id,
StaffId = App.User.StaffId,
StaffName = App.User.StaffName + "(" + App.User.StaffNo + ")",
Source = "TransferHasSendOffer",
Reverse1 = offerFileUrl,
UserId = App.User.ID,
UserName = App.User.Name,
RemarkSz = content1
});
return ServiceResult.OprateSuccess();
}
public async Task SendOffer(long id, long templateId, Dictionary extFields)
{
var entity = await base.QueryById(id);
if (entity == null)
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历ID!"));
if (entity.Email.IsNullOrEmpty())
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0178", "简历中尚未设置邮箱,暂不可发送!"));
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, $"给【{entity.StaffName}】发送Offer!", id, null, "SendOffer");
var content = (await _ghrh_TemplateServices.Preview(id, templateId, extFields)).Data;
#region 发送邮件
var mailOutbox = new Ghrs_MailOutbox();
mailOutbox.TOMail = entity.Email;
mailOutbox.MailTitle = "录用通知";
mailOutbox.MailBody = content;
mailOutbox.MailPriority = 1;
mailOutbox.ScheduleTime = DateTime.Now;
mailOutbox.IsEnable = 1;
mailOutbox.SortNo = 1;
mailOutbox.CompanyID = 0;
mailOutbox.IsDefault = 0;
mailOutbox.CreateProg = "SendOffer";
var id1 = await Db.Insertable(mailOutbox).ExecuteReturnIdentityAsync();
#endregion
#region 生成Offer PDf
entity.OfferFileUrl = await GenerateOffer(entity, content);
await Update(entity, ["OfferFileUrl"]);
var ontent1 = await QueryLangValue("F_ResumeMaintenance_0179", "给【{0}】发送Offer!");
ontent1 = string.Format(ontent1, entity.StaffName);
await _ghrh_InterviewLogServices.Add(new InsertGhrh_InterviewLogInput()
{
InterviewOrderId = order.Id,
ResumeId = id,
StaffId = App.User.StaffId,
StaffName = App.User.StaffName + "(" + App.User.StaffNo + ")",
Source = "SendOffer",
Reverse1 = entity.OfferFileUrl,
UserId = App.User.ID,
UserName = App.User.Name,
RemarkSz = ontent1,
});
#endregion
#region 处理人力需求单 录用人数
if (order.RequestId.IsNotEmptyOrNull())
{
var sql = $@"UPDATE Ghrh_HumanRequest
SET OfferCount = ISNULL (OfferCount, 0) + 1
WHERE Id = {order.RequestId}";
await Db.Ado.ExecuteCommandAsync(sql);
}
#endregion
return ServiceResult.OprateSuccess();
}
///
/// 生成Offer
///
///
///
///
///
public async Task GenerateOffer(Ghrh_ResumeDto entity, string content)
{
#region 生成Offer PDf
var globalSettings = new GlobalSettings
{
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
DocumentTitle = entity.StaffName,
};
var objectSettings = new ObjectSettings
{
PagesCount = true,
HtmlContent = content,
WebSettings = { DefaultEncoding = "utf-8" },
};
var pdf = new HtmlToPdfDocument()
{
GlobalSettings = globalSettings,
Objects = { objectSettings }
};
var fileBytes = _converter.Convert(pdf);
string pathHeader = "wwwroot/files/pdf_files";
if (!Directory.Exists(pathHeader))
Directory.CreateDirectory(pathHeader);
var ms = new MemoryStream(fileBytes);
var file = new FormFile(ms, 0, ms.Length, Path.GetFileNameWithoutExtension(pathHeader), Path.GetFileName(pathHeader));
var fileName = entity.StaffName + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf";
await using (var fs = System.IO.File.Create(pathHeader + "/" + fileName))
{
await file.CopyToAsync(fs);
fs.Flush();
}
return "/Advanced/files/pdf_files/" + fileName;
#endregion
}
#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(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历ID!"));
if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.HasSendOffer)
{
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0180", "非【已发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([record.StaffId.Value], await QueryLangValue("F_ResumeMaintenance_0153", "简历提醒"), await QueryLangValue("F_ResumeMaintenance_0181", "您有个简历【待面试】,请及时查看面试时间!"));
await LogRecord(order.Id, await QueryLangValue("F_ResumeMaintenance_0182", "发送待已发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(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历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 SyncToStaff(id);
}
else
{
entity.Status = DIC_INTERVIEW_ORDER_STATUS.HasSendOffer;
order.Status = DIC_INTERVIEW_ORDER_STATUS.HasSendOffer;
records.ForEach(record => record.Status = DIC_INTERVIEW_ORDER_STATUS.HasSendOffer);
}
await Update(entity, ["Status"]);
await _ghrh_InterviewOrderServices.Update(order, ["Status"]);
//await _ghrh_InterviewRecordServices.Update(records, ["Status"]);
await LogRecord(order.Id, isOffer == true ? await QueryLangValue("F_ResumeMaintenance_0183", "标记为已报到!") : await QueryLangValue("F_ResumeMaintenance_0184", "标记为未报到!"), id, null, "CheckIn");
}
else
{
}
}
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", "FilterFeedback", "UpdateTime"]);
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;
});
var content = await QueryLangValue("F_ResumeMaintenance_0185", "变更状态为:不合适,不合适原因:{0}", input.Content ?? "无");
await _ghrh_InterviewRecordServices.Update(records, ["Status", "InterviewResult", "FilterFeedback", "UpdateTime"]);
await LogRecord(order.Id, content, id, null, "Fail");
}
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(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历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.Status = DIC_INTERVIEW_ORDER_STATUS.Cancel;
record.CancelReason = input.CancelReason;
await _ghrh_InterviewRecordServices.Update(record, ["Status", "CancelReason", "UpdateTime"]);
order.Status = DIC_INTERVIEW_ORDER_STATUS.Cancel;
await _ghrh_InterviewOrderServices.Update(order, ["Status", "UpdateTime"]);
var content = await QueryLangValue("F_ResumeMaintenance_0186", "取消面试,取消原因:{0}", record.CancelReason ?? "无");
await LogRecord(order.Id, content, id, null, "Cancel");
await UpdateResumeStatus(entity, DIC_INTERVIEW_ORDER_STATUS.Cancel);
return ServiceResult.OprateSuccess();
}
#endregion
#region 转入待发Offer
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(await QueryLangValue("F_ResumeMaintenance_0149", "无效的简历ID!"));
//if (entity.Status != DIC_INTERVIEW_ORDER_STATUS.HasInterview || entity.Status != DIC_INTERVIEW_ORDER_STATUS.WaitRecommended)
// return ServiceResult.OprateFailed("只有在【已面试】、【待推荐】状态下,才能转入待发Offer!");
if (await Db.Queryable().AnyAsync(x => x.WorkState == 0 && x.ResumeId == id))
return ServiceResult.OprateFailed(await QueryLangValue("F_ResumeMaintenance_0187", "当前简历录用审批处于审批中,不可转入待发Offer!"));
await UpdateResumeStatus(entity, DIC_INTERVIEW_ORDER_STATUS.WaitSendOffer);
var order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
if (order == null)
{
var orderId = await _ghrh_InterviewOrderServices.Add(new InsertGhrh_InterviewOrderInput()
{
ResumeId = id,
RecommendTime = DateTime.Now,
RecommendId = App.User.ID,
Round = 1,
OrderNo = await GenerateContinuousSequence("Ghrh_InterviewOrder", "OrderNo", "V"),
Status = DIC_INTERVIEW_ORDER_STATUS.WaitSendOffer,
});
order = await _ghrh_InterviewOrderServices.QuerySingle(x => x.ResumeId == id);
}
if (order != null)
{
await UpdateInterviewOrderStatus(order, DIC_INTERVIEW_ORDER_STATUS.WaitSendOffer);
//await UpdateInterviewRecordStatus(order, DIC_INTERVIEW_ORDER_STATUS.WaitSendOffer);
var records = await _ghrh_InterviewRecordServices.Query(x => x.Round == order.Round && x.OrderId == order.Id && x.Status == DIC_INTERVIEW_ORDER_STATUS.WaitInterview);
for (int j = 0; j < records.Count; j++)
{
records[j].Status = DIC_INTERVIEW_ORDER_STATUS.HasInterview;
var staff = await Db.Queryable().Where(x => x.StaffID == records[j].StaffId).FirstAsync();
await LogRecord(order.Id, await QueryLangValue("F_ResumeMaintenance_0188", "因状态转入待发Offer,【0】未及时提交评估,自动转入【已面试】!", $"{staff?.StaffName}({staff?.StaffNo})"), id, records[j].Id, "TransferWaitSendOffer");
}
await _ghrh_InterviewRecordServices.Update(records, ["Status", "UpdateTime", "UpdateBy"]);
await LogRecord(order.Id, await QueryLangValue("F_ResumeMaintenance_0189", "转入待发Offer!"), id, null, "TransferWaitSendOffer");
}
}
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 DISTINCT A.Id,
A.Id ResumeId,
A.CreateBy,
A.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,
CASE C.Status WHEN 'HasInterview' THEN NULL ELSE B.OrderNo END
OrderNo,
CASE C.Status WHEN 'HasInterview' THEN NULL ELSE B.RecommendTime END
RecommendTime,
CASE C.Status WHEN 'HasInterview' THEN NULL ELSE B.[Round] END
[Round],
CASE C.Status WHEN 'HasInterview' THEN NULL ELSE B.IsPass END
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,
ISNULL(A.UpdateTime, A.CreateTime) CreateTime1,
C.IsPrimary
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
-- AND C.Status = A.Status AND B.IsEnable = 1
";
if (string.IsNullOrWhiteSpace(filter.orderBy))
filter.orderBy = "CreateTime1 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}'";
//sql += $" AND B.Status = '{DIC_INTERVIEW_ORDER_STATUS.WaitInterview}'";
//sql += $" AND (B.Status = '{DIC_INTERVIEW_ORDER_STATUS.HasInterview}' OR B.Status = '{DIC_INTERVIEW_ORDER_STATUS.InterviewFail}' OR B.Status = '{DIC_INTERVIEW_ORDER_STATUS.WaitSendOffer}' OR B.Status = '{DIC_INTERVIEW_ORDER_STATUS.HasSendOffer}' OR B.Status = '{DIC_INTERVIEW_ORDER_STATUS.HasOffer}')";
}
break;
case "HasInterview":
if (jsonParam.columnValue.ObjToInt() == 1)
{
sql += $" AND C.Status = '{DIC_INTERVIEW_ORDER_STATUS.HasInterview}'";
//sql += $" AND (B.Status = '{DIC_INTERVIEW_ORDER_STATUS.HasInterview}' OR B.Status = '{DIC_INTERVIEW_ORDER_STATUS.InterviewFail}' OR B.Status = '{DIC_INTERVIEW_ORDER_STATUS.WaitSendOffer}' OR B.Status = '{DIC_INTERVIEW_ORDER_STATUS.HasSendOffer}' OR B.Status = '{DIC_INTERVIEW_ORDER_STATUS.HasOffer}')";
//sql += $" AND (C.Status = '{DIC_INTERVIEW_ORDER_STATUS.WaitInterview}' OR 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 "Expire":
if (jsonParam.columnValue.ObjToInt() == 1)
sql += $" AND C.Status = '{DIC_INTERVIEW_ORDER_STATUS.Expire}'";
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