作者 郑周

1. 新增项目管理-总览

package adapter
import "time"
type SummaryBlock struct {
Name string `json:"name"` // 数据名称
Total int `json:"total"` // 总数量
Completed int `json:"completed"` // 完成数量
EndTime *time.Time `json:"endTime"` // 截止时间
}
... ...
package query
// SummaryCommand 查询项目管理-总览
type SummaryCommand struct {
CycleId int `cname:"周期ID" json:"cycleId,string"`
BeginDay string `cname:"日期" json:"beginDay"`
CompanyId int `cname:"公司ID" json:"companyId"`
OperatorId int `cname:"操作人ID" json:"operatorId"`
}
... ...
package service
import (
"github.com/linmadan/egglib-go/core/application"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/staff_assess/command"
)
//调试用,手动调用CreateStaffAssessTask
func (srv StaffAssessServeice) InvokCreateStaffAssessTask(param *command.CreateStaffAssessTask) (map[string]interface{}, error) {
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
_ = transactionContext.RollbackTransaction()
}()
data, err := srv.CreateStaffAssessTask(transactionContext, param)
if err != nil {
return nil, err
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
return data, nil
}
package service
import (
"github.com/linmadan/egglib-go/core/application"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/staff_assess/adapter"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/staff_assess/command"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/staff_assess/query"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/infrastructure/dao"
)
//调试用,手动调用CreateStaffAssessTask
func (srv StaffAssessServeice) InvokCreateStaffAssessTask(param *command.CreateStaffAssessTask) (map[string]interface{}, error) {
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
_ = transactionContext.RollbackTransaction()
}()
data, err := srv.CreateStaffAssessTask(transactionContext, param)
if err != nil {
return nil, err
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
return data, nil
}
func (srv StaffAssessServeice) QuerySummary(in *query.SummaryCommand) (map[string]interface{}, error) {
transactionContext, err := factory.ValidateStartTransaction(in)
if err != nil {
return nil, err
}
defer func() {
transactionContext.RollbackTransaction()
}()
roleRepo := factory.CreateRoleRepository(map[string]interface{}{"transactionContext": transactionContext})
roleUserRepo := factory.CreateRoleUserRepository(map[string]interface{}{"transactionContext": transactionContext})
_, roleList, err := roleRepo.Find(map[string]interface{}{"type": domain.RoleTypeSystem, "companyId": in.CompanyId})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取角色信息列表"+err.Error())
}
_, userRoleList, err := roleUserRepo.Find(map[string]interface{}{"companyId": in.CompanyId, "userId": in.OperatorId})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取用户的角色信息列表"+err.Error())
}
// 拥有HRBP权限
hrbp := -1
for _, v := range userRoleList {
for _, v2 := range roleList {
if v.RoleId == v2.Id {
hrbp = 1
break
}
}
if hrbp == 1 {
break
}
}
assessDao := dao.NewStaffAssessDao(map[string]interface{}{"transactionContext": transactionContext})
data, err := assessDao.SummaryAssess(in.CompanyId, in.OperatorId, in.CycleId, in.BeginDay, hrbp)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取用户的角色信息列表"+err.Error())
}
self := adapter.SummaryBlock{Name: "填写反馈自评"}
invite := adapter.SummaryBlock{Name: "360°邀请"}
inviteAssess := adapter.SummaryBlock{Name: "360°评估"}
supper := adapter.SummaryBlock{Name: "上级评估"}
inviteTargetIdMap := map[string]int{} // 过滤相同的目标用户ID
for i := range data {
d := data[i]
d.EndTime = d.EndTime.Local() // 输出本地时间
switch d.Types {
case domain.AssessSelf:
self.Total++
if d.Status == domain.StaffAssessCompleted {
self.Completed++
}
if self.EndTime == nil {
self.EndTime = &d.EndTime
}
invite.Total++ // 发起360邀请的人数 = 自评人数
if invite.EndTime == nil {
invite.EndTime = &d.EndTime
}
break
case domain.AssessSuper:
supper.Total++
if d.Status == domain.StaffAssessCompleted {
supper.Completed++
}
if supper.EndTime == nil {
supper.EndTime = &d.EndTime
}
break
case domain.AssessInviteDiffSuper, domain.AssessInviteSameSuper:
inviteAssess.Total++
if d.Status == domain.StaffAssessCompleted {
inviteAssess.Completed++
}
if inviteAssess.EndTime == nil {
inviteAssess.EndTime = &d.EndTime
}
inviteTargetIdMap[d.TargetUserId] = 0 // 360评估类型都是被人邀请的评估,过滤相同的目标用户后,就是完成邀请的数量
break
}
}
invite.Completed = len(inviteTargetIdMap)
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
return map[string]interface{}{"list": []adapter.SummaryBlock{self, invite, inviteAssess, supper}}, nil
}
... ...
package dao
import (
"fmt"
"strconv"
"github.com/go-pg/pg/v10"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
)
type StaffAssessDao struct {
transactionContext *pgTransaction.TransactionContext
}
func NewStaffAssessDao(options map[string]interface{}) *StaffAssessDao {
var transactionContext *pgTransaction.TransactionContext
if value, ok := options["transactionContext"]; ok {
transactionContext = value.(*pgTransaction.TransactionContext)
}
return &StaffAssessDao{
transactionContext: transactionContext,
}
}
type CountData struct {
TargetUserId int
InviteTotal int
InviteCompleted int
}
// 获取员工邀请的人完成360评估的数量
func (d *StaffAssessDao) CountInviteAssessByTargetUser(userIds []int, assessTaskId int) ([]CountData, error) {
sqlStr := `SELECT staff_assess.target_user->>'userId' as target_user_id,
count(staff_assess."id") AS invite_total,
sum(
case WHEN staff_assess.status='completed' THEN 1
ELSE 0 END
) as invite_completed
FROM staff_assess
WHERE staff_assess.target_user->>'userId' IN(?)
AND staff_assess.types IN ('invite_same_super','invite_diff_super')
AND staff_assess.staff_assess_task_id = ?
GROUP BY target_user_id`
userIdList := []string{}
for _, v := range userIds {
uid := strconv.Itoa(v)
userIdList = append(userIdList, uid)
}
condition := []interface{}{
pg.In(userIdList), assessTaskId,
}
tx := d.transactionContext.PgTx
result := []CountData{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
func (d *StaffAssessDao) CountTargetUserInviteAssess1(userIds []int, cycleId int, beginDay string) ([]CountData, error) {
sqlStr := `SELECT
staff_assess.target_user->>'userId' as target_user_id,
count(staff_assess."id") AS invite_total,
sum(
case WHEN staff_assess.status='completed' THEN 1
ELSE 0 END
) as invite_completed
FROM staff_assess
WHERE staff_assess.target_user->>'userId' IN(?)
AND staff_assess.types IN ('invite_same_super','invite_diff_super')
and to_char(staff_assess.begin_time at time zone 'PRC','YYYY-MM-DD') = ?
and staff_assess.cycle_id =?
GROUP BY target_user_id`
userIdStr := []string{}
for _, v := range userIds {
str := strconv.Itoa(v)
userIdStr = append(userIdStr, str)
}
condition := []interface{}{
pg.In(userIdStr), beginDay, cycleId,
}
tx := d.transactionContext.PgTx
result := []CountData{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
// 根据评估的人执行人id,搜索 executorId参与的评估任务
func (d *StaffAssessDao) SearchAssessTaskMe(executorId int, companyId int, limit int, offset int) ([]*domain.StaffAssessTask, error) {
if limit < 0 {
limit = 20
}
if offset < 0 {
offset = 0
}
sqlStr := `SELECT DISTINCT staff_assess_task.* FROM staff_assess_task
JOIN staff_assess ON staff_assess_task."id" = staff_assess."staff_assess_task_id"
WHERE staff_assess.company_id=?
and staff_assess_task.deleted_at isnull
and staff_assess.executor->>'userId'='?'
order by staff_assess_task.id desc
limit ? offset ?
`
tx := d.transactionContext.PgTx
condition := []interface{}{
companyId, executorId, limit, offset,
}
result := []*domain.StaffAssessTask{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
// 搜索 executorId 参与的评估任务
func (d *StaffAssessDao) CountAssessTaskMe(executorId int, companyId int) (int, error) {
sqlStr := `SELECT count( DISTINCT staff_assess_task."id") FROM staff_assess_task
JOIN staff_assess ON staff_assess_task."id" = staff_assess."staff_assess_task_id"
WHERE staff_assess.company_id=?
and staff_assess_task.deleted_at isnull
and staff_assess.executor->>'userId'='?'
`
tx := d.transactionContext.PgTx
condition := []interface{}{
companyId, executorId,
}
result := 0
_, err := tx.QueryOne(pg.Scan(&result), sqlStr, condition...)
return result, err
}
// 获取所以已经执行的评估周期
type AssessCycle struct {
CycleId string `json:"cycleId"` //周期id
CompanyId string `json:"companyId"`
CycleName string `json:"cycleName"` //周期名称
}
// 获取所以已经执行的评估周期
func (d *StaffAssessDao) AllAssessCycleList(companyId int) ([]AssessCycle, error) {
sqlStr := `select
distinct
staff_assess_task.cycle_id ,
staff_assess_task.company_id ,
staff_assess_task.cycle_name
from staff_assess_task
where staff_assess_task.company_id = ?
and staff_assess_task.deleted_at isnull
order by staff_assess_task.cycle_id desc
`
tx := d.transactionContext.PgTx
condition := []interface{}{
companyId,
}
result := []AssessCycle{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
// 获取评估周期中的绩效考核日期
type AssessCycleDay struct {
BeginDay string `json:"beginDay"`
CycleId int `json:"cycleId"`
CycleName string `json:"cycleName"`
CompanyId string `json:"companyId"`
}
// 获取评估周期中的绩效考核日期
func (d *StaffAssessDao) AllAssessCycleDayList(companyId int, cycleId int) ([]AssessCycleDay, error) {
sqlStr := `select distinct staff_assess_task.begin_day ,
staff_assess_task.cycle_id ,
staff_assess_task.cycle_name,
staff_assess_task.company_id
from staff_assess_task
where staff_assess_task.cycle_id = ?
and company_id =?
and staff_assess_task.deleted_at isnull
order by staff_assess_task.begin_day desc `
tx := d.transactionContext.PgTx
condition := []interface{}{
cycleId, companyId,
}
result := []AssessCycleDay{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
// 获取员工填写评估内容
type UserAssessContent struct {
AssessId string `json:"assessId"`
ContentId int `json:"contentId"`
TargetUserId string `json:"targetUserId"` //被评估人的id
TargetUserName string `json:"targetUserName"` //被评估人的名称
BeginDay string `json:"beginDay"` //评估的日期
EvaluationProjectId string `json:"evaluationProjectId"` //项目id
Value string `json:"value"` //评估填写的值
LevelValue string `json:"levelValue"` //评级的值
Rule domain.EvaluationRule `json:"rule"` //规则
SortBy int `json:"sortBy"` //评估项顺序
Category string `json:"category"` //评估项分类
ContentName string `json:"contentName"` //评估项名称
Weight float64 `json:"weight"` //权重
CycleId string `json:"cycleId"` //周期id
}
type SearchConditin1 struct {
CompanyId int //公司id
AssessId int //评估任务id
CycleId int //周期id
BeginDay string //评估的日期
TargetUserName string //被评估人的名称
TargetUserId []string //查询指定的人
Limit int //分页
Offset int //分页
OperaterId int //用户的id是谁在搜索数据
Hrbp int //
}
// 项目管理-成员列表 根据周期的id和日期获取员工填写的评估内容
// companyId int 公司id
// cycleId int, 评估周期id
// userId int, 用户id,谁要查看数据
// beginDay string, 周期中执行项目的时间
// hrbp 是否搜索HRBP角色的用户可以查看,1:是;-1:否
// limit int, 分页条数
// offset int 分页偏移
func (d *StaffAssessDao) SearchUserAssessContent(param SearchConditin1) ([]UserAssessContent, error) {
if param.Offset < 0 {
param.Offset = 0
}
if param.Limit < 0 {
param.Limit = 20
}
sqlStr := ` select
t_staff_assess_1.target_user_id,t_staff_assess_1.target_user_name,t_staff_assess_1.begin_day,
t_staff_assess_1.assess_id,staff_assess_content.id as content_id,
staff_assess_content.value ,staff_assess_content.sort_by ,t_staff_assess_1.cycle_id,
staff_assess_content.category ,staff_assess_content."name" as content_name ,
staff_assess_content.weight,staff_assess_content.level_value,staff_assess_content."rule"
from t_staff_assess_1
left join staff_assess_content on t_staff_assess_1.assess_id = staff_assess_content.staff_assess_id
where 1=1
`
condition := []interface{}{}
if len(param.TargetUserName) > 0 {
sqlStr += ` and t_staff_assess_1.target_user_name like ? `
condition = append(condition, "%"+param.TargetUserName+"%")
}
//加入排序
sqlStr += ` order by convert_to(t_staff_assess_1.target_user_name,'GBK'),staff_assess_content.sort_by `
//获取前置sql语句
sqlStr0 := d.useTStaffAssess(param.CompanyId, param.CycleId, param.OperaterId, param.BeginDay, param.Hrbp, param.Limit, param.Offset, string(domain.AssessSelf))
sqlStr = sqlStr0 + sqlStr
tx := d.transactionContext.PgTx
result := []UserAssessContent{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
// 项目管理-成员列表 根据周期的id和日期获取员工填写的评估内容,数量统计
// companyId int 公司id
// cycleId int, 评估周期id
// userId int, 用户id,谁要查看数据
// beginDay string, 周期中执行项目的时间
// hrbp 是否搜索HRBP角色的用户可以查看,1:是;-1:否
// limit int, 分页条数
// offset int 分页偏移
func (d *StaffAssessDao) CountUserAssess(param SearchConditin1) (int, error) {
sqlStr := ` select
count( distinct t_staff_assess_1.target_user_id) cnt
from t_staff_assess_1
where 1=1 `
condition := []interface{}{}
if len(param.TargetUserName) > 0 {
sqlStr += ` and t_staff_assess_1.target_user_name like ? `
condition = append(condition, "%"+param.TargetUserName+"%")
}
//获取前置sql语句
sqlStr0 := d.useTStaffAssess(param.CompanyId, param.CycleId, param.OperaterId, param.BeginDay, param.Hrbp, 5000, 0, string(domain.AssessSelf))
sqlStr = sqlStr0 + sqlStr
tx := d.transactionContext.PgTx
var result int
_, err := tx.QueryOne(pg.Scan(&result), sqlStr, condition...)
return result, err
}
// 生成的sql 根据用户的查看权限 ,获取可查看的评估任务,
// companyId int 公司id
// cycleId int, 评估周期id
// userId int, 用户id,谁要查看数据
// beginDay string, 周期中执行项目的时间
// hrbp 是否搜索HRBP角色的用户可以查看,1:是;-1:否
// limit int, 分页条数
// offset int 分页偏移
// assessType string 评估的类型
func (d *StaffAssessDao) useTStaffAssess(companyId int, cycleId int, userId int, beginDay string, hrbp int, limit int, offset int, assessType string) string {
sqlstr := `
set time zone 'PRC';
with t_user_department as (
select "user".id as user_id ,jsonb_array_elements_text ("user".department_id) as depart_id from "user"
where "user".company_id= %d and "user".deleted_at isnull
),
t_department as (
select department.id::text as depart_id from department where charge_user_ids @>'[%d]'
and "department".deleted_at isnull
),
-- 部门主管
t_user_1 as (
select t_user_department.user_id::text from t_user_department
join t_department on t_user_department.depart_id = t_department.depart_id
),
-- 如果是hrbp
t_project_1 as(
select evaluation_project.id as project_id
from evaluation_project
where evaluation_project.cycle_id =%d
and evaluation_project.hr_bp = %d
and evaluation_project.deleted_at isnull
),
-- 如果的项目管理员
t_project_2 as(
select evaluation_project.id as project_id
from evaluation_project
where evaluation_project.cycle_id =%d
and evaluation_project.pmp =1
and evaluation_project.pmp_ids @>'["%d"]'
and evaluation_project.deleted_at isnull
),
-- 合并数据
t_project_3 as (
select t_project_2.project_id from t_project_2
union
select t_project_1.project_id from t_project_1
),
-- 初步过滤数据
t_staff_assess_0 as (
select staff_assess.id as assess_id,
staff_assess.cycle_id,
staff_assess.target_user->>'userId' as target_user_id,
staff_assess.target_user->>'userName' as target_user_name,
to_char(staff_assess.begin_time,'YYYY-MM-DD') as begin_day,
staff_assess.evaluation_project_id
from staff_assess
join staff_assess_task on staff_assess.staff_assess_task_id = staff_assess_task.id
and staff_assess_task.deleted_at isnull
where staff_assess.cycle_id = %d
and to_char(staff_assess.begin_time,'YYYY-MM-DD')='%s'
and staff_assess."types" ='%s'
),
-- 根据查看权限过滤合并数据
t_staff_assess_1 as (
(select t_staff_assess_0.assess_id,
t_staff_assess_0.target_user_id,
t_staff_assess_0.target_user_name,
t_staff_assess_0.begin_day,
t_staff_assess_0.cycle_id
from t_staff_assess_0
join t_project_3 on t_staff_assess_0.evaluation_project_id = t_project_3.project_id
) union (select t_staff_assess_0.assess_id,
t_staff_assess_0.target_user_id,
t_staff_assess_0.target_user_name,
t_staff_assess_0.begin_day,
t_staff_assess_0.cycle_id
from t_staff_assess_0
join t_user_1 on t_staff_assess_0.target_user_id=t_user_1.user_id
)
limit %d offset %d
)
`
params := []interface{}{
companyId, userId, cycleId, hrbp, cycleId, userId, cycleId, beginDay, assessType, limit, offset,
}
sqlstr = fmt.Sprintf(sqlstr, params...)
return sqlstr
}
type ExportData1 struct {
AssessId string
ContentId int
TargetUserId string //被评估人的id
TargetUserName string //被评估人的名称
BeginDay string //评估的日期
EvaluationProjectId string //项目id
Value string //评估填写的值
SortBy int //评估项顺序
Category string //评估项分类
ContentName string //评估项名称
Weight float64 //权重
PromptText string //评估标准
Remark []domain.AssessContemtRemark
}
// 项目管理-成员列表 导出数据
func (d *StaffAssessDao) ExportDataUserAssess(param SearchConditin1) ([]ExportData1, error) {
if param.Offset < 0 {
param.Offset = 0
}
if param.Limit < 0 {
param.Limit = 5000
}
sqlStr := ` select
t_staff_assess_1.target_user_id,t_staff_assess_1.target_user_name,t_staff_assess_1.begin_day,
t_staff_assess_1.assess_id,staff_assess_content.id as content_id,
staff_assess_content.value ,staff_assess_content.sort_by ,
staff_assess_content.category ,staff_assess_content."name" as content_name ,
staff_assess_content.weight,staff_assess_content.prompt_text ,staff_assess_content.remark
from t_staff_assess_1
left join staff_assess_content on t_staff_assess_1.assess_id = staff_assess_content.staff_assess_id
where 1=1
`
condition := []interface{}{}
if len(param.TargetUserName) > 0 {
sqlStr += ` and t_staff_assess_1.target_user_name like ? `
condition = append(condition, "%"+param.TargetUserName+"%")
}
if len(param.TargetUserId) > 0 {
sqlStr += ` and t_staff_assess_1.target_user_id in (?) `
condition = append(condition, pg.In(param.TargetUserId))
}
//加入排序
sqlStr += ` order by convert_to(t_staff_assess_1.target_user_name,'GBK'),staff_assess_content.sort_by `
//获取前置sql语句
sqlStr0 := d.useTStaffAssess(param.CompanyId, param.CycleId, param.OperaterId, param.BeginDay, param.Hrbp, param.Limit, param.Offset, string(domain.AssessSelf))
sqlStr = sqlStr0 + sqlStr
tx := d.transactionContext.PgTx
var result []ExportData1
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
type AssessCycleDayMe struct {
BeginDay string
CycleId string
CycleName string
EndTime string
BeginTime string
}
// 根据评估的人执行人id,搜索 executorId参与的评估周期
func (d *StaffAssessDao) SearchAssessCycleMe(executorId int, companyId int, limit int, offset int) ([]AssessCycleDayMe, error) {
if limit < 0 {
limit = 20
}
if offset < 0 {
offset = 0
}
sqlStr := `
SELECT
distinct on(staff_assess_task.cycle_id,staff_assess_task.begin_day)
staff_assess_task.cycle_id,staff_assess_task.cycle_name ,
staff_assess_task.begin_day,
to_char(staff_assess_task.end_time at time zone 'PRC','YYYY-MM-DD HH24:MI:SS') as end_time,
to_char(staff_assess_task.begin_time at time zone 'PRC','YYYY-MM-DD HH24:MI:SS') as begin_time
FROM staff_assess_task
JOIN staff_assess ON staff_assess_task."id" = staff_assess."staff_assess_task_id"
WHERE staff_assess.company_id=?
and staff_assess_task.deleted_at isnull
and staff_assess.executor->>'userId'='?'
order by staff_assess_task.begin_day desc
limit ? offset ?
`
tx := d.transactionContext.PgTx
condition := []interface{}{
companyId, executorId, limit, offset,
}
result := []AssessCycleDayMe{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
// 根据评估的人执行人id,统计executorId参与的评估周期
func (d *StaffAssessDao) CountAssessCycleMe(executorId int, companyId int) (int, error) {
sqlStr := `
select count(DISTINCT (staff_assess_task.cycle_id,staff_assess_task.begin_day )) as cnt
FROM staff_assess_task
JOIN staff_assess ON staff_assess_task."id" = staff_assess."staff_assess_task_id"
WHERE staff_assess.company_id=?
and staff_assess_task.deleted_at isnull
and staff_assess.executor->>'userId'='?'
`
tx := d.transactionContext.PgTx
condition := []interface{}{
companyId, executorId,
}
var result int
_, err := tx.QueryOne(pg.Scan(&result), sqlStr, condition...)
return result, err
}
package dao
import (
"fmt"
"strconv"
"time"
"github.com/go-pg/pg/v10"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
)
type StaffAssessDao struct {
transactionContext *pgTransaction.TransactionContext
}
func NewStaffAssessDao(options map[string]interface{}) *StaffAssessDao {
var transactionContext *pgTransaction.TransactionContext
if value, ok := options["transactionContext"]; ok {
transactionContext = value.(*pgTransaction.TransactionContext)
}
return &StaffAssessDao{
transactionContext: transactionContext,
}
}
type CountData struct {
TargetUserId int
InviteTotal int
InviteCompleted int
}
// 获取员工邀请的人完成360评估的数量
func (d *StaffAssessDao) CountInviteAssessByTargetUser(userIds []int, assessTaskId int) ([]CountData, error) {
sqlStr := `SELECT staff_assess.target_user->>'userId' as target_user_id,
count(staff_assess."id") AS invite_total,
sum(
case WHEN staff_assess.status='completed' THEN 1
ELSE 0 END
) as invite_completed
FROM staff_assess
WHERE staff_assess.target_user->>'userId' IN(?)
AND staff_assess.types IN ('invite_same_super','invite_diff_super')
AND staff_assess.staff_assess_task_id = ?
GROUP BY target_user_id`
userIdList := []string{}
for _, v := range userIds {
uid := strconv.Itoa(v)
userIdList = append(userIdList, uid)
}
condition := []interface{}{
pg.In(userIdList), assessTaskId,
}
tx := d.transactionContext.PgTx
result := []CountData{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
func (d *StaffAssessDao) CountTargetUserInviteAssess1(userIds []int, cycleId int, beginDay string) ([]CountData, error) {
sqlStr := `SELECT
staff_assess.target_user->>'userId' as target_user_id,
count(staff_assess."id") AS invite_total,
sum(
case WHEN staff_assess.status='completed' THEN 1
ELSE 0 END
) as invite_completed
FROM staff_assess
WHERE staff_assess.target_user->>'userId' IN(?)
AND staff_assess.types IN ('invite_same_super','invite_diff_super')
and to_char(staff_assess.begin_time at time zone 'PRC','YYYY-MM-DD') = ?
and staff_assess.cycle_id =?
GROUP BY target_user_id`
userIdStr := []string{}
for _, v := range userIds {
str := strconv.Itoa(v)
userIdStr = append(userIdStr, str)
}
condition := []interface{}{
pg.In(userIdStr), beginDay, cycleId,
}
tx := d.transactionContext.PgTx
result := []CountData{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
// 根据评估的人执行人id,搜索 executorId参与的评估任务
func (d *StaffAssessDao) SearchAssessTaskMe(executorId int, companyId int, limit int, offset int) ([]*domain.StaffAssessTask, error) {
if limit < 0 {
limit = 20
}
if offset < 0 {
offset = 0
}
sqlStr := `SELECT DISTINCT staff_assess_task.* FROM staff_assess_task
JOIN staff_assess ON staff_assess_task."id" = staff_assess."staff_assess_task_id"
WHERE staff_assess.company_id=?
and staff_assess_task.deleted_at isnull
and staff_assess.executor->>'userId'='?'
order by staff_assess_task.id desc
limit ? offset ?
`
tx := d.transactionContext.PgTx
condition := []interface{}{
companyId, executorId, limit, offset,
}
result := []*domain.StaffAssessTask{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
// 搜索 executorId 参与的评估任务
func (d *StaffAssessDao) CountAssessTaskMe(executorId int, companyId int) (int, error) {
sqlStr := `SELECT count( DISTINCT staff_assess_task."id") FROM staff_assess_task
JOIN staff_assess ON staff_assess_task."id" = staff_assess."staff_assess_task_id"
WHERE staff_assess.company_id=?
and staff_assess_task.deleted_at isnull
and staff_assess.executor->>'userId'='?'
`
tx := d.transactionContext.PgTx
condition := []interface{}{
companyId, executorId,
}
result := 0
_, err := tx.QueryOne(pg.Scan(&result), sqlStr, condition...)
return result, err
}
// 获取所以已经执行的评估周期
type AssessCycle struct {
CycleId string `json:"cycleId"` //周期id
CompanyId string `json:"companyId"`
CycleName string `json:"cycleName"` //周期名称
}
// 获取所以已经执行的评估周期
func (d *StaffAssessDao) AllAssessCycleList(companyId int) ([]AssessCycle, error) {
sqlStr := `select
distinct
staff_assess_task.cycle_id ,
staff_assess_task.company_id ,
staff_assess_task.cycle_name
from staff_assess_task
where staff_assess_task.company_id = ?
and staff_assess_task.deleted_at isnull
order by staff_assess_task.cycle_id desc
`
tx := d.transactionContext.PgTx
condition := []interface{}{
companyId,
}
result := []AssessCycle{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
// 获取评估周期中的绩效考核日期
type AssessCycleDay struct {
BeginDay string `json:"beginDay"`
CycleId int `json:"cycleId"`
CycleName string `json:"cycleName"`
CompanyId string `json:"companyId"`
}
// 获取评估周期中的绩效考核日期
func (d *StaffAssessDao) AllAssessCycleDayList(companyId int, cycleId int) ([]AssessCycleDay, error) {
sqlStr := `select distinct staff_assess_task.begin_day ,
staff_assess_task.cycle_id ,
staff_assess_task.cycle_name,
staff_assess_task.company_id
from staff_assess_task
where staff_assess_task.cycle_id = ?
and company_id =?
and staff_assess_task.deleted_at isnull
order by staff_assess_task.begin_day desc `
tx := d.transactionContext.PgTx
condition := []interface{}{
cycleId, companyId,
}
result := []AssessCycleDay{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
// 获取员工填写评估内容
type UserAssessContent struct {
AssessId string `json:"assessId"`
ContentId int `json:"contentId"`
TargetUserId string `json:"targetUserId"` //被评估人的id
TargetUserName string `json:"targetUserName"` //被评估人的名称
BeginDay string `json:"beginDay"` //评估的日期
EvaluationProjectId string `json:"evaluationProjectId"` //项目id
Value string `json:"value"` //评估填写的值
LevelValue string `json:"levelValue"` //评级的值
Rule domain.EvaluationRule `json:"rule"` //规则
SortBy int `json:"sortBy"` //评估项顺序
Category string `json:"category"` //评估项分类
ContentName string `json:"contentName"` //评估项名称
Weight float64 `json:"weight"` //权重
CycleId string `json:"cycleId"` //周期id
}
type SearchConditin1 struct {
CompanyId int //公司id
AssessId int //评估任务id
CycleId int //周期id
BeginDay string //评估的日期
TargetUserName string //被评估人的名称
TargetUserId []string //查询指定的人
Limit int //分页
Offset int //分页
OperaterId int //用户的id是谁在搜索数据
Hrbp int //
}
// 项目管理-成员列表 根据周期的id和日期获取员工填写的评估内容
// companyId int 公司id
// cycleId int, 评估周期id
// userId int, 用户id,谁要查看数据
// beginDay string, 周期中执行项目的时间
// hrbp 是否搜索HRBP角色的用户可以查看,1:是;-1:否
// limit int, 分页条数
// offset int 分页偏移
func (d *StaffAssessDao) SearchUserAssessContent(param SearchConditin1) ([]UserAssessContent, error) {
if param.Offset < 0 {
param.Offset = 0
}
if param.Limit < 0 {
param.Limit = 20
}
sqlStr := ` select
t_staff_assess_1.target_user_id,t_staff_assess_1.target_user_name,t_staff_assess_1.begin_day,
t_staff_assess_1.assess_id,staff_assess_content.id as content_id,
staff_assess_content.value ,staff_assess_content.sort_by ,t_staff_assess_1.cycle_id,
staff_assess_content.category ,staff_assess_content."name" as content_name ,
staff_assess_content.weight,staff_assess_content.level_value,staff_assess_content."rule"
from t_staff_assess_1
left join staff_assess_content on t_staff_assess_1.assess_id = staff_assess_content.staff_assess_id
where 1=1
`
condition := []interface{}{}
if len(param.TargetUserName) > 0 {
sqlStr += ` and t_staff_assess_1.target_user_name like ? `
condition = append(condition, "%"+param.TargetUserName+"%")
}
//加入排序
sqlStr += ` order by convert_to(t_staff_assess_1.target_user_name,'GBK'),staff_assess_content.sort_by `
//获取前置sql语句
sqlStr0 := d.useTStaffAssess(param.CompanyId, param.CycleId, param.OperaterId, param.BeginDay, param.Hrbp, param.Limit, param.Offset, string(domain.AssessSelf))
sqlStr = sqlStr0 + sqlStr
tx := d.transactionContext.PgTx
result := []UserAssessContent{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
// 项目管理-成员列表 根据周期的id和日期获取员工填写的评估内容,数量统计
// companyId int 公司id
// cycleId int, 评估周期id
// userId int, 用户id,谁要查看数据
// beginDay string, 周期中执行项目的时间
// hrbp 是否搜索HRBP角色的用户可以查看,1:是;-1:否
// limit int, 分页条数
// offset int 分页偏移
func (d *StaffAssessDao) CountUserAssess(param SearchConditin1) (int, error) {
sqlStr := ` select
count( distinct t_staff_assess_1.target_user_id) cnt
from t_staff_assess_1
where 1=1 `
condition := []interface{}{}
if len(param.TargetUserName) > 0 {
sqlStr += ` and t_staff_assess_1.target_user_name like ? `
condition = append(condition, "%"+param.TargetUserName+"%")
}
//获取前置sql语句
sqlStr0 := d.useTStaffAssess(param.CompanyId, param.CycleId, param.OperaterId, param.BeginDay, param.Hrbp, 5000, 0, string(domain.AssessSelf))
sqlStr = sqlStr0 + sqlStr
tx := d.transactionContext.PgTx
var result int
_, err := tx.QueryOne(pg.Scan(&result), sqlStr, condition...)
return result, err
}
// 生成的sql 根据用户的查看权限 ,获取可查看的评估任务,
// companyId int 公司id
// cycleId int, 评估周期id
// userId int, 用户id,谁要查看数据
// beginDay string, 周期中执行项目的时间
// hrbp 是否搜索HRBP角色的用户可以查看,1:是;-1:否
// limit int, 分页条数
// offset int 分页偏移
// assessType string 评估的类型
func (d *StaffAssessDao) useTStaffAssess(companyId int, cycleId int, userId int, beginDay string, hrbp int, limit int, offset int, assessType string) string {
sqlstr := `
set time zone 'PRC';
with t_user_department as (
select "user".id as user_id ,jsonb_array_elements_text ("user".department_id) as depart_id from "user"
where "user".company_id= %d and "user".deleted_at isnull
),
t_department as (
select department.id::text as depart_id from department where charge_user_ids @>'[%d]'
and "department".deleted_at isnull
),
-- 部门主管
t_user_1 as (
select t_user_department.user_id::text from t_user_department
join t_department on t_user_department.depart_id = t_department.depart_id
),
-- 如果是hrbp
t_project_1 as(
select evaluation_project.id as project_id
from evaluation_project
where evaluation_project.cycle_id =%d
and evaluation_project.hr_bp = %d
and evaluation_project.deleted_at isnull
),
-- 如果的项目管理员
t_project_2 as(
select evaluation_project.id as project_id
from evaluation_project
where evaluation_project.cycle_id =%d
and evaluation_project.pmp =1
and evaluation_project.pmp_ids @>'["%d"]'
and evaluation_project.deleted_at isnull
),
-- 合并数据
t_project_3 as (
select t_project_2.project_id from t_project_2
union
select t_project_1.project_id from t_project_1
),
-- 初步过滤数据
t_staff_assess_0 as (
select staff_assess.id as assess_id,
staff_assess.cycle_id,
staff_assess.target_user->>'userId' as target_user_id,
staff_assess.target_user->>'userName' as target_user_name,
to_char(staff_assess.begin_time,'YYYY-MM-DD') as begin_day,
staff_assess.evaluation_project_id
from staff_assess
join staff_assess_task on staff_assess.staff_assess_task_id = staff_assess_task.id
and staff_assess_task.deleted_at isnull
where staff_assess.cycle_id = %d
and to_char(staff_assess.begin_time,'YYYY-MM-DD')='%s'
and staff_assess."types" ='%s'
),
-- 根据查看权限过滤合并数据
t_staff_assess_1 as (
(select t_staff_assess_0.assess_id,
t_staff_assess_0.target_user_id,
t_staff_assess_0.target_user_name,
t_staff_assess_0.begin_day,
t_staff_assess_0.cycle_id
from t_staff_assess_0
join t_project_3 on t_staff_assess_0.evaluation_project_id = t_project_3.project_id
) union (select t_staff_assess_0.assess_id,
t_staff_assess_0.target_user_id,
t_staff_assess_0.target_user_name,
t_staff_assess_0.begin_day,
t_staff_assess_0.cycle_id
from t_staff_assess_0
join t_user_1 on t_staff_assess_0.target_user_id=t_user_1.user_id
)
limit %d offset %d
)
`
params := []interface{}{
companyId, userId, cycleId, hrbp, cycleId, userId, cycleId, beginDay, assessType, limit, offset,
}
sqlstr = fmt.Sprintf(sqlstr, params...)
return sqlstr
}
type SummaryAssess struct {
AssessId string `json:"assessId"`
TargetUserId string `json:"targetUserId"` // 被评估人的id
TargetUserName string `json:"targetUserName"` // 被评估人的名称
BeginDay string `json:"beginDay"` // 评估的开始日期
EndTime time.Time `json:"endTime"` // 评估的截止日期
EvaluationProjectId string `json:"evaluationProjectId"` // 项目id
CycleId string `json:"cycleId"` // 周期id
Types domain.StaffAssessType `json:"types"` // 评估类型
Status domain.StaffAssessStatus `json:"status"` // 评估状态
}
func (d *StaffAssessDao) SummaryAssess(companyId int, operatorId int, cycleId int, beginDay string, hrbp int) ([]SummaryAssess, error) {
sqlString := `
set time zone 'PRC';
with t_user_department as (
select "user".id as user_id ,jsonb_array_elements_text ("user".department_id) as depart_id from "user"
where "user".company_id= %d and "user".deleted_at isnull
),
t_department as (
select department.id::text as depart_id from department where charge_user_ids @>'[%d]'
and "department".deleted_at isnull
),
-- 部门主管(所有下级用户ID)
t_user_1 as (
select t_user_department.user_id::text from t_user_department
join t_department on t_user_department.depart_id = t_department.depart_id
),
-- 如果是HRBP
t_project_1 as(
select evaluation_project.id as project_id
from evaluation_project
where evaluation_project.cycle_id =%d
and evaluation_project.hr_bp = %d
and evaluation_project.deleted_at isnull
),
-- 如果的项目管理员
t_project_2 as(
select evaluation_project.id as project_id
from evaluation_project
where evaluation_project.cycle_id =%d
and evaluation_project.pmp =1
and evaluation_project.pmp_ids @>'["%d"]'
and evaluation_project.deleted_at isnull
),
-- 合并数据
t_project_3 as (
select t_project_2.project_id from t_project_2
union
select t_project_1.project_id from t_project_1
),
-- 初步过滤数据
t_staff_assess_0 as (
select
staff_assess.id as assess_id,
staff_assess.cycle_id,
staff_assess.target_user->>'userId' as target_user_id,
staff_assess.target_user->>'userName' as target_user_name,
to_char(staff_assess.begin_time,'YYYY-MM-DD') as begin_day,
staff_assess.evaluation_project_id,
staff_assess.types,
staff_assess.status,
staff_assess.end_time
from staff_assess
join staff_assess_task on staff_assess.staff_assess_task_id = staff_assess_task.id
and staff_assess_task.deleted_at isnull
where staff_assess.cycle_id = %d
and to_char(staff_assess.begin_time,'YYYY-MM-DD')='%s'
),
-- 根据查看权限过滤合并数据
t_staff_assess_1 as (
( select
t_staff_assess_0.assess_id,
t_staff_assess_0.target_user_id,
t_staff_assess_0.target_user_name,
t_staff_assess_0.begin_day,
t_staff_assess_0.cycle_id,
t_staff_assess_0.evaluation_project_id,
t_staff_assess_0.types,
t_staff_assess_0.status,
t_staff_assess_0.end_time
from t_staff_assess_0
join t_project_3 on t_staff_assess_0.evaluation_project_id = t_project_3.project_id
) union
( select
t_staff_assess_0.assess_id,
t_staff_assess_0.target_user_id,
t_staff_assess_0.target_user_name,
t_staff_assess_0.begin_day,
t_staff_assess_0.cycle_id,
t_staff_assess_0.evaluation_project_id,
t_staff_assess_0.types,
t_staff_assess_0.status,
t_staff_assess_0.end_time
from t_staff_assess_0
join t_user_1 on t_staff_assess_0.target_user_id = t_user_1.user_id
)
)
`
params := []interface{}{companyId, operatorId, cycleId, hrbp, cycleId, operatorId, cycleId, beginDay}
sqlString = fmt.Sprintf(sqlString, params...)
sqlString = sqlString + ` select
t_staff_assess_1.target_user_id,
t_staff_assess_1.target_user_name,
t_staff_assess_1.begin_day,
t_staff_assess_1.cycle_id,
t_staff_assess_1.assess_id,
t_staff_assess_1.evaluation_project_id,
t_staff_assess_1.types,
t_staff_assess_1.status,
t_staff_assess_1.end_time
from t_staff_assess_1
where 1=1
`
tx := d.transactionContext.PgTx
var result = make([]SummaryAssess, 0)
_, err := tx.Query(&result, sqlString)
return result, err
}
type ExportData1 struct {
AssessId string
ContentId int
TargetUserId string //被评估人的id
TargetUserName string //被评估人的名称
BeginDay string //评估的日期
EvaluationProjectId string //项目id
Value string //评估填写的值
SortBy int //评估项顺序
Category string //评估项分类
ContentName string //评估项名称
Weight float64 //权重
PromptText string //评估标准
Remark []domain.AssessContemtRemark
}
// 项目管理-成员列表 导出数据
func (d *StaffAssessDao) ExportDataUserAssess(param SearchConditin1) ([]ExportData1, error) {
if param.Offset < 0 {
param.Offset = 0
}
if param.Limit < 0 {
param.Limit = 5000
}
sqlStr := ` select
t_staff_assess_1.target_user_id,t_staff_assess_1.target_user_name,t_staff_assess_1.begin_day,
t_staff_assess_1.assess_id,staff_assess_content.id as content_id,
staff_assess_content.value ,staff_assess_content.sort_by ,
staff_assess_content.category ,staff_assess_content."name" as content_name ,
staff_assess_content.weight,staff_assess_content.prompt_text ,staff_assess_content.remark
from t_staff_assess_1
left join staff_assess_content on t_staff_assess_1.assess_id = staff_assess_content.staff_assess_id
where 1=1
`
condition := []interface{}{}
if len(param.TargetUserName) > 0 {
sqlStr += ` and t_staff_assess_1.target_user_name like ? `
condition = append(condition, "%"+param.TargetUserName+"%")
}
if len(param.TargetUserId) > 0 {
sqlStr += ` and t_staff_assess_1.target_user_id in (?) `
condition = append(condition, pg.In(param.TargetUserId))
}
//加入排序
sqlStr += ` order by convert_to(t_staff_assess_1.target_user_name,'GBK'),staff_assess_content.sort_by `
//获取前置sql语句
sqlStr0 := d.useTStaffAssess(param.CompanyId, param.CycleId, param.OperaterId, param.BeginDay, param.Hrbp, param.Limit, param.Offset, string(domain.AssessSelf))
sqlStr = sqlStr0 + sqlStr
tx := d.transactionContext.PgTx
var result []ExportData1
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
type AssessCycleDayMe struct {
BeginDay string
CycleId string
CycleName string
EndTime string
BeginTime string
}
// 根据评估的人执行人id,搜索 executorId参与的评估周期
func (d *StaffAssessDao) SearchAssessCycleMe(executorId int, companyId int, limit int, offset int) ([]AssessCycleDayMe, error) {
if limit < 0 {
limit = 20
}
if offset < 0 {
offset = 0
}
sqlStr := `
SELECT
distinct on(staff_assess_task.cycle_id,staff_assess_task.begin_day)
staff_assess_task.cycle_id,staff_assess_task.cycle_name ,
staff_assess_task.begin_day,
to_char(staff_assess_task.end_time at time zone 'PRC','YYYY-MM-DD HH24:MI:SS') as end_time,
to_char(staff_assess_task.begin_time at time zone 'PRC','YYYY-MM-DD HH24:MI:SS') as begin_time
FROM staff_assess_task
JOIN staff_assess ON staff_assess_task."id" = staff_assess."staff_assess_task_id"
WHERE staff_assess.company_id=?
and staff_assess_task.deleted_at isnull
and staff_assess.executor->>'userId'='?'
order by staff_assess_task.begin_day desc
limit ? offset ?
`
tx := d.transactionContext.PgTx
condition := []interface{}{
companyId, executorId, limit, offset,
}
result := []AssessCycleDayMe{}
_, err := tx.Query(&result, sqlStr, condition...)
return result, err
}
// 根据评估的人执行人id,统计executorId参与的评估周期
func (d *StaffAssessDao) CountAssessCycleMe(executorId int, companyId int) (int, error) {
sqlStr := `
select count(DISTINCT (staff_assess_task.cycle_id,staff_assess_task.begin_day )) as cnt
FROM staff_assess_task
JOIN staff_assess ON staff_assess_task."id" = staff_assess."staff_assess_task_id"
WHERE staff_assess.company_id=?
and staff_assess_task.deleted_at isnull
and staff_assess.executor->>'userId'='?'
`
tx := d.transactionContext.PgTx
condition := []interface{}{
companyId, executorId,
}
var result int
_, err := tx.QueryOne(pg.Scan(&result), sqlStr, condition...)
return result, err
}
... ...
... ... @@ -359,6 +359,21 @@ func (c *StaffAssessController) SaveAssessCache() {
}
}
// QuerySummary 项目管理-查询总览
func (c *StaffAssessController) QuerySummary() {
srv := service.NewStaffAssessServeice()
in := &query.SummaryCommand{}
if err := c.Unmarshal(in); err != nil {
c.Response(nil, application.ThrowError(application.ARG_ERROR, err.Error()))
} else {
if user := middlewares.GetUser(c.Ctx); user != nil {
in.CompanyId = int(user.CompanyId)
in.OperatorId = int(user.UserId)
}
c.Response(srv.QuerySummary(in))
}
}
// 员工绩效-项目管理-矩阵分析
func (c *StaffAssessController) AnalysisData() {
srv := service.NewStaffAssessServeice()
... ...
... ... @@ -32,6 +32,7 @@ func init() {
web.NSCtrlPost("/info", (*controllers.StaffAssessController).GetAssessInfo), //通用获取员工评估的详情
web.NSCtrlPut("/info", (*controllers.StaffAssessController).SaveAssessInfo), //通用保存员工评估的详情
web.NSCtrlPut("/info-cache", (*controllers.StaffAssessController).SaveAssessCache), //通用保存员工评估的详情(缓存)
web.NSCtrlPost("/summary", (*controllers.StaffAssessController).QuerySummary), //项目管理-总览
// web.NSCtrlPost("/target-user/invite/list", (*controllers.StaffAssessController).ListTargetUserInviteAssess), //获取被评估员工360评估的列表
//web.NSCtrlPost("/me/target-user/supper/list", (*controllers.StaffAssessController).ListTargetUserMeSupperAssess), //获取我被上级评估的列表
// web.NSCtrlPost("/target-user/self/info", (*controllers.StaffAssessController).GetAssessTargetUserSelfInfo), //获取被评估员工的自评反馈详情
... ...