diff --git a/README.md b/README.md index 00017e4..e215c53 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # KPI综合管理系统 - ```Project |—— api └── version1 @@ -21,31 +20,32 @@ |—— overall |—— middleware ``` -## Hr 文件结构说明 -| 文件夹 | 说明 | 描述| -|--------- |------ |-----| -| `api` | api相关业务 | api业务实现 | -| `--version1` | 业务版本文件夹 | 版本界定 | -| `--empower` |OAuth 2.0 授权 |授权Token| -| `apirouter` | 路由器 | 业务路由设定 | -| `initialization` | 初始化相关业务 | 系统初始化方面的实现 | -| `--database` | 数据库业务 | 数据库业务初始化实现 | -| `--nosql` | nosql数据库业务 | nosql业务初始化实现(例:Redis) | -| `--app` | app数据库业务 | app业务初始化实现 | -| `--route` | 路由初始化 | 路由初始化 | -| `identification` | 授权验证器 | 授权验证器 | -| `config` | 系统配置相关业务 | 系统系统配置方面的实现 | -| `--configDatabase` | 数据库业务 | 数据库业务系统配置实现 | -| `--configNosql` | nosql数据库业务 | nosql业务系统配置实现(例:Redis) | -| `--configAapp` | app系统业务 | app业务系统配置实现 | -| `--configJson` | app JSON业务 | app业务系统配置实现 | -| `models` | 数据模型 | 数据库方面的配置 | -| `overall` | 全局对象 | 全局对象| -| `middleware` | 中间件 | 中间件 | +## Hr 文件结构说明 +| 文件夹 | 说明 | 描述 | +| -------------------- | ---------------- | ---------------------------------- | +| `api` | api相关业务 | api业务实现 | +| `--version1` | 业务版本文件夹 | 版本界定 | +| `--empower` | OAuth 2.0 授权 | 授权Token | +| `apirouter` | 路由器 | 业务路由设定 | +| `initialization` | 初始化相关业务 | 系统初始化方面的实现 | +| `--database` | 数据库业务 | 数据库业务初始化实现 | +| `--nosql` | nosql数据库业务 | nosql业务初始化实现(例:Redis) | +| `--app` | app数据库业务 | app业务初始化实现 | +| `--route` | 路由初始化 | 路由初始化 | +| `identification` | 授权验证器 | 授权验证器 | +| `config` | 系统配置相关业务 | 系统系统配置方面的实现 | +| `--configDatabase` | 数据库业务 | 数据库业务系统配置实现 | +| `--configNosql` | nosql数据库业务 | nosql业务系统配置实现(例:Redis) | +| `--configAapp` | app系统业务 | app业务系统配置实现 | +| `--configJson` | app JSON业务 | app业务系统配置实现 | +| `models` | 数据模型 | 数据库方面的配置 | +| `overall` | 全局对象 | 全局对象 | +| `middleware` | 中间件 | 中间件 | ## 加密规则 + ``` 1、分解步骤 one = md5(CodeString)+md5(AppKey) @@ -54,15 +54,15 @@ 2、合并 md5(md5(md5(CodeString)+md5(AppKey))+AppKey) ``` + ## 企业微信按钮key定义 KPI_post_OrderId_1_1 或 KPI_post_OrderId_2_1 -|系统 |类别 |审批流ID|操作|步进器| -|---------|---------|---------|---------|---------| -| KPI | post | OrderId | 1:批准;2:驳回 | 当前步进位 | -| KPI | department | OrderId | 1:批准;2:驳回 | 当前步进位 | - +| 系统 | 类别 | 审批流ID | 操作 | 步进器 | +| ---- | ---------- | -------- | --------------- | ---------- | +| KPI | post | OrderId | 1:批准;2:驳回 | 当前步进位 | +| KPI | department | OrderId | 1:批准;2:驳回 | 当前步进位 | ## 开发日志 @@ -132,23 +132,24 @@ CREATE TABLE `target_report` ( ``` - ``` Time:2022-08-16 创建子栏目关联指标视图 son_target_father select `qt`.`q_id` AS `q_id`,`qt`.`q_title` AS `q_title`,`qt`.`q_parent_id` AS `q_parent_id`,`qt`.`q_state` AS `q_state`,`qt`.`q_time` AS `q_time`,`qt`.`q_depart` AS `q_depart`,`et`.`et_title` AS `et_title`,`et`.`et_type` AS `et_type`,`et`.`et_dimension` AS `et_dimension`,`et`.`et_key` AS `et_key`,`et`.`et_unit` AS `et_unit`,`et`.`et_cycle` AS `et_cycle`,`et`.`et_cycleattr` AS `et_cycleattr`,`et`.`et_scoring_method` AS `et_scoring_method` from (`qualitative_target` `qt` left join `evaluationtarget` `et` on((`qt`.`q_parent_id` = `et`.`et_id`))) ``` + 创建用户与职务、岗位关联视图 user_post_duties (HR数据库) + ``` select `pc`.`mobilephone` AS `mobilephone`,`pc`.`gender` AS `gender`,`ps`.`name` AS `postname`,`ps`.`person_in_charge` AS `leading_cadre`,`ps`.`superior` AS `post_superior`,`ps`.`menu_permit` AS `menu_permit`,`ps`.`button_permit` AS `button_permit`,`pd`.`name` AS `duties_name`,`pa`.`id` AS `id`,`pa`.`number` AS `number`,`pa`.`name` AS `name`,`pa`.`icon` AS `icon`,`pa`.`company` AS `company`,`pa`.`maindeparment` AS `maindeparment`,`pa`.`admin_org` AS `admin_org`,`pa`.`position` AS `position`,`pa`.`job_id` AS `job_id`,`pa`.`job_leve` AS `job_leve`,`pa`.`wechat` AS `wechat`,`pa`.`work_wechat` AS `work_wechat`,`pa`.`is_admin` AS `is_admin`,`pa`.`key` AS `key`,`pa`.`role` AS `role`,`pa`.`password` AS `password`,`pa`.`sun_main_deparment` AS `sun_main_deparment`,`pa`.`teamid` AS `teamid` from (((`person_archives` `pa` join `personnel_content` `pc` on((`pa`.`key` = `pc`.`key`))) join `position` `ps` on((`pa`.`position` = `ps`.`id`))) join `duties` `pd` on((`pa`.`job_id` = `pd`.`id`))) ``` - -Time:2022-08-16
+`` +Time:2022-08-16 埋坑(1) 待以后编写相应模块 PS:该问题解决后删除此记录 - +`
` ``` @@ -162,22 +163,20 @@ F:\goobject\src\key_performance_indicators\api\version1\departmentseting\departm ``` - -Time:2022-08-24
+`` +Time:2022-08-24 `
` 数据库增加考核项目与提报人关联视图 -
+`
` ``` select `qes`.`id` AS `id`,`qes`.`version_number` AS `version_number`,`qes`.`company_id` AS `company_id`,`qes`.`department_id` AS `department_id`,`qes`.`org_id` AS `org_id`,`qes`.`post_id` AS `post_id`,`qes`.`title` AS `title`,`qes`.`dimension_id` AS `dimension_id`,`qes`.`target_id` AS `target_id`,`qes`.`son_target_id` AS `son_target_id`,`qes`.`details_id` AS `details_id`,`qes`.`attribute` AS `attribute`,`qes`.`min_score` AS `min_score`,`qes`.`max_score` AS `max_score`,`qes`.`scoring_method` AS `scoring_method`,`qes`.`state` AS `state`,`qes`.`addtime` AS `addtime`,`qes`.`eitetime` AS `eitetime`,`qes`.`censor_type` AS `censor_type`,`qes`.`source` AS `source`,`qes`.`run_state` AS `run_state`,`tr`.`type` AS `tr_type`,`tr`.`man_key` AS `man_key`,`tr`.`man_department` AS `man_department`,`tr`.`class` AS `tr_class`,`tr`.`type_level` AS `tr_level` from (`qualitative_evaluation_scheme` `qes` join `target_report` `tr` on(((`qes`.`dimension_id` = `tr`.`dimension_id`) and (`qes`.`target_id` = `tr`.`target_id`) and (`qes`.`son_target_id` = `tr`.`target_sun_id`) and (`qes`.`details_id` = `tr`.`target_bylaws`) and (`qes`.`post_id` = `tr`.`post_id`) and (`qes`.`org_id` = `tr`.`department_id`)))) ``` - - - -Time:2022-08-29
+`` +Time:2022-08-29 `
` 数据库增加 岗位审批工作流 数据表 -
+`
` ``` CREATE TABLE `post_workflow_orders` ( @@ -207,10 +206,10 @@ CREATE TABLE `post_workflow_orders` ( ``` - -Time:2022-08-29
+`` +Time:2022-08-29 `
` 数据库增加 定性考核流水 数据表 -
+`
` ``` CREATE TABLE `post_nature_flow` ( @@ -247,11 +246,10 @@ CREATE TABLE `post_nature_flow` ( ``` - - -Time:2022-08-29
+`` +Time:2022-08-29 `
` 数据库增加 岗位定量考核流水 数据表 -
+`
` ``` CREATE TABLE `post_metering_flow` ( @@ -282,14 +280,14 @@ CREATE TABLE `post_metering_flow` ( ``` - - -Time:2022-09-04
+`` +Time:2022-09-04 `
` 增加权限配置管理相关模块 -
## database.yaml添加权限数据库配置 +`
` + ``` 1、文件地址:config\configDatabase\database.yaml 2、系统权限配置数据库 @@ -330,8 +328,6 @@ systemPermission: } ``` - - ## 增加仓储系统参数 1、config\configDatabase\database.go @@ -353,11 +349,10 @@ systemPermission: } ``` - - -Time:2022-09-07
+`` +Time:2022-09-07 `
` 数据库增加 应用系统 数据表 -
+`
` ``` CREATE TABLE `appsystem` ( @@ -372,10 +367,10 @@ CREATE TABLE `appsystem` ( ``` - -Time:2022-10-05
+`` +Time:2022-10-05 `
` 数据库增加 审批记录 数据表 -
+`
` ``` CREATE TABLE `open_approval_change_log` ( @@ -392,10 +387,10 @@ CREATE TABLE `open_approval_change_log` ( ``` - -Time:2022-10-05
+`` +Time:2022-10-05 `
` 数据库增加 当前节点是否可操作 数据表 -
+`
` ``` CREATE TABLE `operator_is_true` ( @@ -412,20 +407,20 @@ CREATE TABLE `operator_is_true` ( ``` - -Time:2022-10-24
+`` +Time:2022-10-24 `
` 数据库增加 定性考核与流程关联视图 nature_flow_order -
+`
` ``` select `pf`.`id` AS `id`,`pf`.`order_id` AS `order_id`,`pf`.`add_or_decrease` AS `add_or_decrease`,`pf`.`score` AS `score`,`pf`.`money` AS `money`,`pf`.`reason` AS `reason`,`pf`.`sheme_id` AS `sheme_id`,`pf`.`sheme_version` AS `sheme_version`,`pf`.`dimension` AS `dimension`,`pf`.`target` AS `target`,`pf`.`son_target` AS `son_target`,`pf`.`detailed` AS `detailed`,`pf`.`year` AS `year`,`pf`.`quarter` AS `quarter`,`pf`.`month` AS `month`,`pf`.`week` AS `week`,`pf`.`person_liable` AS `person_liable`,`pf`.`company_id` AS `company_id`,`pf`.`department_id` AS `department_id`,`pf`.`org_id` AS `org_id`,`pf`.`post_id` AS `post_id`,`pf`.`executor` AS `executor`,`pf`.`executor_department` AS `executor_department`,`pf`.`rectification` AS `rectification`,`pf`.`correction_time` AS `correction_time`,`pf`.`happen_time` AS `happen_time`,`pf`.`happen_count` AS `happen_count`,`pf`.`time` AS `time`,`po`.`class` AS `class`,`po`.`state` AS `state`,`po`.`participants` AS `participants` from (`post_nature_flow` `pf` left join `post_workflow_orders` `po` on((`pf`.`order_id` = `po`.`order_id`))) ``` - -Time:2022-11-08
+`` +Time:2022-11-08 `
` 数据库增加 角色权限分配 role_empower -
+`
` ``` CREATE TABLE `role_empower` ( @@ -442,10 +437,10 @@ CREATE TABLE `role_empower` ( ``` - -Time:2022-11-08
+`` +Time:2022-11-08 `
` 数据库增加 系统角色表 system_role -
+`
` ``` CREATE TABLE `system_role` ( @@ -456,4 +451,31 @@ CREATE TABLE `system_role` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COMMENT='系统角色表'; +``` +`` +Time:2023-03-24 +数据库增加 工作流主体 work_flow 、工作流版本 work_flow_version +增加数据视图 work_flow_cont +`` + +``` +CREATE TABLE `work_flow` ( + `id` bigint(20) unsigned NOT NULL, + `name` varchar(255) DEFAULT '', + `time` bigint(20) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `id` (`id`) USING HASH COMMENT '主键' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='工作流主体'; + +CREATE TABLE `work_flow_version` ( + `id` bigint(20) unsigned NOT NULL, + `content` longtext COMMENT '流程主体', + `version` varchar(255) DEFAULT '' COMMENT '版本号', + `time` bigint(20) unsigned NOT NULL DEFAULT '0', + `state` int(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态(1:启用;2:禁用;3:删除)', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='工作流版本'; + +select `wf`.`id` AS `id`,`wf`.`name` AS `name`,`wf`.`time` AS `time`,`wfv`.`content` AS `content`,`wfv`.`version` AS `version`,`wfv`.`state` AS `state` from (`work_flow` `wf` join `work_flow_version` `wfv` on((`wf`.`id` = `wfv`.`id`))) + ``` \ No newline at end of file diff --git a/api/shiyan/maptostruct/department.go b/api/shiyan/maptostruct/department.go index 39d0929..eec00b8 100644 --- a/api/shiyan/maptostruct/department.go +++ b/api/shiyan/maptostruct/department.go @@ -2,6 +2,7 @@ package maptostruct import ( "fmt" + "key_performance_indicators/api/workflow/currency_recipe" "key_performance_indicators/models/modelshr" "key_performance_indicators/models/modelskpi" "key_performance_indicators/overall" @@ -355,3 +356,36 @@ func HuiGaiDingXing(key int64) { } } } + +// 验证工作流 +func (a *ApiMethod) TestAndVerifyWorkflow(c *gin.Context) { + var receivedValue publicmethod.PublicId + c.ShouldBindJSON(&receivedValue) + //自定义判断 + var zdyPd []currency_recipe.CustomFields + var zdyPdOne currency_recipe.CustomFields + zdyPdOne.WordField = "istrue" + zdyPdOne.LeftVal = "1" + zdyPd = append(zdyPd, zdyPdOne) + + var zdyPdTwo currency_recipe.CustomFields + zdyPdTwo.WordField = "isok" + zdyPdTwo.LeftVal = "1" + zdyPd = append(zdyPd, zdyPdTwo) + //条件设定 + var tijiao1 currency_recipe.JudgingCondition + tijiao1.Class = 1 + tijiao1.MyCustom = zdyPd + + var workflowInfo currency_recipe.WorkflowEngine + workflowInfo.JudCond = append(workflowInfo.JudCond, tijiao1) + // workflowInfo.VersionId = "1" + jieguo := workflowInfo.InitWorkflow(receivedValue.Id, "", "16047344045376832", "103").SendData() + + if jieguo.IsTrue != true { + publicmethod.Result(1000, jieguo, c) + } else { + publicmethod.Result(0, jieguo, c) + } + +} diff --git a/api/version1/departmentseting/departmentpc/dingliang.go b/api/version1/departmentseting/departmentpc/dingliang.go index dd657ea..406ee2c 100644 --- a/api/version1/departmentseting/departmentpc/dingliang.go +++ b/api/version1/departmentseting/departmentpc/dingliang.go @@ -44,7 +44,7 @@ func (a *ApiMethod) GetQuantitativeTasks(c *gin.Context) { gormDb = gormDb.Where("qe_accept_evaluation = ?", receivedValue.OrgId) } if receivedValue.Title != "" { - gormDb = gormDb.Where("et_title LIKE ?", "%"+receivedValue.Title+"%") + gormDb = gormDb.Joins("LEFT JOIN evaluationtarget ON et_id = qe_target").Where("et_title LIKE ?", "%"+receivedValue.Title+"%") } err := gormDb.Order("qe_type ASC,qe_group ASC,qe_accept_evaluation ASC,qe_dimension ASC,qe_target ASC,qe_target_sun ASC,qe_detailed_target ASC").Find(&listCont).Error if err != nil || len(listCont) < 1 { @@ -187,7 +187,7 @@ func (a *ApiMethod) GetQuantitativeTasks(c *gin.Context) { shiJiZhi["fl_day"] = publicmethod.ComputingTime(operationTime, 5) } sendCont.ReferTo = JudgeDingLiangIsTrue(v.Target, v.AcceptEvaluation, years, quarter, months, v.Cycles) - actualValue := GetTimeIntervalDuty(shiJiZhi, v.Id) //实际值 + actualValue, shouDongScore := GetTimeIntervalDuty(shiJiZhi, v.Id) //实际值 sendCont.Actual = strconv.FormatFloat(actualValue/100, 'f', -1, 64) // chuShuVal := actualValue - quanTitCont.Zeroprize // beiChuShuVal := quanTitCont.Allprize - quanTitCont.Zeroprize @@ -196,30 +196,12 @@ func (a *ApiMethod) GetQuantitativeTasks(c *gin.Context) { // } else { // sendCont.ReachScore = 0 // } - _, sendCont.ReachScore = postweb.GetAchieAndActual(actualValue, float64(sendCont.TargetWeight), quanTitCont.Zeroprize, quanTitCont.Allprize, quanTitCont.CappingVal) - /* - * - @ 作者: 秦东 - @ 时间: 2022-10-28 15:09:33 - @ 功能: 计算达成率及得分 - @ 参数 - - #score 实际分 - #weight 指标权重 - #zeroprize 零奖值 - #allprize 全奖值 - #cappingval 封顶值 - - @ 返回值 - - #achievement 达成率 - #actual 得分 - - @ 函数原型 - - #GetAchieAndActual(score, weight, zeroprize, allprize, cappingval float64) (achievement, actual float64) - */ - + var actual float64 + actual, sendCont.ReachScore = postweb.GetAchieAndActual(actualValue, float64(sendCont.TargetWeight), quanTitCont.Zeroprize, quanTitCont.Allprize, quanTitCont.CappingVal) + if targetCont.ScoringMethod != 1 { + sendCont.ReachScore = publicmethod.DecimalEs(shouDongScore/100, 2) + } + // fmt.Printf("All--->score:%v------>weight:%v------>zeroprize:%v------>allprize:%v------>cappingval:%v------>achievement:%v------>actual:%v\n", actualValue, sendCont.TargetWeight, quanTitCont.Zeroprize, quanTitCont.Allprize, quanTitCont.CappingVal, sendCont.ReachScore, actual) if quanTitCont.Zeroprize == 0 && quanTitCont.Allprize == 0 { sendCont.Reach = "未设置目标值" } else { @@ -227,12 +209,36 @@ func (a *ApiMethod) GetQuantitativeTasks(c *gin.Context) { if dividend == 0 { sendCont.Reach = "未设置目标值" } else { - sendCont.Reach = fmt.Sprintf("(实际值-零奖值)/(全奖值-零奖值)") + // sendCont.Reach = fmt.Sprintf("(实际值-零奖值)/(全奖值-零奖值)") + actual = publicmethod.DecimalEs(actual*100, 2) + sendCont.Reach = fmt.Sprintf("%v%v", actual, "%") + if actualValue == 0 { + sendCont.Reach = "100%" + } } } sendCont.Reason = "" sendCont.DetailedTarget = strconv.FormatInt(v.DetailedTarget, 10) - sendListCont = append(sendListCont, sendCont) + + switch v.Cycles { + case 5: + banNian := []int64{3, 6, 9, 12} + if publicmethod.IsInTrue[int64](months, banNian) { + sendListCont = append(sendListCont, sendCont) + } + case 6: + if months == 12 { + sendListCont = append(sendListCont, sendCont) + } + case 7: + banNian := []int64{6, 12} + if publicmethod.IsInTrue[int64](months, banNian) { + sendListCont = append(sendListCont, sendCont) + } + default: + sendListCont = append(sendListCont, sendCont) + } + } publicmethod.Result(0, sendListCont, c) } @@ -331,7 +337,7 @@ func AllZreoConfig(cycles int) (monthInt int64) { } // 获取定量考核时间内审批通过的考核数据 -func GetTimeIntervalDuty(whereData interface{}, schemeID int64) (actual float64) { +func GetTimeIntervalDuty(whereData interface{}, schemeID int64) (actual, shouDongScore float64) { // jsonStr, _ := json.Marshal(whereData) // fmt.Printf("jsonStr------1------>%v\n", string(jsonStr)) actual = 0 @@ -342,15 +348,19 @@ func GetTimeIntervalDuty(whereData interface{}, schemeID int64) (actual float64) return } for _, v := range flowLogList { - actual = actual + GetSchemeFlowData(v.Key, schemeID) + ziDongScore, sdScore := GetSchemeFlowData(v.Key, schemeID) + actual = actual + ziDongScore + shouDongScore = shouDongScore + sdScore } return } // 获取指定审批流方案数据 -func GetSchemeFlowData(flowKwy, schemeID int64) (weightSum float64) { +func GetSchemeFlowData(flowKwy, schemeID int64) (weightSum, shouDongScore float64) { weightSum = 0 - overall.CONSTANT_DB_KPI.Model(&modelskpi.FlowLogData{}).Where("`fld_evaluation_id` = ? AND `fld_flow_log` = ?", schemeID, flowKwy).Pluck("COALESCE(SUM(fld_score), 0) as qe_reference_score", &weightSum) + overall.CONSTANT_DB_KPI.Model(&modelskpi.FlowLogData{}).Where("`fld_evaluation_id` = ? AND `fld_flow_log` = ?", schemeID, flowKwy).Pluck("COALESCE(SUM(fld_score), 0) as flscore", &weightSum) + // weightSum = 0 + overall.CONSTANT_DB_KPI.Model(&modelskpi.FlowLogData{}).Where("`fld_evaluation_id` = ? AND `fld_flow_log` = ?", schemeID, flowKwy).Pluck("COALESCE(SUM(fld_scoring_score), 0) as scoring_score", &shouDongScore) return } diff --git a/api/version1/departmentseting/departmentpc/type.go b/api/version1/departmentseting/departmentpc/type.go index cf75c55..b81604f 100644 --- a/api/version1/departmentseting/departmentpc/type.go +++ b/api/version1/departmentseting/departmentpc/type.go @@ -324,25 +324,25 @@ type GetQuanTasks struct { // 考核方案细则列表输出 type TargetContOutCont struct { - Id string `json:"id"` - Type int `json:"type"` - Group string `json:"group"` - GroupNAme string `json:"groupname"` - DepartmentId string `json:"parentid"` - DepartmentName string `json:"parentname"` - Dimension string `json:"dimension"` - DimensionName string `json:"dimensionname"` - Target string `json:"target"` - TargetName string `json:"targetname"` - TargetSun string `json:"targetsun"` - TargetSunName string `json:"targetsunname"` - DetailedTarget string `json:"detailedtarget"` - DetailedTargetName string `json:"detailedtargetname"` - 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"` //辅助计数"` + Id string `json:"id"` //指标ID + Type int `json:"type"` //1:定性考核;2:定量考核 + Group string `json:"group"` //公司 + GroupNAme string `json:"groupname"` //公司名称 + DepartmentId string `json:"parentid"` //主部门 + DepartmentName string `json:"parentname"` //主部门名称 + Dimension string `json:"dimension"` //纬度 + DimensionName string `json:"dimensionname"` //纬度名称 + Target string `json:"target"` //指标 + TargetName string `json:"targetname"` //指标名称 + TargetSun string `json:"targetsun"` //栏目 + TargetSunName string `json:"targetsunname"` //栏目名称 + DetailedTarget string `json:"detailedtarget"` //细则 + DetailedTargetName string `json:"detailedtargetname"` //细则名称 + 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"` UserList []string `json:"userlist"` //执行人列表 UserListAry []QualEvalArrt `json:"userlistary"` //执行人列表 @@ -354,8 +354,8 @@ type TargetContOutCont struct { ReachScore float64 `json:"reachscore"` //手动分 CappingVal float64 `json:"cappingcal"` //封顶值 - Reason string `json:"reason"` //说明 - ScoringMethod int64 `json:"scoringmethod"` + Reason string `json:"reason"` //说明 + ScoringMethod int64 `json:"scoringmethod"` //计分方式(1:自动;2:手动) DimensionWeight int64 `json:"dimensionweight"` //权重 TargetWeight int64 `json:"targetweight"` //权重 PlanVersionNumber string `json:"planversionnumber"` //版本号 diff --git a/api/version1/jurisdiction/jurisdictionpc/people.go b/api/version1/jurisdiction/jurisdictionpc/people.go new file mode 100644 index 0000000..d4ab22a --- /dev/null +++ b/api/version1/jurisdiction/jurisdictionpc/people.go @@ -0,0 +1,76 @@ +package jurisdictionpc + +import ( + "key_performance_indicators/models/modelshr" + "key_performance_indicators/overall" + "key_performance_indicators/overall/publicmethod" + "strconv" + + "github.com/gin-gonic/gin" +) + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-21 11:06:07 +@ 功能: 搜索人员 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) SearchPeople(c *gin.Context) { + var receivedValue FlowGetRoleList + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if receivedValue.Name == "" { + publicmethod.Result(101, receivedValue, c) + return + } + if receivedValue.Page == 0 { + receivedValue.Page = 1 + } + if receivedValue.PageSize == 0 { + receivedValue.PageSize = 20 + } + var listCont []modelshr.PersonArchives + gormDb := overall.CONSTANT_DB_HR.Model(&modelshr.PersonArchives{}).Where("`emp_type` BETWEEN ? AND ?", 1, 10) + if receivedValue.Name != "" { + gormDb = gormDb.Where("`name` LIKE ?", "%"+receivedValue.Name+"%") + } + var total int64 + gormDbTotal := gormDb + totalErr := gormDbTotal.Count(&total).Error + if totalErr != nil { + total = 0 + } + gormDb = publicmethod.PageTurningSettings(gormDb, receivedValue.Page, receivedValue.PageSize) + err = gormDb.Find(&listCont).Error + if err != nil { + publicmethod.Result(107, err, c) + return + } + var sendContList []EmployeesCont + for _, v := range listCont { + var sendCont EmployeesCont + sendCont.Id = strconv.FormatInt(v.Id, 10) //`json:"id"` + sendCont.EmployeeName = v.Name //`json:"employeeName"` //人员名称 + sendCont.IsLeave = "0" //`json:"isLeave"` //行政组织名称 + sendCont.Open = "false" //`json:"open"` //上级ID + sendCont.Icon = v.Icon //`json:"icon"` //头像 + sendCont.IconToBase64 = v.IconPhoto //`json:"iconToBase64"` //头像 + sendContList = append(sendContList, sendCont) + } + publicmethod.ResultList(0, receivedValue.Page, receivedValue.PageSize, total, int64(len(sendContList)), sendContList, c) + +} diff --git a/api/version1/jurisdiction/jurisdictionpc/systemrole.go b/api/version1/jurisdiction/jurisdictionpc/systemrole.go index b387622..0423e32 100644 --- a/api/version1/jurisdiction/jurisdictionpc/systemrole.go +++ b/api/version1/jurisdiction/jurisdictionpc/systemrole.go @@ -1,6 +1,7 @@ package jurisdictionpc import ( + "encoding/json" "fmt" "key_performance_indicators/models/modelshr" "key_performance_indicators/models/modelssystempermission" @@ -442,3 +443,142 @@ func (a *ApiMethod) AddRoleUser(c *gin.Context) { } publicmethod.Result(0, nil, c) } + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-21 10:48:54 +@ 功能: 系统角色列表(工作流专版) +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) SystemRoleListFlow(c *gin.Context) { + var receivedValue FlowGetRoleList + c.ShouldBindJSON(&receivedValue) + if receivedValue.Page == 0 { + receivedValue.Page = 1 + } + if receivedValue.PageSize == 0 { + receivedValue.PageSize = 20 + } + var systemRoleInfoList []modelssystempermission.SystemRole + gormDb := overall.CONSTANT_DB_System_Permission.Model(&modelssystempermission.SystemRole{}).Where("`state` = ?", 1) + if receivedValue.Name != "" { + gormDb = gormDb.Where("`name` LIKE ?", "%"+receivedValue.Name+"%") + } + var total int64 + gormDbTotal := gormDb + totalErr := gormDbTotal.Count(&total).Error + if totalErr != nil { + total = 0 + } + gormDb = publicmethod.PageTurningSettings(gormDb, receivedValue.Page, receivedValue.PageSize) + err := gormDb.Order("`sort` ASC").Order("`id` DESC").Find(&systemRoleInfoList).Error + if err != nil { + publicmethod.Result(107, err, c) + return + } + var sendContList []OutPutRoleList + for _, v := range systemRoleInfoList { + var sendCont OutPutRoleList + sendCont.Code = strconv.FormatInt(v.Id, 10) //`json:"code"` //编号 + sendCont.RoleId = strconv.FormatInt(v.Id, 10) //`json:"roleId"` //角色ID + sendCont.Scope = strconv.Itoa(v.Sort) //`json:"scope"` //范围 + sendCont.RoleName = v.Name //`json:"roleName"` //角色名称 + sendCont.Description = v.Name //`json:"description"` //描述 + sendCont.Status = strconv.Itoa(v.State) //`json:"status"` //状态 + sendContList = append(sendContList, sendCont) + } + publicmethod.ResultList(0, receivedValue.Page, receivedValue.PageSize, total, int64(len(sendContList)), sendContList, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-28 14:05:00 +@ 功能: 获取统一岗位 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) GetPositionUnify(c *gin.Context) { + var uniflList []modelshr.PositionUnify + err := overall.CONSTANT_DB_HR.Where("`state` = ?", 1).Find(&uniflList).Error + if err != nil { + publicmethod.Result(105, err, c) + return + } + var sendData []OutPutUnify + for _, v := range uniflList { + var sendCont OutPutUnify + sendCont.Id = v.Id + sendCont.Name = v.Name //职位名称"` + sendCont.Time = v.Time //创建时间"` + sendCont.State = v.State //状态(1:启用;2:禁用;3:删除)"` + sendCont.Content = v.Content //关联具体岗位ID"` + json.Unmarshal([]byte(v.Content), &sendCont.PositionListId) + sendData = append(sendData, sendCont) + } + publicmethod.Result(0, sendData, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-28 14:07:58 +@ 功能: +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) SearchPositionUnify(c *gin.Context) { + var receivedValue publicmethod.PublicName + c.ShouldBindJSON(&receivedValue) + var uniflList []modelshr.PositionUnify + gormDb := overall.CONSTANT_DB_HR.Where("`state` = ?", 1) + if receivedValue.Name != "" { + gormDb = gormDb.Where("`name` LIKE ?", "%"+receivedValue.Name+"%") + } + err := gormDb.Find(&uniflList).Error + if err != nil { + publicmethod.Result(105, err, c) + return + } + var sendData []OutPutUnify + for _, v := range uniflList { + var sendCont OutPutUnify + sendCont.Id = v.Id + sendCont.Name = v.Name //职位名称"` + sendCont.Time = v.Time //创建时间"` + sendCont.State = v.State //状态(1:启用;2:禁用;3:删除)"` + sendCont.Content = v.Content //关联具体岗位ID"` + json.Unmarshal([]byte(v.Content), &sendCont.PositionListId) + sendData = append(sendData, sendCont) + } + publicmethod.Result(0, sendData, c) +} diff --git a/api/version1/jurisdiction/jurisdictionpc/type.go b/api/version1/jurisdiction/jurisdictionpc/type.go index 230f636..6b59c4c 100644 --- a/api/version1/jurisdiction/jurisdictionpc/type.go +++ b/api/version1/jurisdiction/jurisdictionpc/type.go @@ -1,6 +1,7 @@ package jurisdictionpc import ( + "key_performance_indicators/models/modelshr" "key_performance_indicators/models/modelssystempermission" "key_performance_indicators/overall/publicmethod" "sync" @@ -183,3 +184,35 @@ type OrgAndPeople struct { AllName string `json:"all_name"` //全部名 // Child []OrgAndPeople `json:"child"` //子栏目 } + +// 工作流获取角色列表 +type FlowGetRoleList struct { + publicmethod.PublicName + publicmethod.PagesTurn +} + +// 审批节点选人人员节点 +type EmployeesCont struct { + Id string `json:"id"` + EmployeeName string `json:"employeeName"` //人员名称 + IsLeave string `json:"isLeave"` //行政组织名称 + Open string `json:"open"` //上级ID + Icon string `json:"icon"` //头像 + IconToBase64 string `json:"iconToBase64"` //头像 +} + +// 工作流审批角色输出 +type OutPutRoleList struct { + Code string `json:"code"` //编号 + RoleId string `json:"roleId"` //角色ID + Scope string `json:"scope"` //范围 + RoleName string `json:"roleName"` //角色名称 + Description string `json:"description"` //描述 + Status string `json:"status"` //状态 +} + +// 输出统一岗位 +type OutPutUnify struct { + modelshr.PositionUnify + PositionListId []int64 `json:"positionListId` //关联岗位ID +} diff --git a/api/version1/postseting/postweb/appflowlog.go b/api/version1/postseting/postweb/appflowlog.go index 20c520b..f7e4614 100644 --- a/api/version1/postseting/postweb/appflowlog.go +++ b/api/version1/postseting/postweb/appflowlog.go @@ -346,42 +346,50 @@ func AnalysisDingLiang(natureCont modelskpi.PostMeteringFlow) (sendData DingLian #GetAchieAndActual(score, weight, zeroprize, allprize, cappingval float64) (achievement, actual float64) */ func GetAchieAndActual(score, weight, zeroprize, allprize, cappingval float64) (achievement, actual float64) { + cappingval = cappingval / 100 + // fmt.Printf("1--->score:%v------>weight:%v------>zeroprize:%v------>allprize:%v------>cappingval:%v------>achievement:%v------>actual:%v\n", score, weight, zeroprize, allprize, cappingval, achievement, actual) if zeroprize == 0 && allprize == 0 { //当全奖值与零奖值都为空时 if score != 0 { //判断实际值是否不为0 actual = weight achievement = 100 } + // fmt.Printf("2--->score:%v------>weight:%v------>zeroprize:%v------>allprize:%v------>cappingval:%v------>achievement:%v------>actual:%v\n", score, weight, zeroprize, allprize, cappingval, achievement, actual) } else { if allprize > zeroprize { //当全奖值大于零奖值时 正向计算 if score <= zeroprize { //实际数值小于零奖值时达成率与得分都为零 actual = 0 achievement = 0 + // fmt.Printf("3--->score:%v------>weight:%v------>zeroprize:%v------>allprize:%v------>cappingval:%v------>achievement:%v------>actual:%v\n", score, weight, zeroprize, allprize, cappingval, achievement, actual) } else { chuShu := score - zeroprize beiChushu := allprize - zeroprize if beiChushu != 0 { //判断除数不能为零 daChengLv := chuShu / beiChushu achievement = publicmethod.DecimalEs(daChengLv, 3) + // fmt.Printf("4-1-->score:%v------>weight:%v------>zeroprize:%v------>allprize:%v------>cappingval:%v------>achievement:%v------>daChengLv:%v\n", score, weight, zeroprize, allprize, cappingval, achievement, daChengLv) if daChengLv*100 >= cappingval { //达成率大于等于封顶值 if cappingval > 0 { - deFen := (weight / 100) * (cappingval / 100) + deFen := weight * (cappingval / 100) actual = publicmethod.DecimalEs(deFen, 2) } else { actual = weight } } else { - deFen := (weight / 100) * (daChengLv / 100) + deFen := weight * daChengLv actual = publicmethod.DecimalEs(deFen, 2) } + // fmt.Printf("4--->score:%v------>weight:%v------>zeroprize:%v------>allprize:%v------>cappingval:%v------>achievement:%v------>actual:%v\n", score, weight, zeroprize, allprize, cappingval, achievement, actual) } else { actual = 0 achievement = 0 + // fmt.Printf("5--->score:%v------>weight:%v------>zeroprize:%v------>allprize:%v------>cappingval:%v------>achievement:%v------>actual:%v\n", score, weight, zeroprize, allprize, cappingval, achievement, actual) } } } else { //如果全奖值小于零奖值 执行一下操作 if score >= zeroprize { //实际结算值大于零奖值 那么达成率和实际得分都是0 actual = 0 achievement = 0 + // fmt.Printf("6--->score:%v------>weight:%v------>zeroprize:%v------>allprize:%v------>cappingval:%v------>achievement:%v------>actual:%v\n", score, weight, zeroprize, allprize, cappingval, achievement, actual) } else { chuShu := score - zeroprize beiChushu := allprize - zeroprize @@ -391,26 +399,30 @@ func GetAchieAndActual(score, weight, zeroprize, allprize, cappingval float64) ( if daChengLv < 0 { actual = 0 achievement = 0 + // fmt.Printf("7--->score:%v------>weight:%v------>zeroprize:%v------>allprize:%v------>cappingval:%v------>achievement:%v------>actual:%v\n", score, weight, zeroprize, allprize, cappingval, achievement, actual) } else { if daChengLv*100 >= cappingval { //达成率大于等于封顶值 if cappingval > 0 { - deFen := (weight / 100) * (cappingval / 100) + deFen := weight * (cappingval / 100) actual = publicmethod.DecimalEs(deFen, 2) } else { actual = weight } } else { - deFen := (weight / 100) * (daChengLv / 100) + deFen := weight * daChengLv actual = publicmethod.DecimalEs(deFen, 2) } + // fmt.Printf("8--->score:%v------>weight:%v------>zeroprize:%v------>allprize:%v------>cappingval:%v------>achievement:%v------>actual:%v\n", score, weight, zeroprize, allprize, cappingval, achievement, actual) } } else { actual = 0 achievement = 0 + // fmt.Printf("9--->score:%v------>weight:%v------>zeroprize:%v------>allprize:%v------>cappingval:%v------>achievement:%v------>actual:%v\n", score, weight, zeroprize, allprize, cappingval, achievement, actual) } } } } + // fmt.Printf("10--->score:%v------>weight:%v------>zeroprize:%v------>allprize:%v------>cappingval:%v------>achievement:%v------>actual:%v\n", score, weight, zeroprize, allprize, cappingval, achievement, actual) return } diff --git a/api/workflow/currency_recipe/general_method.go b/api/workflow/currency_recipe/general_method.go new file mode 100644 index 0000000..7bdf748 --- /dev/null +++ b/api/workflow/currency_recipe/general_method.go @@ -0,0 +1,650 @@ +package currency_recipe + +import ( + "encoding/json" + "fmt" + "key_performance_indicators/models/modelshr" + "key_performance_indicators/models/modelskpi" + "key_performance_indicators/overall" + "key_performance_indicators/overall/publicmethod" + "strconv" +) + +//工作流解析函数 + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-29 09:03:15 +@ 功能: 初始化方法 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (w *WorkflowEngine) InitWorkflow(fields ...string) *WorkflowEngine { + if w.Id == "" { + if len(fields) > 0 { + for i, v := range fields { + switch i { + case 0: + w.Id = v + case 1: + w.VersionId = v + case 2: + w.Applicant = v + case 3: + w.AcceptOrg = v + default: + } + } + } + } + if w.Id != "" { + var workflowInfo modelskpi.WorkFlowVersion + var err error + if w.VersionId != "" { + err = workflowInfo.GetCont(map[string]interface{}{"`key`": w.Id, "`version`": w.VersionId}) + } else { + err = workflowInfo.GetCont(map[string]interface{}{"`key`": w.Id, "`state`": 1}) + } + if err == nil { + json.Unmarshal([]byte(workflowInfo.Content), &w.WorkflowCont) + } + } + // fmt.Printf("工作流接卸--->%v\n", w) + return w +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-29 09:26:47 +@ 功能: 输出工作流 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (w *WorkflowEngine) SendData() (sendCont SendOneWorkflow) { + var nodeInfo []NodeCont + nodeInfo, sendCont.IsTrue, sendCont.Msg = w.promoter() + sendCont.NodeContList = RectificationNode(nodeInfo) + // fmt.Printf("输出工作流--->%v\n", sendCont) + return +} + +// 整流 +func RectificationNode(nodeInfo []NodeCont) (nodeInfoOk []NodeCont) { + for i := 0; i < len(nodeInfo); i++ { + nextId := i + 1 + if nextId < len(nodeInfo) { + nodeInfo[i].ArriveNode = nodeInfo[nextId].NodeNumber + nodeInfo[nextId].FromNode = nodeInfo[i].NodeNumber + } + } + nodeInfoOk = nodeInfo + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-29 09:42:16 +@ 功能: 判断发起人 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (w *WorkflowEngine) promoter() (nodeList []NodeCont, isTrue bool, msg string) { + if w.Applicant == "" { + isTrue = false + msg = "未知申请人!流程不成立!" + return + } + err := w.ApplicantCont.GetCont(map[string]interface{}{"`key`": w.Applicant}) + if err != nil { + isTrue = false + msg = "未知申请人!流程不成立!" + return + } + + if len(w.WorkflowCont.FlowPermission) > 0 { + isTrue, msg = JudgeHaveApply(w.ApplicantCont, w.WorkflowCont.FlowPermission) + if !isTrue { + return + } + } + nodeConfig := w.WorkflowCont.NodeConfig + w.Step = 1 + w.StarNodeNumber = nodeConfig.NodeNumber + //流程线 + var nodeCont NodeCont + nodeCont.Step = w.Step //步伐 + nodeCont.NodeNumber = nodeConfig.NodeNumber //节点编号 + nodeCont.NodeName = nodeConfig.NodeName //节点名称 + nodeCont.State = 1 //状态 1、不点亮;2、点亮 + nodeCont.GoBackNode = w.StarNodeNumber //可得返回节点 + // nodeCont.UserList []UserListFlowAll //节点操作人 + nodeCont.UserList = append(nodeCont.UserList, SetOperator(w.ApplicantCont)) + nodeList = append(nodeList, nodeCont) + var childNode *PublicChildNode + childNode = nodeConfig.ChildNode + acceptOrgId, _ := strconv.ParseInt(w.AcceptOrg, 10, 64) + // nodeListCont, isTrues, msgs := childNode.AnalysisNode(w.Step, childNode.Attribute, w.StarNodeNumber, w.ApplicantCont, acceptOrgId) + // nodeList = append(nodeList, nodeListCont) + // isTrue = isTrues + // msg = msgs + // isTrue = true + listNode := childNode.CircularParsing(w.Step, childNode.Attribute, w.StarNodeNumber, w.ApplicantCont, acceptOrgId, w.JudCond) + // fmt.Printf("childNode.NodeContList-->%v\n", listNode) + if len(listNode) > 1 { + for _, v := range listNode { + nodeList = append(nodeList, v) + } + } + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-29 14:00:06 +@ 功能: 解析下级节点(废弃) +@ 参数 + + #step 执行到第几步 + #sendBackNode 开始节点编号 + #applicantCont 申请人信息 + #acceptorg 接受行政组织 + #attribute 1:申请人为基线;2:目标人为基线 + +@ 返回值 + + # + +@ 方法原型 + + #func (p *PublicChildNode) AnalysisNode(step int, attribute, sendBackNode string, applicantCont modelshr.PersonArchives, acceptorg int64) (nodeList NodeCont, isTrue bool, msg string) +*/ +func (p *PublicChildNode) AnalysisNode(step int, attribute, sendBackNode string, applicantCont modelshr.PersonArchives, acceptorg int64) (nodeList NodeCont, isTrue bool, msg string) { + step++ + switch p.Type { //节点类型 + case 1, 3: //审批 + //流程线 + nodeList.Step = step //步伐 + nodeList.NodeNumber = p.NodeNumber //节点编号 + nodeList.NodeName = p.NodeName //节点名称 + nodeList.FromNode = p.FromNode //来源节点 + nodeList.State = 1 //状态 1、不点亮;2、点亮 + if p.SendBackNode == "beginnode" { + nodeList.GoBackNode = sendBackNode //可得返回节点 + } else { + nodeList.GoBackNode = p.SendBackNode + } + nodeList.ExamineMode = p.ExamineMode + nodeList.NoHanderAction = p.NoHanderAction + //判断审批人设置 + switch p.Settype { + case 1: //指定成员 + isOk := false + if len(p.NodeUserList) > 0 { + for _, v := range p.NodeUserList { + if v.Type == "1" { + var userCont modelshr.PersonArchives + userCont.GetCont(map[string]interface{}{"`key`": v.TargetID}) + nodeList.UserList = append(nodeList.UserList, SetOperator(userCont)) + isOk = true + } + } + } + if isOk { + isTrue = true + } else { + isTrue = false + msg = "未设置审批人" + } + case 2: //主管 + var gainUser GainLeveDirector + gainUser.Step = 0 + gainUser.Leve = p.DirectorLevel + if attribute == "1" { + gainUser.GainLeveDirector(applicantCont.AdminOrg) + } else { + gainUser.GainLeveDirector(acceptorg) + } + if len(gainUser.UserList) > 0 { + for _, v := range gainUser.UserList { + nodeList.UserList = append(nodeList.UserList, SetOperator(v)) + } + } else { + isTrue = false + msg = "未设置审批人" + } + case 3: //行政岗位 + if len(p.NodeUserList) > 0 { + var userList []modelshr.PersonArchives + if attribute == "1" { + userList = BaseOrgGainOperator(applicantCont.AdminOrg, p.NodeUserList) + } else { + userList = BaseOrgGainOperator(acceptorg, p.NodeUserList) + } + if len(userList) > 0 { + for _, v := range userList { + nodeList.UserList = append(nodeList.UserList, SetOperator(v)) + } + } else { + isTrue = false + msg = "未设置审批人" + } + } else { + isTrue = false + msg = "未设置审批人" + } + case 4: //发起人自选 + nodeList.RunType = 0 + nodeList.RunScope = 0 + switch p.SelectRange { + case 1: //全公司 + nodeList.RunType = 1 + nodeList.RunScope = 1 + case 2: //指定成员 + isOk := false + if len(p.NodeUserList) > 0 { + for _, v := range p.NodeUserList { + if v.Type == "1" { + var userCont modelshr.PersonArchives + userCont.GetCont(map[string]interface{}{"`key`": v.TargetID}) + nodeList.UserList = append(nodeList.UserList, SetOperator(userCont)) + isOk = true + } + } + } + if isOk { + isTrue = true + } else { + isTrue = false + msg = "未设置审批人" + } + case 3: //指定角色 + var roleId []string + if len(p.NodeUserList) > 0 { + for _, v := range p.NodeUserList { + if v.Type == "2" { + if !publicmethod.IsInTrue[string](v.TargetID, roleId) { + roleId = append(roleId, v.TargetID) + } + } + } + } + fmt.Printf("指定角色-->") + isOk := false + if len(roleId) > 0 { + for _, v := range roleId { + var userContList []modelshr.PersonArchives + err := overall.CONSTANT_DB_HR.Where("`emp_type` BETWEEN ? AND ? AND FIND_IN_SET(?,`role`)", 1, 10, v).Find(&userContList).Error + if err == nil && len(userContList) > 0 { + for _, uvr := range userContList { + nodeList.UserList = append(nodeList.UserList, SetOperator(uvr)) + } + isOk = true + } + } + } + if isOk { + isTrue = true + } else { + isTrue = false + msg = "未设置审批人" + } + case 4: //本部门 + nodeList.RunType = 1 + nodeList.RunScope = 2 + default: + isTrue = false + msg = "未设置审批人" + } + case 5: //发起人自己 + nodeList.RunType = 2 + nodeList.RunScope = 0 + nodeList.UserList = append(nodeList.UserList, SetOperator(applicantCont)) + case 7: //联系多层主管 + var gainUser GainLeveDirector + gainUser.Step = 0 + if p.ExamineEndDirectorLevel == 1 { + gainUser.Leve = 10 + } else { + gainUser.Leve = p.ExamineEndDirectorLevel + } + + // gainUser.Leve = 1 + if attribute == "1" { + gainUser.GainLeveDirectoSseries(applicantCont.AdminOrg) + } else { + gainUser.GainLeveDirectoSseries(acceptorg) + } + if len(gainUser.UserList) > 0 { + for _, v := range gainUser.UserList { + nodeList.UserList = append(nodeList.UserList, SetOperator(v)) + } + } else { + isTrue = false + msg = "未设置审批人" + } + case 8: + nodeList.RunType = 3 + nodeList.RunScope = 0 + nodeList.CustomNode = p.CustomNode + nodeList.ExecutionAddress = p.ExecutionAddress + default: + isTrue = false + msg = "未设置审批人" + } + + case 2: //抄送 + //流程线 + nodeList.Step = step //步伐 + nodeList.NodeNumber = p.NodeNumber //节点编号 + nodeList.NodeName = p.NodeName //节点名称 + nodeList.FromNode = p.FromNode //来源节点 + nodeList.State = 1 //状态 1、不点亮;2、点亮 + nodeList.RunType = 4 + nodeList.RunScope = p.CcSelfSelectFlag + if p.SendBackNode == "beginnode" { + nodeList.GoBackNode = sendBackNode //可得返回节点 + } else { + nodeList.GoBackNode = p.SendBackNode + } + isOk := false + if len(p.NodeUserList) > 0 { + for _, v := range p.NodeUserList { + if v.Type == "1" { + var userCont modelshr.PersonArchives + userCont.GetCont(map[string]interface{}{"`key`": v.TargetID}) + nodeList.UserList = append(nodeList.UserList, SetOperator(userCont)) + isOk = true + } + } + } + if isOk { + isTrue = true + } else { + isTrue = false + msg = "未设置审批人" + } + // case 3: //执行人 + case 4: //路由 + case 5: //条件 + default: + } + + return +} + +// // 获取节点审批人 +// func GetNodeApprover(nodeKey string, nodeList []NodeCont) (UserList []UserListFlowAll) { +// lf len(nodeList) > 0{ + +// } +// return +// } + +//根据行政岗位识别操作人 +/* +#orgId 行政组织Id +#performAction 节点操作设定 +*/ +func BaseOrgGainOperator(orgId int64, performAction []NodeUserListCont) (userList []modelshr.PersonArchives) { + if len(performAction) > 0 { + //获取行政组织所有行政组织上级和下级 + allOrg := publicmethod.HaveAllOrgRelation(orgId) + // fmt.Printf("获取行政组织所有行政组织上级和下级--->%v\n", allOrg) + // postOftoOrg := make(map[string][]int64, 0) + var gainDirector GainLeveDirector + for _, v := range performAction { + if v.Type == "position" { + gainDirector.GetPostBaseOrg(v.TargetID, allOrg) + // postOftoOrg[v.TargetID] = GetPostBaseOrg(v.TargetID) + } + } + userList = gainDirector.UserList + + } + return +} + +// 获取职务关联得行政组织 +/* +#unifyPosId 统一职务名称ID +#orgList 行政组织ID列表 +*/ +func (g *GainLeveDirector) GetPostBaseOrg(unifyPosId string, orgList []int64) { + var positionInfo modelshr.PositionUnify + err := positionInfo.GetCont(map[string]interface{}{"`id`": unifyPosId}, "`content`") + if err != nil { + return + } + // fmt.Printf("获取职务关联得行政组织-2-->%v\n", positionInfo) + var posIdStr []int64 + err = json.Unmarshal([]byte(positionInfo.Content), &posIdStr) + if err != nil { + return + } + //获取相关职务数据 + var posCont []modelshr.PostDutiesJob + err = overall.CONSTANT_DB_HR.Model(&modelshr.PostDutiesJob{}).Select("`id`,`adm_org`,`weight`").Where("`id` IN ?", posIdStr).Find(&posCont).Error + // fmt.Printf("获取职务关联得行政组织-1-->%v\n", orgIdList) + if err != nil || len(posCont) < 1 { + return + } + var orgIdList []int64 + var orgPosId []JudgeOrgOfPosition + for _, v := range posCont { //组织岗位与行政组织关系 + if !publicmethod.IsInTrue[int64](v.AdministrativeOrganization, orgIdList) { + orgIdList = append(orgIdList, v.AdministrativeOrganization) + var orgPosIdCont JudgeOrgOfPosition + orgPosIdCont.OrgId = v.AdministrativeOrganization + orgPosIdCont.PositionId = v.Id + orgPosIdCont.Weight = v.Weight + orgPosId = append(orgPosId, orgPosIdCont) + } + } + jieguo := publicmethod.Intersect[int64](orgList, orgIdList) //获取交集,判断是否有相关职位 + //获取相关岗位人员 + if len(jieguo) > 0 { + for _, ovp := range orgPosId { + if publicmethod.IsInTrue[int64](ovp.OrgId, jieguo) { + var userInfoList []modelshr.PersonArchives + gormDb := overall.CONSTANT_DB_HR.Where("`position` = ? AND `admin_org` = ? AND `emp_type` BETWEEN ? AND ?", ovp.PositionId, ovp.OrgId, 1, 10) + if ovp.Weight >= 8 { + gormDb = gormDb.Where("`person_in_charge` = 1") + } + err = gormDb.Find(&userInfoList).Error + if err == nil && len(userInfoList) > 0 { + for _, usev := range userInfoList { + g.UserList = append(g.UserList, usev) + } + } + } + } + } + +} + +// 获取第几级主管 +/* +#orgId 行政组织Id +*/ +func (g *GainLeveDirector) GainLeveDirector(orgId int64) { + var orgCont modelshr.AdministrativeOrganization + err := orgCont.GetCont(map[string]interface{}{"`id`": orgId}, "`superior`") + if err == nil { + //获取改行政组织下的负责人 + var userCont []modelshr.PersonArchives + errs := overall.CONSTANT_DB_HR.Model(&modelshr.PersonArchives{}).Where("`person_in_charge` = 1 AND FIND_IN_SET(?,`responsible_department`)", orgId).Find(&userCont).Error + if errs == nil { + g.Step++ + if g.Step == g.Leve { + for _, v := range userCont { + g.UserList = append(g.UserList, v) + } + } else if g.Step < g.Leve { + g.GainLeveDirector(orgCont.Superior) + } + } else { + g.GainLeveDirector(orgCont.Superior) + } + } +} + +// 获取连续多级主管 +/* +#orgId 行政组织Id +*/ +func (g *GainLeveDirector) GainLeveDirectoSseries(orgId int64) { + if orgId > 0 { + var orgCont modelshr.AdministrativeOrganization + err := orgCont.GetCont(map[string]interface{}{"`id`": orgId}, "`superior`") + if err == nil { + //获取改行政组织下的负责人 + var userCont []modelshr.PersonArchives + errs := overall.CONSTANT_DB_HR.Model(&modelshr.PersonArchives{}).Where("`person_in_charge` = 1 AND FIND_IN_SET(?,`responsible_department`)", orgId).Find(&userCont).Error + + if errs == nil { + g.Step++ + if g.Step <= g.Leve { + for _, v := range userCont { + g.UserList = append(g.UserList, v) + } + g.GainLeveDirectoSseries(orgCont.Superior) + } + } else { + g.GainLeveDirectoSseries(orgCont.Superior) + } + } + } + +} + +// 判断发起人是否具备使用该流程权限 +func JudgeHaveApply(applicant modelshr.PersonArchives, FlowPermission []FlowPermissionStruct) (isTrue bool, msg string) { + if len(FlowPermission) < 1 { + isTrue = true + return + } + //获取申请人所有行政组织上级 + var getAllOrg publicmethod.GetOrgAllParent + getAllOrg.GetOrgParentAllId(applicant.AdminOrg) + // fmt.Printf("所有行政组织--->%v\n", getAllOrg.Id) + havePurview := false + for _, v := range FlowPermission { + // fmt.Printf("所有行政组织--1->%v---------->%v\n", v.Type, v) + switch v.Type { + case "1": //个人 + keyStr := strconv.FormatInt(applicant.Key, 10) + if v.TargetId == keyStr { + havePurview = true + } + case "2": + var roleAry []string + jsonErr := json.Unmarshal([]byte(applicant.Role), &roleAry) + if jsonErr == nil { + if len(roleAry) > 0 { + if publicmethod.IsInTrue[string](v.TargetId, roleAry) == true { + havePurview = true + } + } + } + case "3": + if len(getAllOrg.Id) > 0 { + targetIdInt, errInt := strconv.ParseInt(v.TargetId, 10, 64) + if errInt == nil { + if publicmethod.IsInTrue[int64](targetIdInt, getAllOrg.Id) == true { + havePurview = true + } + } + } + default: + + } + } + if !havePurview { + isTrue = false + msg = "你没有发起此流程得权限!" + } else { + isTrue = true + } + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-29 11:48:12 +@ 功能: 操作人记录信息 +@ 参数 + + #userCont 人员信息 + +@ 返回值 + + #userNode 操作信息 + +@ 方法原型 + + # +*/ +func SetOperator(userCont modelshr.PersonArchives) (userNode UserListFlowAll) { + userNode.Id = strconv.FormatInt(userCont.Key, 10) //操作人ID + userNode.Name = userCont.Name //操作人姓名 + userNode.Icon = userCont.Icon //操作人头像 + userNode.IconBase64 = userCont.IconPhoto + userNode.Wechat = userCont.Wechat //微信Openid + if userCont.WorkWechat != "" { + userNode.Wechat = userCont.WorkWechat //微信Openid + } + _, companyId, _, _, _ := publicmethod.GetOrgStructurees(userCont.AdminOrg) + if companyId != 0 { + var orgCont modelshr.AdministrativeOrganization + orgCont.GetCont(map[string]interface{}{"`id`": companyId}, "`name`") + userNode.DepartmentId = companyId //分厂Id + userNode.DepartmentName = orgCont.Name //分厂名称 + } + //获取岗位 + if userCont.Position != 0 { + var postCont modelshr.Position + postCont.GetCont(map[string]interface{}{"`id`": userCont.Position}, "`name`") + userNode.PostId = userCont.Position //职务Id + userNode.PostName = postCont.Name //职务名称 + } + if userCont.TeamId != 0 { + var teamCont modelshr.TeamGroup + teamCont.GetCont(map[string]interface{}{"`id`": userCont.TeamId}, "`name`") + userNode.Tema = userCont.TeamId //班组Id + userNode.TemaName = teamCont.Name //班组名称 + } + + return +} diff --git a/api/workflow/currency_recipe/structural_analysis.go b/api/workflow/currency_recipe/structural_analysis.go new file mode 100644 index 0000000..030fd1b --- /dev/null +++ b/api/workflow/currency_recipe/structural_analysis.go @@ -0,0 +1,556 @@ +package currency_recipe + +import ( + "fmt" + "key_performance_indicators/models/modelshr" + "key_performance_indicators/overall" + "key_performance_indicators/overall/publicmethod" + "sort" + "strconv" + "strings" +) + +/** +@ 作者: 秦东 +@ 时间: 2023-03-31 08:11:58 +@ 功能: +@ 参数 + #step 步进值 + #attribute 1:申请人为基线;2:目标人为基线 + #sendBackNode 开始节点编号 + #applicantCont 申请人信息 + #acceptorg 接受行政组织 +@ 返回值 + #NodeContList 节点列表 +@ 方法原型 + #func (p *PublicChildNode) CircularParsing(step int, attribute, sendBackNode string, applicantCont modelshr.PersonArchives, acceptorg int64) (NodeContList []NodeCont) +*/ + +func (p *PublicChildNode) CircularParsing(step int, attribute, sendBackNode string, applicantCont modelshr.PersonArchives, acceptorg int64, judgingCondition []JudgingCondition) (NodeContList []NodeCont) { + // fmt.Printf("循环接卸--->%v---->%v\n", p.NodeName, p.NodeNumber) + step++ + var nodeCont NodeCont + nodeCont.Step = step //步伐 + nodeCont.NodeNumber = p.NodeNumber //节点编号 + nodeCont.NodeName = p.NodeName //节点名称 + nodeCont.FromNode = p.FromNode + // nodeCont.ArriveNode = p.GotoNode + nodeCont.State = 1 //状态 1、不点亮;2、点亮 + if p.SendBackNode == "beginnode" { + nodeCont.GoBackNode = sendBackNode //可得返回节点 + } else { + nodeCont.GoBackNode = p.SendBackNode + } + nodeCont.ExamineMode = p.ExamineMode + nodeCont.NoHanderAction = p.NoHanderAction + + switch p.Type { //节点类型 + case 1, 3: //审批&执行人 + //判断审批人设置 + switch p.Settype { + case 1: //指定成员 + if len(p.NodeUserList) > 0 { + for _, v := range p.NodeUserList { + if v.Type == "1" { + var userCont modelshr.PersonArchives + userCont.GetCont(map[string]interface{}{"`key`": v.TargetID}) + nodeCont.UserList = append(nodeCont.UserList, SetOperator(userCont)) + } + } + } + + case 2: //主管 + var gainUser GainLeveDirector + gainUser.Step = 0 + gainUser.Leve = p.DirectorLevel + if attribute == "1" { + gainUser.GainLeveDirector(applicantCont.AdminOrg) + } else { + gainUser.GainLeveDirector(acceptorg) + } + if len(gainUser.UserList) > 0 { + for _, v := range gainUser.UserList { + nodeCont.UserList = append(nodeCont.UserList, SetOperator(v)) + } + } + case 3: //行政岗位 + if len(p.NodeUserList) > 0 { + var userList []modelshr.PersonArchives + if attribute == "1" { + userList = BaseOrgGainOperator(applicantCont.AdminOrg, p.NodeUserList) + } else { + userList = BaseOrgGainOperator(acceptorg, p.NodeUserList) + } + if len(userList) > 0 { + for _, v := range userList { + nodeCont.UserList = append(nodeCont.UserList, SetOperator(v)) + } + } + } + case 4: //发起人自选 + nodeCont.RunType = 0 + nodeCont.RunScope = 0 + switch p.SelectRange { + case 1: //全公司 + nodeCont.RunType = 1 + nodeCont.RunScope = 1 + case 2: //指定成员 + + if len(p.NodeUserList) > 0 { + for _, v := range p.NodeUserList { + if v.Type == "1" { + var userCont modelshr.PersonArchives + userCont.GetCont(map[string]interface{}{"`key`": v.TargetID}) + nodeCont.UserList = append(nodeCont.UserList, SetOperator(userCont)) + + } + } + } + + case 3: //指定角色 + var roleId []string + if len(p.NodeUserList) > 0 { + for _, v := range p.NodeUserList { + if v.Type == "2" { + if !publicmethod.IsInTrue[string](v.TargetID, roleId) { + roleId = append(roleId, v.TargetID) + } + } + } + } + fmt.Printf("指定角色-->") + + if len(roleId) > 0 { + for _, v := range roleId { + var userContList []modelshr.PersonArchives + err := overall.CONSTANT_DB_HR.Where("`emp_type` BETWEEN ? AND ? AND FIND_IN_SET(?,`role`)", 1, 10, v).Find(&userContList).Error + if err == nil && len(userContList) > 0 { + for _, uvr := range userContList { + nodeCont.UserList = append(nodeCont.UserList, SetOperator(uvr)) + } + + } + } + } + + case 4: //本部门 + nodeCont.RunType = 1 + nodeCont.RunScope = 2 + default: + + } + case 5: //发起人自己 + nodeCont.RunType = 2 + nodeCont.RunScope = 0 + nodeCont.UserList = append(nodeCont.UserList, SetOperator(applicantCont)) + case 7: //联系多层主管 + var gainUser GainLeveDirector + gainUser.Step = 0 + if p.ExamineEndDirectorLevel == 1 { + gainUser.Leve = 10 + } else { + gainUser.Leve = p.ExamineEndDirectorLevel + } + + // gainUser.Leve = 1 + if attribute == "1" { + gainUser.GainLeveDirectoSseries(applicantCont.AdminOrg) + } else { + gainUser.GainLeveDirectoSseries(acceptorg) + } + if len(gainUser.UserList) > 0 { + for _, v := range gainUser.UserList { + nodeCont.UserList = append(nodeCont.UserList, SetOperator(v)) + } + } + case 8: + nodeCont.RunType = 3 + nodeCont.RunScope = 0 + nodeCont.CustomNode = p.CustomNode + nodeCont.ExecutionAddress = p.ExecutionAddress + default: + + } + NodeContList = append(NodeContList, nodeCont) + if p.ChildNode != nil { + // listCont := p.ChildNode.CircularParsing(step, p.Attribute, sendBackNode) + NodeContList = append(NodeContList, p.ChildNode.CircularParsing(step, p.Attribute, sendBackNode, applicantCont, acceptorg, judgingCondition)...) + + } + case 2: //抄送 + if nodeCont.GoBackNode == "" { + nodeCont.GoBackNode = sendBackNode //可得返回节点 + } + nodeCont.RunType = 4 + nodeCont.RunScope = p.CcSelfSelectFlag + if len(p.NodeUserList) > 0 { + for _, v := range p.NodeUserList { + if v.Type == "1" { + var userCont modelshr.PersonArchives + userCont.GetCont(map[string]interface{}{"`key`": v.TargetID}) + nodeCont.UserList = append(nodeCont.UserList, SetOperator(userCont)) + } + } + } + NodeContList = append(NodeContList, nodeCont) + if p.ChildNode != nil { + // listCont := p.ChildNode.CircularParsing(step, p.Attribute, sendBackNode) + NodeContList = append(NodeContList, p.ChildNode.CircularParsing(step, p.Attribute, sendBackNode, applicantCont, acceptorg, judgingCondition)...) + + } + case 4: //路由 + step = step - 1 + if step < 1 { + step = 1 + } + if p.ConditionNodes != nil { + //根据维度序号排序 + sort.Slice(p.ConditionNodes, func(i, j int) bool { + return p.ConditionNodes[i].PriorityLevel < p.ConditionNodes[j].PriorityLevel + }) + lastStrp := step + for _, pv := range p.ConditionNodes { + listContNode, isOk := pv.ResolveRouting(step, p.Attribute, sendBackNode, applicantCont, acceptorg, judgingCondition) + fmt.Printf("提交满足---->%v---->%v\n", isOk, listContNode) + if isOk && len(listContNode) > 0 { + // for _, lcnv := range listContNode { + // NodeContList = append(NodeContList, lcnv) + // } + // if pv.ChildNode != nil{ + // NodeContListEnd := pv.ChildNode.CircularParsing(step, pv.Attribute, sendBackNode, applicantCont, acceptorg, judgingCondition) + // NodeContList = append(NodeContList, NodeContListEnd...) + // } + + fmt.Printf("提交满足--12213-->%v---->%v\n", isOk, listContNode) + + lastStrp = lastStrp + len(listContNode) + NodeContList = append(NodeContList, listContNode...) + + break + } + } + if p.ChildNode != nil { + // listCont := p.ChildNode.CircularParsing(step, p.Attribute, sendBackNode) + // NodeContListEnd := append(NodeContList, p.ChildNode.CircularParsing(step, p.Attribute, sendBackNode, applicantCont, acceptorg, judgingCondition)...) + NodeContListEnd := p.ChildNode.CircularParsing(lastStrp, p.Attribute, sendBackNode, applicantCont, acceptorg, judgingCondition) + // for _, nclev := range NodeContListEnd { + // NodeContList = append(NodeContList, nclev) + // } + if len(NodeContListEnd) > 0 { + NodeContList = append(NodeContList, NodeContListEnd...) + } + + } + } else { + if p.ChildNode != nil { + // listCont := p.ChildNode.CircularParsing(step, p.Attribute, sendBackNode) + NodeContList = append(NodeContList, p.ChildNode.CircularParsing(step, p.Attribute, sendBackNode, applicantCont, acceptorg, judgingCondition)...) + + } + } + case 5: //条件 + default: + } + + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-31 08:14:04 +@ 功能: 解析路由得判断条件 +@ 参数 + + #step 步进值 + #attribute 1:申请人为基线;2:目标人为基线 + #sendBackNode 开始节点编号 + #applicantCont 申请人信息 + #acceptorg 接受行政组织 + #judgingCondition 判断条件 + +@ 返回值 + + #NodeContList 节点列表 + #isTrue 条件满足 + +@ 方法原型 + + #func (p *PublicChildNode) ResolveRouting(step int, attribute, sendBackNode string, applicantCont modelshr.PersonArchives, acceptorg int64, judgingCondition []JudgingCondition) (NodeContList []NodeCont, isTrue bool) +*/ +func (p *PublicChildNode) ResolveRouting(step int, attribute, sendBackNode string, applicantCont modelshr.PersonArchives, acceptorg int64, judgingCondition []JudgingCondition) (NodeContList []NodeCont, isTrue bool) { + fmt.Printf("条件名称----->%v----->%v\n", p.NodeName, p.NodeNumber) + if len(p.ConditionList) > 0 { + var areYourOk []InterimCondition + for _, c := range p.ConditionList { + // fmt.Printf("can--->%v\n", c) + var areYourOkCont InterimCondition + areYourOkCont.Class = c.Type + switch c.Type { + case "1": //发起人 + areYourOkCont.TsTrue = true + areYourOkCont.IsOk = JudgePeopleIsTrue(p.NodeUserList, p.Attribute, applicantCont, acceptorg) + + case "3": //关联数据库 + areYourOkCont.TsTrue = true + if len(judgingCondition) < 1 { + areYourOkCont.IsOk = true + } else { + areYourOkCont.IsOk = true + } + case "4": //自定义表单 + areYourOkCont.TsTrue = true + if len(judgingCondition) < 1 { + areYourOkCont.IsOk = false + } else { + for _, jv := range judgingCondition { + if jv.Class == 1 { + areYourOkCont.IsOk = JudgeCustomConditions(c.Condition, jv.MyCustom) + } + } + + } + default: + } + areYourOk = append(areYourOk, areYourOkCont) + } + // jsonStr, _ := json.Marshal(p.ChildNode) + // fmt.Printf("判断提交结果-----》%v-----》%v\n", areYourOk, judgingCondition) + areYourOkLen := len(areYourOk) + jiShuQi := 0 + for i := 0; i < areYourOkLen; i++ { + if areYourOk[i].IsOk && areYourOk[i].TsTrue { + jiShuQi++ + } + } + if jiShuQi == areYourOkLen { + isTrue = true + if p.ChildNode != nil { + NodeContList = p.ChildNode.CircularParsing(step, p.Attribute, sendBackNode, applicantCont, acceptorg, judgingCondition) + } + + } else { + isTrue = false + } + return + } + + if len(judgingCondition) < 1 && len(p.ConditionList) < 1 { + isTrue = true + if p.ChildNode != nil { + NodeContList = p.ChildNode.CircularParsing(step, p.Attribute, sendBackNode, applicantCont, acceptorg, judgingCondition) + } + return + } + if len(p.ConditionList) < 1 { + isTrue = true + if p.ChildNode != nil { + NodeContList = p.ChildNode.CircularParsing(step, p.Attribute, sendBackNode, applicantCont, acceptorg, judgingCondition) + } + } + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-31 13:09:39 +@ 功能: 判断自定义条件 +@ 参数 + + #condition 节点设定条件 + #myCondition 自定义条件 + +@ 返回值 + + #isOk 条件是否通过 + +@ 方法原型 + + #func JudgeCustomConditions(condition []ConditionStruct, myCondition []CustomFields) (isOk bool) +*/ +func JudgeCustomConditions(condition []ConditionStruct, myCondition []CustomFields) (isOk bool) { + if len(condition) < 1 || len(myCondition) < 1 { + isOk = false + return + } + var isTrue []InterimCondition + for _, v := range condition { + var isTrueCont InterimCondition + isTrueCont.Class = v.WordField + isTrueCont.TsTrue = true + for _, mv := range myCondition { + + if v.WordField == mv.WordField { + switch v.OptType { //["", "<", ">", "≤", "=", "≥","in","not in"][optType] 计算符号 1-8 + case "1": + if mv.LeftVal < v.Factor.LeftVal { + isTrueCont.IsOk = true + } else { + isTrueCont.IsOk = false + } + case "2": + if mv.LeftVal > v.Factor.LeftVal { + isTrueCont.IsOk = true + } else { + isTrueCont.IsOk = false + } + case "3": + if mv.LeftVal <= v.Factor.LeftVal { + isTrueCont.IsOk = true + } else { + isTrueCont.IsOk = false + } + case "4": + if mv.LeftVal == v.Factor.LeftVal { + isTrueCont.IsOk = true + } else { + isTrueCont.IsOk = false + } + case "5": + if mv.LeftVal >= v.Factor.LeftVal { + isTrueCont.IsOk = true + } else { + isTrueCont.IsOk = false + } + case "6": + guoDuoLeft := false + guoDuoRight := false + if v.Factor.LeftOptType == "1" { + if mv.LeftVal < v.Factor.LeftVal { + guoDuoLeft = true + } else { + guoDuoLeft = false + } + } else { + if mv.LeftVal <= v.Factor.LeftVal { + guoDuoLeft = true + } else { + guoDuoLeft = false + } + } + if v.Factor.RightOptType == "1" { + if mv.RightVal < v.Factor.RightVal { + guoDuoRight = true + } else { + guoDuoRight = false + } + } else { + if mv.RightVal <= v.Factor.RightVal { + guoDuoRight = true + } else { + guoDuoRight = false + } + } + if guoDuoLeft && guoDuoRight { + isTrueCont.IsOk = true + } else { + isTrueCont.IsOk = false + } + case "7": + isTrueCont.IsOk = strings.Contains(v.Factor.LeftVal, mv.LeftVal) + case "8": + baohan := strings.Contains(v.Factor.LeftVal, mv.LeftVal) + isTrueCont.IsOk = !baohan + default: + } + isTrue = append(isTrue, isTrueCont) + } + + } + + } + if len(isTrue) < 1 { + isOk = false + } else { + countIsTrue := len(isTrue) + trueSum := 0 + for i := 0; i < countIsTrue; i++ { + if isTrue[i].IsOk && isTrue[i].TsTrue { + trueSum++ + } + } + if trueSum == countIsTrue { + isOk = true + } else { + isOk = false + } + } + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-31 10:47:41 +@ 功能: 判断人员信息是否符合要求 +@ 参数 + + #condition 节点设定条件(发起人相关) + #attribute 1:申请人为基线;2:目标人为基线 + #applicantCont 申请人信息 + #acceptorg 接受行政组织 + +@ 返回值 + + #isOk 条件是否通过 + +@ 方法原型 + + #func JudgePeopleIsTrue(condition []NodeUserListCont, attribute, sendBackNode string, applicantCont modelshr.PersonArchives, acceptorg int64) (isOk bool) +*/ +func JudgePeopleIsTrue(condition []NodeUserListCont, attribute string, applicantCont modelshr.PersonArchives, acceptorg int64) (isOk bool) { + isOk = false + var panDing []InterimCondition + for _, v := range condition { + var panDingCont InterimCondition + panDingCont.Class = v.Type + switch v.Type { + case "1": + myKey := strconv.FormatInt(applicantCont.Key, 10) + if v.TargetID == myKey { + panDingCont.IsOk = true + } else { + panDingCont.IsOk = false + } + panDingCont.TsTrue = true + case "2": + if applicantCont.Role != "" { + myRole := strings.Split(applicantCont.Role, ",") + if publicmethod.IsInTrue[string](v.TargetID, myRole) { + panDingCont.IsOk = true + } else { + panDingCont.IsOk = false + } + } else { + panDingCont.IsOk = false + } + panDingCont.TsTrue = true + case "3": + allOrg := publicmethod.HaveAllOrgRelation(applicantCont.AdminOrg) + targetIdInt, _ := strconv.ParseInt(v.TargetID, 10, 64) + if publicmethod.IsInTrue[int64](targetIdInt, allOrg) { + panDingCont.IsOk = true + } else { + panDingCont.IsOk = false + } + panDingCont.TsTrue = true + default: + isOk = false + } + panDing = append(panDing, panDingCont) + // fmt.Printf("角色哈哈哈哈--->%v--->%v\n", v, panDingCont) + } + if len(panDing) < 1 { + isOk = false + } else { + for _, v := range panDing { + if v.TsTrue && v.IsOk { + isOk = true + break + } + } + } + fmt.Printf("角色哈哈哈哈-1-->%v\n", panDing) + return +} diff --git a/api/workflow/currency_recipe/type.go b/api/workflow/currency_recipe/type.go new file mode 100644 index 0000000..43368b9 --- /dev/null +++ b/api/workflow/currency_recipe/type.go @@ -0,0 +1,233 @@ +package currency_recipe + +import ( + "key_performance_indicators/models/modelshr" + "key_performance_indicators/overall/publicmethod" +) + +// 工作流引擎 +type WorkflowEngine struct { + Id string `json:"id"` //版本识别符 + VersionId string `json:"versionid"` //版本Id + WorkflowCont FlowStructIng `json:"workflowcont"` //流程主体 + Applicant string `json:"applicant"` //申请人 + ApplicantCont modelshr.PersonArchives `json:"applicantcont"` //申请人信息 + Step int `json:"step"` //计步器 + StarNodeNumber string `json:"starnodenumber"` //开始节点 + AcceptOrg string `json:"acceptorg"` //接受考核行政组织 + JudCond []JudgingCondition `json:"judgingcondition` //关联条件 +} + +// 工作流结构体 +type FlowStructIng struct { + TableId string `json:"tableId"` //流程ID + WorkFlowDef WorkFlowDefStruct `json:"workFlowDef"` //工作流程定义 + DirectorMaxLevel int `json:"directorMaxLevel"` //审批主管最大层级 + FlowPermission []FlowPermissionStruct `json:"flowPermission"` //发起人 + NodeConfig PublicChildNode `json:"nodeConfig"` //流程结构体 +} + +// 工作流程定义 +type WorkFlowDefStruct struct { + publicmethod.PublicName //流程名称 +} + +// 流程发起权限 +type FlowPermissionStruct struct { + Type string `json:"type"` // 1、人员 2、 3、行政组织 + TargetId string `json:"targetId"` //人员Key或行政组织ID + publicmethod.PublicName //人名或行政组织名称 + Icon string `json:"icon"` //人员头像URL + IconToBase64 string `json:"iconToBase64"` //人员头像 base64加密 +} + +// 通用字段 +type PublicChildNode struct { + NodePublicStruct + Error bool `json:"error"` //当前审批是否通过校验 + PriorityLevel int `json:"priorityLevel"` // 条件优先级 + Settype int `json:"settype"` // 审批人设置 1指定成员 2主管 4发起人自选 5发起人自己 7连续多级主管 8:指定审批节点自选 + SelectMode int `json:"selectMode"` //审批人数 1选一个人 2选多个人 + SelectRange int `json:"selectRange"` //选择范围 1.全公司 2指定成员 3指定角色 4:指定部门 + DirectorLevel int `json:"directorLevel"` //审批终点 最高层主管数 + ExamineMode int `json:"examineMode"` //多人审批时采用的审批方式 1依次审批 2会签 + NoHanderAction int `json:"noHanderAction"` //审批人为空时 1自动审批通过/不允许发起 2转交给审核管理员 + ExamineEndDirectorLevel int `json:"examineEndDirectorLevel"` //审批终点 第n层主管 + NodeUserList []NodeUserListCont `json:"nodeUserList"` //操作人 + CcSelfSelectFlag int `json:"ccSelfSelectFlag"` //允许发起人自选抄送人 + ConditionList []ConditionListCont `json:"conditionList"` //当审批单同时满足以下条件时进入此流程 + ChildNode *PublicChildNode `json:"childNode"` + ConditionNodes []PublicChildNode `json:"conditionNodes"` //条件节点 + SendBackNode string `json:"sendBackNode"` //退回到哪个节点 + DataBaseCondition []DataBaseConditionStruct `json:"databasecondition"` //关联数据库操作 + CustomNode string `json:"customNode"` //由哪个节点指定本节点审批人 + ExecutionAddress string `json:"executionaddress"` //执行节点跳转页面 +} + +// 基础结构 +type NodePublicStruct struct { + NodeNumber string `json:"nodeNumber"` //节点编号 + NodeName string `json:"nodeName"` //节点名称 + Type int `json:"type"` // 0 发起人 1审批 2抄送 3执行人 4路由 5条件 + FromNode string `json:"fromNode"` //来源节点 + GotoNode []string `json:"gotoNode"` //去向节点 + Attribute string `json:"attribute"` // 1:申请人为基线;2:目标人为基线 +} + +// 操作人 +type NodeUserListCont struct { + TargetID string `json:"targetId"` + Type string `json:"type"` // 1、人员 2、 3、行政组织,4: + Name string `json:"name"` + Icon string `json:"icon"` //人员头像URL + IconToBase64 string `json:"iconToBase64"` //人员头像 base64加密 +} + +// 当审批单同时满足以下条件时进入此流程 +type ConditionListCont struct { + ColumnID string `json:"columnId"` // + Type string `json:"type"` //1:发起人;2:关联数据表;3:自定义字段 + ConditionEn string `json:"conditionEn"` + ConditionCn string `json:"conditionCn"` + OptType string `json:"optType"` //["", "<", ">", "≤", "=", "≥"][optType] 计算符号 + Zdy1 string `json:"zdy1"` //左侧自定义内容 + Zdy2 string `json:"zdy2"` //右侧自定义内容 + Opt1 string `json:"opt1"` //左侧符号 < ≤ + Opt2 string `json:"opt2"` //右侧符号 < ≤ + ColumnDbname string `json:"columnDbname"` //条件字段名称 + ColumnType string `json:"columnType"` //条件字段类型 + ShowType string `json:"showType"` //checkBox多选 其他 + ShowName string `json:"showName"` //展示名 + FixedDownBoxValue string `json:"fixedDownBoxValue"` //多选数组 + DataBaseCondition []string `json:"databaseCondition"` //自定义数据库条件 + Condition []ConditionStruct `json:"condition"` //自定义字段 +} + +// 关联数据库执行条件 +type DataBaseConditionStruct struct { + DataBaseName string `json:"databasename"` //数据库 + TableKey string `json:"tablekey"` //数据表 + WordList []WordListCont `json:"wordlist"` //规则列表 +} + +// 自定义条件字段 +type ConditionStruct struct { + WordField string `json:"wordfield"` //字段名称 + OptType string `json:"optType"` //["", "<", ">", "≤", "=", "≥","in","not in"][optType] 计算符号 1-8 + Factor FactorStruct `json:"factor"` //等式 +} + +// 等式 +type FactorStruct struct { + LeftOptType string `json:"leftoptType"` //左侧等式符号 + LeftVal string `json:"leftval"` //左侧等式值 + RightOptType string `json:"rightoptType"` //右侧等式符号 + RightVal string `json:"rightval"` //右侧等式值 +} + +// 关联数据规则列表 +type WordListCont struct { + Key string `json:"key"` //字段 + Type string `json:"type"` //等式类行 1:小于;2:大于;3:小于等于;4:等于;5:大于等于;6:介于两数之间;in:包含;notin:不包含 + Comment string `json:"comment"` //字段描述 + Notation string `json:"notation"` //符号 + Equation EquationStruct `json:"equation"` //等式关系 +} + +// 等式关系 +type EquationStruct struct { + LeftNotation string `json:"leftnotation"` //左侧等式符号 + LetfVal string `json:"letfval"` //左侧等式值 + RightNotation string `json:"rightnotation"` //右侧等式符号 + RightVal string `json:"rightval"` //右侧等式符号 +} + +// 输出单条结构工作流 +type SendOneWorkflow struct { + IsTrue bool `json:"istrue"` //是否允许 + Msg string `json:"msg"` //错误信息 + NodeContList []NodeCont `json:"nodecontlist"` //审批节点列表 +} + +// 节点信息 +type NodeCont struct { + Step int `json:"step"` //步伐 + NodeNumber string `json:"nodenumber"` //节点编号 + NodeName string `json:"nodename"` //节点名称 + State int `json:"state"` //状态 1、不点亮;2、点亮 + FromNode string `json:"fromnode"` //来至哪个节点 + ArriveNode string `json:"arrivenode"` //到哪个节点 + GoBackNode string `json:"gobacknode"` //可得返回节点 + ExamineMode int `json:"examinemode"` //多人审批时采用的审批方式 1依次审批 2会签 3:非会签 + NoHanderAction int `json:"nohanderaction"` //审批人为空时 1自动审批通过/不允许发起 2转交给审核管理员 + UserList []UserListFlowAll `json:"userlist"` //节点操作人 + RunType int `json:"runtype"` //运行时选择 0:禁闭;1:发起人自选,2:发起人自己,3:有选中得节点指定,4:抄送节点 + RunScope int `json:"runscope"` //运行时选择范围 0:不可选,1:本公司;2:本部门;当RunType = 4时:1:自选;非1:不可自选 + CustomNode string `json:"customNode"` //由哪个节点指定本节点审批人 + ExecutionAddress string `json:"executionaddress"` //执行节点跳转页面 +} + +// 节点操作人 +type UserListFlowAll struct { + Id string `json:"id"` //操作人ID + Name string `json:"name"` //操作人姓名 + Icon string `json:"icon"` //操作人头像 + IconBase64 string `json:"iconbase64"` //操作人头像 + Wechat string `json:"wechat"` //微信Openid + DepartmentId int64 `json:"departmentid"` //分厂Id + DepartmentName string `json:"departmentname"` //分厂名称 + PostId int64 `json:"postid"` //职务Id + PostName string `json:"postname"` //职务名称 + Tema int64 `json:"tema"` //班组Id + TemaName string `json:"temaname"` //班组名称 + LogList []LogList `json:"log"` //操作记录 +} + +// 节点操作人操作记录 +type LogList struct { + State int `json:"state"` //状态 1、未操作;2、通过;3、驳回 + TimeVal string `json:"time"` + Enclosure []EnclosureFormat `json:"enclosure"` //附件 +} + +// 附件格式 +type EnclosureFormat struct { + FileName string `json:"filename"` //附件名称 + FilePath string `json:"filepath"` //附件地址 + Type int `json:"type"` //附件类型 +} + +// 获取第几级主管 +type GainLeveDirector struct { + Step int `json:"step"` // + Leve int `json:"leve"` + UserList []modelshr.PersonArchives +} + +// 判断事那个行政组织得相关岗位 +type JudgeOrgOfPosition struct { + OrgId int64 + PositionId int64 + Weight int64 +} + +// 判断条件 +type JudgingCondition struct { + Class int `json:"class"` //类型 1:自定义判断条件;2:关联数据库 + DataBaseCont DataBaseConditionStruct `json:"dataBaseCont"` //数据库判断条件 + MyCustom []CustomFields `json:"mycustom"` //自定义字段 +} + +// 自定义字段 +type CustomFields struct { + WordField string `json:"wordfield"` //字段名称 + LeftVal string `json:"leftval"` //左侧等式值 + RightVal string `json:"rightval"` //右侧等式值 +} + +// 临时条件 +type InterimCondition struct { + Class string `json:"class"` //类型 + IsOk bool `json:"isok"` //符合与不符合 + TsTrue bool `json:"istrue"` //操作与为操作 +} diff --git a/api/workflow/workflowengine/class.go b/api/workflow/workflowengine/class.go index eda6918..e4d09dd 100644 --- a/api/workflow/workflowengine/class.go +++ b/api/workflow/workflowengine/class.go @@ -4,64 +4,121 @@ import "key_performance_indicators/overall/publicmethod" //当审批单同时满足以下条件时进入此流程 type ConditionListCont struct { - ColumnID int `json:"columnId"` - Type int `json:"type"` - ConditionEn string `json:"conditionEn"` - ConditionCn string `json:"conditionCn"` - OptType string `json:"optType"` - Zdy1 string `json:"zdy1"` - Zdy2 string `json:"zdy2"` - Opt1 string `json:"opt1"` - Opt2 string `json:"opt2"` - ColumnDbname string `json:"columnDbname"` - ColumnType string `json:"columnType"` - ShowType string `json:"showType"` - ShowName string `json:"showName"` - FixedDownBoxValue string `json:"fixedDownBoxValue"` + ColumnID string `json:"columnId"` // + Type int `json:"type"` //1:发起人;2:关联数据表;3:自定义字段 + ConditionEn string `json:"conditionEn"` + ConditionCn string `json:"conditionCn"` + OptType string `json:"optType"` //["", "<", ">", "≤", "=", "≥"][optType] 计算符号 + Zdy1 string `json:"zdy1"` //左侧自定义内容 + Zdy2 string `json:"zdy2"` //右侧自定义内容 + Opt1 string `json:"opt1"` //左侧符号 < ≤ + Opt2 string `json:"opt2"` //右侧符号 < ≤ + ColumnDbname string `json:"columnDbname"` //条件字段名称 + ColumnType string `json:"columnType"` //条件字段类型 + ShowType string `json:"showType"` //checkBox多选 其他 + ShowName string `json:"showName"` //展示名 + FixedDownBoxValue string `json:"fixedDownBoxValue"` //多选数组 + DataBaseCondition []string `json:"databaseCondition"` //自定义数据库条件 + Condition []ConditionStruct `json:"condition"` //自定义字段 +} + +//自定义条件字段 +type ConditionStruct struct { + WordField string `json:"wordfield"` //字段名称 + OptType string `json:"optType"` //["", "<", ">", "≤", "=", "≥","in","not in"][optType] 计算符号 1-8 + Factor FactorStruct `json:"factor"` //等式 +} + +//等式 +type FactorStruct struct { + LeftOptType string `json:"leftoptType"` //左侧等式符号 + LeftVal string `json:"leftval"` //左侧等式值 + RightOptType string `json:"rightoptType"` //右侧等式符号 + RightVal string `json:"rightval"` //右侧等式值 } //操作人 type NodeUserListCont struct { - TargetID int `json:"targetId"` - Type int `json:"type"` - Name string `json:"name"` + TargetID string `json:"targetId"` + Type string `json:"type"` // 1、人员 2、 3、行政组织,4: + Name string `json:"name"` + Icon string `json:"icon"` //人员头像URL + IconToBase64 string `json:"iconToBase64"` //人员头像 base64加密 } //通用字段 type PublicChildNode struct { NodePublicStruct - Error bool `json:"error"` //当前审批是否通过校验 - PriorityLevel int `json:"priorityLevel"` // 条件优先级 - 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"` //审批终点 最高层主管数 - ExamineMode int `json:"examineMode"` //多人审批时采用的审批方式 1依次审批 2会签 - NoHanderAction int `json:"noHanderAction"` //审批人为空时 1自动审批通过/不允许发起 2转交给审核管理员 - ExamineEndDirectorLevel int `json:"examineEndDirectorLevel"` //审批终点 第n层主管 - NodeUserList []NodeUserListCont `json:"nodeUserList"` //操作人 - CcSelfSelectFlag int `json:"ccSelfSelectFlag"` //允许发起人自选抄送人 - ConditionList []ConditionListCont `json:"conditionList"` //当审批单同时满足以下条件时进入此流程 - ChildNode *PublicChildNode `json:"childNode"` - ConditionNodes *[]PublicChildNode `json:"conditionNodes"` //条件节点 + Error bool `json:"error"` //当前审批是否通过校验 + PriorityLevel int `json:"priorityLevel"` // 条件优先级 + 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"` //审批终点 最高层主管数 + ExamineMode int `json:"examineMode"` //多人审批时采用的审批方式 1依次审批 2会签 + NoHanderAction int `json:"noHanderAction"` //审批人为空时 1自动审批通过/不允许发起 2转交给审核管理员 + ExamineEndDirectorLevel int `json:"examineEndDirectorLevel"` //审批终点 第n层主管 + NodeUserList []NodeUserListCont `json:"nodeUserList"` //操作人 + CcSelfSelectFlag int `json:"ccSelfSelectFlag"` //允许发起人自选抄送人 + ConditionList []ConditionListCont `json:"conditionList"` //当审批单同时满足以下条件时进入此流程 + ChildNode *PublicChildNode `json:"childNode"` + ConditionNodes *[]PublicChildNode `json:"conditionNodes"` //条件节点 + SendBackNode string `json:"sendBackNode"` //退回到哪个节点 + DataBaseCondition []DataBaseConditionStruct `json:"databasecondition"` //关联数据库操作 + CustomNode string `json:"customNode"` //由哪个节点指定本节点审批人 + ExecutionAddress string `json:"executionaddress"` //执行节点跳转页面 +} + +//关联数据库执行条件 +type DataBaseConditionStruct struct { + DataBaseName string `json:"databasename"` //数据库 + TableKey string `json:"tablekey"` //数据表 + WordList []WordListCont `json:"wordlist"` //规则列表 +} + +//关联数据规则列表 +type WordListCont struct { + Key string `json:"key"` //字段 + Type string `json:"type"` //等式类行 1:小于;2:大于;3:小于等于;4:等于;5:大于等于;6:介于两数之间;in:包含;notin:不包含 + Comment string `json:"comment"` //字段描述 + Notation string `json:"notation"` //符号 + Equation EquationStruct `json:"equation"` //等式关系 +} + +//等式关系 +type EquationStruct struct { + LeftNotation string `json:"leftnotation"` //左侧等式符号 + LetfVal string `json:"letfval"` //左侧等式值 + RightNotation string `json:"rightnotation"` //右侧等式符号 + RightVal string `json:"rightval"` //右侧等式符号 } //基础结构 type NodePublicStruct struct { NodeNumber string `json:"nodeNumber"` //节点编号 NodeName string `json:"nodeName"` //节点名称 - Type int `json:"type"` // 0 发起人 1审批 2抄送 3条件 4路由 + Type int `json:"type"` // 0 发起人 1审批 2抄送 3执行人 4路由 5条件 FromNode string `json:"fromNode"` //来源节点 GotoNode []string `json:"gotoNode"` //去向节点 + Attribute string `json:"attribute"` // 1:申请人为基线;2:目标人为基线 } //工作流结构体 type FlowStructIng struct { - TableId string `json:"tableId"` //流程ID - WorkFlowDef WorkFlowDefStruct `json:"workFlowDef"` //工作流程定义 - DirectorMaxLevel int `json:"directorMaxLevel"` //审批主管最大层级 - FlowPermission []string `json:"flowPermission"` //发起人 - NodeConfig PublicChildNode `json:"nodeConfig"` //流程结构体 + TableId string `json:"tableId"` //流程ID + WorkFlowDef WorkFlowDefStruct `json:"workFlowDef"` //工作流程定义 + DirectorMaxLevel int `json:"directorMaxLevel"` //审批主管最大层级 + FlowPermission []FlowPermissionStruct `json:"flowPermission"` //发起人 + NodeConfig PublicChildNode `json:"nodeConfig"` //流程结构体 +} + +//流程发起权限 +type FlowPermissionStruct struct { + Type string `json:"type"` // 1、人员 2、 3、行政组织 + TargetId string `json:"targetId"` //人员Key或行政组织ID + publicmethod.PublicName //人名或行政组织名称 + Icon string `json:"icon"` //人员头像URL + IconToBase64 string `json:"iconToBase64"` //人员头像 base64加密 } //输出全部节点信息 diff --git a/api/workflow/workflowengine/flowhandle.go b/api/workflow/workflowengine/flowhandle.go index 8b5923a..66d16e4 100644 --- a/api/workflow/workflowengine/flowhandle.go +++ b/api/workflow/workflowengine/flowhandle.go @@ -1,7 +1,11 @@ package workflowengine import ( + "encoding/json" + "fmt" + "key_performance_indicators/overall" "key_performance_indicators/overall/publicmethod" + "strings" "github.com/gin-gonic/gin" ) @@ -115,7 +119,7 @@ func (a *ApiMethod) GetAllParentNode(c *gin.Context) { func (o *outAllNodeCont) SeekFromNodeCont(parentNumber string, allListCont []NodePublicStruct) { for _, v := range allListCont { if v.NodeNumber == parentNumber { - if v.Type == 1 { + if v.Type == 1 || v.Type == 3 { if publicmethod.IsInTrue[string](v.NodeNumber, o.AllNumber) == false { o.AllCont = append(o.AllCont, v) o.AllNumber = append(o.AllNumber, v.NodeNumber) @@ -147,5 +151,139 @@ func (o *outAllNodeCont) SeekFromNodeCont(parentNumber string, allListCont []Nod */ func (a *ApiMethod) JudgingCondition(c *gin.Context) { var sendListCont []BranchingCondition + //自定义判断条件 + var customConditions BranchingCondition + customConditions.ColumnId = "99143260231966110" //条件id columnId == 0 为发起人 + customConditions.ShowType = "input" //columnType == "String" && showType == "checkBox"为多选 + customConditions.ShowName = "自定义判断条件" //名称 + customConditions.ColumnName = "customConditions" //columnName 条件自定义字段 + customConditions.ColumnType = "custom" //columnType == "Double"为区间 + sendListCont = append(sendListCont, customConditions) + //数据库表 + var datatableList []DataBaseCont + var dataBaseCont DataBaseCont + dataBaseCont.Key = "hr_new" + dataBaseCont.Name = "HR数据库" + datatableList = append(datatableList, dataBaseCont) + var dataBaseCont1 DataBaseCont + dataBaseCont1.Key = "perform" + dataBaseCont1.Name = "绩效考核数据库" + datatableList = append(datatableList, dataBaseCont1) + var dataBaseTable BranchingCondition + dataBaseTable.ColumnId = "99143260231966720" //条件id columnId == 0 为发起人 + dataBaseTable.ShowType = "datatable" //columnType == "String" && showType == "checkBox"为多选 + dataBaseTable.ShowName = "关联数据表" //名称 + dataBaseTable.ColumnName = "datatablelist" //columnName 条件自定义字段 + dataBaseTable.ColumnType = "datatable" //columnType == "Double"为区间 + // + datatableListStr, _ := json.Marshal(datatableList) + dataBaseTable.FixedDownBoxValue = string(datatableListStr) //fixedDownBoxValue 匹配 columnType == "String" && showType == "checkBox"时子选项内容 + + sendListCont = append(sendListCont, dataBaseTable) + publicmethod.Result(0, sendListCont, c) } + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-22 14:14:05 +@ 功能: 获取数据表结构 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) GetDataBaseTable(c *gin.Context) { + var receivedValue publicmethod.PublicName + err := c.ShouldBindJSON(&receivedValue) + if err != nil || receivedValue.Name == "" { + receivedValue.Name = "perform" + } + gormDb := overall.CONSTANT_DB_KPI + switch receivedValue.Name { + case "perform": + gormDb = overall.CONSTANT_DB_KPI + case "hr_new": + gormDb = overall.CONSTANT_DB_HR + default: + gormDb = overall.CONSTANT_DB_KPI + } + tables := make([]string, 0) + // tableint := publicmethod.MapOut[string]() + gormDb.Raw("SHOW TABLES").Scan(&tables) + // gormDb.Raw("SHOW TABLES").Scan(&tableint) + var datatableList []DataBaseCont + for _, v := range tables { + var tableCont DataBaseCont + tableCont.Key = v + tableCont.Name = v + datatableList = append(datatableList, tableCont) + } + // sendData := publicmethod.MapOut[string]() + // sendData["tables"] = tables + // sendData["tableint"] = tableint + publicmethod.Result(0, datatableList, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-22 14:32:05 +@ 功能: 获取数据表结构 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) GetDataBaseTableCont(c *gin.Context) { + var receivedValue DataBaseInfo + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if receivedValue.DataBaseName == "" { + publicmethod.Result(1, err, c, "未知数据库") + return + } + if receivedValue.TablesName == "" { + publicmethod.Result(1, err, c, "未知数据表") + return + } + gormDb := overall.CONSTANT_DB_KPI + switch receivedValue.DataBaseName { + case "perform": + gormDb = overall.CONSTANT_DB_KPI + case "hr_new": + gormDb = overall.CONSTANT_DB_HR + default: + gormDb = overall.CONSTANT_DB_KPI + } + sqlStr := fmt.Sprintf("SHOW FULL COLUMNS FROM %v", receivedValue.TablesName) + var tableList []OutPutDataBaseTable + gormDb.Raw(sqlStr).Scan(&tableList) + for i, v := range tableList { + if strings.Contains(v.Type, "int") || strings.Contains(v.Type, "float") || strings.Contains(v.Type, "double") || strings.Contains(v.Type, "decimal") { + tableList[i].Type = "int" + } + if strings.Contains(v.Type, "char") || strings.Contains(v.Type, "text") || strings.Contains(v.Type, "year") || strings.Contains(v.Type, "time") || strings.Contains(v.Type, "date") { + tableList[i].Type = "string" + } + } + publicmethod.Result(0, tableList, c) +} diff --git a/api/workflow/workflowengine/shiyan.go b/api/workflow/workflowengine/shiyan.go index ba12037..90427ad 100644 --- a/api/workflow/workflowengine/shiyan.go +++ b/api/workflow/workflowengine/shiyan.go @@ -53,8 +53,9 @@ func (a *ApiMethod) ShiyanData(c *gin.Context) { // }` var workFlowStruct FlowStructIng - uuidInt := publicmethod.GetUUid(5) - workFlowStruct.NodeConfig.NodeNumber = strconv.FormatInt(uuidInt, 10) + workFlowStruct.TableId = strconv.FormatInt(publicmethod.GetUUid(2), 10) + workFlowStruct.WorkFlowDef.Name = "自定义工作流" + workFlowStruct.NodeConfig.NodeNumber = strconv.FormatInt(publicmethod.GetUUid(5), 10) workFlowStruct.NodeConfig.NodeName = "发起人" workFlowStruct.DirectorMaxLevel = 4 // err := json.Unmarshal([]byte(jsonStrSmaill), &workFlowStruct) diff --git a/api/workflow/workflowengine/type.go b/api/workflow/workflowengine/type.go index 77e9838..c465ec0 100644 --- a/api/workflow/workflowengine/type.go +++ b/api/workflow/workflowengine/type.go @@ -1,8 +1,11 @@ package workflowengine -import "key_performance_indicators/overall/publicmethod" +import ( + "key_performance_indicators/models/modelskpi" + "key_performance_indicators/overall/publicmethod" +) -//工作流结构体 +// 工作流结构体 type FlowStruct struct { TableId string `json:"tableId"` //流程ID WorkFlowDef WorkFlowDefStruct `json:"workFlowDef"` //工作流程定义 @@ -11,18 +14,18 @@ type FlowStruct struct { NodeConfig NodeConfigStruct `json:"nodeConfig"` //流程结构体 } -//工作流程定义 +// 工作流程定义 type WorkFlowDefStruct struct { publicmethod.PublicName //流程名称 } -//流程结构体 +// 流程结构体 type NodeConfigStruct struct { PublicNodeWord ChildNode PublicNodeWord `json:"childNode"` //流程标准结构 } -//流程结构体通用字段 +// 流程结构体通用字段 type PublicNodeWord struct { IsTrue bool `json:"error"` //当前审批是否通过校验 NodeName string `json:"nodeName"` //节点名称 @@ -41,7 +44,7 @@ type PublicNodeWord struct { } -//审批条件结构体 +// 审批条件结构体 type ConditionListStruct struct { ColumnId string `json:"columnId"` //发起人 OptType string `json:"optType"` //运算符 ["", "<", ">", "≤", "=", "≥"][optType] @@ -56,8 +59,64 @@ type ConditionListStruct struct { FixedDownBoxValue string `json:"fixedDownBoxValue"` //多选数组 } -//操作人 +// 操作人 type NodeUserListType struct { TargetId string `json:"targetId"` //操作人Key publicmethod.PublicName //操作人姓名 } + +// 输出数据库列表 +type DataBaseCont struct { + Key string `json:"key"` //数据库识别符 + publicmethod.PublicName //数据库名称 +} + +// 数据表结构 +type DataBaseInfo struct { + DataBaseName string `json:"databasename"` + TablesName string `json:"tablesname"` +} + +// 输出数据库表格字段 +type OutPutDataBaseTable struct { + Field string `json:"field"` //字段名 + Key string `json:"key"` //是否有索引;PRI表示是主键的一部分;UNI表示该列是UNIQUE索引的一部分;MUL表示某个给定值允许出现多次 + Type string `json:"type"` //字段类型 + Default string `json:"default"` //默认值 + Null string `json:"null"` //是否可以为空 + Extra string `json:"extra"` //表示可以获取的与给定列有关的附加信息 + Privileges string `json:"privileges"` //可执行操作 + Comment string `json:"comment"` //字段描述 +} + +// 获取工作流列表 +type GetWorkFlow struct { + publicmethod.PublicName + publicmethod.PagesTurn +} + +// 接收发布工作流数据 +type PublishWorkFlowCont struct { + Flowid string `json:"flowid"` //工作流ID + publicmethod.PublicName //工作流名称 + Describe string `json:"describe"` //描述 + Flowcont FlowStructIng `json:"flowcont"` //流程主体 +} + +// 输出工作流列表 +type WorkFlowList struct { + modelskpi.WorkFlowCont + Key string `json:"key"` +} + +// 查看工作流 +type LookWorkFlow struct { + publicmethod.PublicId //工作流编号 + Version string `json:"version"` //版本 +} + +// 编辑工作流 +type EditWorkFlowInfo struct { + PublishWorkFlowCont + VersionId string `json:"versionid"` //版本ID +} diff --git a/api/workflow/workflowengine/workflow.go b/api/workflow/workflowengine/workflow.go new file mode 100644 index 0000000..08416ae --- /dev/null +++ b/api/workflow/workflowengine/workflow.go @@ -0,0 +1,527 @@ +package workflowengine + +import ( + "encoding/json" + "fmt" + "key_performance_indicators/models/modelskpi" + "key_performance_indicators/overall" + "key_performance_indicators/overall/publicmethod" + "strconv" + "time" + + "github.com/gin-gonic/gin" +) + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-24 14:41:00 +@ 功能: 获取工作流列表 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) GetWorkFlowList(c *gin.Context) { + var receivedValue GetWorkFlow + c.ShouldBindJSON(&receivedValue) + if receivedValue.Page == 0 { + receivedValue.Page = 1 + } + if receivedValue.PageSize == 0 { + receivedValue.PageSize = 20 + } + var listCont []modelskpi.WorkFlowCont + gormDb := overall.CONSTANT_DB_KPI.Model(&modelskpi.WorkFlowCont{}).Where("`state` = 1 AND `vstate` = 1") + if receivedValue.Name != "" { + gormDb = gormDb.Where("`name` LIKE ?", "%"+receivedValue.Name+"%") + } + var total int64 + totalErr := gormDb.Count(&total).Error + if totalErr != nil { + total = 0 + } + gormDb = publicmethod.PageTurningSettings(gormDb, receivedValue.Page, receivedValue.PageSize) + err := gormDb.Find(&listCont).Error + if err != nil || len(listCont) < 1 { + publicmethod.Result(107, err, c) + return + } + var sendListCont []WorkFlowList + for _, v := range listCont { + var sendCont WorkFlowList + sendCont.Id = v.Id //Id"` + sendCont.Name = v.Name //维度"` + sendCont.Content = v.Content //关联部门"` + sendCont.Version = v.Version //维度"` + sendCont.Describe = v.Describe //描述"` + sendCont.State = v.State //状态(1:启用;2:禁用;3:删除)"` + sendCont.VersionState = v.VersionState //状态(1:启用;2:禁用;3:删除)"` + sendCont.Time = v.Time //写入时间"` + sendCont.VersionId = v.VersionId //附表ID + sendCont.Key = strconv.FormatInt(v.Id, 10) + sendListCont = append(sendListCont, sendCont) + } + publicmethod.ResultList(0, receivedValue.Page, receivedValue.PageSize, total, int64(len(sendListCont)), sendListCont, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-25 10:42:01 +@ 功能: 发布工作流 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) PublishWorkFlow(c *gin.Context) { + var receivedValue PublishWorkFlowCont + + c.ShouldBindJSON(&receivedValue) + + if receivedValue.Name == "" { + publicmethod.Result(100, receivedValue, c) + return + } + if receivedValue.Flowid == "" { + publicmethod.Result(100, receivedValue, c) + return + } + + flowContStr, err := json.Marshal(receivedValue.Flowcont) + if err != nil { + publicmethod.Result(1, err, c, "您提交的流程格式不正确!") + return + } + + flowKey, _ := strconv.ParseInt(receivedValue.Flowid, 10, 64) + var workFlowCont modelskpi.WorkFlow + var workFlowVerSion modelskpi.WorkFlowVersion + //判断是否已经存在 + where := publicmethod.MapOut[string]() + where["`key`"] = receivedValue.Flowid + err = workFlowVerSion.GetCont(where, "`id`") + dayTime := time.Now().Unix() + if err == nil { + //已经存在此流程编号新增流程版本 + var totalFlowVersion int64 + err = overall.CONSTANT_DB_KPI.Model(&modelskpi.WorkFlowVersion{}).Select("`id`").Count(&totalFlowVersion).Error + if err != nil { + totalFlowVersion = 1 + } else { + totalFlowVersion = totalFlowVersion + 1 + } + stateVersion := 1 + where["`state`"] = 1 + err = workFlowVerSion.GetCont(where, "`id`") + if err == nil { + stateVersion = 2 + } + + workFlowVerSion.Id = flowKey //流程标号 + workFlowVerSion.Content = string(flowContStr) //工作流主体 + workFlowVerSion.Version = strconv.FormatInt(totalFlowVersion, 10) //版本 + workFlowVerSion.Time = dayTime //写入时间"` + workFlowVerSion.State = stateVersion //状态(1:启用;2:禁用;3:删除)"` + + err := overall.CONSTANT_DB_KPI.Create(&workFlowVerSion).Error + if err == nil { + + publicmethod.Result(0, err, c) + } else { + + publicmethod.Result(104, err, c) + } + + } else { + workFlowCont.Id = flowKey //流程标号 + workFlowCont.Name = receivedValue.Name // + workFlowCont.Time = dayTime //写入时间"` + workFlowCont.Describe = receivedValue.Describe //描述 + workFlowCont.State = 1 + + workFlowVerSion.Key = flowKey //流程标号 + workFlowVerSion.Content = string(flowContStr) //工作流主体 + workFlowVerSion.Version = "1" //版本 + workFlowVerSion.Time = dayTime //写入时间"` + workFlowVerSion.State = 1 //状态(1:启用;2:禁用;3:删除)"` + + //写入数据 + gormDb := overall.CONSTANT_DB_KPI.Begin() + + flowContErr := gormDb.Create(&workFlowCont).Error + flowVersion := gormDb.Create(&workFlowVerSion).Error + + if flowContErr == nil && flowVersion == nil { + addErr := gormDb.Commit().Error + publicmethod.Result(0, addErr, c) + } else { + addErr := gormDb.Rollback().Error + publicmethod.Result(104, addErr, c) + } + } + +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-25 15:12:44 +@ 功能: 编辑主流程状态 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) EditWorkFlowState(c *gin.Context) { + var receivedValue publicmethod.PublicState + c.ShouldBindJSON(&receivedValue) + if receivedValue.Id == "" { + publicmethod.Result(100, receivedValue, c) + return + } + if receivedValue.State == 0 { + receivedValue.State = 1 + } + + if receivedValue.IsTrue == 0 { + receivedValue.IsTrue = 2 + } + where := publicmethod.MapOut[string]() + where["`id`"] = receivedValue.Id + var workFlowCont modelskpi.WorkFlow + err := workFlowCont.GetCont(where) + if err != nil { + publicmethod.Result(104, err, c) + return + } + if receivedValue.IsTrue != 1 { + saveData := publicmethod.MapOut[string]() + saveData["`state`"] = receivedValue.State + saveData["`time`"] = time.Now().Unix() + err = workFlowCont.EiteCont(where, saveData) + publicmethod.Result(0, err, c) + } else { + if receivedValue.State != 3 { + saveData := publicmethod.MapOut[string]() + saveData["`state`"] = receivedValue.State + saveData["`time`"] = time.Now().Unix() + err = workFlowCont.EiteCont(where, saveData) + publicmethod.Result(0, err, c) + } else { + gormDb := overall.CONSTANT_DB_KPI.Begin() + delContErr := gormDb.Where("`id` = ?", receivedValue.Id).Delete(&workFlowCont).Error + delVersiontErr := gormDb.Where("`key` = ?", receivedValue.Id).Delete(&modelskpi.WorkFlowVersion{}).Error + if delContErr == nil && delVersiontErr == nil { + addErr := gormDb.Commit().Error + publicmethod.Result(0, addErr, c) + } else { + addErr := gormDb.Rollback().Error + publicmethod.Result(104, addErr, c) + } + } + + } +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-25 15:40:10 +@ 功能: 查看工作流 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) LookWorkFlowCont(c *gin.Context) { + var receivedValue LookWorkFlow + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if receivedValue.Id == "" { + publicmethod.Result(1, err, c, "未知流程") + return + } + if receivedValue.Version == "" { + publicmethod.Result(1, err, c, "wei") + return + } + where := publicmethod.MapOut[string]() + where["`id`"] = receivedValue.Id + where["`version`"] = receivedValue.Version + var workFlowCont modelskpi.WorkFlowCont + err = workFlowCont.GetCont(where) + if err != nil { + publicmethod.Result(107, err, c) + return + } + var sendCont PublishWorkFlowCont + sendCont.Flowid = strconv.FormatInt(workFlowCont.Id, 10) + sendCont.Name = workFlowCont.Name + sendCont.Describe = workFlowCont.Describe + // sendCont.Flowcont = json.Unmarshal() + err = json.Unmarshal([]byte(workFlowCont.Content), &sendCont.Flowcont) + fmt.Printf("err ---->%v\n", err) + publicmethod.Result(0, sendCont, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-25 16:30:22 +@ 功能: +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) InitializeWorkFlow(c *gin.Context) { + var workFlowStruct FlowStructIng + workFlowStruct.TableId = strconv.FormatInt(publicmethod.GetUUid(2), 10) + workFlowStruct.WorkFlowDef.Name = "自定义工作流" + workFlowStruct.NodeConfig.NodeNumber = strconv.FormatInt(publicmethod.GetUUid(5), 10) + workFlowStruct.NodeConfig.NodeName = "发起人" + workFlowStruct.DirectorMaxLevel = 4 + // err := json.Unmarshal([]byte(jsonStrSmaill), &workFlowStruct) + outData := publicmethod.MapOut[string]() + outData["workFlowStruct"] = workFlowStruct + // outData["err"] = err + publicmethod.Result(0, workFlowStruct, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-27 15:17:50 +@ 功能: 获取流程版本列表 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) GetWorkFlowVersionList(c *gin.Context) { + var receivedValue publicmethod.PublicId + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if receivedValue.Id == "" { + publicmethod.Result(101, err, c) + return + } + var flowVersionList []modelskpi.WorkFlowVersion + err = overall.CONSTANT_DB_KPI.Where("`key` = ? AND `state` BETWEEN ? AND ?", receivedValue.Id, 1, 2).Order("id asc").Find(&flowVersionList).Error + if err != nil { + publicmethod.Result(107, err, c) + return + } + publicmethod.Result(0, flowVersionList, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-28 08:55:54 +@ 功能:编辑流程主体 +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) EditWorkFlowCont(c *gin.Context) { + var receivedValue EditWorkFlowInfo + c.ShouldBindJSON(&receivedValue) + if receivedValue.Flowid == "" { + publicmethod.Result(100, receivedValue, c) + return + } + if receivedValue.Name == "" { + publicmethod.Result(100, receivedValue, c) + return + } + if receivedValue.VersionId == "" { + publicmethod.Result(100, receivedValue, c) + return + } + flowContStr, err := json.Marshal(receivedValue.Flowcont) + if err != nil { + publicmethod.Result(1, err, c, "您提交的流程格式不正确!") + return + } + + flowKey, _ := strconv.ParseInt(receivedValue.Flowid, 10, 64) + + var workFlowCont modelskpi.WorkFlowCont + //判断是否已经存在 + where := publicmethod.MapOut[string]() + where["`id`"] = receivedValue.Flowid + err = workFlowCont.GetCont(where, "`id`") + dayTime := time.Now().Unix() + if err != nil { + publicmethod.Result(107, err, c) + return + } + saveMainData := publicmethod.MapOut[string]() + if workFlowCont.Name != receivedValue.Name { + saveMainData["`name`"] = receivedValue.Name + } + if workFlowCont.Describe != receivedValue.Describe { + saveMainData["`describe`"] = receivedValue.Describe + } + if len(saveMainData) > 0 { + saveMainData["`time`"] = dayTime + var editWorkFlowMain modelskpi.WorkFlow + editWorkFlowMain.EiteCont(where, saveMainData) + } + whereVersion := publicmethod.MapOut[string]() + whereVersion["`id`"] = receivedValue.VersionId + var workVersion modelskpi.WorkFlowVersion + err = workVersion.GetCont(whereVersion) + if err != nil { + var totalFlowVersion int64 + err = overall.CONSTANT_DB_KPI.Model(&modelskpi.WorkFlowVersion{}).Select("`id`").Count(&totalFlowVersion).Error + if err != nil { + totalFlowVersion = 1 + } else { + totalFlowVersion = totalFlowVersion + 1 + } + stateVersion := 1 + whersse := publicmethod.MapOut[string]() + whersse["`state`"] = 1 + whersse["`key`"] = flowKey + var workFlowVeIstrue modelskpi.WorkFlowVersion + err = workFlowVeIstrue.GetCont(whersse, "`id`") + if err == nil { + stateVersion = 2 + } + vid, _ := strconv.ParseInt(receivedValue.VersionId, 10, 64) + var workFlowVerSion modelskpi.WorkFlowVersion + workFlowVerSion.Id = vid + workFlowVerSion.Key = flowKey //流程标号 + workFlowVerSion.Content = string(flowContStr) //工作流主体 + workFlowVerSion.Version = strconv.FormatInt(totalFlowVersion, 10) //版本 + workFlowVerSion.Time = dayTime //写入时间"` + workFlowVerSion.State = stateVersion //状态(1:启用;2:禁用;3:删除)"` + + err := overall.CONSTANT_DB_KPI.Create(workFlowVerSion).Error + if err == nil { + + publicmethod.Result(0, err, c) + } else { + + publicmethod.Result(104, err, c) + } + } else { + saveVersion := publicmethod.MapOut[string]() + saveVersion["`content`"] = string(flowContStr) + saveVersion["`time`"] = dayTime + err = workVersion.EiteCont(whereVersion, saveVersion) + if err == nil { + + publicmethod.Result(0, err, c) + } else { + + publicmethod.Result(104, err, c) + } + } + +} + +/* +* +@ 作者: 秦东 +@ 时间: 2023-03-29 08:22:36 +@ 功能: +@ 参数 + + # + +@ 返回值 + + # + +@ 方法原型 + + # +*/ +func (a *ApiMethod) StartUsingVersion(c *gin.Context) { + var receivedValue publicmethod.PublicId + err := c.ShouldBindJSON(&receivedValue) + if err != nil { + publicmethod.Result(100, err, c) + return + } + if receivedValue.Id == "" { + publicmethod.Result(101, err, c) + return + } + where := publicmethod.MapOut[string]() + where["`id`"] = receivedValue.Id + var versionCont modelskpi.WorkFlowVersion + err = versionCont.GetCont(where) + if err != nil { + publicmethod.Result(1, err, c, "未知版本!不可操作!") + return + } + var oldVersionCont modelskpi.WorkFlowVersion + err = oldVersionCont.EiteCont(map[string]interface{}{"`key`": versionCont.Key}, map[string]interface{}{"`state`": 2}) + if err == nil { + var newVersionCont modelskpi.WorkFlowVersion + newVersionCont.EiteCont(where, map[string]interface{}{"`state`": 1}) + } + publicmethod.Result(0, err, c) +} diff --git a/apirouter/apishiyan/maptostruct.go b/apirouter/apishiyan/maptostruct.go index ee34ccd..8c89c17 100644 --- a/apirouter/apishiyan/maptostruct.go +++ b/apirouter/apishiyan/maptostruct.go @@ -31,5 +31,8 @@ func (a *ApiRouter) RouterGroup(router *gin.RouterGroup) { apiRouter.POST("verif_depart_detasil", methodBinding.VerifDepartDetasil) //验证部门指标细则关系对照 apiRouter.POST("xzbkhbm", methodBinding.XiangzhengBeikaoBumen) //验证部门指标细则关系对照 + + //验证工作流 + apiRouter.POST("test_verify_workflow", methodBinding.TestAndVerifyWorkflow) //验证工作流函数 } } diff --git a/apirouter/v1/systempower/pc.go b/apirouter/v1/systempower/pc.go index a84fc0f..b5afe93 100644 --- a/apirouter/v1/systempower/pc.go +++ b/apirouter/v1/systempower/pc.go @@ -36,5 +36,10 @@ func (a *ApiRouter) RouterGroupPc(router *gin.RouterGroup) { apiRouter.POST("batch_del_roleman", methodBinding.BatchDeletToRoleAboutMan) //批量删除角色关联人员 apiRouter.POST("add_role_user", methodBinding.AddRoleUser) //添加角色关联人员 + //工作流使用APi列表 + apiRouter.POST("system_role_list_flow", methodBinding.SystemRoleListFlow) //系统角色列表(工作流专版) + apiRouter.POST("search_people", methodBinding.SearchPeople) //搜索人员 + apiRouter.POST("get_position_unify", methodBinding.GetPositionUnify) //获取统一岗位 + apiRouter.POST("search_position_unify", methodBinding.SearchPositionUnify) //搜索统一岗位 } } diff --git a/apirouter/workflowrouter/flowrouter.go b/apirouter/workflowrouter/flowrouter.go index f07cd22..2126bd8 100644 --- a/apirouter/workflowrouter/flowrouter.go +++ b/apirouter/workflowrouter/flowrouter.go @@ -18,8 +18,19 @@ 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) //判断条件 + apiRouter.POST("judge_optional_node", workFlow.JudgeOptionalNode) //判断是否显示(指定审批节点自选)选项及可选节点 + apiRouter.POST("get_all_parent_node", workFlow.GetAllParentNode) //获取所有父级审批节点 + apiRouter.POST("judging_condition", workFlow.JudgingCondition) //判断条件 + apiRouter.POST("get_data_base_table", workFlow.GetDataBaseTable) //获取数据表列表 + apiRouter.POST("get_data_base_tablecont", workFlow.GetDataBaseTableCont) //获取数据表结构 + + apiRouter.POST("get_work_flow_list", workFlow.GetWorkFlowList) //获取工作流列表 + apiRouter.POST("publish_work_flow", workFlow.PublishWorkFlow) //发布工作流 + apiRouter.POST("edit_work_flow_state", workFlow.EditWorkFlowState) //编辑工作流主体状态 + apiRouter.POST("look_work_flow", workFlow.LookWorkFlowCont) //查看工作流 + apiRouter.POST("init_work_flow", workFlow.InitializeWorkFlow) //初始化流程 + apiRouter.POST("get_workflow_version_list", workFlow.GetWorkFlowVersionList) //获取流程版本列表 + apiRouter.POST("edit_workflow_cont", workFlow.EditWorkFlowCont) //编辑流程主体 + apiRouter.POST("start_using_version", workFlow.StartUsingVersion) //启用流程版本 } } diff --git a/models/modelshr/position.go b/models/modelshr/position.go index aada05e..90a975a 100644 --- a/models/modelshr/position.go +++ b/models/modelshr/position.go @@ -21,6 +21,7 @@ type Position struct { ButtonPermit string `json:"buttonpermit" gorm:"column:button_permit;type:longtext;comment:按钮许可"` School int64 `json:"school" gorm:"column:school;type:bigint(20) unsigned;default:0;not null;comment:部门"` KingdeeId string `json:"kingdeeid" gorm:"column:kingdeeid;type:varchar(255) unsigned;default:'';comment:金蝶对照ID"` + UnifyId int64 `json:"unifyid" gorm:"column:unify_id;type:bigint(20) unsigned;default:0;not null;comment:统一名称"` } func (Position *Position) TableName() string { diff --git a/models/modelshr/position_unify.go b/models/modelshr/position_unify.go new file mode 100644 index 0000000..ea70778 --- /dev/null +++ b/models/modelshr/position_unify.go @@ -0,0 +1,43 @@ +package modelshr + +import ( + "key_performance_indicators/overall" + "strings" +) + +// 职位(岗位) +type PositionUnify struct { + Id int64 `json:"id" gorm:"primaryKey;column:id;type:bigint(20) unsigned;not null;comment:Id;index"` + Name string `json:"name" gorm:"column:name;type:varchar(200) unsigned;default:'';not null;comment:职位名称"` + Time int64 `json:"time" gorm:"column:time;type:bigint(20) unsigned;default:0;not null;comment:创建时间"` + State int `json:"state" gorm:"column:state;type:int(1) unsigned;default:1;not null;comment:状态(1:启用;2:禁用;3:删除)"` + Content string `json:"content" gorm:"column:content;type:longtext;comment:关联具体岗位ID"` +} + +func (PositionUnify *PositionUnify) TableName() string { + return "position_unify" +} + +// 编辑职务分类内容 +func (cont *PositionUnify) EiteCont(whereMap interface{}, saveData map[string]interface{}) (err error) { + err = overall.CONSTANT_DB_HR.Model(&cont).Where(whereMap).Updates(saveData).Error + return +} + +// 获取行政组织内容 +func (cont *PositionUnify) GetCont(whereMap interface{}, field ...string) (err error) { + gormDb := overall.CONSTANT_DB_HR.Model(&cont) + if len(field) > 0 { + fieldStr := strings.Join(field, ",") + gormDb = gormDb.Select(fieldStr) + } + gormDb = gormDb.Where(whereMap) + err = gormDb.First(&cont).Error + return +} + +// 根据条件获取总数 +func (cont *PositionUnify) CountCont(whereMap interface{}) (countId int64) { + overall.CONSTANT_DB_HR.Model(&cont).Where(whereMap).Count(&countId) + return +} diff --git a/models/modelskpi/work_flow.go b/models/modelskpi/work_flow.go new file mode 100644 index 0000000..971a2fc --- /dev/null +++ b/models/modelskpi/work_flow.go @@ -0,0 +1,60 @@ +package modelskpi + +import ( + "key_performance_indicators/overall" + "strings" +) + +// 工作流 +type WorkFlow struct { + Id int64 `json:"id" gorm:"primaryKey;column:id;type:bigint(20) unsigned;not null;comment:Id"` + Name string `json:"name" gorm:"column:name;type:varchar(255) ;default:'';comment:维度"` + Time int64 `json:"time" gorm:"column:time;type:bigint(20) unsigned;default:0;not null;comment:写入时间"` + Describe string `json:"describe" gorm:"column:describe;type:longtext ;comment:描述"` + State int `json:"state" gorm:"column:state;type:int(1) unsigned;default:1;not null;comment:状态(1:启用;2:禁用;3:删除)"` +} + +func (WorkFlow *WorkFlow) TableName() string { + return "work_flow" +} + +// 编辑内容 +func (cont *WorkFlow) EiteCont(whereMap interface{}, saveData interface{}) (err error) { + err = overall.CONSTANT_DB_KPI.Model(&cont).Where(whereMap).Updates(saveData).Error + return +} + +// 获取内容 +func (cont *WorkFlow) GetCont(whereMap interface{}, field ...string) (err error) { + gormDb := overall.CONSTANT_DB_KPI.Model(&cont) + if len(field) > 0 { + fieldStr := strings.Join(field, ",") + gormDb = gormDb.Select(fieldStr) + } + gormDb = gormDb.Where(whereMap) + err = gormDb.First(&cont).Error + return +} + +// 根据条件获取总数 +func (cont *WorkFlow) CountCont(whereMap interface{}) (countId int64) { + overall.CONSTANT_DB_KPI.Model(&cont).Where(whereMap).Count(&countId) + return +} + +// 读取全部信息 +func (cont *WorkFlow) ContMap(whereMap interface{}, field ...string) (countAry []WorkFlow, err error) { + gormDb := overall.CONSTANT_DB_KPI.Model(&cont) + if len(field) > 0 { + fieldStr := strings.Join(field, ",") + gormDb = gormDb.Select(fieldStr) + } + err = gormDb.Where(whereMap).Order("sort ASC").Find(&countAry).Error + return +} + +// 删除内容 +func (cont *WorkFlow) DelCont(whereMap interface{}) (err error) { + err = overall.CONSTANT_DB_KPI.Where(whereMap).Delete(&cont).Error + return +} diff --git a/models/modelskpi/work_flow_cont.go b/models/modelskpi/work_flow_cont.go new file mode 100644 index 0000000..f33ab0d --- /dev/null +++ b/models/modelskpi/work_flow_cont.go @@ -0,0 +1,64 @@ +package modelskpi + +import ( + "key_performance_indicators/overall" + "strings" +) + +// 工作流视图 +type WorkFlowCont struct { + Id int64 `json:"id" gorm:"primaryKey;column:id;type:bigint(20) unsigned;not null;comment:Id"` + Name string `json:"name" gorm:"column:name;type:varchar(255) ;default:'';comment:维度"` + Content string `json:"content" gorm:"column:content;type:longtext ;comment:关联部门"` + Version string `json:"version" gorm:"column:version;type:varchar(255) ;default:'';comment:维度"` + Describe string `json:"describe" gorm:"column:describe;type:longtext ;comment:描述"` + State int `json:"state" gorm:"column:state;type:int(1) unsigned;default:1;not null;comment:状态(1:启用;2:禁用;3:删除)"` + VersionState int `json:"vstate" gorm:"column:vstate;type:int(1) unsigned;default:1;not null;comment:状态(1:启用;2:禁用;3:删除)"` + Time int64 `json:"time" gorm:"column:time;type:bigint(20) unsigned;default:0;not null;comment:写入时间"` + VersionId int64 `json:"vid" gorm:"column:vid;type:bigint(20) unsigned;not null;comment:Id"` //附表ID +} + +func (WorkFlowCont *WorkFlowCont) TableName() string { + return "work_flow_cont" +} + +// 编辑内容 +func (cont *WorkFlowCont) EiteCont(whereMap interface{}, saveData interface{}) (err error) { + err = overall.CONSTANT_DB_KPI.Model(&cont).Where(whereMap).Updates(saveData).Error + return +} + +// 获取内容 +func (cont *WorkFlowCont) GetCont(whereMap interface{}, field ...string) (err error) { + gormDb := overall.CONSTANT_DB_KPI.Model(&cont) + if len(field) > 0 { + fieldStr := strings.Join(field, ",") + gormDb = gormDb.Select(fieldStr) + } + gormDb = gormDb.Where(whereMap) + err = gormDb.First(&cont).Error + return +} + +// 根据条件获取总数 +func (cont *WorkFlowCont) CountCont(whereMap interface{}) (countId int64) { + overall.CONSTANT_DB_KPI.Model(&cont).Where(whereMap).Count(&countId) + return +} + +// 读取全部信息 +func (cont *WorkFlowCont) ContMap(whereMap interface{}, field ...string) (countAry []WorkFlowCont, err error) { + gormDb := overall.CONSTANT_DB_KPI.Model(&cont) + if len(field) > 0 { + fieldStr := strings.Join(field, ",") + gormDb = gormDb.Select(fieldStr) + } + err = gormDb.Where(whereMap).Order("sort ASC").Find(&countAry).Error + return +} + +// 删除内容 +func (cont *WorkFlowCont) DelCont(whereMap interface{}) (err error) { + err = overall.CONSTANT_DB_KPI.Where(whereMap).Delete(&cont).Error + return +} diff --git a/models/modelskpi/work_flow_version.go b/models/modelskpi/work_flow_version.go new file mode 100644 index 0000000..f52eaac --- /dev/null +++ b/models/modelskpi/work_flow_version.go @@ -0,0 +1,61 @@ +package modelskpi + +import ( + "key_performance_indicators/overall" + "strings" +) + +// 工作流版本 +type WorkFlowVersion struct { + Id int64 `json:"id" gorm:"column:id;type:bigint(20) unsigned;not null;comment:Id"` + Content string `json:"content" gorm:"column:content;type:longtext ;comment:关联部门"` + Version string `json:"version" gorm:"column:version;type:varchar(255) ;default:'';comment:维度"` + Time int64 `json:"time" gorm:"column:time;type:bigint(20) unsigned;default:0;not null;comment:写入时间"` + State int `json:"state" gorm:"column:state;type:int(1) unsigned;default:1;not null;comment:状态(1:启用;2:禁用;3:删除)"` + Key int64 `json:"key" gorm:"column:key;type:bigint(20) unsigned;default:0;not null;comment:标识符"` +} + +func (WorkFlowVersion *WorkFlowVersion) TableName() string { + return "work_flow_version" +} + +// 编辑内容 +func (cont *WorkFlowVersion) EiteCont(whereMap interface{}, saveData interface{}) (err error) { + err = overall.CONSTANT_DB_KPI.Model(&cont).Where(whereMap).Updates(saveData).Error + return +} + +// 获取内容 +func (cont *WorkFlowVersion) GetCont(whereMap interface{}, field ...string) (err error) { + gormDb := overall.CONSTANT_DB_KPI.Model(&cont) + if len(field) > 0 { + fieldStr := strings.Join(field, ",") + gormDb = gormDb.Select(fieldStr) + } + gormDb = gormDb.Where(whereMap) + err = gormDb.First(&cont).Error + return +} + +// 根据条件获取总数 +func (cont *WorkFlowVersion) CountCont(whereMap interface{}) (countId int64) { + overall.CONSTANT_DB_KPI.Model(&cont).Where(whereMap).Count(&countId) + return +} + +// 读取全部信息 +func (cont *WorkFlowVersion) ContMap(whereMap interface{}, field ...string) (countAry []WorkFlowVersion, err error) { + gormDb := overall.CONSTANT_DB_KPI.Model(&cont) + if len(field) > 0 { + fieldStr := strings.Join(field, ",") + gormDb = gormDb.Select(fieldStr) + } + err = gormDb.Where(whereMap).Order("sort ASC").Find(&countAry).Error + return +} + +// 删除内容 +func (cont *WorkFlowVersion) DelCont(whereMap interface{}) (err error) { + err = overall.CONSTANT_DB_KPI.Where(whereMap).Delete(&cont).Error + return +} diff --git a/overall/publicmethod/technique.go b/overall/publicmethod/technique.go index 9489c60..cf17366 100644 --- a/overall/publicmethod/technique.go +++ b/overall/publicmethod/technique.go @@ -393,6 +393,25 @@ func DifferenceSet[T GenericityVariable](one, two []T) []T { return three } +// 两个切片的交集 +func Intersect[T GenericityVariable](a, b []T) []T { + inter := make([]T, 0) + mp := make(map[T]bool) + + for _, s := range a { + if _, ok := mp[s]; !ok { + mp[s] = true + } + } + for _, s := range b { + if _, ok := mp[s]; ok { + inter = append(inter, s) + } + } + + return inter +} + //判断类型转换成 /* 字符转int @@ -1826,3 +1845,45 @@ func JudjeMaxOfMinVal(maxVal, minVal float64) (maxVals, minVals float64) { // fmt.Printf("ge---1-->%v----->%v\n", maxVals, minVals) return } + +// 获取行政组织所有上级 +func (g *GetOrgAllParent) GetOrgParentAllId(orgId int64) { + var orgCont modelshr.AdministrativeOrganization + err := orgCont.GetCont(map[string]interface{}{"`id`": orgId, "`state`": 1}, "`superior`") + if err == nil { + if IsInTrue[int64](orgId, g.Id) == false { + g.Id = append(g.Id, orgId) + } + g.GetOrgParentAllId(orgCont.Superior) + } else { + return + } +} + +// 获取所有下级 +func (g *GetOrgAllParent) GetOrgSonAllId(orgId int64) { + var orgAry []int64 + err := overall.CONSTANT_DB_HR.Model(&modelshr.AdministrativeOrganization{}).Select("`id`").Where("`state` = 1 AND `superior` = ?", orgId).Find(&orgAry).Error + if err != nil { + return + } + for _, v := range orgAry { + if IsInTrue[int64](v, g.Id) == false { + g.Id = append(g.Id, v) + g.GetOrgSonAllId(v) + } else { + g.GetOrgSonAllId(v) + } + } +} + +// 获取行政组织所有上级和下级 +func HaveAllOrgRelation(orgId int64) []int64 { + departmentId := RecursionOrgLeve(orgId, 4) + var getAllOrg GetOrgAllParent + getAllOrg.GetOrgParentAllId(departmentId) + getAllOrg.GetOrgSonAllId(departmentId) + + // getAllOrg.GetOrgSonAllId(orgId) + return getAllOrg.Id +} diff --git a/overall/publicmethod/type.go b/overall/publicmethod/type.go index 85a19dc..6263ed2 100644 --- a/overall/publicmethod/type.go +++ b/overall/publicmethod/type.go @@ -269,3 +269,8 @@ type DateTimeTotimes struct { Second string `json:"second"` AllTime int64 `json:"alltime"` } + +// 获取行政组织所有上级 +type GetOrgAllParent struct { + Id []int64 `json:"id"` +}