From cc449056a215d4d77028871f365556c44b493185 Mon Sep 17 00:00:00 2001 From: herenshan112 Date: Sat, 18 Mar 2023 09:29:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=8B=E6=9C=BA=E7=AB=AF=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/shiyan/maptostruct/department.go | 87 +- api/shiyan/maptostruct/type.go | 4 + .../departmentpc/dingliang.go | 10 +- .../departmentweb/department.go | 1614 +++++++++++++++++ .../departmentseting/departmentweb/type.go | 209 +++ api/workflow/workflowengine/class.go | 46 +- api/workflow/workflowengine/flowhandle.go | 151 ++ api/workflow/workflowengine/shiyan.go | 3 + apirouter/apishiyan/maptostruct.go | 2 + apirouter/v1/departmentseting/web.go | 10 + apirouter/workflowrouter/flowrouter.go | 4 + config/configDatabase/database.go | 4 +- .../modelshr/administrative_organization.go | 1 + overall/publicmethod/technique.go | 201 +- overall/publicmethod/type.go | 16 + 15 files changed, 2335 insertions(+), 27 deletions(-) create mode 100644 api/version1/departmentseting/departmentweb/department.go create mode 100644 api/workflow/workflowengine/flowhandle.go diff --git a/api/shiyan/maptostruct/department.go b/api/shiyan/maptostruct/department.go index 03b148f..39d0929 100644 --- a/api/shiyan/maptostruct/department.go +++ b/api/shiyan/maptostruct/department.go @@ -1,6 +1,7 @@ package maptostruct import ( + "fmt" "key_performance_indicators/models/modelshr" "key_performance_indicators/models/modelskpi" "key_performance_indicators/overall" @@ -273,26 +274,84 @@ func ChuLiTiBaoRenGuoDu(dimensionId, targetId, targetSunId, targetBylaws, postId /* * @ 作者: 秦东 -@ 时间: 2023-02-07 11:29:53 -@ 功能: 处理指标提交人 +@ 时间: 2023-03-17 14:00:49 +@ 功能: 校正被考核部门 @ 参数 - #dimensionId 纬度 - #targetId 指标 - #targetSunId 栏目 - #targetBylaws 指标细则 - #orgId 行政组织ID - #postId 岗位 - #typeInt 类型(1:公司级;2:部门级) - #manKey 提报人Key - #class 1:定性考核;2:定量考核 - #level (1:指标;2:子目标;3:细则) + # @ 返回值 - #err + # @ 方法原型 - #handTarReport(dimensionId, targetId, targetSunId, targetBylaws, postId int64, typeInt, class, level int, orgId, manKey string) (err error) + # */ +func (a *ApiMethod) XiangzhengBeikaoBumen(c *gin.Context) { + var receivedValue XiaoZengTime + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if receivedValue.DateTime == "" { + publicmethod.Result(100, err, c) + return + } + tayTime := time.Now().Unix() + currentYears := publicmethod.UnixTimeToDay(tayTime, 16) + currentMonths := publicmethod.UnixTimeToDay(tayTime, 17) + if receivedValue.DateTime != "" { + var dayTime publicmethod.DateTimeTotimes + dayTime.BaisStrToTime(receivedValue.DateTime) + if dayTime.Years != "" { + currentYears = dayTime.Years + } + if dayTime.Months != "" { + currentMonths = dayTime.Months + } + } + riQiStr := fmt.Sprintf("%v-%v", currentYears, currentMonths) + startTime, endTime := publicmethod.GetAppointMonthStarAndEndTime(riQiStr) + var evalProcess []modelskpi.EvaluationProcess + err = overall.CONSTANT_DB_KPI.Where("`ep_happen_time` BETWEEN ? AND ?", startTime, endTime).Find(&evalProcess).Error + if err != nil || len(evalProcess) < 1 { + publicmethod.Result(107, err, c) + return + } + for _, v := range evalProcess { + if v.TypeClass == 1 { + //定性 + HuiGaiDingXing(v.OrderKey) + } else { + //定量 + HuiGaiDingLiang(v.OrderKey) + } + } + publicmethod.Result(0, err, c) +} + +// 回改定量考核部门 +func HuiGaiDingLiang(key int64) { + var scoreFlowCont modelskpi.FlowLog + err := scoreFlowCont.GetCont(map[string]interface{}{"`fl_key`": key}, "`fl_duty_department`") + if err == nil { + if scoreFlowCont.DutyDepartment != 0 { + var evalProCont modelskpi.EvaluationProcess + evalProCont.EiteCont(map[string]interface{}{"`ep_order_key`": key}, map[string]interface{}{"`ep_accept_department`": scoreFlowCont.DutyDepartment}) + } + } +} + +// 回改定性考核部门 +func HuiGaiDingXing(key int64) { + var scoreFlowCont modelskpi.ScoreFlow + err := scoreFlowCont.GetCont(map[string]interface{}{"`sf_key`": key}, "`sf_duty_department`") + if err == nil { + if scoreFlowCont.DutyDepartment != 0 { + var evalProCont modelskpi.EvaluationProcess + evalProCont.EiteCont(map[string]interface{}{"`ep_order_key`": key}, map[string]interface{}{"`ep_accept_department`": scoreFlowCont.DutyDepartment}) + } + } +} diff --git a/api/shiyan/maptostruct/type.go b/api/shiyan/maptostruct/type.go index f4a97a2..92362f4 100644 --- a/api/shiyan/maptostruct/type.go +++ b/api/shiyan/maptostruct/type.go @@ -66,3 +66,7 @@ type hrUsernameAndPassword struct { VerificationCode string `json:"verification_code"` publicmethod.PublicName } + +type XiaoZengTime struct { + DateTime string `json"datetime"` +} diff --git a/api/version1/departmentseting/departmentpc/dingliang.go b/api/version1/departmentseting/departmentpc/dingliang.go index a591293..dd657ea 100644 --- a/api/version1/departmentseting/departmentpc/dingliang.go +++ b/api/version1/departmentseting/departmentpc/dingliang.go @@ -113,17 +113,17 @@ func (a *ApiMethod) GetQuantitativeTasks(c *gin.Context) { sendCont.DimensionWeight, sendCont.TargetWeight = getPlanVersionWeghit(v.QualEvalId, strconv.FormatInt(v.Dimension, 10), strconv.FormatInt(v.Target, 10)) //获取目标设定 quanTitWhere := publicmethod.MapOut[string]() - quanTitWhere["company_id"] = v.Group - quanTitWhere["department_id"] = v.AcceptEvaluation - quanTitWhere["dimension"] = v.Dimension + // quanTitWhere["company_id"] = v.Group + quanTitWhere["departmentid"] = v.AcceptEvaluation + // quanTitWhere["dimension"] = v.Dimension quanTitWhere["target"] = v.Target if v.DetailedTarget != 0 { - quanTitWhere["detailed"] = v.DetailedTarget + quanTitWhere["targetconfig"] = v.DetailedTarget } quanTitWhere["year"] = publicmethod.UnixTimeToDay(time.Now().Unix(), 16) quanTitWhere["timecopy"] = AllZreoConfig(v.Cycles) //目标值设定 - var quanTitCont modelskpi.QuanPeopleConfig + var quanTitCont modelskpi.QuantitativeConfig quanTitCont.GetCont(quanTitWhere) //全奖值、零奖值、封顶值 sendCont.ZeroPrize = strconv.FormatFloat(float64(quanTitCont.Zeroprize)/100, 'f', -1, 64) diff --git a/api/version1/departmentseting/departmentweb/department.go b/api/version1/departmentseting/departmentweb/department.go new file mode 100644 index 0000000..46e62ef --- /dev/null +++ b/api/version1/departmentseting/departmentweb/department.go @@ -0,0 +1,1614 @@ +package departmentweb + +import ( + "encoding/json" + "fmt" + "key_performance_indicators/models/modelshr" + "key_performance_indicators/models/modelskpi" + "key_performance_indicators/overall" + "key_performance_indicators/overall/publicmethod" + "math" + "sort" + "time" + + "strconv" + + "github.com/gin-gonic/gin" +) + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-11 08:40:44 +@ 功能: 指标列表 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) TargetListForDepartment(c *gin.Context) { + var receivedValue GetDepartTargetCont + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if receivedValue.Id == "" { + publicmethod.Result(1, err, c, "未知行政组织结构!") + return + } + var targetCont modelskpi.EvaluationTarget + gormDb := overall.CONSTANT_DB_KPI.Table(fmt.Sprintf("%s et", targetCont.TableName())).Where("et.`et_state` = 1 ") + if receivedValue.Attribute != 0 { + gormDb = gormDb.Where("et.`et_type` = ?", receivedValue.Attribute) + } + gormDb = gormDb.Joins("JOIN target_department td ON et.et_id = td.target_id AND td.target_sun_id = 0 AND td.target_bylaws = 0 AND td.`type` = 1 AND td.`post_id` = 0 AND td.state = 1 AND td.level = 1 AND td.`department_id` = ?", receivedValue.Id) + var targetIdAry []int64 + err = gormDb.Distinct("et.et_id").Find(&targetIdAry).Error + if err != nil || len(targetIdAry) < 1 { + publicmethod.Result(105, err, c) + return + } + var departmentTargetList []modelskpi.EvaluationTarget + err = overall.CONSTANT_DB_KPI.Model(&modelskpi.EvaluationTarget{}).Select("et_id,et_title").Where("et_id IN ?", targetIdAry).Order("`et_id` ASC").Find(&departmentTargetList).Error + if err != nil || len(departmentTargetList) < 1 { + publicmethod.Result(105, err, c) + return + } + var outputContent []SendTargetCont + for _, v := range departmentTargetList { + var outCont SendTargetCont + outCont.Id = strconv.FormatInt(v.Id, 10) + outCont.Name = v.Title + outputContent = append(outputContent, outCont) + } + publicmethod.Result(0, outputContent, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-11 11:14:41 +@ 功能: 根据部门、指标、年份统计每月的目标值、实际值、达成率 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) BasisDepartTargetTimeStatistics(c *gin.Context) { + var receivedValue BaseDepartTargetTime + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if receivedValue.OrgId == "" { + publicmethod.Result(1, err, c, "未知行政组织!无法统计!") + return + } + if receivedValue.TargetId == "" { + publicmethod.Result(1, err, c, "未知指标!无法统计!") + return + } + tarWhere := publicmethod.MapOut[string]() + tarWhere["et_id"] = receivedValue.TargetId + //获取指标信息 + var targetCont modelskpi.EvaluationTarget + err = targetCont.GetCont(tarWhere) + if err != nil { + publicmethod.Result(1, err, c, "未知指标!无法统计!") + return + } + tadyTime := time.Now().Unix() + dateYear := publicmethod.UnixTimeToDay(tadyTime, 16) + dateMonthMAx := 12 + if receivedValue.DateTime == "" { + receivedValue.DateTime = dateYear + dateMonthVal := publicmethod.UnixTimeToDay(tadyTime, 17) + dateMonthMAx, _ = strconv.Atoi(dateMonthVal) + } else { + if receivedValue.DateTime == dateYear { + dateMonthVal := publicmethod.UnixTimeToDay(tadyTime, 17) + dateMonthMAx, _ = strconv.Atoi(dateMonthVal) + } + } + mubiaozhiTitle := fmt.Sprintf("目标值(%v)", targetCont.Uniteing) + shijizhiTitle := fmt.Sprintf("实际值(%v)", targetCont.Uniteing) + dachenglvTitle := fmt.Sprintf("达成率(%v)", "%") + + var sendCont DrawEcharStatisticsCont + sendCont.Legend = []string{mubiaozhiTitle, shijizhiTitle, dachenglvTitle} + var dttsbSync GetDttsb + for i := 1; i <= dateMonthMAx; i++ { + sendCont.XAxisVal = append(sendCont.XAxisVal, fmt.Sprintf("%v月", i)) + SyncSeting.Add(1) + go dttsbSync.PerformCalculation(receivedValue.OrgId, receivedValue.TargetId, receivedValue.DateTime, i) + } + SyncSeting.Wait() + Target, Actuality, CompletionRate, axisLeftMax, axisLeftMin, axisRightMax, axisRightMin := dttsbSync.readPlanTaskData() //读取协程数据 + + //根据维度序号排序 + sort.Slice(Target, func(i, j int) bool { + return Target[i].Sort < Target[j].Sort + }) + sort.Slice(Actuality, func(i, j int) bool { + return Actuality[i].Sort < Actuality[j].Sort + }) + sort.Slice(CompletionRate, func(i, j int) bool { + return CompletionRate[i].Sort < CompletionRate[j].Sort + }) + var muBiaoVal Seriescont + muBiaoVal.Name = mubiaozhiTitle //名称 + muBiaoVal.Type = "bar" //图像类型 + muBiaoVal.Tooltip = targetCont.Uniteing //单位 + for _, tv := range Target { + muBiaoVal.Data = append(muBiaoVal.Data, tv.Val) + } + sendCont.Series = append(sendCont.Series, muBiaoVal) + var siJiVal Seriescont + siJiVal.Name = shijizhiTitle //名称 + siJiVal.Type = "bar" //图像类型 + siJiVal.Tooltip = targetCont.Uniteing //单位 + for _, av := range Actuality { + siJiVal.Data = append(siJiVal.Data, av.Val) + } + sendCont.Series = append(sendCont.Series, siJiVal) + var daChengLvVal Seriescont + daChengLvVal.Name = dachenglvTitle //名称 + daChengLvVal.Type = "line" //图像类型 + daChengLvVal.Tooltip = "%" //单位 + for _, cv := range CompletionRate { + daChengLvVal.Data = append(daChengLvVal.Data, cv.Val) + } + sendCont.Series = append(sendCont.Series, daChengLvVal) + + var yMaxValLeft float64 + var yMinValLeft float64 + var yMaxValRight float64 + var yMinValRight float64 + + yMinValLeft = axisLeftMin + if axisLeftMin < 0 { + yMinValLeft = 0 + } + if axisLeftMax == 0 && axisLeftMin == 0 { + yMaxValLeft = 10 + } else { + yMaxValLeft = axisLeftMax + } + fmt.Printf("yMinValLeft:%v----------->yMinValLeft:%v----------->axisLeftMax:%v\n", yMinValLeft, yMinValLeft, axisLeftMax) + maxYZhiStr := strconv.FormatFloat(yMaxValLeft, 'f', 0, 64) + maxYZhiInt, _ := strconv.ParseInt(maxYZhiStr, 10, 64) + quyuzhi := maxYZhiInt % 10 + if yMaxValLeft > 1000 { + yMaxValLeft = yMaxValLeft - float64(quyuzhi) + 100 + } else { + if yMaxValLeft < 10 { + yMaxValLeft = yMaxValLeft + 1 + } else { + yMaxValLeft = yMaxValLeft - float64(quyuzhi) + 10 + } + + } + + fmt.Printf("maxYZhiStr:%v----------->maxYZhiInt:%v----------->quyuzhi:%v----------->yMaxValLeft:%v\n", maxYZhiStr, maxYZhiInt, quyuzhi, yMaxValLeft) + + yMinValRight = axisRightMin + if axisRightMin < 0 { + yMinValRight = 0 + } + if axisRightMax == 0 && axisRightMin == 0 { + yMaxValRight = 10 + } else { + yMaxValRight = axisRightMax + } + + fmt.Printf("yMaxValRight:%v----------->yMinValRight:%v----------->axisRightMax:%v\n", yMaxValRight, yMinValRight, axisRightMax) + + maxYZhiStrRight := strconv.FormatFloat(yMaxValRight, 'f', 0, 64) + maxYZhiIntRight, _ := strconv.ParseInt(maxYZhiStrRight, 10, 64) + quyuzhiRight := maxYZhiIntRight % 10 + if yMaxValRight < 10 { + yMaxValRight = yMaxValRight + 1 + } else { + yMaxValRight = yMaxValRight - float64(quyuzhiRight) + 10 + } + + // if yMaxValRight > 100 { + // yMaxValRight = 100 + // } + + fmt.Printf("maxYZhiStrRight:%v----------->maxYZhiIntRight:%v----------->quyuzhiRight:%v\n", maxYZhiStrRight, maxYZhiIntRight, quyuzhiRight) + + var yAxisOne YaxisStruct + yAxisOne.Name = "目标值 / 实际值 / 单位" + // yAxisOne.Name = fmt.Sprintf("目标值(%v)/实际值(%v)/单位(%v)", targetCont.Uniteing, targetCont.Uniteing, "%") + yAxisOne.Type = "value" //图像类型 + yAxisOne.Min = yMinValLeft //最小值 + yAxisOne.Max = yMaxValLeft //最大值 + yAxisOne.FormAtter = targetCont.Uniteing + sendCont.YAxis = append(sendCont.YAxis, yAxisOne) + var yAxisTwo YaxisStruct + yAxisTwo.Name = "达成率" + yAxisTwo.Type = "value" //图像类型 + yAxisTwo.Min = yMinValRight //最小值 + yAxisTwo.Max = yMaxValRight //最大值 + yAxisTwo.FormAtter = "%" + sendCont.YAxis = append(sendCont.YAxis, yAxisTwo) + fmt.Printf("%v---------->%v------------->%v------------->%v------------->%v------------->%v------------->%v\n", axisLeftMax, axisLeftMin, axisRightMax, axisRightMin, yAxisOne, yAxisTwo, yMaxValLeft) + publicmethod.Result(0, sendCont, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-11 14:42:20 +@ 功能: 计算目标值,实际值,达成率 +@ 参数 + + #orgId 行政组织 + #targetId 指标 + #years 年 + #month 月 + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (g *GetDttsb) PerformCalculation(orgId, targetId, years string, month int) { + g.mutext.Lock() + defer g.mutext.Unlock() + var listCont []modelskpi.FlowDataLogType + err := overall.CONSTANT_DB_KPI.Where("`department` = ? AND `targetid` = ? AND `year` = ? AND `month` = ?", orgId, targetId, years, month).Find(&listCont).Error + var maxAllPrize float64 + var minZeroPrize float64 + var maxCappingPrize float64 + var sumScore float64 + if err == nil && len(listCont) > 0 { + for _, v := range listCont { //遍历数据 + minZeroPrize, maxAllPrize, maxCappingPrize = GetTargetSetUp(v.Baseline, orgId, targetId, years, month, 3) + + if v.ScoringMethod == 1 { + sumScore = sumScore + float64(v.Score) + } else { + sumScore = sumScore + float64(v.ScoringScore) + } + } + } + + maxAllPrizeChuLi := publicmethod.DecimalEs(maxAllPrize/100, 2) + sumScoreChuLi := publicmethod.DecimalEs(sumScore/100, 2) + + if g.AxisLeftMax < maxAllPrizeChuLi { + g.AxisLeftMax = maxAllPrizeChuLi + } + if g.AxisLeftMax < sumScoreChuLi { + g.AxisLeftMax = sumScoreChuLi + } + if g.AxisLeftMin > maxAllPrizeChuLi { + g.AxisLeftMin = maxAllPrizeChuLi + } + if g.AxisLeftMin > sumScoreChuLi { + g.AxisLeftMin = sumScoreChuLi + } + //目标值 + var targetConfig GetDttsbCont + targetConfig.Val = publicmethod.DecimalEs(maxAllPrize/100, 2) + targetConfig.Sort = month + g.Target = append(g.Target, targetConfig) + //实际值 + var actualityConfig GetDttsbCont + actualityConfig.Val = publicmethod.DecimalEs(sumScore/100, 2) + actualityConfig.Sort = month + g.Actuality = append(g.Actuality, actualityConfig) + //达成率 + dachenglv := DepartTargetCompletionRate(sumScore, minZeroPrize, maxAllPrize, maxCappingPrize) + var completionRateConfig GetDttsbCont + completionRateConfig.Val = dachenglv + completionRateConfig.Sort = month + g.CompletionRate = append(g.CompletionRate, completionRateConfig) + + if g.AxisRightMax < dachenglv { + g.AxisRightMax = dachenglv + } + if g.AxisRightMin > dachenglv { + g.AxisRightMin = dachenglv + } + + SyncSeting.Done() +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-11 15:56:21 +@ 功能: 计算达成率 +@ 参数 + + #actualValue 实际值 + #zeroPrize 零奖值 + #allPrize 全奖值 + #cappingPrize 封顶值 + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func DepartTargetCompletionRate(actualValue, zeroPrize, allPrize, cappingPrize float64) (percentageComplete float64) { + + if allPrize == 0 && zeroPrize == 0 { //全奖值与零奖值都为0 那么达成率 100 + percentageComplete = 10000 + } else { + if allPrize > zeroPrize { //如果全奖值大于零奖值 执行一下操作 + if actualValue <= zeroPrize { //实际结算值小于零奖值 那么达成率0 + percentageComplete = 0 + } else { //实际结算值大于零奖值 + chushu := actualValue - zeroPrize + beiChuShu := allPrize - zeroPrize + if beiChuShu != 0 { + percentageComplete = publicmethod.DecimalEs(chushu/beiChuShu, 4) + + if percentageComplete > 0 { + percentageComplete = percentageComplete * 10000 + if percentageComplete > cappingPrize { + percentageComplete = cappingPrize + } + } + } else { //被除数为0时 那么达成率0 + percentageComplete = 0 + } + } + } else { //如果全奖值小于零奖值 执行一下操作 + if actualValue >= zeroPrize { //实际结算值大于零奖值 那么达成率0 + percentageComplete = 0 + } else { //实际值小于零奖值 + chushu := actualValue - zeroPrize + beiChuShu := allPrize - zeroPrize + if beiChuShu != 0 { + percentageComplete = publicmethod.DecimalEs(chushu/beiChuShu, 4) + if percentageComplete > 0 { + percentageComplete = percentageComplete * 10000 + if percentageComplete > cappingPrize { + percentageComplete = cappingPrize + } + } + } else { //被除数为0时 那么达成率0 + percentageComplete = 0 + } + } + } + } + percentageComplete = publicmethod.DecimalEs(percentageComplete/100, 2) + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-11 15:55:35 +@ 功能: 获取目标设置 +@ 参数 + + #targetConfigStr 当前数据记录的全奖值、零奖值、封顶值 + #orgId 行政组织 + #targetId 指标 + #years 年 + #month 月 + +@ 返回值 + + #zeroPrize 零奖值 + #allPrize 全奖值 + #cappingPrize 封顶值 + +@ 方法原型 + + #func GetTargetSetUp(targetConfigStr, orgId, targetId, years string, month, class int) (zeroPrize, allPrize, cappingPrize float64) +*/ +func GetTargetSetUp(targetConfigStr, orgId, targetId, years string, month, class int) (zeroPrize, allPrize, cappingPrize float64) { + var targetConfig []FlowLogAllZreo + jsonErr := json.Unmarshal([]byte(targetConfigStr), &targetConfig) + + if jsonErr != nil || len(targetConfig) < 1 { + var qualConfig modelskpi.QuantitativeConfig + where := publicmethod.MapOut[string]() + where["departmentid"] = orgId + where["target"] = orgId + where["type"] = class + where["year"] = years + where["timecopy"] = month + where["`state`"] = 1 + qualConfig.GetCont(where, "`zeroprize`", "`allprize`", "`capping_val`") + zeroPrize = qualConfig.Zeroprize + allPrize = qualConfig.Allprize + cappingPrize = qualConfig.CappingVal + } + for _, v := range targetConfig { + if v.TargetId == targetId { + zeroPrize = v.Zeroprize + allPrize = v.Allprize + cappingPrize = v.Capping + // return + } + } + // fmt.Printf("这是获取目标值数据------------>targetConfigStr:%v----------->orgId:%v----------->targetId:%v----------->years:%v----------->month:%v----------->class:%v----------->jsonErr:%v----------->targetConfig:%v----------->zeroPrize:%v----------->allPrize:%v----------->cappingPrize:%v\n", targetConfigStr, orgId, targetId, years, month, class, jsonErr, targetConfig, zeroPrize, allPrize, cappingPrize) + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-13 13:42:07 +@ 功能: 历史同比根据部门、指标、年份统计每月的目标值、实际值、达成率 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) BasisDepartTargetTimeStatisticsYOY(c *gin.Context) { + var receivedValue BaseDepartTargetTimeYOY + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if receivedValue.OrgId == "" { + publicmethod.Result(1, err, c, "未知行政组织!无法统计!") + return + } + if receivedValue.TargetId == "" { + publicmethod.Result(1, err, c, "未知指标!无法统计!") + return + } + tarWhere := publicmethod.MapOut[string]() + tarWhere["et_id"] = receivedValue.TargetId + //获取指标信息 + var targetCont modelskpi.EvaluationTarget + err = targetCont.GetCont(tarWhere) + if err != nil { + publicmethod.Result(1, err, c, "未知指标!无法统计!") + return + } + tadyTime := time.Now().Unix() + dateYear, _ := strconv.Atoi(publicmethod.UnixTimeToDay(tadyTime, 16)) + dateMonthMAx := 12 + if len(receivedValue.DateTime) > 0 { + if len(receivedValue.DateTime) == 1 { + if receivedValue.DateTime[0] == dateYear { + dateMonthVal := publicmethod.UnixTimeToDay(tadyTime, 17) + dateMonthMAx, _ = strconv.Atoi(dateMonthVal) + } + } else { + sort.Slice(receivedValue.DateTime, func(i, j int) bool { + return receivedValue.DateTime[i] < receivedValue.DateTime[j] + }) + } + } else { + dateMonthVal := publicmethod.UnixTimeToDay(tadyTime, 17) + dateMonthMAx, _ = strconv.Atoi(dateMonthVal) + receivedValue.DateTime = append(receivedValue.DateTime, dateYear) + } + var sendData SendYOYData + sendData.YAxis.Type = "value" + sendData.YAxis.Name = "实际值" + sendData.YAxis.FormAtter = targetCont.Uniteing + var goSyncData GeteveryYearDttsb + //获取X轴数据 + for i := 1; i <= dateMonthMAx; i++ { + sendData.XAxisVal = append(sendData.XAxisVal, fmt.Sprintf("%v月", i)) + } + //获取Y轴数据 + for _, v := range receivedValue.DateTime { + SyncSeting.Add(1) + go goSyncData.getOrgBylawsTime(receivedValue.OrgId, receivedValue.TargetId, v, dateMonthMAx) + } + + SyncSeting.Wait() + targetData, maxVal, minVal := goSyncData.readPlanTaskData() + if maxVal == 0 && minVal == 0 { + sendData.YAxis.Max = 10 + sendData.YAxis.Min = 0 + } else { + chaYiZhi := math.Ceil((maxVal - minVal) / 5) + if maxVal < 0 { + sendData.YAxis.Max = maxVal - chaYiZhi + } else { + sendData.YAxis.Max = maxVal + chaYiZhi + } + } + maxYZhiStr := strconv.FormatFloat(sendData.YAxis.Max, 'f', 0, 64) + maxYZhiInt, _ := strconv.ParseInt(maxYZhiStr, 10, 64) + quyuzhi := maxYZhiInt % 10 + sendData.YAxis.Max = sendData.YAxis.Max - float64(quyuzhi) + 10 + + fmt.Printf("maxYZhiStr:%v------------------>maxYZhiInt:%v---------------->quyuzhi:%v\n", maxYZhiStr, maxYZhiInt, quyuzhi) + //根据维度月份排序 + sort.Slice(targetData, func(i, j int) bool { + return targetData[i].Months < targetData[j].Months + }) + for _, v := range targetData { + var serInfo Seriescont + serInfo.Name = v.MonthStr + serInfo.Type = "bar" + serInfo.Tooltip = targetCont.Uniteing + serInfo.Data = v.MonthDataList + sendData.Series = append(sendData.Series, serInfo) + } + fmt.Printf("targetData:%v------------------>maxVal:%v---------------->minVal:%v---------------->Max:%v\n", targetData, maxVal, minVal, sendData.YAxis.Max) + publicmethod.Result(0, sendData, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-13 14:33:07 +@ 功能: 协程计算月份历史值 +@ 参数 + + #orgId 行政组织 + #targetId 指标 + #years 时间(年) + #months 时间(月) + +@ 返回值 + + # + +@ 方法原型 + + #(g *GeteveryYearDttsb) getOrgBylawsTime(orgId, targetId string, dateTime []int, months int) +*/ +func (g *GeteveryYearDttsb) getOrgBylawsTime(orgId, targetId string, years, months int) { + g.mutext.Lock() + defer g.mutext.Unlock() + var dataCont HistorMonthData + dataCont.Months = years + dataCont.MonthStr = fmt.Sprintf("%v年", years) + for i := 1; i <= months; i++ { + // SyncSetinges.Add(1) + // go g.CalculateYearMonthData(orgId, targetId, v, months) + + var listCont []modelskpi.FlowDataLogType + err := overall.CONSTANT_DB_KPI.Model(&modelskpi.FlowDataLogType{}).Select("`score`,`method`,`scoring_score`").Where("`department` = ? AND `targetid` = ? AND `year` = ? AND `month` = ?", orgId, targetId, years, i).Find(&listCont).Error + if err != nil { + + dataCont.MonthDataList = append(dataCont.MonthDataList, 0) + } else { + var fenScore float64 + for _, v := range listCont { + if v.ScoringMethod == 1 { + fenScore = fenScore + float64(v.Score) + } else { + fenScore = fenScore + float64(v.ScoringScore) + } + } + fenScore = publicmethod.DecimalEs(fenScore/100, 2) + dataCont.MonthDataList = append(dataCont.MonthDataList, fenScore) + if g.AxisMax < fenScore { + g.AxisMax = fenScore + } + if g.AxisMin > fenScore { + g.AxisMin = fenScore + } + + } + + } + g.Target = append(g.Target, dataCont) + // SyncSetinges.Wait() + + SyncSeting.Done() +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-14 16:11:04 +@ 功能: 通过时间获取组织总分 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) TotalScoreOFOrgComesFromTimeSearch(c *gin.Context) { + var receivedValue OrgSecrcFormTime + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if receivedValue.OrgId == "" { + myCont, myErr := publicmethod.LoginMyCont(c) + if myErr != nil { + receivedValue.OrgId = "309" + } else { + if myCont.Company != 0 { + receivedValue.OrgId = strconv.FormatInt(myCont.Company, 10) + } else { + receivedValue.OrgId = "309" + } + } + } + + tayTime := time.Now().Unix() + currentYears := publicmethod.UnixTimeToDay(tayTime, 16) + currentMonths := publicmethod.UnixTimeToDay(tayTime, 17) + if receivedValue.DateTimes != "" { + var dayTime publicmethod.DateTimeTotimes + dayTime.BaisStrToTime(receivedValue.DateTimes) + if dayTime.Years != "" { + currentYears = dayTime.Years + } + if dayTime.Months != "" { + currentMonths = dayTime.Months + } + } + //获取行政组织列表 + var orgListCont []modelshr.AdministrativeOrganization + err = overall.CONSTANT_DB_HR.Model(&modelshr.AdministrativeOrganization{}).Select("`id`,`number`,`name`,`ispower`,`sort`").Where("ispower = 1 AND state = 1 AND organization_type > 2 AND superior = ? AND `id` NOT IN ?", receivedValue.OrgId, []int{281, 163}).Find(&orgListCont).Error + if err != nil || len(orgListCont) < 1 { + publicmethod.Result(107, err, c) + return + } + //获取一级主部门下是否由二级主部门 + var allOrgListCont []modelshr.AdministrativeOrganization + for _, ov := range orgListCont { + sunOrgListCont, sunOrgErr := publicmethod.GetSunOrgList(ov.Id) + if sunOrgErr == nil && len(sunOrgListCont) > 0 { + for _, sv := range sunOrgListCont { + allOrgListCont = append(allOrgListCont, sv) + } + } else { + allOrgListCont = append(allOrgListCont, ov) + } + } + //根据维度序号排序 + sort.Slice(allOrgListCont, func(i, j int) bool { + return allOrgListCont[i].Sort < allOrgListCont[j].Sort + }) + var sendData SendTimeOfOrgSumScore + //开启协程,分别获取行政组织时间总分 + var syncOrgTimeScore SyncOrgTimeAllScore + for _, v := range allOrgListCont { + sendData.XAxisVal = append(sendData.XAxisVal, v.Name) + SyncSeting.Add(1) + go syncOrgTimeScore.OrgCalculateScore(v, currentYears, currentMonths) + } + SyncSeting.Wait() + scoreList, maxScore, minSchor := syncOrgTimeScore.readPlanTaskData() + // sendDataMap := publicmethod.MapOut[string]() + var suo []Seriescont + for _, ov := range allOrgListCont { + var seriesInfo Seriescont + seriesInfo.Name = ov.Name + seriesInfo.Type = "bar" + orgScore := GetAryValue(ov.Id, scoreList) + seriesInfo.Data = append(seriesInfo.Data, orgScore) + sendData.Series = append(sendData.Series, orgScore) + suo = append(suo, seriesInfo) + } + + if maxScore > 0 && minSchor < 0 { + if maxScore < 10 { + maxScore = maxScore + 1 + } else { + maxScore = maxScore + maxScore/5 + } + if minSchor > -10 { + minSchor = minSchor - 1 + } else { + minSchor = minSchor + minSchor/5 + } + } else if maxScore > 0 && minSchor > 0 { + maxScore = maxScore + (maxScore-minSchor)/5 + minSchor = float64(int64(minSchor/10)) * 10 + } + + sendData.YAxis.Min = math.Ceil(minSchor) + sendData.YAxis.Max = math.Ceil(maxScore) + // sendDataMap["sendData"] = sendData + // sendDataMap["receivedValue"] = receivedValue + // sendDataMap["currentYears"] = currentYears + // sendDataMap["currentMonths"] = currentMonths + // sendDataMap["allOrgListCont"] = allOrgListCont + // sendDataMap["syncOrgTimeScore"] = syncOrgTimeScore + // sendDataMap["suo"] = suo + // sendDataMap["maxScore"] = maxScore + // sendDataMap["minSchor"] = minSchor + + publicmethod.Result(0, sendData, c) +} + +// 获取数值值 +func GetAryValue(orgId int64, orgScoreList []SyncOTASVal) float64 { + for _, v := range orgScoreList { + if orgId == v.OrgId { + return v.Score + } + } + return 0 +} + +// 获取数值值 +func GetAryValueMonth(months int, orgScoreList []SyncOTASVal) float64 { + for _, v := range orgScoreList { + if months == v.Months { + return v.Score + } + } + return 0 +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-15 11:14:37 +@ 功能: 计算行政组织成绩 +@ 参数 + + #orgCont 行政组织薪资 + #years 年 + #months 月 + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (s *SyncOrgTimeAllScore) OrgCalculateScore(orgCont modelshr.AdministrativeOrganization, years, months string) { + //锁操作 + s.mutext.Lock() + defer s.mutext.Unlock() + tayTime := time.Now().Unix() + currentYears := publicmethod.UnixTimeToDay(tayTime, 16) + currentMonth := publicmethod.UnixTimeToDay(tayTime, 17) + //获取执行的考核方案 + var schemeCont modelskpi.PlanVersio + var err error + if currentYears == years { + where := publicmethod.MapOut[string]() + where["`state`"] = 1 + where["`department`"] = orgCont.Id + err = schemeCont.GetCont(where) + } else { + err = overall.CONSTANT_DB_KPI.Where("state = 2 AND department = ? AND yeares = ?", orgCont.Id, years).Order("addtime desc").First(&schemeCont).Error + if err != nil { + err = overall.CONSTANT_DB_KPI.Where("state = 3 AND department = ? AND yeares = ?", orgCont.Id, years).Order("addtime desc").First(&schemeCont).Error + } + } + var getPoints float64 + if err == nil { + //将考核方案解析 + var schemeInfoCont []SchemeInfo + jsonErr := json.Unmarshal([]byte(schemeCont.Content), &schemeInfoCont) + if jsonErr == nil { + for _, v := range schemeInfoCont { //维度层面 + for _, sv := range v.Child { //指标 + //判断是不是观察指标 + if sv.Status == 3 { + getPoints = getPoints + float64(sv.ReferenceScore) + } else { + if sv.Status == 1 && sv.Status != 3 { //判断指标是否启用并且不是观察指标 + //获取指标内容 + var targetInfo modelskpi.EvaluationTarget + targetInfo.GetCont(map[string]interface{}{"`et_id`": sv.Id}, "et_id", "et_type", "et_cycle") + if sv.Cycles == 0 { //判断统计方式 + sv.Cycles = targetInfo.Cycles + } + //判断指标类型 + if targetInfo.Type == 1 { + //定性考核 + dingXingScore := OrgSchemeDingXing(orgCont.Id, sv.ReferenceScore, targetInfo.Id, sv.Cycles, sv.Status, years, months) + getPoints = getPoints + dingXingScore + } else { + //定量考核 + dingLiangScore := OrgSchemeDingLiang(orgCont.Id, sv.ReferenceScore, targetInfo.Id, sv.Cycles, sv.Status, years, months) + getPoints = getPoints + dingLiangScore + } + } + } + + } + } + } + } + currentYearsInt, _ := strconv.Atoi(currentYears) + yearsInt, _ := strconv.Atoi(years) + monthsInt, _ := strconv.Atoi(months) + currentMonthInt, _ := strconv.Atoi(currentMonth) + if currentYearsInt == yearsInt && monthsInt > currentMonthInt { + getPoints = 0 + fmt.Printf("currentYears:%v---->years:%v---->months:%v---->currentMonth:%v---->getPoints:%v\n", currentYearsInt, yearsInt, monthsInt, currentMonthInt, getPoints) + } + + if s.AxisMax < getPoints { + s.AxisMax = getPoints + } + if s.AxisMin == 0 { + s.AxisMin = getPoints + } else { + if s.AxisMin > getPoints { + s.AxisMin = getPoints + } + } + + var orgScore SyncOTASVal + orgScore.OrgId = orgCont.Id + orgScore.Score = publicmethod.DecimalEs(getPoints, 2) + orgScore.Months, _ = strconv.Atoi(months) + s.OrgScore = append(s.OrgScore, orgScore) + SyncSeting.Done() +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-15 14:35:59 +@ 功能: 计算行政组织考核方案指定时间内定量指标得分 +@ 参数 + + #orgId 行政组织 + #targetWeight 指标权重 + #targetId 指标Id + #cycles 周期(1:班;2:天;3:周;4:月;5:季度;6:年) + #attribute 属性(1:启用;2:禁用;3:观察) + #years 年 + #months 月 + +@ 返回值 + + #score 最终得分 + +@ 方法原型 + + #func OrgSchemeDingLiang(orgId, targetWeight, targetId int64, cycles, attribute int, years, months string) (score float64) +*/ +func OrgSchemeDingLiang(orgId, targetWeight, targetId int64, cycles, attribute int, years, months string) (score float64) { + //获取定量考核记录 + var examineListCont []modelskpi.FlowDataLogType + err := overall.CONSTANT_DB_KPI.Where("`department` = ? AND `year` = ? AND `month` = ? AND `targetid` = ?", orgId, years, months, targetId).Find(&examineListCont).Error + if err != nil || len(examineListCont) < 1 { + score = float64(targetWeight) + return + } + var actualValue float64 //实际值 + var resultValue float64 //得分 + for _, v := range examineListCont { + actualValue = actualValue + float64(v.Score) + //判断自动还是手动 + if v.ScoringMethod == 1 { + classVal := 3 + switch cycles { + case 5: + classVal = 1 + case 6: + classVal = 2 + default: + classVal = 3 + } + + monthsInt, _ := strconv.Atoi(months) + //自动计算 + zeroPrize, allPrize, cappingPrize := GetTargetSetUp(v.Baseline, strconv.FormatInt(orgId, 10), strconv.FormatInt(targetId, 10), years, monthsInt, classVal) + //达成率 + dachenglv := DepartTargetCompletionRate(float64(v.Score), zeroPrize, allPrize, cappingPrize) + score = float64(targetWeight) * (dachenglv / 100) + resultValue = resultValue + score + // fmt.Printf("自动得分------->%v------->%v------->%v------->%v\n", orgId, resultValue, dachenglv, score) + } else { + resultValue = resultValue + publicmethod.DecimalEs(v.ScoringScore/100, 2) + } + } + // score = publicmethod.DecimalEs(resultValue, 2) + score = resultValue + if attribute == 3 { + score = float64(targetWeight) + } else { + switch cycles { + case 5: + if publicmethod.IsInTrue[string](months, []string{"3", "6", "9", "12"}) == false { + score = float64(targetWeight) + } + case 6: + if months != "12" { + score = float64(targetWeight) + } + case 7: + if publicmethod.IsInTrue[string](months, []string{"6", "12"}) == false { + score = float64(targetWeight) + } + default: + } + } + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-15 13:09:16 +@ 功能: 计算行政组织考核方案指定时间内定性指标得分 +@ 参数 + + #orgId 行政组织 + #targetWeight 指标权重 + #targetId 指标Id + #cycles 周期(1:班;2:天;3:周;4:月;5:季度;6:年) + #attribute 属性(1:启用;2:禁用;3:观察) + #years 年 + #months 月 + +@ 返回值 + + #score 最终得分 + +@ 方法原型 + + #func OrgSchemeDingXing(orgId, targetWeight, targetId int64, cycles, attribute int, years, months string) (score float64) +*/ +func OrgSchemeDingXing(orgId, targetWeight, targetId int64, cycles, attribute int, years, months string) (score float64) { + //获取指定指标的所有满足条件的定性考核记录 + var examineListCont []modelskpi.ScoreFlow + err := overall.CONSTANT_DB_KPI.Model(&modelskpi.ScoreFlow{}).Select("sf_score,sf_plus_reduce_score,sf_count").Where("sf_reply IN ? AND sf_duty_department = ? AND sf_year = ? AND sf_month = ? AND sf_target_id = ?", []int{2, 3}, orgId, years, months, targetId).Find(&examineListCont).Error + if err == nil && len(examineListCont) > 0 { + var minusPoints float64 //减分 + var bonusPoint float64 //加分 + for _, v := range examineListCont { + if v.PlusReduceScore == 1 { + //加分操作 + bonusPoint = bonusPoint + (float64(v.Score) * float64(v.Count)) //分值=原分值+(评分乘以发生次数) + } else { + //减分操作 + minusPoints = minusPoints + (float64(v.Score) * float64(v.Count)) //分值=原分值+(评分乘以发生次数) + } + } + resultVal := (float64(targetWeight) + bonusPoint/100) - minusPoints/100 + // score = publicmethod.DecimalEs(resultVal, 3) + score = resultVal + if attribute == 3 { + score = float64(targetWeight) + } else { + switch cycles { + case 5: + if publicmethod.IsInTrue[string](months, []string{"3", "6", "9", "12"}) == false { + score = float64(targetWeight) + } + case 6: + if months != "12" { + score = float64(targetWeight) + } + case 7: + if publicmethod.IsInTrue[string](months, []string{"6", "12"}) == false { + score = float64(targetWeight) + } + default: + } + } + + } else { + score = float64(targetWeight) + } + + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-16 08:40:24 +@ 功能: 获取关键指标 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) GetHingeTarget(c *gin.Context) { + var receivedValue HingeTarget + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if len(receivedValue.Id) < 1 { + publicmethod.Result(107, err, c) + return + } + tayTime := time.Now().Unix() + currentYears := publicmethod.UnixTimeToDay(tayTime, 16) + currentMonths := publicmethod.UnixTimeToDay(tayTime, 17) + if receivedValue.DateTime != "" { + var dayTime publicmethod.DateTimeTotimes + dayTime.BaisStrToTime(receivedValue.DateTime) + if dayTime.Years != "" { + currentYears = dayTime.Years + } + if dayTime.Months != "" { + currentMonths = dayTime.Months + } + } + + var targetListCont []modelskpi.EvaluationTarget + err = overall.CONSTANT_DB_KPI.Model(&modelskpi.EvaluationTarget{}).Select("`et_id`,`et_title`,`et_type`,`et_key`").Where("`et_id` IN ?", receivedValue.Id).Find(&targetListCont).Error + if err != nil && len(targetListCont) < 1 { + publicmethod.Result(107, err, c) + return + } + var sendListCont []OutPutHingeTarget + for _, v := range targetListCont { + var sendCont OutPutHingeTarget + sendCont.Id = strconv.FormatInt(v.Id, 10) + sendCont.Title = fmt.Sprintf("%v年%v月份 %v", currentYears, currentMonths, v.Title) + sendCont.CharKey = fmt.Sprintf("chars_%v", v.Key) + if len(receivedValue.OrgId) > 1 { + sendCont.DataList, sendCont.XAxisVal, sendCont.YAxis.Max, sendCont.YAxis.Min = GetOrgHingeTarget(v.Id, v.Type, currentYears, currentMonths, receivedValue.OrgId) + } + sendCont.YAxis.Max, sendCont.YAxis.Min = publicmethod.JudjeMaxOfMinVal(sendCont.YAxis.Max, sendCont.YAxis.Min) + // sendCont.DataList []float64 `json:"datalist"` + // sendCont.XAxisVal []string `json:"xaxis"` //X轴坐标值 + sendListCont = append(sendListCont, sendCont) + } + publicmethod.Result(0, sendListCont, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-16 09:21:11 +@ 功能: 获取行政组织指标指定时间内的得分· +@ 参数 + + #targetId 指标Id + #attribute 属性(1:定性考核;2:定量考核) + #ysers 年 + #months 月 + #orgId 行政组织 + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func GetOrgHingeTarget(targetId int64, attribute int, ysers, months string, orgId []string) (dataList []float64, titleList []string, maxVal, minVal float64) { + if len(orgId) < 0 { + return + } + var orgCont []modelshr.AdministrativeOrganization + err := overall.CONSTANT_DB_HR.Model(&modelshr.AdministrativeOrganization{}).Select("`id`,`name`,`sort`").Where("`id` IN ?", orgId).Order("`sort`").Find(&orgCont).Error + if err != nil || len(orgCont) < 1 { + return + } + var syncListCont SyncOrgTimeAllScore + for _, v := range orgCont { + titleList = append(titleList, v.Name) + SyncSeting.Add(1) + go syncListCont.GetOrgTargetVal(v.Id, targetId, attribute, ysers, months) + } + SyncSeting.Wait() + orgScore, maxVal, minVal := syncListCont.readPlanTaskData() + + for _, ov := range orgCont { + orgScore := GetAryValue(ov.Id, orgScore) + dataList = append(dataList, orgScore) + } + fmt.Printf("orgScore------->%v------->%v------->%v\n", orgScore, maxVal, minVal) + return +} + +func (s *SyncOrgTimeAllScore) GetOrgTargetVal(orgId, targetId int64, attribute int, ysers, months string) { + //锁操作 + s.mutext.Lock() + defer s.mutext.Unlock() + var tirgetScore SyncOTASVal + if attribute == 1 { + tirgetScore.Score = AuxiliaryCalculationSumNature(orgId, targetId, ysers, months) + tirgetScore.OrgId = orgId + s.OrgScore = append(s.OrgScore, tirgetScore) + } else { + tirgetScore.Score = AuxiliaryCalculationSum(orgId, targetId, attribute, ysers, months) + tirgetScore.OrgId = orgId + s.OrgScore = append(s.OrgScore, tirgetScore) + } + if s.AxisMin == 0 { + s.AxisMin = tirgetScore.Score + } else { + if s.AxisMin > tirgetScore.Score { + s.AxisMin = tirgetScore.Score + } + } + if s.AxisMax == 0 { + s.AxisMax = tirgetScore.Score + } else { + if s.AxisMax < tirgetScore.Score { + s.AxisMax = tirgetScore.Score + } + } + // fmt.Printf("计算最大====》%v=====>最小值=========>%v\n", s.AxisMax, s.AxisMin) + SyncSeting.Done() +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-16 10:00:53 +@ 功能: 获取定量指标总值 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func AuxiliaryCalculationSum(orgId, targetId int64, attribute int, years, months string) (sumScore float64) { + //获取定量考核记录 + var examineListCont []modelskpi.FlowDataLogType + err := overall.CONSTANT_DB_KPI.Where("`department` = ? AND `year` = ? AND `month` = ? AND `targetid` = ?", orgId, years, months, targetId).Find(&examineListCont).Error + if err != nil || len(examineListCont) < 1 { + sumScore = 0 + return + } + for _, v := range examineListCont { + sumScore = sumScore + float64(v.Score) + } + sumScore = publicmethod.DecimalEs(sumScore/100, 2) + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-16 09:44:31 +@ 功能: 获取定性指标总值 +@ 参数 + + #orgId 行政组织 + #targetId 指标ID + #years 年 + #months 月 + +@ 返回值 + + #sumScore 加减分 + +@ 方法原型 + + #func AuxiliaryCalculationSumNature(orgId, targetId int64, years, months string) (sumScore float64) +*/ +func AuxiliaryCalculationSumNature(orgId, targetId int64, years, months string) (sumScore float64) { + var examineListCont []modelskpi.ScoreFlow + err := overall.CONSTANT_DB_KPI.Model(&modelskpi.ScoreFlow{}).Select("sf_score,sf_plus_reduce_score,sf_count").Where("sf_reply IN ? AND sf_duty_department = ? AND sf_year = ? AND sf_month = ? AND sf_target_id = ?", []int{2, 3}, orgId, years, months, targetId).Find(&examineListCont).Error + if err == nil && len(examineListCont) > 0 { + var minusPoints float64 //减分 + var bonusPoint float64 //加分 + for _, v := range examineListCont { + if v.PlusReduceScore == 1 { + //加分操作 + bonusPoint = bonusPoint + (float64(v.Score) * float64(v.Count)) //分值=原分值+(评分乘以发生次数) + } else { + //减分操作 + minusPoints = minusPoints + (float64(v.Score) * float64(v.Count)) //分值=原分值+(评分乘以发生次数) + } + } + sumScore = (bonusPoint - minusPoints) / 100 + } + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-16 15:50:20 +@ 功能: 获取单一行政组织指定年度各月份成绩 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) GetEveryOneOrgToMonthResult(c *gin.Context) { + var receivedValue OrgMonthResult + c.ShouldBindJSON(&receivedValue) + if receivedValue.OrgId == "" { + publicmethod.Result(107, receivedValue, c) + return + } + tayTime := time.Now().Unix() + tadyYear := publicmethod.UnixTimeToDay(tayTime, 16) + currentYears := tadyYear + currentMonths := 12 + if receivedValue.DateTime != "" { + var dayTime publicmethod.DateTimeTotimes + dayTime.BaisStrToTime(receivedValue.DateTime) + if dayTime.Years != "" { + currentYears = dayTime.Years + } + } + if currentYears == tadyYear { + currentMonths, _ = strconv.Atoi(publicmethod.UnixTimeToDay(tayTime, 17)) + } + var orgCont modelshr.AdministrativeOrganization + err := orgCont.GetCont(map[string]interface{}{"`id`": receivedValue.OrgId}) + if err != nil { + publicmethod.Result(107, receivedValue, c) + return + } + fmt.Printf("年月---->%v---->%v\n", currentYears, currentMonths) + var sendData SendTimeOfOrgSumScore + //开启协程,分别获取行政组织时间总分 + var syncOrgTimeScore SyncOrgTimeAllScore + for i := 1; i <= currentMonths; i++ { + iStr := strconv.Itoa(i) + iAxis := fmt.Sprintf("%v月", iStr) + sendData.XAxisVal = append(sendData.XAxisVal, iAxis) + SyncSeting.Add(1) + go syncOrgTimeScore.OrgCalculateScore(orgCont, currentYears, iStr) + } + SyncSeting.Wait() + scoreList, maxScore, minSchor := syncOrgTimeScore.readPlanTaskData() + //根据维度序号排序 + sort.Slice(scoreList, func(i, j int) bool { + return scoreList[i].Months < scoreList[j].Months + }) + var suo []Seriescont + for i := 1; i <= currentMonths; i++ { + var seriesInfo Seriescont + seriesInfo.Name = fmt.Sprintf("%v月", i) + seriesInfo.Type = "bar" + orgScore := GetAryValueMonth(i, scoreList) + seriesInfo.Data = append(seriesInfo.Data, orgScore) + sendData.Series = append(sendData.Series, orgScore) + suo = append(suo, seriesInfo) + } + sendData.YAxis.Max, sendData.YAxis.Min = publicmethod.JudjeMaxOfMinVal(maxScore, minSchor) + // outData := publicmethod.MapOut[string]() + // outData["scoreList"] = scoreList + // outData["maxScore"] = maxScore + // outData["minSchor"] = minSchor + // outData["sendData"] = sendData + // outData["suo"] = suo + publicmethod.Result(0, sendData, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-17 09:04:49 +@ 功能: 定性指标同比环比分析 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) BasisDepartAttrTargetTimeStatistics(c *gin.Context) { + var receivedValue BaseDepartTargetTimeYOY + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if receivedValue.OrgId == "" { + publicmethod.Result(1, err, c, "未知行政组织!无法统计!") + return + } + if receivedValue.TargetId == "" { + publicmethod.Result(1, err, c, "未知指标!无法统计!") + return + } + tarWhere := publicmethod.MapOut[string]() + tarWhere["et_id"] = receivedValue.TargetId + //获取指标信息 + var targetCont modelskpi.EvaluationTarget + err = targetCont.GetCont(tarWhere) + if err != nil { + publicmethod.Result(1, err, c, "未知指标!无法统计!") + return + } + tadyTime := time.Now().Unix() + dateYear, _ := strconv.Atoi(publicmethod.UnixTimeToDay(tadyTime, 16)) + dateMonthMAx := 12 + if len(receivedValue.DateTime) > 0 { + if len(receivedValue.DateTime) == 1 { + if receivedValue.DateTime[0] == dateYear { + dateMonthVal := publicmethod.UnixTimeToDay(tadyTime, 17) + dateMonthMAx, _ = strconv.Atoi(dateMonthVal) + } + } else { + sort.Slice(receivedValue.DateTime, func(i, j int) bool { + return receivedValue.DateTime[i] < receivedValue.DateTime[j] + }) + } + } else { + dateMonthVal := publicmethod.UnixTimeToDay(tadyTime, 17) + dateMonthMAx, _ = strconv.Atoi(dateMonthVal) + receivedValue.DateTime = append(receivedValue.DateTime, dateYear) + } + var sendData SendYOYData + sendData.YAxis.Type = "value" + sendData.YAxis.Name = "实际值" + sendData.YAxis.FormAtter = targetCont.Uniteing + var goSyncData GeteveryYearDttsb + //获取X轴数据 + for i := 1; i <= dateMonthMAx; i++ { + sendData.XAxisVal = append(sendData.XAxisVal, fmt.Sprintf("%v月", i)) + } + //获取Y轴数据 + for _, v := range receivedValue.DateTime { + SyncSeting.Add(1) + go goSyncData.GetOrgAttrtargetTime(receivedValue.OrgId, receivedValue.TargetId, v, dateMonthMAx) + } + + SyncSeting.Wait() + targetData, maxVal, minVal := goSyncData.readPlanTaskData() + + sendData.YAxis.Max, sendData.YAxis.Min = publicmethod.JudjeMaxOfMinVal(maxVal, minVal) + + //根据维度月份排序 + sort.Slice(targetData, func(i, j int) bool { + return targetData[i].Months < targetData[j].Months + }) + for _, v := range targetData { + var serInfo Seriescont + serInfo.Name = v.MonthStr + serInfo.Type = "bar" + serInfo.Tooltip = targetCont.Uniteing + serInfo.Data = v.MonthDataList + sendData.Series = append(sendData.Series, serInfo) + } + // fmt.Printf("targetData:%v------------------>maxVal:%v---------------->minVal:%v---------------->Max:%v\n", targetData, maxVal, minVal, sendData.YAxis.Max) + publicmethod.Result(0, sendData, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-13 14:33:07 +@ 功能: 协程定性指标计算月份历史值 +@ 参数 + + #orgId 行政组织 + #targetId 指标 + #years 时间(年) + #months 时间(月) + +@ 返回值 + + # + +@ 方法原型 + + #(g *GeteveryYearDttsb) getOrgBylawsTime(orgId, targetId string, dateTime []int, months int) +*/ +func (g *GeteveryYearDttsb) GetOrgAttrtargetTime(orgId, targetId string, years, months int) { + g.mutext.Lock() + defer g.mutext.Unlock() + var dataCont HistorMonthData + dataCont.Months = years + dataCont.MonthStr = fmt.Sprintf("%v年", years) + for i := 1; i <= months; i++ { + + orgIdInt, _ := strconv.ParseInt(orgId, 10, 64) + targetIdInt, _ := strconv.ParseInt(targetId, 10, 64) + yearsStr := strconv.Itoa(years) + monthsStr := strconv.Itoa(i) + scoreVal := AuxiliaryCalculationSumNature(orgIdInt, targetIdInt, yearsStr, monthsStr) + // scoreVal := 100 + AuxiliaryCalculationSumNature(orgIdInt, targetIdInt, yearsStr, monthsStr) + + dataCont.MonthDataList = append(dataCont.MonthDataList, scoreVal) + + if g.AxisMax < scoreVal { + g.AxisMax = scoreVal + } + if g.AxisMin > scoreVal { + g.AxisMin = scoreVal + } + + } + g.Target = append(g.Target, dataCont) + // SyncSetinges.Wait() + + SyncSeting.Done() +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-17 09:50:12 +@ 功能: 获取单一行政组织多年度各月份成绩 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) GetEveryOneOrgToMonthsResult(c *gin.Context) { + var receivedValue BaseDepartTimeYOY + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if receivedValue.OrgId == "" { + publicmethod.Result(1, err, c, "未知行政组织!无法统计!") + return + } + tarWhere := publicmethod.MapOut[string]() + tarWhere["`id`"] = receivedValue.OrgId + //获取指标信息 + var orgCont modelshr.AdministrativeOrganization + err = orgCont.GetCont(tarWhere) + if err != nil { + publicmethod.Result(1, err, c, "未知指标!无法统计!") + return + } + tadyTime := time.Now().Unix() + dateYear, _ := strconv.Atoi(publicmethod.UnixTimeToDay(tadyTime, 16)) + dateMonthMAx := 12 + if len(receivedValue.DateTime) > 0 { + if len(receivedValue.DateTime) == 1 { + if receivedValue.DateTime[0] == dateYear { + dateMonthVal := publicmethod.UnixTimeToDay(tadyTime, 17) + dateMonthMAx, _ = strconv.Atoi(dateMonthVal) + } + } else { + sort.Slice(receivedValue.DateTime, func(i, j int) bool { + return receivedValue.DateTime[i] < receivedValue.DateTime[j] + }) + } + } else { + dateMonthVal := publicmethod.UnixTimeToDay(tadyTime, 17) + dateMonthMAx, _ = strconv.Atoi(dateMonthVal) + receivedValue.DateTime = append(receivedValue.DateTime, dateYear) + } + var sendData SendYOYData + sendData.YAxis.Type = "value" + sendData.YAxis.Name = "成绩" + sendData.YAxis.FormAtter = "分" + + //获取X轴数据 + for i := 1; i <= dateMonthMAx; i++ { + sendData.XAxisVal = append(sendData.XAxisVal, fmt.Sprintf("%v月", i)) + } + var goSyncData GeteveryYearDttsb + //获取Y轴数据 + for _, v := range receivedValue.DateTime { + SyncSetinges.Add(1) + go goSyncData.GetOrgMoreTimeScore(orgCont, v, dateMonthMAx) + } + + SyncSetinges.Wait() + targetData, maxVal, minVal := goSyncData.readPlanTaskData() + + sendData.YAxis.Max, sendData.YAxis.Min = publicmethod.JudjeMaxOfMinVal(maxVal, minVal) + + //根据维度月份排序 + sort.Slice(targetData, func(i, j int) bool { + return targetData[i].Months < targetData[j].Months + }) + for _, v := range targetData { + var serInfo Seriescont + serInfo.Name = v.MonthStr + serInfo.Type = "bar" + serInfo.Tooltip = "分" + serInfo.Data = v.MonthDataList + sendData.Series = append(sendData.Series, serInfo) + } + // fmt.Printf("targetData:%v------------------>maxVal:%v---------------->minVal:%v---------------->Max:%v\n", targetData, maxVal, minVal, sendData.YAxis.Max) + publicmethod.Result(0, sendData, c) +} + +// 获取 +func (g *GeteveryYearDttsb) GetOrgMoreTimeScore(orgCont modelshr.AdministrativeOrganization, years, months int) { + //锁操作 + g.mutext.Lock() + defer g.mutext.Unlock() + yearsStr := strconv.Itoa(years) + var syncOrgTimeScore SyncOrgTimeAllScore + for i := 1; i <= months; i++ { + monthStr := strconv.Itoa(i) + SyncSeting.Add(1) + go syncOrgTimeScore.OrgCalculateScore(orgCont, yearsStr, monthStr) + } + SyncSeting.Wait() + scoreList, maxScore, minSchor := syncOrgTimeScore.readPlanTaskData() + //根据维度序号排序 + sort.Slice(scoreList, func(i, j int) bool { + return scoreList[i].Months < scoreList[j].Months + }) + + if g.AxisMax == 0 { + g.AxisMax = maxScore + } else { + if g.AxisMax < maxScore { + g.AxisMax = maxScore + } + } + + if g.AxisMin == 0 { + g.AxisMin = minSchor + } else { + if g.AxisMin > minSchor { + g.AxisMin = minSchor + } + } + var dataCont HistorMonthData + dataCont.Months = years + dataCont.MonthStr = fmt.Sprintf("%v年", years) + for _, v := range scoreList { + dataCont.MonthDataList = append(dataCont.MonthDataList, v.Score) + } + g.Target = append(g.Target, dataCont) + // fmt.Printf("获取:%v------------------>%v------------------>%v------------------>scoreList:%v------------------>maxScore:%v---------------->minSchor:%v\n", orgCont.Name, years, months, scoreList, maxScore, minSchor) + SyncSetinges.Done() +} diff --git a/api/version1/departmentseting/departmentweb/type.go b/api/version1/departmentseting/departmentweb/type.go index 93517db..a0fe6c5 100644 --- a/api/version1/departmentseting/departmentweb/type.go +++ b/api/version1/departmentseting/departmentweb/type.go @@ -2,15 +2,224 @@ package departmentweb import ( "key_performance_indicators/overall/publicmethod" + "sync" "github.com/gin-gonic/gin" ) type ApiMethod struct{} +// 协程设置 +var SyncSeting = sync.WaitGroup{} +var SyncSetinges = sync.WaitGroup{} + +// 获取综合统计数值 +type GetDttsb struct { + Target []GetDttsbCont + Actuality []GetDttsbCont + CompletionRate []GetDttsbCont + AxisLeftMax float64 + AxisLeftMin float64 + AxisRightMax float64 + AxisRightMin float64 + mutext sync.RWMutex +} +type GetDttsbCont struct { + Val float64 + Sort int +} + +// 读取数据 +func (g *GetDttsb) readPlanTaskData() ([]GetDttsbCont, []GetDttsbCont, []GetDttsbCont, float64, float64, float64, float64) { + g.mutext.RLock() + defer g.mutext.RUnlock() + return g.Target, g.Actuality, g.CompletionRate, g.AxisLeftMax, g.AxisLeftMin, g.AxisRightMax, g.AxisRightMin +} + // 部门考核WEB端入口 func (a *ApiMethod) Index(c *gin.Context) { outputCont := publicmethod.MapOut[string]() outputCont["index"] = "部门考核WEB端入口" publicmethod.Result(0, outputCont, c) } + +// 获取部门指标列表 +type GetDepartTargetCont struct { + publicmethod.PublicId + Attribute int `json:"attribute"` //1:定性考核;2:定量考核 +} + +// 输出指标信息 +type SendTargetCont struct { + publicmethod.PublicId + publicmethod.PublicName +} + +// 根据部门、指标、年份统计每月的目标值、实际值、达成率 +type BaseDepartTargetTime struct { + OrgId string `json:"orgid"` //行政组织 + TargetId string `json:"targetid"` //指标ID + DateTime string `json:"datetime"` //时间 +} + +// 输出部门、指标、年份统计图目标值、实际值、达成率数据结构 +type DrawEcharStatisticsCont struct { + Legend []string `json:"legend"` //项目名称 + XAxisVal []string `json:"xaxis"` //X轴坐标值 + YAxis []YaxisStruct `json:"yaxis"` //Y轴坐标值 + Series []Seriescont `json:"series"` //图表数值 +} + +// Y轴属性 +type YaxisStruct struct { + Type string `json:"type"` //坐标轴类型 + publicmethod.PublicName //坐标轴名称。 + Min float64 `json:"min"` //最小值 + Max float64 `json:"max"` //最大值 + FormAtter string `json:"formatter"` //单位 +} + +// 图表值 +type Seriescont struct { + publicmethod.PublicName //名称 + Type string `json:"type"` //图像类型 + Tooltip string `json:"tooltip"` //单位 + Data []float64 `json:"data"` //结果 +} + +// 定量流水全奖值、零奖值、封顶值 +type FlowLogAllZreo struct { + Id string `json:"id"` + TargetId string `json:"targetid"` //指标ID` + Zeroprize float64 `json:"zeroprize"` //零奖值"` + Allprize float64 `json:"allprize"` //全奖值"` + Capping float64 `json:"capping"` //封顶值"` +} + +// 根据部门、指标、年份统计历史同比每月的目标值、实际值、达成率 +type BaseDepartTargetTimeYOY struct { + OrgId string `json:"orgid"` //行政组织 + TargetId string `json:"targetid"` //指标ID + DateTime []int `json:"datetime"` //时间 +} + +// 输出历史同比数据 +type SendYOYData struct { + XAxisVal []string `json:"xaxis"` //X轴坐标值 + YAxis YaxisStruct `json:"yaxis"` //Y轴坐标值 + Series []Seriescont `json:"series"` //图表数值 +} + +// 协程获取每个年份数据 +// 获取综合统计数值 +type GeteveryYearDttsb struct { + Target []HistorMonthData + AxisMax float64 + AxisMin float64 + mutext sync.RWMutex +} + +// 历史同比记录 +type HistorMonthData struct { + Months int + MonthStr string + MonthDataList []float64 +} + +// 读取数据 +func (g *GeteveryYearDttsb) readPlanTaskData() ([]HistorMonthData, float64, float64) { + g.mutext.RLock() + defer g.mutext.RUnlock() + return g.Target, g.AxisMax, g.AxisMin +} + +// 通过时间获取组织总分 +type OrgSecrcFormTime struct { + OrgId string `json:"orgid"` //行政组织 + DateTimes string `json:"datetimes"` //时间 +} + +// 根据时间查询行政组织总成绩协程设置 +type SyncOrgTimeAllScore struct { + OrgScore []SyncOTASVal + AxisMax float64 + AxisMin float64 + mutext sync.RWMutex +} + +type SyncOTASVal struct { + OrgId int64 //行政组织ID + Score float64 //分 + Months int //月 +} + +// 读取数据 +func (s *SyncOrgTimeAllScore) readPlanTaskData() ([]SyncOTASVal, float64, float64) { + s.mutext.RLock() + defer s.mutext.RUnlock() + return s.OrgScore, s.AxisMax, s.AxisMin +} + +// 按时间输出行政组织总成 +type SendTimeOfOrgSumScore struct { + XAxisVal []string `json:"xaxis"` //X轴坐标值 + YAxis YaxisOrgAllScore `json:"yaxis"` //Y轴坐标值 + Series []float64 `json:"series"` //图表数值 +} +type YaxisOrgAllScore struct { + Min float64 `json:"min"` //最小值 + Max float64 `json:"max"` //最大值 + +} + +// 考核方案 +type SchemeInfo struct { + publicmethod.PublicId + publicmethod.PublicName + DimensionScore float64 `json:"dimensionscore"` //维度分数 + Child []SchemeTarget `json:"child"` //方案指标 +} + +// 方案指标 +type SchemeTarget struct { + publicmethod.PublicId + publicmethod.PublicName + Content string `json:"content"` //指标说明 + Unit string `json:"unit"` //单位"` + ReferenceScore int64 `json:"referencescore"` //标准分值"` + Cycles int `json:"cycle"` //1:班;2:天;3:周;4:月;5:季度;6:年"` + CycleAttres int `json:"cycleattr"` //辅助计数"` + State int `json:"state"` + Score int64 `json:"score"` //分数 + QualEvalId string `json:"qeid"` + Status int `json:"status"` //1:启用;2:禁用;3:为观察指标 +} + +// 获取关键指标列表 +type HingeTarget struct { + Id []string `json:"id"` //指标ID + OrgId []string `json:"orgid"` //行政组织 + DateTime string `json:"datetime"` //时间 +} + +// 输出关键指标 +type OutPutHingeTarget struct { + Id string `json:"id"` + Title string `json:"title"` + CharKey string `json:"CharKey"` + DataList []float64 `json:"datalist"` + XAxisVal []string `json:"xaxis"` //X轴坐标值 + YAxis YaxisOrgAllScore `json:"yaxis"` //Y轴坐标值 +} + +// 获取行政组织月度成绩 +type OrgMonthResult struct { + OrgId string `json:"orgid"` //行政组织 + DateTime string `json:"datetime"` //时间 +} + +// 根据部门、指标、年份统计历史同比每月的目标值、实际值、达成率 +type BaseDepartTimeYOY struct { + OrgId string `json:"orgid"` //行政组织 + DateTime []int `json:"datetime"` //时间 +} diff --git a/api/workflow/workflowengine/class.go b/api/workflow/workflowengine/class.go index 5b70d52..eda6918 100644 --- a/api/workflow/workflowengine/class.go +++ b/api/workflow/workflowengine/class.go @@ -1,5 +1,7 @@ package workflowengine +import "key_performance_indicators/overall/publicmethod" + //当审批单同时满足以下条件时进入此流程 type ConditionListCont struct { ColumnID int `json:"columnId"` @@ -27,11 +29,10 @@ type NodeUserListCont struct { //通用字段 type PublicChildNode struct { - NodeName string `json:"nodeName"` //节点名称 + NodePublicStruct Error bool `json:"error"` //当前审批是否通过校验 - Type int `json:"type"` // 0 发起人 1审批 2抄送 3条件 4路由 PriorityLevel int `json:"priorityLevel"` // 条件优先级 - Settype int `json:"settype"` // 审批人设置 1指定成员 2主管 4发起人自选 5发起人自己 7连续多级主管 + Settype int `json:"settype"` // 审批人设置 1指定成员 2主管 4发起人自选 5发起人自己 7连续多级主管 8:指定审批节点自选 SelectMode int `json:"selectMode"` //审批人数 1选一个人 2选多个人 SelectRange int `json:"selectRange"` //选择范围 1.全公司 2指定成员 2指定角色 DirectorLevel int `json:"directorLevel"` //审批终点 最高层主管数 @@ -42,7 +43,16 @@ type PublicChildNode struct { CcSelfSelectFlag int `json:"ccSelfSelectFlag"` //允许发起人自选抄送人 ConditionList []ConditionListCont `json:"conditionList"` //当审批单同时满足以下条件时进入此流程 ChildNode *PublicChildNode `json:"childNode"` - ConditionNodes *[]PublicChildNode `json:"conditionNodes"` // + ConditionNodes *[]PublicChildNode `json:"conditionNodes"` //条件节点 +} + +//基础结构 +type NodePublicStruct struct { + NodeNumber string `json:"nodeNumber"` //节点编号 + NodeName string `json:"nodeName"` //节点名称 + Type int `json:"type"` // 0 发起人 1审批 2抄送 3条件 4路由 + FromNode string `json:"fromNode"` //来源节点 + GotoNode []string `json:"gotoNode"` //去向节点 } //工作流结构体 @@ -53,3 +63,31 @@ type FlowStructIng struct { FlowPermission []string `json:"flowPermission"` //发起人 NodeConfig PublicChildNode `json:"nodeConfig"` //流程结构体 } + +//输出全部节点信息 +type outAllNodeCont struct { + AllCont []NodePublicStruct `json:"allcont"` + AllNumber []string `json:"allnumber"` +} + +//判断上级操作节点 +type JudgePrintNode struct { + publicmethod.PublicId + AllCont []NodePublicStruct `json:"allcont"` +} + +//输出上级操作节点 +type OutputPrintNode struct { + AllCont []NodePublicStruct `json:"allcont"` + Total int `json:"total"` //总数 +} + +//分支条件 +type BranchingCondition struct { + ColumnId string `json:"columnId"` //条件id columnId == 0 为发起人 + ShowType string `json:"showType"` //columnType == "String" && showType == "checkBox"为多选 + ShowName string `json:"showName"` //名称 + ColumnName string `json:"columnName"` //columnName 条件自定义字段 + ColumnType string `json:"columnType"` //columnType == "Double"为区间 + FixedDownBoxValue string `json:"fixedDownBoxValue"` //fixedDownBoxValue 匹配 columnType == "String" && showType == "checkBox"时子选项内容 +} diff --git a/api/workflow/workflowengine/flowhandle.go b/api/workflow/workflowengine/flowhandle.go new file mode 100644 index 0000000..8b5923a --- /dev/null +++ b/api/workflow/workflowengine/flowhandle.go @@ -0,0 +1,151 @@ +package workflowengine + +import ( + "key_performance_indicators/overall/publicmethod" + + "github.com/gin-gonic/gin" +) + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-06 13:35:25 +@ 功能: 判断是否显示(指定审批节点自选)选项及可选节点 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) JudgeOptionalNode(c *gin.Context) { + var receivedValue PublicChildNode + c.ShouldBindJSON(&receivedValue) + var alc outAllNodeCont + alc.sendAllNode(receivedValue) + publicmethod.Result(0, alc, c) +} + +// 递归输出所有节点 +func (o *outAllNodeCont) sendAllNode(val PublicChildNode) { + var cont NodePublicStruct + cont.NodeName = val.NodeName + cont.NodeNumber = val.NodeNumber + cont.Type = val.Type + cont.FromNode = val.FromNode + cont.GotoNode = val.GotoNode + if publicmethod.IsInTrue[string](val.NodeNumber, o.AllNumber) == false { + o.AllCont = append(o.AllCont, cont) + o.AllNumber = append(o.AllNumber, val.NodeNumber) + } + if val.ChildNode != nil { + o.sendAllNode(*val.ChildNode) + } + if val.ConditionNodes != nil && len(*val.ConditionNodes) > 0 { + for _, v := range *val.ConditionNodes { + o.sendAllNode(v) + } + } +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-06 14:53:49 +@ 功能: 获取所有父级审批节点 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) GetAllParentNode(c *gin.Context) { + var receivedValue JudgePrintNode + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if receivedValue.Id == "" { + publicmethod.Result(101, err, c) + return + } + var sendCont OutputPrintNode + if len(receivedValue.AllCont) < 1 { + sendCont.Total = 0 + publicmethod.Result(0, sendCont, c) + return + } + var outCont outAllNodeCont + outCont.SeekFromNodeCont(receivedValue.Id, receivedValue.AllCont) + sendCont.AllCont = outCont.AllCont + sendCont.Total = len(outCont.AllCont) + publicmethod.Result(0, sendCont, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-07 08:35:59 +@ 功能: 递归查找所有上级审批点 +@ 参数 + + #parentNumber 来源节点编号 + #allListCont 所有可操作节点 + +@ 返回值 + + #outAllNodeCont 结果集 + +@ 方法原型 + + #func (o *outAllNodeCont) SeekFromNodeCont(parentNumber string, allListCont []NodePublicStruct) +*/ +func (o *outAllNodeCont) SeekFromNodeCont(parentNumber string, allListCont []NodePublicStruct) { + for _, v := range allListCont { + if v.NodeNumber == parentNumber { + if v.Type == 1 { + if publicmethod.IsInTrue[string](v.NodeNumber, o.AllNumber) == false { + o.AllCont = append(o.AllCont, v) + o.AllNumber = append(o.AllNumber, v.NodeNumber) + } + } + if v.FromNode != "" { + o.SeekFromNodeCont(v.FromNode, allListCont) + } + } + } +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-08 16:00:58 +@ 功能: 判断条件 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) JudgingCondition(c *gin.Context) { + var sendListCont []BranchingCondition + publicmethod.Result(0, sendListCont, c) +} diff --git a/api/workflow/workflowengine/shiyan.go b/api/workflow/workflowengine/shiyan.go index 08af7c6..ba12037 100644 --- a/api/workflow/workflowengine/shiyan.go +++ b/api/workflow/workflowengine/shiyan.go @@ -2,6 +2,7 @@ package workflowengine import ( "key_performance_indicators/overall/publicmethod" + "strconv" "github.com/gin-gonic/gin" ) @@ -52,6 +53,8 @@ func (a *ApiMethod) ShiyanData(c *gin.Context) { // }` var workFlowStruct FlowStructIng + uuidInt := publicmethod.GetUUid(5) + workFlowStruct.NodeConfig.NodeNumber = strconv.FormatInt(uuidInt, 10) workFlowStruct.NodeConfig.NodeName = "发起人" workFlowStruct.DirectorMaxLevel = 4 // err := json.Unmarshal([]byte(jsonStrSmaill), &workFlowStruct) diff --git a/apirouter/apishiyan/maptostruct.go b/apirouter/apishiyan/maptostruct.go index 7ee6b05..ee34ccd 100644 --- a/apirouter/apishiyan/maptostruct.go +++ b/apirouter/apishiyan/maptostruct.go @@ -29,5 +29,7 @@ func (a *ApiRouter) RouterGroup(router *gin.RouterGroup) { apiRouter.POST("correcting_depart_man", methodBinding.CorrectingDepartAndMan) //验证指标关联部门与指标关联提报人数据 apiRouter.POST("verif_depart_sontarget", methodBinding.VerifDepartSonTarget) //验证部门子栏目关联对照 apiRouter.POST("verif_depart_detasil", methodBinding.VerifDepartDetasil) //验证部门指标细则关系对照 + + apiRouter.POST("xzbkhbm", methodBinding.XiangzhengBeikaoBumen) //验证部门指标细则关系对照 } } diff --git a/apirouter/v1/departmentseting/web.go b/apirouter/v1/departmentseting/web.go index 04b9728..2f7952e 100644 --- a/apirouter/v1/departmentseting/web.go +++ b/apirouter/v1/departmentseting/web.go @@ -15,5 +15,15 @@ func (a *ApiRouter) RouterGroupWeb(router *gin.RouterGroup) { apiRouter.GET("", methodBinding.Index) //入口 apiRouter.POST("", methodBinding.Index) //入口 + apiRouter.POST("target_list_for_department", methodBinding.TargetListForDepartment) //指标列表 + apiRouter.POST("bdtts", methodBinding.BasisDepartTargetTimeStatistics) //根据部门、指标、年份统计每月的目标值、实际值、达成率 + apiRouter.POST("bdttsyoy", methodBinding.BasisDepartTargetTimeStatisticsYOY) //历史同比根据部门、定量指标、年份统计每月的实际值 + + apiRouter.POST("totalscore_org_from_timesearch", methodBinding.TotalScoreOFOrgComesFromTimeSearch) //通过时间获取组织总分 + apiRouter.POST("get_hinge_target", methodBinding.GetHingeTarget) //获取关键指标 + apiRouter.POST("get_everyone_org_month_result", methodBinding.GetEveryOneOrgToMonthResult) //获取单一行政组织指定年度各月份成绩 + apiRouter.POST("get_everyone_org_months_result", methodBinding.GetEveryOneOrgToMonthsResult) //获取单一行政组织多年度各月份成绩 + + apiRouter.POST("bdttsattryoy", methodBinding.BasisDepartAttrTargetTimeStatistics) //历史同比根据部门、定性指标、年份统计每月的实际值 } } diff --git a/apirouter/workflowrouter/flowrouter.go b/apirouter/workflowrouter/flowrouter.go index 8033668..f07cd22 100644 --- a/apirouter/workflowrouter/flowrouter.go +++ b/apirouter/workflowrouter/flowrouter.go @@ -17,5 +17,9 @@ func (a *ApiRouter) RouterGroup(router *gin.RouterGroup) { //实验用接口 apiRouter.POST("shiyan_data", workFlow.ShiyanData) //入口 + + apiRouter.POST("judge_optional_node", workFlow.JudgeOptionalNode) //判断是否显示(指定审批节点自选)选项及可选节点 + apiRouter.POST("get_all_parent_node", workFlow.GetAllParentNode) //获取所有父级审批节点 + apiRouter.POST("judging_condition", workFlow.JudgingCondition) //判断条件 } } diff --git a/config/configDatabase/database.go b/config/configDatabase/database.go index b5f7a94..5ca7be9 100644 --- a/config/configDatabase/database.go +++ b/config/configDatabase/database.go @@ -45,7 +45,7 @@ type MasterMysqlSetUp struct { func (m *MasterMysqlSetUp) SqlDsn() (dsnStr string) { dsnStr = fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=%v", m.UserName, m.PassWord, m.UrlPath, m.Port, m.Name, m.Charset) - if m.ParseTime == true { + if m.ParseTime { dsnStr = fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=%v&parseTime=%v&loc=%v", m.UserName, m.PassWord, m.UrlPath, m.Port, m.Name, m.Charset, m.ParseTime, m.Loc) } return @@ -60,7 +60,7 @@ func (m *MasterMysqlSetUp) OpenSql() *gorm.DB { DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列 SkipInitializeWithVersion: false, // 根据版本自动配置 } - if m.GormLog == true { + if m.GormLog { if opDb, err := gorm.Open(mysql.New(sqlConfig), &gorm.Config{ Logger: logger.Default.LogMode(logger.Info), }); err != nil { diff --git a/models/modelshr/administrative_organization.go b/models/modelshr/administrative_organization.go index 0bfb9b0..062450f 100644 --- a/models/modelshr/administrative_organization.go +++ b/models/modelshr/administrative_organization.go @@ -20,6 +20,7 @@ type AdministrativeOrganization struct { Schoole int64 `json:"schoole" gorm:"column:schoole;type:bigint(20) unsigned;default:0;not null;comment:原知行学院对照码"` KingdeeId string `json:"kingdeeid" gorm:"column:kingdeeid;type:varchar(255) unsigned;default:'';comment:金蝶对照ID"` IsPower int `json:"ispower" gorm:"column:ispower;type:int(1) unsigned;default:2;not null;comment:是否为实权部门"` + Sort int `json:"sort" gorm:"column:sort;type:int(6) unsigned;default:100;not null;comment:是否为实权部门"` } func (AdministrativeOrganization *AdministrativeOrganization) TableName() string { diff --git a/overall/publicmethod/technique.go b/overall/publicmethod/technique.go index 48c95a1..9489c60 100644 --- a/overall/publicmethod/technique.go +++ b/overall/publicmethod/technique.go @@ -898,7 +898,7 @@ func GetMinMainDutyDeparment(company string) (organization []modelshr.Administra return } for _, v := range allOrg { - sunOrgList, orgSunErr := getSunOrgList(v.Id) + sunOrgList, orgSunErr := GetSunOrgList(v.Id) if orgSunErr == nil && len(sunOrgList) > 0 { for _, sv := range sunOrgList { organization = append(organization, sv) @@ -911,7 +911,7 @@ func GetMinMainDutyDeparment(company string) (organization []modelshr.Administra } // 获取下级行政组织是否有主行政部门 -func getSunOrgList(orgId int64) (orgList []modelshr.AdministrativeOrganization, ovErr error) { +func GetSunOrgList(orgId int64) (orgList []modelshr.AdministrativeOrganization, ovErr error) { ovErr = overall.CONSTANT_DB_HR.Where("state = 1").Where("ispower = 1 AND superior = ?", orgId).Find(&orgList).Error return } @@ -1629,3 +1629,200 @@ func MergeStruct[T GenericityVariable](aryOen, aryTwo []T) (structAry []T) { } return } + +// 根据字符串组合时间 +/* +#dateTime 日期 +*/ +func (d *DateTimeTotimes) BaisStrToTime(dateTime string) { + timeStrAry := strings.Split(dateTime, "-") + switch len(timeStrAry) { + case 1: + dateTime = fmt.Sprintf("%v-01-01 12:00:00", dateTime) + case 2: + if len(timeStrAry[1]) < 2 { + dateTime = fmt.Sprintf("%v-0%v-01 12:00:00", timeStrAry[0], timeStrAry[1]) + } + case 3: + monthStr := timeStrAry[1] + if len(timeStrAry[1]) < 2 { + monthStr = fmt.Sprintf("0%v", timeStrAry[1]) + } + dayAry := strings.Split(timeStrAry[2], " ") + // fmt.Printf("dayAry:%v------>%v\n", dayAry, len(dayAry)) + dayStr := dayAry[0] + if len(dayAry[0]) < 2 { + dayStr = fmt.Sprintf("0%v", dayAry[0]) + } + if len(dayAry) > 1 { + // fmt.Printf("dayAry[1]:%v------>%v\n", dayAry[1], len(dayAry[1])) + if len(dayAry[1]) > 0 { + Hours := "00" + minutes := "00" + seconds := "00" + hisAry := strings.Split(dayAry[1], ":") + switch len(hisAry) { + case 1: + if len(hisAry[0]) < 2 { + Hours = fmt.Sprintf("0%v", hisAry[0]) + } else { + Hours = hisAry[0] + } + case 2: + if len(hisAry[0]) < 2 { + Hours = fmt.Sprintf("0%v", hisAry[0]) + } else { + Hours = hisAry[0] + } + if len(hisAry[1]) < 2 { + minutes = fmt.Sprintf("0%v", hisAry[1]) + } else { + minutes = hisAry[1] + } + case 3: + if len(hisAry[0]) < 2 { + Hours = fmt.Sprintf("0%v", hisAry[0]) + } else { + Hours = hisAry[0] + } + if len(hisAry[1]) < 2 { + minutes = fmt.Sprintf("0%v", hisAry[1]) + } else { + minutes = hisAry[1] + } + if len(hisAry[2]) < 2 { + seconds = fmt.Sprintf("0%v", hisAry[2]) + } else { + seconds = hisAry[2] + } + default: + } + dayStr = fmt.Sprintf("%v %v:%v:%v", dayStr, Hours, minutes, seconds) + } + } + // dayStr := timeStrAry[2] + // if len(timeStrAry[2]) < 2 { + // dayStr = fmt.Sprintf("0%v", timeStrAry[2]) + // } + dateTime = fmt.Sprintf("%v-%v-%v", timeStrAry[0], monthStr, dayStr) + + default: + } + // fmt.Printf("dateTime:%v---1--->%v\n", dateTime, len(dateTime)) + orgTime, orgTimeErr := DateToTimeStamp(fmt.Sprintf("%v-01-01 12:00:00", dateTime)) + if orgTimeErr { + d.AllTime = orgTime + d.Years = UnixTimeToDay(orgTime, 16) + d.Months = UnixTimeToDay(orgTime, 17) + d.Days = UnixTimeToDay(orgTime, 18) + d.Hours = UnixTimeToDay(orgTime, 7) + d.Minutes = UnixTimeToDay(orgTime, 9) + d.Second = UnixTimeToDay(orgTime, 10) + } else { + + orgTime, orgTimeErr = DateToTimeStamp(fmt.Sprintf("%v-01 12:00:00", dateTime)) + if orgTimeErr { + d.AllTime = orgTime + d.Years = UnixTimeToDay(orgTime, 16) + d.Months = UnixTimeToDay(orgTime, 17) + d.Days = UnixTimeToDay(orgTime, 18) + d.Hours = UnixTimeToDay(orgTime, 7) + d.Minutes = UnixTimeToDay(orgTime, 9) + d.Second = UnixTimeToDay(orgTime, 10) + } else { + orgTime, orgTimeErr = DateToTimeStamp(fmt.Sprintf("%v 12:00:00", dateTime)) + if orgTimeErr { + d.AllTime = orgTime + d.Years = UnixTimeToDay(orgTime, 16) + d.Months = UnixTimeToDay(orgTime, 17) + d.Days = UnixTimeToDay(orgTime, 18) + d.Hours = UnixTimeToDay(orgTime, 7) + d.Minutes = UnixTimeToDay(orgTime, 9) + d.Second = UnixTimeToDay(orgTime, 10) + } else { + orgTime, orgTimeErr = DateToTimeStamp(fmt.Sprintf("%v:00:00", dateTime)) + if orgTimeErr { + d.AllTime = orgTime + d.Years = UnixTimeToDay(orgTime, 16) + d.Months = UnixTimeToDay(orgTime, 17) + d.Days = UnixTimeToDay(orgTime, 18) + d.Hours = UnixTimeToDay(orgTime, 7) + d.Minutes = UnixTimeToDay(orgTime, 9) + d.Second = UnixTimeToDay(orgTime, 10) + } else { + orgTime, orgTimeErr = DateToTimeStamp(fmt.Sprintf("%v:00", dateTime)) + if orgTimeErr { + d.AllTime = orgTime + d.Years = UnixTimeToDay(orgTime, 16) + d.Months = UnixTimeToDay(orgTime, 17) + d.Days = UnixTimeToDay(orgTime, 18) + d.Hours = UnixTimeToDay(orgTime, 7) + d.Minutes = UnixTimeToDay(orgTime, 9) + d.Second = UnixTimeToDay(orgTime, 10) + } else { + orgTime, orgTimeErr = DateToTimeStamp(dateTime) + if orgTimeErr { + d.AllTime = orgTime + d.Years = UnixTimeToDay(orgTime, 16) + d.Months = UnixTimeToDay(orgTime, 17) + d.Days = UnixTimeToDay(orgTime, 18) + d.Hours = UnixTimeToDay(orgTime, 7) + d.Minutes = UnixTimeToDay(orgTime, 9) + d.Second = UnixTimeToDay(orgTime, 10) + } + } + } + } + } + } +} + +//统一图标计算最大值最小值方法 +/* +maxVal 最大值 +minVal 最小值 +*/ +func JudjeMaxOfMinVal(maxVal, minVal float64) (maxVals, minVals float64) { + if maxVal > 0 { + if minVal > 0 { + if maxVal < 10 { + if maxVal < 1 { + maxVal = math.Ceil(maxVal) + 0.1 + minVals = math.Ceil(minVal) - 0.1 + } else { + maxVal = math.Ceil(maxVal) + 1 + minVals = math.Ceil(minVal) - 1 + } + } else { + jianGe := math.Ceil((maxVal - minVal) / 5) + if jianGe <= 0 { + jianGe = 1 + } + maxVals = math.Ceil(maxVal) + jianGe + minVals = math.Ceil(minVal) - jianGe + if minVals < 0 { + minVals = 0 + } + } + } else { + jianGe := math.Ceil(maxVal / 5) + maxVals = math.Ceil(maxVal) + jianGe + } + } else { + if minVal > -1 { + minVals = minVal - 0.1 + } else { + maxGuoDu := maxVal * -1 + minGuoDu := minVal * -1 + jianGe := math.Ceil((minGuoDu - maxGuoDu) / 5) + if jianGe > 0 { + minVals = minVal - jianGe + } else { + minVals = minVal - 1 + } + } + + } + // fmt.Printf("ge---1-->%v----->%v\n", maxVals, minVals) + return +} diff --git a/overall/publicmethod/type.go b/overall/publicmethod/type.go index 09e8e53..85a19dc 100644 --- a/overall/publicmethod/type.go +++ b/overall/publicmethod/type.go @@ -10,6 +10,11 @@ type GenericityVariable interface { int | int8 | int16 | int32 | int64 | float32 | float64 | string } +// 数值泛型基础变量类型 +type GenericityVariableNumber interface { + int | int8 | int16 | int32 | int64 | float32 | float64 +} + // 格式化输出 type Reply struct { Code int `json:"code"` @@ -253,3 +258,14 @@ type EvaluPross struct { QualEvalId string `json:"qeid"` Status int `json:"status"` //1:使用;2:禁用;3:观察 } + +// 时间转换 +type DateTimeTotimes struct { + Years string `json:"years"` + Months string `json:"months"` + Days string `json:"days"` + Hours string `json:"hours"` + Minutes string `json:"minutes"` + Second string `json:"second"` + AllTime int64 `json:"alltime"` +}