作者 郑周

1. 增加暂停和恢复

... ... @@ -3,6 +3,7 @@ package service
import (
"fmt"
"strconv"
"strings"
"time"
"github.com/linmadan/egglib-go/core/application"
... ... @@ -170,7 +171,7 @@ func (rs *EvaluationProjectService) UpdateTemplate(in *command.UpdateProjectTemp
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
// 项目调整截止时间,同步更新任务时间
if err := rs.updateTaskTime(transactionContext, in.Id, end); err != nil {
if err := rs.updateTaskTime(transactionContext, in.Id, &end); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
... ... @@ -179,31 +180,35 @@ func (rs *EvaluationProjectService) UpdateTemplate(in *command.UpdateProjectTemp
}
return project, nil
} else {
_, projects, err := projectRepository.Find(map[string]interface{}{"companyId": in.CompanyId, "cycleId": in.CycleId}, "template")
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
// 周期内的所有项目,员工不能重复被评估
rids := map[string]bool{}
for i := range projects {
// 排除当前项目
if in.Id != projects[i].Id {
ids := projects[i].Recipients
for j := range ids {
rids[ids[j]] = true
}
}
}
repeatNum := 0
for i := range in.Recipients {
id := in.Recipients[i]
if _, ok := rids[id]; ok {
repeatNum++
}
}
if repeatNum > 0 {
return nil, application.ThrowError(application.BUSINESS_ERROR, fmt.Sprintf("有%d人已经在本周期其他项目内,需要将他们移除", repeatNum))
}
//_, projects, err := projectRepository.Find(map[string]interface{}{"companyId": in.CompanyId, "cycleId": in.CycleId}, "template")
//if err != nil {
// return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
//}
//// 周期内的所有项目,员工不能重复被评估
//rids := map[string]bool{}
//for i := range projects {
// it := projects[i]
// // 排除当前项目
// if in.Id == it.Id {
// continue
// }
// // 启用状态
// if it.State == domain.ProjectStateEnable {
// for j := range it.Recipients {
// rids[it.Recipients[j]] = true
// }
// }
//}
//repeatNum := 0
//for i := range in.Recipients {
// id := in.Recipients[i]
// if _, ok := rids[id]; ok {
// repeatNum++
// }
//}
//if repeatNum > 0 {
// return nil, application.ThrowError(application.BUSINESS_ERROR, fmt.Sprintf("有%d人已经在本周期其他项目内,需要将他们移除", repeatNum))
//}
cycleTemplate, err := cycleTemplateRepository.FindOne(map[string]interface{}{"id": in.TemplateId, "includeDeleted": true})
if err != nil {
... ... @@ -237,6 +242,32 @@ func (rs *EvaluationProjectService) UpdateTemplate(in *command.UpdateProjectTemp
return nil, application.ThrowError(application.BUSINESS_ERROR, "评估截至时间不能超出周期截至时间")
}
// 判断起始时间,是否有被评估人的任务
assessTaskRepository := factory.CreateStaffAssessTaskRepository(map[string]interface{}{"transactionContext": transactionContext})
_, assessTasks, err := assessTaskRepository.Find(map[string]interface{}{
"companyId": in.CompanyId,
"cycleId": in.CycleId,
"beginDay": start.Format("2006-01-02"),
})
rids := map[int]int{}
for i1 := range assessTasks {
it := assessTasks[i1]
for i2 := range it.ExecutorId {
rids[it.ExecutorId[i2]] = 0
}
}
for i := range in.Recipients {
id := in.Recipients[i]
id2, _ := strconv.Atoi(id)
if _, ok := rids[id2]; ok {
year, month, day := start.Date()
start0 := time.Date(year, month, day, 0, 0, 0, 0, time.Local) // 当前时间0点0分0秒时刻
today := start0.Add(24 * time.Hour).Format("2006-01-02 15:04:05")
return nil, application.ThrowError(application.BUSINESS_ERROR, fmt.Sprintf("当前时间已有正在进行的项目,请将项目开始时间设置至 %s 之后", today))
}
}
if project.State == domain.ProjectStateWaitConfig {
project.State = domain.ProjectStateWaitActive
}
... ... @@ -264,7 +295,7 @@ func (rs *EvaluationProjectService) UpdateTemplate(in *command.UpdateProjectTemp
}
// 更新项目截止时间,同步任务截止时间
func (rs *EvaluationProjectService) updateTaskTime(context application.TransactionContext, projectId int64, end time.Time) error {
func (rs *EvaluationProjectService) updateTaskTime(context application.TransactionContext, projectId int64, end *time.Time) error {
// 查看任务过程,重新日计算任务截至期
taskRepository := factory.CreateNodeTaskRepository(map[string]interface{}{"transactionContext": context})
tasks, err := taskRepository.Find(map[string]interface{}{"projectId": projectId})
... ... @@ -278,7 +309,10 @@ func (rs *EvaluationProjectService) updateTaskTime(context application.Transacti
for i := range tasks {
task := tasks[i]
task.TimeEnd = &end // 先赋值
if end != nil {
task.TimeEnd = end // 先赋值
}
if task.NextSentAt == nil { // 重新计算
// 环节起始和截止本地时间
... ... @@ -424,10 +458,14 @@ func (rs *EvaluationProjectService) List(in *command.QueryProjectCommand) (inter
pmpUserIds = append(pmpUserIds, userId)
}
// 如果是已启用状态时,当前时间超过截至时间显示【已结束】
if project.State == domain.ProjectStateEnable {
// 如果是已启用或暂停状态时,当前时间超过截至时间显示【已结束】
if project.State == domain.ProjectStateEnable || project.State == domain.ProjectStatePause {
if now > project.EndTime.Unix() {
project.State = domain.ProjectStateDisable
_, err = projectRepository.Insert(project)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
}
}
... ... @@ -469,11 +507,58 @@ func (rs *EvaluationProjectService) Activate(in *command.ActivateProjectCommand)
if len(project.Recipients) == 0 {
return nil, application.ThrowError(application.BUSINESS_ERROR, "请添加被评估人")
}
if project.State == domain.TemplateStateEnable {
if project.State == domain.ProjectStateEnable {
return nil, application.ThrowError(application.BUSINESS_ERROR, "项目已启动")
}
project.State = domain.TemplateStateEnable
// 周期内的所有项目,已启用的员工不能重复被评估
_, projects, err := projectRepository.Find(map[string]interface{}{"companyId": project.CompanyId, "cycleId": project.CycleId}, "template")
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
userMap := map[string]*domain.User{}
for i := range projects {
it := projects[i]
// 排除当前项目
if in.Id == it.Id {
continue
}
// 启用状态的被评估人
if it.State == domain.ProjectStateEnable {
for j := range it.Recipients {
userMap[it.Recipients[j]] = nil
}
}
}
ids := make([]string, 0)
for k := range userMap {
ids = append(ids, k)
}
if len(ids) > 0 {
userRepository := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
_, users, err := userRepository.Find(map[string]interface{}{"ids": ids})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
for i := range users {
s64 := strconv.FormatInt(users[i].Id, 10)
userMap[s64] = users[i]
}
var build strings.Builder
for i := range project.Recipients {
id := project.Recipients[i]
if user, ok := userMap[id]; ok {
build.WriteString("[")
build.WriteString(user.Name)
build.WriteString("]")
}
}
if build.Len() > 0 {
return nil, application.ThrowError(application.BUSINESS_ERROR, fmt.Sprintf("请先停止%s正在进行的项目", build.String()))
}
}
project.State = domain.ProjectStateEnable
project, err = projectRepository.Insert(project)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
... ... @@ -535,6 +620,139 @@ func (rs *EvaluationProjectService) Activate(in *command.ActivateProjectCommand)
return project, nil
}
func (rs *EvaluationProjectService) Pause(in *command.ActivateProjectCommand) (interface{}, error) {
transactionContext, err := factory.ValidateStartTransaction(in)
if err != nil {
return nil, err
}
defer func() {
transactionContext.RollbackTransaction()
}()
projectRepository := factory.CreateEvaluationProjectRepository(map[string]interface{}{"transactionContext": transactionContext})
taskRepository := factory.CreateNodeTaskRepository(map[string]interface{}{"transactionContext": transactionContext})
project, err := projectRepository.FindOne(map[string]interface{}{"id": in.Id})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if project.State != domain.ProjectStateEnable {
return nil, application.ThrowError(application.BUSINESS_ERROR, "项目未启动")
}
project.State = domain.ProjectStatePause
project, err = projectRepository.Insert(project)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
tasks, err := taskRepository.Find(map[string]interface{}{"projectId": project.Id})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
for i := range tasks {
it := tasks[i]
it.NextSentAt = nil
_, err = taskRepository.Insert(it)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return project, nil
}
func (rs *EvaluationProjectService) Resume(in *command.ActivateProjectCommand) (interface{}, error) {
transactionContext, err := factory.ValidateStartTransaction(in)
if err != nil {
return nil, err
}
defer func() {
transactionContext.RollbackTransaction()
}()
projectRepository := factory.CreateEvaluationProjectRepository(map[string]interface{}{"transactionContext": transactionContext})
project, err := projectRepository.FindOne(map[string]interface{}{"id": in.Id})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if project.Template == nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, "请添加评估模板")
}
if len(project.Recipients) == 0 {
return nil, application.ThrowError(application.BUSINESS_ERROR, "请添加被评估人")
}
if project.State == domain.ProjectStateEnable {
return nil, application.ThrowError(application.BUSINESS_ERROR, "项目已启动")
}
// 周期内的所有项目,已启用的员工不能重复被评估
_, projects, err := projectRepository.Find(map[string]interface{}{"companyId": project.CompanyId, "cycleId": project.CycleId}, "template")
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
userMap := map[string]*domain.User{}
for i := range projects {
it := projects[i]
// 排除当前项目
if in.Id == it.Id {
continue
}
// 启用状态的被评估人
if it.State == domain.ProjectStateEnable {
for j := range it.Recipients {
userMap[it.Recipients[j]] = nil
}
}
}
ids := make([]string, 0)
for k := range userMap {
ids = append(ids, k)
}
if len(ids) > 0 {
userRepository := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
_, users, err := userRepository.Find(map[string]interface{}{"ids": ids})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
for i := range users {
s64 := strconv.FormatInt(users[i].Id, 10)
userMap[s64] = users[i]
}
var build strings.Builder
for i := range project.Recipients {
id := project.Recipients[i]
if user, ok := userMap[id]; ok {
build.WriteString("[")
build.WriteString(user.Name)
build.WriteString("]")
}
}
if build.Len() > 0 {
return nil, application.ThrowError(application.BUSINESS_ERROR, fmt.Sprintf("请先停止%s正在进行的项目", build.String()))
}
}
project.State = domain.ProjectStateEnable
project, err = projectRepository.Insert(project)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
// 项目恢复,同步更新任务时间
if err = rs.updateTaskTime(transactionContext, in.Id, nil); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return project, nil
}
func (rs *EvaluationProjectService) Copy(in *command.CopyProjectCommand) (interface{}, error) {
transactionContext, err := factory.ValidateStartTransaction(in)
if err != nil {
... ... @@ -555,7 +773,7 @@ func (rs *EvaluationProjectService) Copy(in *command.CopyProjectCommand) (interf
project.Recipients = make([]string, 0) // 重置被评估人
// 如果拷贝已经启用的模板,默认先设置为待启用
if project.State == domain.ProjectStateEnable {
if project.State == domain.ProjectStateEnable || project.State == domain.ProjectStatePause {
project.State = domain.ProjectStateWaitActive
}
project, err = projectRepository.Insert(project)
... ... @@ -587,11 +805,14 @@ func (rs *EvaluationProjectService) CheckRecipients(in *command.CheckRecipientCo
// 周期内的所有项目,员工不能重复被评估
rids := map[string]bool{}
for i := range projects {
it := projects[i]
// 排除当前项目
if in.Id != projects[i].Id {
ids := projects[i].Recipients
for j := range ids {
rids[ids[j]] = true
if in.Id == it.Id {
continue
}
if it.State == domain.ProjectStateEnable {
for j := range it.Recipients {
rids[it.Recipients[j]] = true
}
}
}
... ...
... ... @@ -234,8 +234,10 @@ func (srv StaffAssessServeice) QueryMemberPerformanceIndicator(in *query.MemberP
var projectItemUsed = map[int][]*domain.EvaluationItemUsed{} // 项目ID-> 评估内容项
var userProjectMap = map[int][]*dao.IndicatorUserProject{} // 用户ID-> 用户评估的项目(用户在周期内可能有多个项目模板,激活状态只能是1个)
var projectIds = make([]int, 0)
var userIds = make([]string, 0)
if len(in.UserIds) > 0 {
userIds = in.UserIds // 赋值
staffAssessRepository := factory.CreateStaffAssessRepository(map[string]interface{}{"transactionContext": transactionContext})
_, assessList, err := staffAssessRepository.Find(map[string]interface{}{
"cycleId": in.CycleId,
... ... @@ -295,7 +297,9 @@ func (srv StaffAssessServeice) QueryMemberPerformanceIndicator(in *query.MemberP
}
userProjectMap[it.TargetUserId] = append(array, &it)
}
for k := range userProjectMap {
userIds = append(userIds, strconv.Itoa(k))
}
for k, _ := range projectIdsMap {
projectIds = append(projectIds, k)
}
... ... @@ -323,8 +327,8 @@ func (srv StaffAssessServeice) QueryMemberPerformanceIndicator(in *query.MemberP
adapterList := make([]*adapter.PerformanceIndicatorAdapter, 0)
categoryMap := map[string]int{} // 内容分类
for i := range in.UserIds {
userId := in.UserIds[i]
for i := range userIds {
userId := userIds[i]
userIdInt, err := strconv.Atoi(userId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
... ...
... ... @@ -7,11 +7,12 @@ import (
const (
ProjectStateWaitConfig int = 0 // 项目状态-待完成配置
ProjectStateWaitActive int = 1 // 项目状态-待启用
ProjectStateEnable int = 2 // 项目状态-启用
ProjectStateDisable int = 3 // 项目状态-停用(假状态)
ProjectStateEnable int = 2 // 项目状态-启动
ProjectStateDisable int = 3 // 项目状态-结束
ProjectStatePause int = 4 // 项目状态-暂停(可恢复启动)
)
// 项目的评估内容配置
// EvaluationProject 项目的评估内容配置
type EvaluationProject struct {
Id int64 `json:"id,string" comment:"ID"`
Name string `json:"name" comment:"名称"`
... ...
... ... @@ -96,6 +96,26 @@ func (controller *ProjectController) ActivateProject() {
}
}
func (controller *ProjectController) PauseProject() {
ruService := service.NewEvaluationProjectService()
in := &command.ActivateProjectCommand{}
if err := controller.Unmarshal(in); err != nil {
controller.Response(nil, application.ThrowError(application.ARG_ERROR, err.Error()))
} else {
controller.Response(ruService.Pause(in))
}
}
func (controller *ProjectController) ResumeProject() {
ruService := service.NewEvaluationProjectService()
in := &command.ActivateProjectCommand{}
if err := controller.Unmarshal(in); err != nil {
controller.Response(nil, application.ThrowError(application.ARG_ERROR, err.Error()))
} else {
controller.Response(ruService.Resume(in))
}
}
func (controller *ProjectController) CopyProject() {
ruService := service.NewEvaluationProjectService()
in := &command.CopyProjectCommand{}
... ...
... ... @@ -19,6 +19,8 @@ func init() {
web.NSRouter("/check-recipients", &controllers.ProjectController{}, "Post:CheckRecipients"),
web.NSRouter("/copy", &controllers.ProjectController{}, "Post:CopyProject"),
web.NSRouter("/activate", &controllers.ProjectController{}, "Post:ActivateProject"),
web.NSRouter("/pause", &controllers.ProjectController{}, "Post:PauseProject"),
web.NSRouter("/resume", &controllers.ProjectController{}, "Post:ResumeProject"),
)
web.AddNamespace(ns)
}
... ...
... ... @@ -58,7 +58,6 @@ func NextTime(now0 time.Time, start time.Time, kpiCycle int) time.Time {
switch kpiCycle {
case domain.KpiCycleDay:
nextTime = now0 // 当前时间的0点开始发送
//nextTime = timeconv.AddDate(now0, 0, 0, 0) // 当前时间的0点开始发送
break
case domain.KpiCycleWeek:
offsetSeconds := int64(now0.Sub(start0).Seconds())
... ...