From d219e983768191104c96d5dda131c6b9fa94e0d2 Mon Sep 17 00:00:00 2001 From: herenshan112 Date: Thu, 6 Oct 2022 07:40:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog.md | 16 + README.md | 47 +++ .../departmentpc/qualitativekpi.go | 341 +++++++++++++++- api/version1/entry.go | 2 + api/version1/flowchart/entry.go | 25 ++ api/version1/flowchart/flow.go | 370 ++++++++++++++++++ api/version1/postseting/postpc/scheme.go | 10 +- api/version1/postseting/postweb/postration.go | 160 +++++++- api/version1/postseting/postweb/posttarget.go | 253 +++++++++++- apirouter/entry.go | 2 + apirouter/wechaturl/wechatrouter.go | 7 +- apirouter/workflowchart/entry.go | 12 + apirouter/workflowchart/flowes.go | 19 + initialization/route/initRoute.go | 4 + .../wechatcallback/event_processing.go | 150 +++++++ .../wechatcallback/geographical_position.go | 64 +++ .../wechatapp/wechatcallback/response.go | 132 +++++-- middleware/wechatapp/wechatcallback/type.go | 103 +++++ .../wechatsendmsg/send_applets_type.go | 23 ++ .../wechatsendmsg/send_ordinary_msg.go | 301 ++++++++++++++ .../wechatsendmsg/send_template_card_type.go | 303 ++++++++++++++ middleware/wechatapp/wechatsendmsg/type.go | 112 ++++++ middleware/wechatapp/wechatstatice/method.go | 18 +- middleware/wechatapp/wechatstatice/type.go | 45 ++- models/modelskpi/open_approval_change_log.go | 73 ++++ models/modelskpi/operator_is_true.go | 69 ++++ models/modelskpi/post_target.go | 9 +- .../qualitative_evaluation_scheme.go | 1 + models/modelsschool/step_role_group.go | 28 +- overall/publicmethod/technique.go | 90 +++++ overall/publicmethod/type.go | 50 +++ 31 files changed, 2744 insertions(+), 95 deletions(-) create mode 100644 api/version1/flowchart/entry.go create mode 100644 api/version1/flowchart/flow.go create mode 100644 apirouter/workflowchart/entry.go create mode 100644 apirouter/workflowchart/flowes.go create mode 100644 middleware/wechatapp/wechatcallback/event_processing.go create mode 100644 middleware/wechatapp/wechatcallback/geographical_position.go create mode 100644 middleware/wechatapp/wechatsendmsg/send_applets_type.go create mode 100644 middleware/wechatapp/wechatsendmsg/send_ordinary_msg.go create mode 100644 middleware/wechatapp/wechatsendmsg/send_template_card_type.go create mode 100644 models/modelskpi/open_approval_change_log.go create mode 100644 models/modelskpi/operator_is_true.go diff --git a/DevLog.md b/DevLog.md index 23e69f6..5c877c6 100644 --- a/DevLog.md +++ b/DevLog.md @@ -37,3 +37,19 @@ ### 2022/8/23 + +//文本信息发送 +{ + "code": 0, + "msg": "成功", + "data": { + "errcode": 0, + "errmsg": "ok", + "invaliduser": "", + "invalidparty": "", + "invalidtag": "", + "unlicenseduser": "", + "msgid": "mrVtVXE39it1tWVvd57npMpx5AjKZ1VvM-pj7nMCULC0FrlcENid7lRqMZbLvltWcOzLOrKSbGUqV0ngefx2xQ", + "response_code": "" + } +} \ No newline at end of file diff --git a/README.md b/README.md index 839c78c..01a52f8 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,14 @@ 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:驳回 | 当前步进位 | ## 开发日志 @@ -362,4 +369,44 @@ CREATE TABLE `appsystem` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COMMENT='应用系统'; +``` + + +Time:2022-10-05
+数据库增加 审批记录 数据表 +
+ +``` +CREATE TABLE `open_approval_change_log` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `type` int(1) unsigned NOT NULL DEFAULT '1' COMMENT '类型(1:部门;2:岗位)', + `title` varchar(255) DEFAULT '' COMMENT '节点名称', + `operator` varchar(255) NOT NULL DEFAULT '' COMMENT '操作人', + `orderid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '订单ID', + `operatortime` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '操作时间', + `step` int(5) unsigned NOT NULL DEFAULT '1' COMMENT '操作第几步', + `operatortype` int(1) unsigned NOT NULL DEFAULT '1' COMMENT '操作状态', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COMMENT='审批记录'; + +``` + + +Time:2022-10-05
+数据库增加 当前节点是否可操作 数据表 +
+ +``` +CREATE TABLE `operator_is_true` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `orderid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '订单ID', + `step` int(5) unsigned NOT NULL DEFAULT '1' COMMENT '审批到第几步', + `state` int(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态:1:可操作;2:不可操作', + `time` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '时间', + `msgid` varchar(255) DEFAULT '' COMMENT '消息id,用于撤回应用消息', + `response_code` varchar(255) DEFAULT '' COMMENT '仅消息类型为“按钮交互型”,“投票选择型”和“多项选择型”的模板卡片消息返回,应用可使用response_code调用更新模版卡片消息接口,24小时内有效,且只能使用一次', + `stepper` int(5) unsigned NOT NULL DEFAULT '1' COMMENT '步进器', + PRIMARY KEY (`id`) +) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='当前节点是否可操作'; + ``` \ No newline at end of file diff --git a/api/version1/departmentseting/departmentpc/qualitativekpi.go b/api/version1/departmentseting/departmentpc/qualitativekpi.go index 381bcbb..042aa5c 100644 --- a/api/version1/departmentseting/departmentpc/qualitativekpi.go +++ b/api/version1/departmentseting/departmentpc/qualitativekpi.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "key_performance_indicators/middleware/snowflake" + "key_performance_indicators/middleware/wechatapp/wechatsendmsg" "key_performance_indicators/models/modelshr" "key_performance_indicators/models/modelskpi" "key_performance_indicators/overall" @@ -139,25 +140,327 @@ func (a *ApiMethod) Shiyan(c *gin.Context) { //校正维度 // xiaoZehgnWeiDu() - var receivedValue publicmethod.PublicId - c.ShouldBindJSON(&receivedValue) - //获取被考核人基本信息 - var userCont modelshr.PersonArchives - err := userCont.GetCont(map[string]interface{}{"`number`": receivedValue.Id}, "`key`", "`company`", "`maindeparment`", "`admin_org`", "`position`") - // err := userCont.GetCont(map[string]interface{}{"`number`": 300595}, "`company`", "`maindeparment`", "`admin_org`", "`position`") - if err != nil { - publicmethod.Result(107, err, c) - return - } - // publicmethod.GetDepartmentLeader(userCont) - var kjskd []publicmethod.PositionDigui - kjskd = publicmethod.GetPositionList(userCont.Key, userCont.AdminOrg, userCont.Position, 1, kjskd) - jsonStr, _ := json.Marshal(kjskd) - fmt.Printf("kjskd---------------->%v\n", string(jsonStr)) - // var ksd []int64 - // ksd = publicmethod.GetDepartmentSun(userCont.Company, ksd) - // fmt.Printf("ksd----------->%v\n", ksd) - publicmethod.Result(0, kjskd, c) + // var receivedValue publicmethod.PublicId + // c.ShouldBindJSON(&receivedValue) + // //获取被考核人基本信息 + // var userCont modelshr.PersonArchives + // err := userCont.GetCont(map[string]interface{}{"`number`": receivedValue.Id}, "`key`", "`company`", "`maindeparment`", "`admin_org`", "`position`") + // // err := userCont.GetCont(map[string]interface{}{"`number`": 300595}, "`company`", "`maindeparment`", "`admin_org`", "`position`") + // if err != nil { + // publicmethod.Result(107, err, c) + // return + // } + // // publicmethod.GetDepartmentLeader(userCont) + // var kjskd []publicmethod.PositionDigui + // kjskd = publicmethod.GetPositionList(userCont.Key, userCont.AdminOrg, userCont.Position, 1, kjskd) + // jsonStr, _ := json.Marshal(kjskd) + // fmt.Printf("kjskd---------------->%v\n", string(jsonStr)) + // // var ksd []int64 + // // ksd = publicmethod.GetDepartmentSun(userCont.Company, ksd) + // // fmt.Printf("ksd----------->%v\n", ksd) + // publicmethod.Result(0, kjskd, c) + + //发送消息 + // var sendTextMsgCont wechatsendmsg.TextMsgCont + // sendTextMsgCont.Content = "你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看邮件中心视频实况,聪明避开排队。" + // var sendTextMsg wechatsendmsg.SendTextMsg + + // sendTextMsg.Touser = "KaiXinGuo" //指定接收消息的成员,成员ID列表;特殊情况:指定为"@all",则向该企业应用的全部成员发送;最多支持1000个 + // sendTextMsg.Toparty = "" //指定接收消息的部门,部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为"@all"时忽略本参数 + // sendTextMsg.Totag = "" //指定接收消息的标签,标签ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为"@all"时忽略本参数 + // sendTextMsg.Msgtype = "text" //消息类型 + // agentIdInt, _ := strconv.ParseInt(overall.CONSTANT_CONFIG.WechatKpi.Agentid, 10, 64) + // sendTextMsg.Agentid = agentIdInt //企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值 + // sendTextMsg.EnableDuplicateCheck = 0 //表示是否开启重复消息检查,0表示否,1表示是,默认0 + // sendTextMsg.DuplicateCheckInterval = 1800 //表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时 + // sendTextMsg.Text = sendTextMsgCont + // sendTextMsg.Safe = 0 //表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0 + // sendTextMsg.EnableIdTrans = 0 //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 + // callData, err := sendTextMsg.SendMsg("kpi") + // fmt.Printf("callData------>%v--------err--------->%v\n", callData, err) + // publicmethod.Result(0, callData, c) + + // var cehui wechatstatice.RevokeMsgSend + // cehui.Msgid = "mrVtVXE39it1tWVvd57npMpx5AjKZ1VvM-pj7nMCULC0FrlcENid7lRqMZbLvltWcOzLOrKSbGUqV0ngefx2xQ" + // callData, err := cehui.RevokeMsgSendCont("kpi") + // fmt.Printf("callData------>%v--------err--------->%v\n", callData, err) + // publicmethod.Result(0, callData, c) + + //发送文本卡片 + // var cardCont wechatsendmsg.TextMsgCont + // cardCont.Content = "您的会议室已经预定,稍后会同步到`邮箱` " + // cardCont.Content = fmt.Sprintf("%v \n>**事项详情** ", cardCont.Content) + // cardCont.Content = fmt.Sprintf("%v \n>事 项:开会 ", cardCont.Content) + // cardCont.Content = fmt.Sprintf("%v \n>组织者:@miglioguan ", cardCont.Content) + // cardCont.Content = fmt.Sprintf("%v \n>参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang ", cardCont.Content) + // cardCont.Content = fmt.Sprintf("%v \n>", cardCont.Content) + // cardCont.Content = fmt.Sprintf("%v \n>会议室:广州TIT 1楼 301", cardCont.Content) + // cardCont.Content = fmt.Sprintf("%v \n>日 期:2018年5月18日 ", cardCont.Content) + // cardCont.Content = fmt.Sprintf("%v \n>时 间:上午9:00-11:00 ", cardCont.Content) + // cardCont.Content = fmt.Sprintf("%v \n>", cardCont.Content) + // cardCont.Content = fmt.Sprintf("%v \n>请准时参加会议。 ", cardCont.Content) + // cardCont.Content = fmt.Sprintf("%v \n>", cardCont.Content) + // cardCont.Content = fmt.Sprintf("%v \n>如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)", cardCont.Content) + + // var sendTextMsg wechatsendmsg.SendMarkDown + + // sendTextMsg.Touser = "KaiXinGuo" //指定接收消息的成员,成员ID列表;特殊情况:指定为"@all",则向该企业应用的全部成员发送;最多支持1000个 + // sendTextMsg.Toparty = "" //指定接收消息的部门,部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为"@all"时忽略本参数 + // sendTextMsg.Totag = "" //指定接收消息的标签,标签ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为"@all"时忽略本参数 + // sendTextMsg.Msgtype = "markdown" //消息类型 + // agentIdInt, _ := strconv.ParseInt(overall.CONSTANT_CONFIG.WechatKpi.Agentid, 10, 64) + // sendTextMsg.Agentid = agentIdInt //企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值 + // sendTextMsg.EnableDuplicateCheck = 0 //表示是否开启重复消息检查,0表示否,1表示是,默认0 + // sendTextMsg.DuplicateCheckInterval = 1800 //表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时 + // sendTextMsg.MsgBody = cardCont + // callData, err := sendTextMsg.SendMsg("kpi") + // jsonstr, _ := json.Marshal(sendTextMsg) + // fmt.Printf("callData------>%v--------err--------->%v--------->%v\n", callData, err, string(jsonstr)) + // publicmethod.Result(0, callData, c) + + //发送模板卡片 + //文本通知 + var sourceText wechatsendmsg.SourceText + sourceText.IconUrl = "https://docu.hxgk.group/images/2022_01/3f7a1120a559e9bee3991b85eb34d103.png" + sourceText.Desc = "恒信高科" + sourceText.DescColor = 1 + + var actionListCont []wechatsendmsg.ActionListCont + + var actionListContOne wechatsendmsg.ActionListCont + actionListContOne.Key = "A" + actionListContOne.Text = "接受推送" + actionListCont = append(actionListCont, actionListContOne) + var actionListContTwo wechatsendmsg.ActionListCont + actionListContTwo.Key = "B" + actionListContTwo.Text = "不再推送" + actionListCont = append(actionListCont, actionListContTwo) + var ActionMenuCont wechatsendmsg.ActionMenuCont + ActionMenuCont.Desc = "卡片副交互辅助文本说明" + ActionMenuCont.ActionList = actionListCont + + // var mainTitleCont wechatsendmsg.MainTitleCont + // mainTitleCont.Title = "一级标题一级标题一级标题\n一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题" + // mainTitleCont.Desc = "一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明一级说明" + + var quoteAreaCont wechatsendmsg.QuoteAreaCont + quoteAreaCont.Type = 1 + quoteAreaCont.Url = "http://admin.hxgk.group" + // quoteAreaCont.Title = "引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题引用文献标题" + quoteAreaCont.QuoteText = "引用文献描述引用文献描述\n引用文献描\n述引用文献描述引用文献描述\n引用文献描述引用\n文献描述引用文献描\n述引用文献描述\n引用文献描述引用文献描述引用文献描述引用文献描\n述引用文献描述引用文献描\n述引用文献描述引用文\n献描述引用文献描述引\n用文献描述引用文献描述引用\n文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述\n引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引\n用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述引用文献描述" + + // var emphasisContentInfo wechatsendmsg.EmphasisContentInfo + // emphasisContentInfo.Title = "关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题" + // emphasisContentInfo.Desc = "关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述关键数据描述" + + var horizontalContentListInfoAry []wechatsendmsg.HorizontalContentListInfo + + // var horizontalContentListInfo wechatsendmsg.HorizontalContentListInfo + // horizontalContentListInfo.KeyName = "邀请人" + // horizontalContentListInfo.Value = "张三" + // horizontalContentListInfoAry = append(horizontalContentListInfoAry, horizontalContentListInfo) + // var horizontalContentLis1 wechatsendmsg.HorizontalContentListInfo + // horizontalContentLis1.KeyName = "企业微信官网" + // horizontalContentLis1.Value = "点击访问" + // horizontalContentLis1.Type = 1 + // horizontalContentLis1.Url = "https://work.weixin.qq.com" + // horizontalContentListInfoAry = append(horizontalContentListInfoAry, horizontalContentLis1) + + // // var horizontalContentLis2 wechatsendmsg.HorizontalContentListInfo + // // horizontalContentLis2.KeyName = "企业微信下载" + // // horizontalContentLis2.Value = "企业微信.apk" + // // horizontalContentLis2.Type = 2 + // // horizontalContentLis2.MediaId = "https://work.weixin.qq.com" + // // horizontalContentListInfoAry = append(horizontalContentListInfoAry, horizontalContentLis2) + + var horizontalContentLis3 wechatsendmsg.HorizontalContentListInfo + horizontalContentLis3.KeyName = "员工信息" + horizontalContentLis3.Value = "点击查看" + horizontalContentLis3.Type = 3 + horizontalContentLis3.Userid = "KaiXinGuo" + horizontalContentListInfoAry = append(horizontalContentListInfoAry, horizontalContentLis3) + + var jumpListContList []wechatsendmsg.JumpListCont + + var jumpList1 wechatsendmsg.JumpListCont + jumpList1.Type = 1 + jumpList1.Title = "企业微信官网===>" + jumpList1.Url = "https://work.weixin.qq.com" + jumpListContList = append(jumpListContList, jumpList1) + + // // var jumpList2 wechatsendmsg.JumpListCont + // // jumpList2.Type = 2 + // // jumpList2.Title = "跳转小程序" + // // jumpList2.Appid = "小程序的appid" + // // jumpList2.PagePath = "/index.html" + // // jumpListContList = append(jumpListContList, jumpList2) + + var cardActionContStr wechatsendmsg.CardActionCont + cardActionContStr.Type = 1 + cardActionContStr.Url = "http://www.baidu.com" + + // uuId := publicmethod.GetUUid(5) + // var tempCardContText wechatsendmsg.TemplateCardContText + // tempCardContText.CardType = "text_notice" + // tempCardContText.Source = sourceText + // tempCardContText.ActionMenu = ActionMenuCont + // uuIdsStr := strconv.FormatInt(uuId, 10) + // tempCardContText.TaskId = fmt.Sprintf("KPI_%v", uuIdsStr) + // tempCardContText.MainTitle = mainTitleCont + // tempCardContText.QuoteArea = quoteAreaCont + // tempCardContText.EmphasisContent = emphasisContentInfo + // tempCardContText.SubTitleText = "二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段二级文本单一字段" + // tempCardContText.HorizontalContentList = horizontalContentListInfoAry + // tempCardContText.JumpList = jumpListContList + // tempCardContText.CardAction = cardActionContStr + + // var sendTextTempl wechatsendmsg.SendTextNoticeAll + // sendTextTempl.Touser = "KaiXinGuo" //指定接收消息的成员,成员ID列表;特殊情况:指定为"@all",则向该企业应用的全部成员发送;最多支持1000个 + // sendTextTempl.Toparty = "" //指定接收消息的部门,部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为"@all"时忽略本参数 + // sendTextTempl.Totag = "" //指定接收消息的标签,标签ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为"@all"时忽略本参数 + // sendTextTempl.Msgtype = "template_card" //消息类型 + // agentIdInt, _ := strconv.ParseInt(overall.CONSTANT_CONFIG.WechatKpi.Agentid, 10, 64) + // sendTextTempl.Agentid = agentIdInt + // sendTextTempl.EnableDuplicateCheck = 0 + // sendTextTempl.DuplicateCheckInterval = 1800 + // sendTextTempl.TemplateCard = tempCardContText + // sendTextTempl.EnableIdTrans = 0 + + // callData, err := sendTextTempl.SendMsg("kpi") + // jsonstr, _ := json.Marshal(sendTextTempl) + // fmt.Printf("callData------>%v--------err--------->%v--------->%v\n", callData, err, string(jsonstr)) + // publicmethod.Result(0, callData, c) + + var mainTitleCont wechatsendmsg.MainTitleCont + mainTitleCont.Title = "关键数据标\n题关键数据标题关键数据\n标题关键数据标题关\n键数据标题关键数据标题关\n键数据标题\n关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据\n标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题关键数据标题" + + var imageTextAreaCont wechatsendmsg.ImageTextAreaCont + imageTextAreaCont.Type = 1 + imageTextAreaCont.Url = "https://work.weixin.qq.com" + imageTextAreaCont.Title = "企业微信的左图右文样式" + imageTextAreaCont.Desc = "企业微信真好用呀真好用" + imageTextAreaCont.ImageUrl = "https://img.iplaysoft.com/wp-content/uploads/2019/free-images/free_stock_photo_2x.jpg" + + var cardImageCont wechatsendmsg.CardImageCont + cardImageCont.Url = "https://docu.hxgk.group/images/2022_01/3f7a1120a559e9bee3991b85eb34d103.png" + cardImageCont.AspectRatio = 2.2 + + var verticalContentListCont wechatsendmsg.VerticalContentListCont + verticalContentListCont.Title = "惊喜红包等你来拿" + verticalContentListCont.Desc = "下载企业微信还能抢红包!" + + var optionListContList []wechatsendmsg.OptionListCont + var optionListCont1 wechatsendmsg.OptionListCont + optionListCont1.Id = "btn_selection_id1" + optionListCont1.Text = "100分" + optionListContList = append(optionListContList, optionListCont1) + var optionListCont2 wechatsendmsg.OptionListCont + optionListCont2.Id = "btn_selection_id2" + optionListCont2.Text = "101分" + optionListContList = append(optionListContList, optionListCont2) + + var buttonSelectionCont wechatsendmsg.ButtonSelectionCont + buttonSelectionCont.QuestionKey = "btn_question_key1" + buttonSelectionCont.Title = "企业微信评分" + buttonSelectionCont.SelectedId = "btn_selection_id1" + buttonSelectionCont.OptionList = optionListContList + + var optionListContList1 []wechatsendmsg.OptionListCont + var optionListCont11 wechatsendmsg.OptionListCont + optionListCont11.Id = "btn_selection_id12" + optionListCont11.Text = "100" + optionListContList1 = append(optionListContList1, optionListCont11) + var optionListCont12 wechatsendmsg.OptionListCont + optionListCont12.Id = "btn_selection_id22" + optionListCont12.Text = "101" + optionListContList1 = append(optionListContList1, optionListCont12) + + var buttonSelectionCont1 wechatsendmsg.ButtonSelectionCont + buttonSelectionCont1.QuestionKey = "btn_question_key12" + buttonSelectionCont1.Title = "评分" + buttonSelectionCont1.SelectedId = "btn_selection_id12" + buttonSelectionCont1.OptionList = optionListContList1 + + var buttonSelectionContList []wechatsendmsg.ButtonSelectionCont + + buttonSelectionContList = append(buttonSelectionContList, buttonSelectionCont) + buttonSelectionContList = append(buttonSelectionContList, buttonSelectionCont1) + var buttonList []wechatsendmsg.ButtonListCont + + var buttonList1 wechatsendmsg.ButtonListCont + buttonList1.Text = "按钮1" + buttonList1.Style = 1 + buttonList1.Key = "button_key_1" + buttonList = append(buttonList, buttonList1) + + var buttonList2 wechatsendmsg.ButtonListCont + buttonList2.Text = "按钮2" + buttonList2.Style = 2 + buttonList2.Key = "button_key_2" + buttonList = append(buttonList, buttonList2) + + var OptionListContCheckBoxList []wechatsendmsg.OptionListContCheckBox + + var OptionListContCheckBox1 wechatsendmsg.OptionListContCheckBox + OptionListContCheckBox1.Id = "option_id1" + OptionListContCheckBox1.Text = "选择题选项1" + OptionListContCheckBox1.IsChecked = true + OptionListContCheckBoxList = append(OptionListContCheckBoxList, OptionListContCheckBox1) + var OptionListContCheckBox2 wechatsendmsg.OptionListContCheckBox + OptionListContCheckBox2.Id = "option_id2" + OptionListContCheckBox2.Text = "选择题选项2" + OptionListContCheckBox2.IsChecked = false + OptionListContCheckBoxList = append(OptionListContCheckBoxList, OptionListContCheckBox2) + + var checkBoxCont wechatsendmsg.CheckBoxCont + checkBoxCont.QuestionKey = "question_key1" + checkBoxCont.Mode = 1 + checkBoxCont.OptionList = OptionListContCheckBoxList + + var submitButton wechatsendmsg.ActionListCont + submitButton.Text = "提交" + submitButton.Key = "key" + + uuId := publicmethod.GetUUid(5) + + var sendCont wechatsendmsg.TemMultipleInteraction + sendCont.CardType = "multiple_interaction" + sendCont.Source = sourceText + // sendCont.ActionMenu = ActionMenuCont + sendCont.TaskId = fmt.Sprintf("KPI_%v", uuId) + sendCont.MainTitle = mainTitleCont + // sendCont.QuoteArea = quoteAreaCont + + // sendCont.SubTitleText = quoteAreaCont.QuoteText + // sendCont.ButtonSelection = buttonSelectionCont + // sendCont.ButtonList = buttonList + // sendCont.ImageTextArea = imageTextAreaCont + // sendCont.CardImage = cardImageCont + // sendCont.VerticalContentList = verticalContentListCont + + // sendCont.CardAction = cardActionContStr + // sendCont.HorizontalContentList = horizontalContentListInfoAry + // sendCont.JumpList = jumpListContList + + sendCont.SelectList = buttonSelectionContList + sendCont.SubmitButton = submitButton + + var sendTextTempl wechatsendmsg.SendMultipleInteraction + sendTextTempl.Touser = "KaiXinGuo" //指定接收消息的成员,成员ID列表;特殊情况:指定为"@all",则向该企业应用的全部成员发送;最多支持1000个 + sendTextTempl.Toparty = "" //指定接收消息的部门,部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为"@all"时忽略本参数 + sendTextTempl.Totag = "" //指定接收消息的标签,标签ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为"@all"时忽略本参数 + sendTextTempl.Msgtype = "template_card" //消息类型 + agentIdInt, _ := strconv.ParseInt(overall.CONSTANT_CONFIG.WechatKpi.Agentid, 10, 64) + sendTextTempl.Agentid = agentIdInt + sendTextTempl.EnableDuplicateCheck = 0 + sendTextTempl.DuplicateCheckInterval = 1800 + sendTextTempl.TemplateCard = sendCont + sendTextTempl.EnableIdTrans = 0 + + callData, err := sendTextTempl.SendMsg("kpi") + jsonstr, _ := json.Marshal(sendTextTempl) + fmt.Printf("callData------>%v--------err--------->%v--------->%v\n", callData, err, string(jsonstr)) + publicmethod.Result(0, callData, c) } // 校正关联维度 diff --git a/api/version1/entry.go b/api/version1/entry.go index ca9b083..7db1163 100644 --- a/api/version1/entry.go +++ b/api/version1/entry.go @@ -5,6 +5,7 @@ import ( "key_performance_indicators/api/version1/departmentseting/departmentpc" "key_performance_indicators/api/version1/departmentseting/departmentweb" "key_performance_indicators/api/version1/empower" + "key_performance_indicators/api/version1/flowchart" "key_performance_indicators/api/version1/honoraryArchives" "key_performance_indicators/api/version1/jurisdiction/jurisdictionpc" "key_performance_indicators/api/version1/postseting/postpc" @@ -20,6 +21,7 @@ type ApiEntry struct { BookImg bookimg.ApiMethod //图文信息管理 JurisdictionpcApi jurisdictionpc.ApiMethod //权限模块PC端 EmpowerApi empower.ApiMethod //系统授权 + WorkFlowChat flowchart.ApiMethod } var AppApiEntry = new(ApiEntry) diff --git a/api/version1/flowchart/entry.go b/api/version1/flowchart/entry.go new file mode 100644 index 0000000..a6106e6 --- /dev/null +++ b/api/version1/flowchart/entry.go @@ -0,0 +1,25 @@ +package flowchart + +import ( + "key_performance_indicators/overall/publicmethod" + + "github.com/gin-gonic/gin" +) + +// 工作流入口 +type ApiMethod struct{} + +// 系统授权配置 +func (a *ApiMethod) Index(c *gin.Context) { + outputCont := publicmethod.MapOut[string]() + outputCont["index"] = "工作流入口" + publicmethod.Result(0, outputCont, c) +} + +// 审批工作流全图 +type ReviewFlow struct { + publicmethod.PublicId //考核项目ID + IsCorrection int `json:"iscorrection"` //是否整改 1:不整改;2:整改 + PlusReduction int `json:"plusreduction"` //加减分 1:减少;2:增加; + PeopleList []string `json:"peopleList"` //被测评的人userKey +} diff --git a/api/version1/flowchart/flow.go b/api/version1/flowchart/flow.go new file mode 100644 index 0000000..f68365c --- /dev/null +++ b/api/version1/flowchart/flow.go @@ -0,0 +1,370 @@ +package flowchart + +import ( + "key_performance_indicators/models/modelshr" + "key_performance_indicators/models/modelskpi" + "key_performance_indicators/overall" + "key_performance_indicators/overall/publicmethod" + "strconv" + "time" + + "github.com/gin-gonic/gin" +) + +// 生成审批流程流 +func (a *ApiMethod) ReviewWorkFlow(c *gin.Context) { + //获取登录人信息 + context, err := publicmethod.LoginMyCont(c) + if err != nil { + publicmethod.Result(1, err, c, "未知身份!不可操作!") + return + } + var receivedValue ReviewFlow + c.ShouldBindJSON(&receivedValue) + if receivedValue.Id == "" { + publicmethod.Result(1, receivedValue, c, "参数错误!") + return + } + if receivedValue.IsCorrection == 0 { + receivedValue.IsCorrection = 2 + } + if len(receivedValue.PeopleList) < 1 { + publicmethod.Result(1, receivedValue, c, "未知被考核人!请指定!") + return + } + //获取考核项性质 + var qualEvalScheme modelskpi.QualitativeEvaluationScheme + err = qualEvalScheme.GetCont(map[string]interface{}{"id": receivedValue.Id}) + if err != nil { + publicmethod.Result(107, err, c) + return + } + //抄送人 + var sendCopyMan []publicmethod.UserListFlowAll + //流程图 + var flowMap []publicmethod.FlowChartList + endStep := 3 + //第一步:创建 + var begin publicmethod.FlowChartList + begin.Step = 1 //步伐 + begin.NodeName = publicmethod.GetSetpName(1) //节点名称 + begin.State = 2 //状态 1、不点亮;2、点亮 + begin.Class = 1 //节点类型 1、普通节点;2、运行中指定节点 + begin.RunType = 1 + beginUserList := append(begin.UserList, GetApproveUser(context.Wechat, context.WorkWechat)) + for _, bv := range beginUserList { + begin.UserList = append(begin.UserList, bv) + if receivedValue.IsCorrection == 1 { + sendCopyMan = append(sendCopyMan, bv) + } + } + + flowMap = append(flowMap, begin) + + //第二步:本部门负责人审批 + var stepTwo publicmethod.FlowChartList + stepTwo.Step = 2 //步伐 + stepTwo.NodeName = publicmethod.GetSetpName(2) //节点名称 + stepTwo.State = 1 //状态 1、不点亮;2、点亮 + stepTwo.Class = 1 //节点类型 1、普通节点;2、运行中指定节点 + if receivedValue.IsCorrection != 1 { + stepTwo.RunType = 2 + } else { + stepTwo.RunType = 3 + } + //获取审批人weChatOpenID + sendUserList, userErr := publicmethod.GetRefereeTeamWorkWechat(16182159043990656, context.MainDeparment) + if userErr == nil { + for iu := 0; iu < len(sendUserList); iu++ { + departListUser := GetApproveUser(sendUserList[iu], sendUserList[iu]) + stepTwo.UserList = append(stepTwo.UserList, departListUser) + if receivedValue.IsCorrection != 1 { + sendCopyMan = append(sendCopyMan, departListUser) + } + } + } + + flowMap = append(flowMap, stepTwo) + + if qualEvalScheme.Attribute == 1 { + //定性 + if receivedValue.IsCorrection != 1 { + //整改措施提交人 + var stepThree publicmethod.FlowChartList + stepThree.Step = 3 //步伐 + stepThree.NodeName = publicmethod.GetSetpName(4) //节点名称 + stepThree.State = 1 //状态 1、不点亮;2、点亮 + stepThree.Class = 2 //节点类型 1、普通节点;2、运行中指定节点 + stepThree.RunType = 2 + //主要责任人负责提交整改措施 + if len(receivedValue.PeopleList) > 0 { + for ipv := 0; ipv < len(receivedValue.PeopleList); ipv++ { + var myUsCont modelshr.PersonArchives + meErr := myUsCont.GetCont(map[string]interface{}{"`key": receivedValue.PeopleList[ipv]}, "`wechat`", "`work_wechat`") + if meErr == nil { + appManList := GetApproveUser(myUsCont.Wechat, myUsCont.WorkWechat) + stepThree.UserList = append(stepThree.UserList, appManList) + sendCopyMan = append(sendCopyMan, appManList) + } + } + } + flowMap = append(flowMap, stepThree) + //发起人验收 + var stepFour publicmethod.FlowChartList + stepFour.Step = 4 + stepFour.NodeName = publicmethod.GetSetpName(5) + stepFour.State = 1 + stepFour.Class = 1 + stepFour.RunType = 2 + stepFour.UserList = append(stepFour.UserList, GetApproveUser(context.Wechat, context.WorkWechat)) + flowMap = append(flowMap, stepFour) + endStep = 5 + } else { + if len(receivedValue.PeopleList) > 0 { + for ipv := 0; ipv < len(receivedValue.PeopleList); ipv++ { + var myUsCont modelshr.PersonArchives + meErr := myUsCont.GetCont(map[string]interface{}{"`key": receivedValue.PeopleList[ipv]}, "`wechat`", "`work_wechat`") + if meErr == nil { + appManList := GetApproveUser(myUsCont.Wechat, myUsCont.WorkWechat) + sendCopyMan = append(sendCopyMan, appManList) + } + } + } + } + } + //抄送 + var stepCopy publicmethod.FlowChartList + stepCopy.Step = endStep + stepCopy.NodeName = publicmethod.GetSetpName(6) + stepCopy.State = 1 + stepCopy.Class = 1 + stepCopy.RunType = 3 + stepCopy.UserList = sendCopyMan + flowMap = append(flowMap, stepCopy) + publicmethod.Result(0, flowMap, c) +} + +/* +* +@ 作者: 秦东 +@ 时间: 2022-10-01 09:50:09 +@ 功能: 获取人员信息 +@ 参数 + + #wechat 微信Openid + #workWechat 企业微信ID + +@ 返回值 + + #userCont 人员信息 +*/ +func GetApproveUser(wechat, workWechat string) (userCont publicmethod.UserListFlowAll) { + openId := wechat + if workWechat != "" { + openId = workWechat + } + var myCont modelshr.PersonArchives + err := overall.CONSTANT_DB_HR.Where("`wechat` = ? OR `work_wechat` = ?", openId, openId).First(&myCont).Error + if err == nil { + userCont.Id = strconv.FormatInt(myCont.Id, 10) //操作人ID + userCont.Name = myCont.Name //操作人姓名 + userCont.Icon = myCont.Icon //操作人头像 + userCont.Wechat = wechat //微信Openid + if workWechat != "" { + userCont.Wechat = workWechat + } + userCont.Company = myCont.Company //集团公司 + if myCont.Company != 0 { + var companyCont modelshr.AdministrativeOrganization + companyCont.GetCont(map[string]interface{}{"`id`": myCont.Company}, "`name`") + userCont.CompanyName = companyCont.Name //分厂名称 + } + + userCont.DepartmentId = myCont.MainDeparment //分厂Id + if myCont.MainDeparment != 0 { + var departmentCont modelshr.AdministrativeOrganization + departmentCont.GetCont(map[string]interface{}{"`id`": myCont.MainDeparment}, "`name`") + userCont.DepartmentName = departmentCont.Name //分厂名称 + } + + userCont.WorkshopId = myCont.AdminOrg //工段Id + if myCont.AdminOrg != 0 { + var adminOrgCont modelshr.AdministrativeOrganization + adminOrgCont.GetCont(map[string]interface{}{"`id`": myCont.AdminOrg}, "`name`") + userCont.WorkshopName = adminOrgCont.Name //工段名称 + } + + userCont.PostId = myCont.JobId //职务Id + if myCont.JobId != 0 { + var dutiesCont modelshr.Duties + dutiesCont.GetCont(map[string]interface{}{"`id`": myCont.JobId}, "`name`") + userCont.PostName = dutiesCont.Name //职务名称 + } + userCont.Tema = myCont.TeamId //班组Id + if myCont.TeamId != 0 { + var teamCont modelshr.TeamGroup + teamCont.GetCont(map[string]interface{}{"`id`": myCont.TeamId}, "`name`") + userCont.TemaName = teamCont.Name //班组名称 + } + + } + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2022-10-01 15:11:56 +@ 功能: 创建流程图 +@ 参数 + + #founderWechat 发起人微信或企业微信Openid + #founderDepartment 发起人部门 + #reviewFlowParameter 创建流程参数 + #isAdd 1:创建;2:其他 + +@ 返回值 + + #flowMap 工作流 + #err 系统信息 +*/ +func SetUpWorkFlow(founderWechat string, founderDepartment int64, reviewFlowParameter ReviewFlow, isAdd int) (flowMap []publicmethod.FlowChartList, err error) { + if reviewFlowParameter.IsCorrection == 0 { + reviewFlowParameter.IsCorrection = 2 + } + if len(reviewFlowParameter.PeopleList) < 1 { + return + } + //获取考核项性质 + var qualEvalScheme modelskpi.QualitativeEvaluationScheme + err = qualEvalScheme.GetCont(map[string]interface{}{"id": reviewFlowParameter.Id}) + if err != nil { + return + } + //抄送人 + var sendCopyMan []publicmethod.UserListFlowAll + var isTureCopyMan []string + //流程图 + // var flowMap []publicmethod.FlowChartList + endStep := 1 + //第一步:创建 + var begin publicmethod.FlowChartList + begin.Step = endStep //步伐 + begin.NodeName = publicmethod.GetSetpName(1) //节点名称 + begin.State = 2 //状态 1、不点亮;2、点亮 + begin.Class = 1 //节点类型 1、普通节点;2、运行中指定节点 + begin.RunType = 1 //运行状态(1:开始;2:操作点;3:结束) + beginUserList := append(begin.UserList, GetApproveUser(founderWechat, founderWechat)) + for _, bv := range beginUserList { + if isAdd == 1 { + var setLogList publicmethod.LogList + setLogList.State = 2 + setLogList.TimeVal = publicmethod.UnixTimeToDay(time.Now().Unix(), 1) + bv.LogList = append(bv.LogList, setLogList) + } + begin.UserList = append(begin.UserList, bv) + if reviewFlowParameter.IsCorrection == 1 { + sendCopyMan = append(sendCopyMan, bv) + isTureCopyMan = append(isTureCopyMan, bv.Id) + } + } + + flowMap = append(flowMap, begin) + + //第二步:本部门负责人审批 + endStep = endStep + 1 + var stepTwo publicmethod.FlowChartList + stepTwo.Step = endStep //步伐 + stepTwo.NodeName = publicmethod.GetSetpName(2) //节点名称 + stepTwo.State = 1 //状态 1、不点亮;2、点亮 + stepTwo.Class = 1 //节点类型 1、普通节点;2、运行中指定节点 + if reviewFlowParameter.IsCorrection == 1 { + stepTwo.RunType = 3 + } else { + stepTwo.RunType = 2 + } + //获取审批人weChatOpenID + sendUserList, userErr := publicmethod.GetRefereeTeamWorkWechat(16182159043990656, founderDepartment) + if userErr == nil { + for iu := 0; iu < len(sendUserList); iu++ { + departListUser := GetApproveUser(sendUserList[iu], sendUserList[iu]) + stepTwo.UserList = append(stepTwo.UserList, departListUser) + if reviewFlowParameter.IsCorrection != 1 { + + if publicmethod.IsInTrue[string](departListUser.Id, isTureCopyMan) == false { + sendCopyMan = append(sendCopyMan, departListUser) + isTureCopyMan = append(isTureCopyMan, departListUser.Id) + } + } + } + } + + flowMap = append(flowMap, stepTwo) + + if qualEvalScheme.Attribute == 1 { + //定性 + if reviewFlowParameter.IsCorrection != 1 { + //整改措施提交人 + endStep = endStep + 1 + var stepThree publicmethod.FlowChartList + stepThree.Step = endStep //步伐 + stepThree.NodeName = publicmethod.GetSetpName(4) //节点名称 + stepThree.State = 1 //状态 1、不点亮;2、点亮 + stepThree.Class = 2 //节点类型 1、普通节点;2、运行中指定节点 + stepThree.RunType = 2 + //主要责任人负责提交整改措施 + if len(reviewFlowParameter.PeopleList) > 0 { + for ipv := 0; ipv < len(reviewFlowParameter.PeopleList); ipv++ { + var myUsCont modelshr.PersonArchives + meErr := myUsCont.GetCont(map[string]interface{}{"`key": reviewFlowParameter.PeopleList[ipv]}, "`wechat`", "`work_wechat`") + if meErr == nil { + appManList := GetApproveUser(myUsCont.Wechat, myUsCont.WorkWechat) + stepThree.UserList = append(stepThree.UserList, appManList) + + if publicmethod.IsInTrue[string](appManList.Id, isTureCopyMan) == false { + isTureCopyMan = append(isTureCopyMan, appManList.Id) + sendCopyMan = append(sendCopyMan, appManList) + } + } + } + } + flowMap = append(flowMap, stepThree) + //发起人验收 + endStep = endStep + 1 + var stepFour publicmethod.FlowChartList + stepFour.Step = endStep + stepFour.NodeName = publicmethod.GetSetpName(5) + stepFour.State = 1 + stepFour.Class = 1 + stepFour.RunType = 3 + stepFour.UserList = append(stepFour.UserList, GetApproveUser(founderWechat, founderWechat)) + flowMap = append(flowMap, stepFour) + // endStep = 5 + } else { + if len(reviewFlowParameter.PeopleList) > 0 { + for ipv := 0; ipv < len(reviewFlowParameter.PeopleList); ipv++ { + var myUsCont modelshr.PersonArchives + meErr := myUsCont.GetCont(map[string]interface{}{"`key": reviewFlowParameter.PeopleList[ipv]}, "`wechat`", "`work_wechat`") + if meErr == nil { + appManList := GetApproveUser(myUsCont.Wechat, myUsCont.WorkWechat) + + if publicmethod.IsInTrue[string](appManList.Id, isTureCopyMan) == false { + isTureCopyMan = append(isTureCopyMan, appManList.Id) + sendCopyMan = append(sendCopyMan, appManList) + } + } + } + } + } + } + //抄送 + endStep = endStep + 1 + var stepCopy publicmethod.FlowChartList + stepCopy.Step = endStep + stepCopy.NodeName = publicmethod.GetSetpName(6) + stepCopy.State = 1 + stepCopy.Class = 1 + stepCopy.UserList = sendCopyMan + flowMap = append(flowMap, stepCopy) + return +} diff --git a/api/version1/postseting/postpc/scheme.go b/api/version1/postseting/postpc/scheme.go index 971e7a4..a0db706 100644 --- a/api/version1/postseting/postpc/scheme.go +++ b/api/version1/postseting/postpc/scheme.go @@ -518,6 +518,7 @@ func postSchemeTargetPost(versionNumber string, source, judgeState int, scheme [ saveData.CensorType = "2" //检查方式(1:现场检查;2:资料检查;3:事件触发)"` saveData.Source = source //来源(1:岗位;2:部门引用)"` saveData.RunState = cv.State //运行状态(1:启用;2:禁用;3:观察) + saveNewData = append(saveNewData, saveData) } @@ -599,6 +600,7 @@ func (p *postShemeListCont) eidtPostSchemeInfo(versionNumber string, companyId, eidtTargetCont["`punishmode`"] = v.Punishmode eidtTargetCont["`maxmoney`"] = v.Maxmoney eidtTargetCont["`minmoney`"] = v.Minmoney + eidtTargetCont["`add_reduce`"] = v.AddReduce saveData.EiteCont(map[string]interface{}{"`id`": saveData.Id}, eidtTargetCont) fmt.Printf("judgeLianErr--------->%v\n", saveData) @@ -625,10 +627,10 @@ func (p *postShemeListCont) eidtPostSchemeInfo(versionNumber string, companyId, saveData.CensorType = "2" //检查方式(1:现场检查;2:资料检查;3:事件触发)"` saveData.Source = 1 //来源(1:岗位;2:部门引用)"` saveData.RunState = runState //运行状态(1:启用;2:禁用;3:观察) - - saveData.Punishmode = v.Punishmode //处罚方式 1:扣分;2:现金处罚;3:扣分加现金 - saveData.Maxmoney = v.Maxmoney //最高罚款 - saveData.Minmoney = v.Minmoney //最低罚款 + saveData.Punishmode = v.Punishmode //处罚方式 1:扣分;2:现金处罚;3:扣分加现金 + saveData.Maxmoney = v.Maxmoney //最高罚款 + saveData.Minmoney = v.Minmoney //最低罚款 + saveData.AddReduce = v.AddReduce //1:减少;2:增加;3:无属性,现场确认加或减"` p.shememList = append(p.shememList, saveData) fmt.Printf("judgeLianErr----saveData----->%v\n", saveData) } diff --git a/api/version1/postseting/postweb/postration.go b/api/version1/postseting/postweb/postration.go index e9c83a6..9050932 100644 --- a/api/version1/postseting/postweb/postration.go +++ b/api/version1/postseting/postweb/postration.go @@ -3,6 +3,8 @@ package postweb import ( "encoding/json" "fmt" + "key_performance_indicators/api/version1/flowchart" + "key_performance_indicators/middleware/wechatapp/wechatsendmsg" "key_performance_indicators/models/modelshr" "key_performance_indicators/models/modelskpi" "key_performance_indicators/overall" @@ -194,9 +196,12 @@ func (a *ApiMethod) SubmitRationPostCont(c *gin.Context) { publicmethod.Result(107, err, c) return } + //获取指标单位 + var targetUnit modelskpi.PostTarget + overall.CONSTANT_DB_KPI.Model(&modelskpi.PostTarget{}).Select("unit").Where(map[string]interface{}{"`id`": postShemeCont.TargetId}).First(&targetUnit) //获取被考核人基本信息 var userCont modelshr.PersonArchives - err = userCont.GetCont(map[string]interface{}{"`key`": receivedValue.PersonLiable}, "`company`", "`maindeparment`", "`admin_org`", "`position`") + err = userCont.GetCont(map[string]interface{}{"`key`": receivedValue.PersonLiable}, "`company`", "`maindeparment`", "`admin_org`", "`position`,`wechat`,`work_wechat`") if err != nil { publicmethod.Result(107, err, c) return @@ -206,12 +211,41 @@ func (a *ApiMethod) SubmitRationPostCont(c *gin.Context) { uuId := publicmethod.GetUUid(1) + //生成工作流 + wechatOpenId := context.Wechat + if context.WorkWechat != "" { + wechatOpenId = context.WorkWechat + } + var reviewFlowCont flowchart.ReviewFlow + reviewFlowCont.Id = receivedValue.Id + reviewFlowCont.IsCorrection = 1 + reviewFlowCont.PlusReduction = 1 + reviewFlowCont.PeopleList = append(reviewFlowCont.PeopleList, receivedValue.PersonLiable) + flowMap, _ := flowchart.SetUpWorkFlow(wechatOpenId, context.MainDeparment, reviewFlowCont, 1) + + var sendUserList []string + var sendTitle string + //获取下一个节点审批人 + for _, v := range flowMap { + if v.Step == 2 { + sendTitle = v.NodeName + for _, vu := range v.UserList { + // fmt.Printf("vu------------>%v\n", vu) + if publicmethod.IsInTrue[string](vu.Wechat, sendUserList) == false { + sendUserList = append(sendUserList, vu.Wechat) + } + } + + } + } + addTime := time.Now().Unix() //流程列表 var flowCont modelskpi.PostWorkflowOrders - flowCont.OrderId = uuId //审批单ID"` - flowCont.Step = 1 //当前执行到第几步"` - flowCont.NextStep = 2 //下一步执行哪个步骤"` - flowCont.WorkFlow = "" //工作流(审批json字符串)"` + flowCont.OrderId = uuId //审批单ID"` + flowCont.Step = 1 //当前执行到第几步"` + flowCont.NextStep = 2 //下一步执行哪个步骤"` + flowMapJson, _ := json.Marshal(flowMap) + flowCont.WorkFlow = string(flowMapJson) //工作流(审批json字符串)"` flowCont.CompanyId = userCont.Company //公司"` flowCont.DepartmentId = userCont.MainDeparment //部门"` flowCont.OrgId = userCont.AdminOrg //行政组织"` @@ -224,8 +258,8 @@ func (a *ApiMethod) SubmitRationPostCont(c *gin.Context) { flowCont.Executor = context.Key //执行人"` flowCont.ExecutorDepartment = context.MainDeparment //执行人部门"` flowCont.State = 3 //流程状态 1:草稿;2:驳回;3:审批中;4:归档;5:废弃;6:删除"` - flowCont.StartTime = time.Now().Unix() //流程开始时间"` - flowCont.Time = time.Now().Unix() //时间"` + flowCont.StartTime = addTime //流程开始时间"` + flowCont.Time = addTime //时间"` if len(receivedValue.Enclosure) > 0 { jsonFileList, _ := json.Marshal(receivedValue.Enclosure) flowCont.EnclosureFormat = string(jsonFileList) //附件"` @@ -265,7 +299,7 @@ func (a *ApiMethod) SubmitRationPostCont(c *gin.Context) { postMeterFlow.Executor = context.Key //执行人"` postMeterFlow.ExecutorDepartment = context.MainDeparment //执行人部门"` postMeterFlow.HappenTime = currentTime //发生时间"` - postMeterFlow.Time = time.Now().Unix() //时间"` + postMeterFlow.Time = addTime //时间"` baseLineJson, _ := json.Marshal(baseLine) postMeterFlow.Baseline = string(baseLineJson) //基准线"` @@ -273,14 +307,122 @@ func (a *ApiMethod) SubmitRationPostCont(c *gin.Context) { if receivedValue.ScoringMethod != 1 { postMeterFlow.ScoringScore = receivedValue.ScoringScore * 100 //手动分 } + //开启事务提交 - gormDbAffair := overall.CONSTANT_DB_KPI + gormDbAffair := overall.CONSTANT_DB_KPI.Begin() passorErr := gormDbAffair.Create(&flowCont).Error flowErr := gormDbAffair.Create(&postMeterFlow).Error + // openAppChangeErr := gormDbAffair.Create(&openAppChangeLog).Error if passorErr == nil && flowErr == nil { addErr := gormDbAffair.Commit().Error publicmethod.Result(0, addErr, c) + + // fmt.Printf("callData---2--->%v--------err--------->%v--------->%v\n", sendUserList, sendTitle, flowMap) + if len(sendUserList) > 0 { + //项下一个审批节点发送审批通知 + //头部信息 + var sourceText wechatsendmsg.SourceText + sourceText.IconUrl = "https://docu.hxgk.group/images/2022_01/3f7a1120a559e9bee3991b85eb34d103.png" + sourceText.Desc = fmt.Sprintf("恒信高科-%v", sendTitle) + sourceText.DescColor = 1 + + //引用文献 + var quoteAreaInfo wechatsendmsg.QuoteAreaCont + quoteAreaInfo.Type = 0 + quoteAreaInfo.Title = "数据详细" + quoteAreaInfo.QuoteText = fmt.Sprintf("数值:%v%v\n备注:%v", receivedValue.Score, targetUnit.Unit, receivedValue.Reason) + //按钮 + var buttonList []wechatsendmsg.ButtonListCont + var buttonList1 wechatsendmsg.ButtonListCont + buttonList1.Text = "批准" + buttonList1.Style = 1 + buttonList1.Key = fmt.Sprintf("KPI_post_%v_%v_%v", uuId, 1, 1) + buttonList = append(buttonList, buttonList1) + var buttonList2 wechatsendmsg.ButtonListCont + buttonList2.Text = "驳回" + buttonList2.Style = 3 + buttonList2.Key = fmt.Sprintf("KPI_post_%v_%v_%v", uuId, 2, 1) + buttonList = append(buttonList, buttonList2) + //二级标题+文本列表 + var twoTitleTextList []wechatsendmsg.HorizontalContentListInfo + //发送人 + var horizontalContentLis3 wechatsendmsg.HorizontalContentListInfo + horizontalContentLis3.KeyName = "申请人" + horizontalContentLis3.Value = "点击查看" + horizontalContentLis3.Type = 3 + horizontalContentLis3.Userid = wechatOpenId + twoTitleTextList = append(twoTitleTextList, horizontalContentLis3) + //被考核人 + if userCont.Wechat != "" || userCont.WorkWechat != "" { + weChatStrs := userCont.Wechat + if userCont.WorkWechat != "" { + weChatStrs = userCont.WorkWechat + } + var twoTitleTextCont wechatsendmsg.HorizontalContentListInfo + twoTitleTextCont.KeyName = "被考核人:" + twoTitleTextCont.Value = "点击查看" + twoTitleTextCont.Type = 3 + twoTitleTextCont.Userid = weChatStrs + twoTitleTextList = append(twoTitleTextList, twoTitleTextCont) + } + //卡片跳转地址 + var cardActionContStr wechatsendmsg.CardActionCont + cardActionContStr.Type = 1 + cardActionContStr.Url = fmt.Sprintf("http://new.hxgk.group/#/quantitativeList?id=%v", uuId) + + var sendButtionMsg wechatsendmsg.SendButtonInteractionSimplify + // sendButtionMsg.Touser = strings.Join(sendUserList, "|") + sendButtionMsg.Touser = "KaiXinGuo" //指定接收消息的成员,成员ID列表;特殊情况:指定为 + sendButtionMsg.Msgtype = "template_card" + agentIdInt, _ := strconv.ParseInt(overall.CONSTANT_CONFIG.WechatKpi.Agentid, 10, 64) + sendButtionMsg.Agentid = agentIdInt + sendButtionMsg.EnableDuplicateCheck = 0 + sendButtionMsg.DuplicateCheckInterval = 1800 + sendButtionMsg.EnableIdTrans = 0 + sendButtionMsg.TemplateCard.CardType = "button_interaction" + sendButtionMsg.TemplateCard.Source = sourceText + sendButtionMsg.TemplateCard.TaskId = fmt.Sprintf("KPI_%v", uuId) + sendButtionMsg.TemplateCard.MainTitle.Title = postShemeCont.Title + sendButtionMsg.TemplateCard.MainTitle.Desc = postShemeCont.Content + sendButtionMsg.TemplateCard.QuoteArea = quoteAreaInfo + // sendButtionMsg.TemplateCard.SubTitleText = fmt.Sprintf("") + sendButtionMsg.TemplateCard.ButtonList = buttonList + sendButtionMsg.TemplateCard.HorizontalContentList = twoTitleTextList + sendButtionMsg.TemplateCard.CardAction = cardActionContStr + // sendButtionMsg.SendMsg("kpi") + callData, err := sendButtionMsg.SendMsg("kpi") + if err == nil { + if callData.Errcode == 0 { + // var operatorIsTrueCont modelskpi.OperatorIsTrue + // operatorIsTrueCont.OrderId = uuId //订单ID"` + // operatorIsTrueCont.Step = 1 //审批到第几步"` + // operatorIsTrueCont.State = 1 //:状态:1:可操作;2:不可操作"` + // operatorIsTrueCont.Time = addTime //操作时间"` + // operatorIsTrueCont.Msgid = callData.Msgid //:消息id,用于撤回应用消息"` + // operatorIsTrueCont.ResponseCode = callData.ResponseCode //仅消息类型为“按钮交互型”,“投票选择型”和“多项选择型”的模板卡片消息返回,应用可使用response_code调用更新模版卡片消息接口,24小时内有效,且只能使用一次"` + // operatorIsTrueCont.Stepper = 1 + // overall.CONSTANT_DB_KPI.Create(&operatorIsTrueCont) + + var openAppChangeLog modelskpi.OpenApprovalChangeLog + openAppChangeLog.Type = 2 + openAppChangeLog.Title = "创建申请" + openAppChangeLog.Operator = context.Key + openAppChangeLog.OrderId = uuId // 审批单ID"` + openAppChangeLog.OperatorTime = addTime + openAppChangeLog.Step = 1 + openAppChangeLog.OperatorType = 2 + openAppChangeLog.Msgid = callData.Msgid //:消息id,用于撤回应用消息"` + openAppChangeLog.ResponseCode = callData.ResponseCode //仅消息类型为“按钮交互型”,“投票选择型”和“多项选择型”的模板卡片消息返回,应用可使用response_code调用更新模版卡片消息接口,24小时内有效,且只能使用一次"` + openAppChangeLog.Stepper = 1 + openAppChangeLog.ChangeIsTrue = 1 //是否可变更(1:可变更;2:不可变更)"` + overall.CONSTANT_DB_KPI.Create(&openAppChangeLog) + } + } + // jsonstr, _ := json.Marshal(sendButtionMsg) + // fmt.Printf("callData------>%v--------err--------->%v--------->%v\n", callData, err, targetUnit) + } + } else { addErr := gormDbAffair.Rollback().Error publicmethod.Result(104, addErr, c) diff --git a/api/version1/postseting/postweb/posttarget.go b/api/version1/postseting/postweb/posttarget.go index 803e105..3de8d8e 100644 --- a/api/version1/postseting/postweb/posttarget.go +++ b/api/version1/postseting/postweb/posttarget.go @@ -3,6 +3,8 @@ package postweb import ( "encoding/json" "fmt" + "key_performance_indicators/api/version1/flowchart" + "key_performance_indicators/middleware/wechatapp/wechatsendmsg" "key_performance_indicators/models/modelshr" "key_performance_indicators/models/modelskpi" "key_performance_indicators/overall" @@ -491,13 +493,26 @@ func (a *ApiMethod) SendUsNatureEvaluation(c *gin.Context) { publicmethod.Result(107, err, c) return } + + //获取指标单位 + var unitTitle string + var postTargetDetailInfo modelskpi.PostTargetDetails + overall.CONSTANT_DB_KPI.Where(map[string]interface{}{"`id`": postShemeCont.DetailsId}).First(&postTargetDetailInfo) + unitTitle = postTargetDetailInfo.Company + var targetUnit modelskpi.PostTarget + overall.CONSTANT_DB_KPI.Model(&modelskpi.PostTarget{}).Select("`unit`,`title`").Where(map[string]interface{}{"`id`": postShemeCont.TargetId}).First(&targetUnit) + if unitTitle == "" { + + unitTitle = targetUnit.Unit + } + if receivedValue.UserKey == "" { publicmethod.Result(101, receivedValue, c) return } //获取被考核人基本信息 var userCont modelshr.PersonArchives - err = userCont.GetCont(map[string]interface{}{"`key`": receivedValue.UserKey}, "`company`", "`maindeparment`", "`admin_org`", "`position`") + err = userCont.GetCont(map[string]interface{}{"`key`": receivedValue.UserKey}, "`company`", "`maindeparment`", "`admin_org`", "`position`,`wechat`,`work_wechat`") if err != nil { publicmethod.Result(107, err, c) return @@ -568,12 +583,42 @@ func (a *ApiMethod) SendUsNatureEvaluation(c *gin.Context) { context, _ := publicmethod.LoginMyCont(c) uuId := publicmethod.GetUUid(1) + addTime := time.Now().Unix() + + //生成工作流 + wechatOpenId := context.Wechat + if context.WorkWechat != "" { + wechatOpenId = context.WorkWechat + } + var reviewFlowCont flowchart.ReviewFlow + reviewFlowCont.Id = receivedValue.Id + reviewFlowCont.IsCorrection = receivedValue.Rectification + reviewFlowCont.PlusReduction = receivedValue.AddOrDecrease + reviewFlowCont.PeopleList = append(reviewFlowCont.PeopleList, receivedValue.UserKey) + flowMap, _ := flowchart.SetUpWorkFlow(wechatOpenId, context.MainDeparment, reviewFlowCont, 1) + + var sendUserList []string //审批人列表 + var sendTitle string //标题 + //获取下一个节点审批人 + for _, v := range flowMap { + if v.Step == 2 { + sendTitle = v.NodeName + for _, vu := range v.UserList { + // fmt.Printf("vu------------>%v\n", vu) + if publicmethod.IsInTrue[string](vu.Wechat, sendUserList) == false { + sendUserList = append(sendUserList, vu.Wechat) + } + } + + } + } //流程列表 var flowCont modelskpi.PostWorkflowOrders - flowCont.OrderId = uuId //审批单ID"` - flowCont.Step = 1 //当前执行到第几步"` - flowCont.NextStep = 2 //下一步执行哪个步骤"` - flowCont.WorkFlow = "" //工作流(审批json字符串)"` + flowCont.OrderId = uuId //审批单ID"` + flowCont.Step = 1 //当前执行到第几步"` + flowCont.NextStep = 2 //下一步执行哪个步骤"` + flowMapJson, _ := json.Marshal(flowMap) + flowCont.WorkFlow = string(flowMapJson) //工作流(审批json字符串)"` flowCont.CompanyId = userCont.Company //公司"` flowCont.DepartmentId = userCont.MainDeparment //部门"` flowCont.OrgId = userCont.AdminOrg //行政组织"` @@ -624,14 +669,210 @@ func (a *ApiMethod) SendUsNatureEvaluation(c *gin.Context) { postNatureFlowCont.Time = time.Now().Unix() //时间"` //开启事务提交 - gormDbAffair := overall.CONSTANT_DB_KPI + gormDbAffair := overall.CONSTANT_DB_KPI.Begin() passorErr := gormDbAffair.Create(&flowCont).Error flowErr := gormDbAffair.Create(&postNatureFlowCont).Error + // openAppChangeErr := gormDbAffair.Create(&openAppChangeLog).Error if passorErr == nil && flowErr == nil { addErr := gormDbAffair.Commit().Error publicmethod.Result(0, addErr, c) + + if len(sendUserList) > 0 { + //项下一个审批节点发送审批通知 + //头部信息 + var sourceText wechatsendmsg.SourceText + sourceText.IconUrl = "https://docu.hxgk.group/images/2022_01/3f7a1120a559e9bee3991b85eb34d103.png" + sourceText.Desc = fmt.Sprintf("恒信高科-%v", sendTitle) + sourceText.DescColor = 1 + + //考核标准 + var sunTextCont string + var quoteTextCont string + switch postTargetDetailInfo.Punishmode { + case 2: + var moneyTitle string + if receivedValue.AddOrDecrease == 1 { + moneyTitle = "现金奖励标准" + quoteTextCont = fmt.Sprintf("奖励现金:%v元", receivedValue.Money) + } else { + moneyTitle = "现金罚款标准" + quoteTextCont = fmt.Sprintf("罚款现金:%v元", receivedValue.Money) + } + var scoreStr string + if postTargetDetailInfo.Minmoney != 0 { + scoreStr = fmt.Sprintf("%v元-%v元", publicmethod.DecimalEs(float64(postTargetDetailInfo.Minmoney)/100, 2), publicmethod.DecimalEs(float64(postTargetDetailInfo.Maxmoney)/100, 2)) + } else { + scoreStr = fmt.Sprintf("%v元", publicmethod.DecimalEs(float64(postTargetDetailInfo.Maxmoney)/100, 2)) + } + sunTextCont = fmt.Sprintf("%v:%v", moneyTitle, scoreStr) + if receivedValue.Reason != "" { + quoteTextCont = fmt.Sprintf("%v\n备注:%v", quoteTextCont, receivedValue.Reason) + } + case 3: + var moneyTitle string + var scoreTitle string + if receivedValue.AddOrDecrease == 1 { + moneyTitle = "现金奖励标准" + scoreTitle = "考核扣分标准" + quoteTextCont = fmt.Sprintf("考核加:%v%v\n奖励现金:%v元", receivedValue.Score, unitTitle, receivedValue.Money) + } else { + moneyTitle = "现金罚款标准" + scoreTitle = "考核加分标准" + quoteTextCont = fmt.Sprintf("考核扣:%v%v\n罚款现金:%v元", receivedValue.Score, unitTitle, receivedValue.Money) + } + var scoreStr string + + if postTargetDetailInfo.MinScore != 0 { + scoreStr = fmt.Sprintf("%v%v-%v%v", publicmethod.DecimalEs(float64(postTargetDetailInfo.MinScore)/100, 2), unitTitle, publicmethod.DecimalEs(float64(postTargetDetailInfo.MaxScore)/100, 2), unitTitle) + } else { + scoreStr = fmt.Sprintf("%v%v", publicmethod.DecimalEs(float64(postTargetDetailInfo.MaxScore)/100, 2), unitTitle) + } + sunTextCont = fmt.Sprintf("%v:%v", scoreTitle, scoreStr) + + if postTargetDetailInfo.Minmoney != 0 { + sunTextCont = fmt.Sprintf("%v\n%v:%v元-%v元", sunTextCont, moneyTitle, publicmethod.DecimalEs(float64(postTargetDetailInfo.Minmoney)/100, 2), publicmethod.DecimalEs(float64(postTargetDetailInfo.Maxmoney)/100, 2)) + } else { + sunTextCont = fmt.Sprintf("%v\n%v:%v元", sunTextCont, moneyTitle, publicmethod.DecimalEs(float64(postTargetDetailInfo.Maxmoney)/100, 2)) + } + + if receivedValue.Reason != "" { + quoteTextCont = fmt.Sprintf("%v\n备注:%v", quoteTextCont, receivedValue.Reason) + } + default: + + var scoreTitle string + if receivedValue.AddOrDecrease == 1 { + scoreTitle = "考核加分标准" + quoteTextCont = fmt.Sprintf("考核加:%v%v", receivedValue.Score, unitTitle) + } else { + scoreTitle = "考核扣分标准" + quoteTextCont = fmt.Sprintf("考核扣:%v%v", receivedValue.Score, unitTitle) + } + var scoreStr string + if postTargetDetailInfo.MinScore != 0 { + scoreStr = fmt.Sprintf("%v%v-%v%v", publicmethod.DecimalEs(float64(postTargetDetailInfo.MinScore)/100, 2), unitTitle, publicmethod.DecimalEs(float64(postTargetDetailInfo.MaxScore)/100, 2), unitTitle) + } else { + scoreStr = fmt.Sprintf("%v%v", publicmethod.DecimalEs(float64(postTargetDetailInfo.MaxScore)/100, 2), unitTitle) + } + sunTextCont = fmt.Sprintf("%v:%v", scoreTitle, scoreStr) + + if receivedValue.Reason != "" { + quoteTextCont = fmt.Sprintf("%v\n备注:%v", quoteTextCont, receivedValue.Reason) + } + } + + //引用文献 + var quoteAreaInfo wechatsendmsg.QuoteAreaCont + quoteAreaInfo.Type = 0 + quoteAreaInfo.Title = "考核明细" + quoteAreaInfo.QuoteText = quoteTextCont + + //按钮 + var buttonList []wechatsendmsg.ButtonListCont + var buttonList1 wechatsendmsg.ButtonListCont + buttonList1.Text = "批准" + buttonList1.Style = 1 + buttonList1.Key = fmt.Sprintf("KPI_post_%v_%v_%v", uuId, 1, 1) + buttonList = append(buttonList, buttonList1) + var buttonList2 wechatsendmsg.ButtonListCont + buttonList2.Text = "驳回" + buttonList2.Style = 3 + buttonList2.Key = fmt.Sprintf("KPI_post_%v_%v_%v", uuId, 2, 1) + buttonList = append(buttonList, buttonList2) + + //二级标题+文本列表 + var twoTitleTextList []wechatsendmsg.HorizontalContentListInfo + //发送人 + var horizontalContentLis3 wechatsendmsg.HorizontalContentListInfo + horizontalContentLis3.KeyName = "申请人:" + horizontalContentLis3.Value = "点击查看" + horizontalContentLis3.Type = 3 + horizontalContentLis3.Userid = wechatOpenId + twoTitleTextList = append(twoTitleTextList, horizontalContentLis3) + //被考核人 + if userCont.Wechat != "" || userCont.WorkWechat != "" { + weChatStrs := userCont.Wechat + if userCont.WorkWechat != "" { + weChatStrs = userCont.WorkWechat + } + var twoTitleTextCont wechatsendmsg.HorizontalContentListInfo + twoTitleTextCont.KeyName = "被考核人:" + twoTitleTextCont.Value = "点击查看" + twoTitleTextCont.Type = 3 + twoTitleTextCont.Userid = weChatStrs + twoTitleTextList = append(twoTitleTextList, twoTitleTextCont) + } + //卡片跳转地址 + var cardActionContStr wechatsendmsg.CardActionCont + cardActionContStr.Type = 1 + cardActionContStr.Url = fmt.Sprintf("http://new.hxgk.group/#/quantitativeList?id=%v", uuId) + + var sendButtionMsg wechatsendmsg.SendButtonInteractionSimplify + // sendButtionMsg.Touser = strings.Join(sendUserList, "|") + sendButtionMsg.Touser = "KaiXinGuo" //指定接收消息的成员,成员ID列表;特殊情况:指定为 + sendButtionMsg.Msgtype = "template_card" + agentIdInt, _ := strconv.ParseInt(overall.CONSTANT_CONFIG.WechatKpi.Agentid, 10, 64) + sendButtionMsg.Agentid = agentIdInt + sendButtionMsg.EnableDuplicateCheck = 0 + sendButtionMsg.DuplicateCheckInterval = 1800 + sendButtionMsg.EnableIdTrans = 0 + sendButtionMsg.TemplateCard.CardType = "button_interaction" + sendButtionMsg.TemplateCard.Source = sourceText + sendButtionMsg.TemplateCard.TaskId = fmt.Sprintf("KPI_%v", uuId) + sendButtionMsg.TemplateCard.MainTitle.Title = targetUnit.Title + descInfo := postTargetDetailInfo.Title + // if postTargetDetailInfo.CensorCont != "" { + // descInfo = fmt.Sprintf("%v\n检查依据:%v", descInfo, postTargetDetailInfo.CensorCont) + // } + // if postTargetDetailInfo.Content != "" { + // if descInfo != "" { + // descInfo = fmt.Sprintf("%v\n备注:%v", descInfo, postTargetDetailInfo.Content) + // } else { + // descInfo = fmt.Sprintf("备注:%v", postTargetDetailInfo.Content) + // } + + // } + sendButtionMsg.TemplateCard.MainTitle.Desc = descInfo + sendButtionMsg.TemplateCard.QuoteArea = quoteAreaInfo + + sendButtionMsg.TemplateCard.SubTitleText = sunTextCont + sendButtionMsg.TemplateCard.ButtonList = buttonList + sendButtionMsg.TemplateCard.HorizontalContentList = twoTitleTextList + sendButtionMsg.TemplateCard.CardAction = cardActionContStr + callData, err := sendButtionMsg.SendMsg("kpi") + if err == nil { + if callData.Errcode == 0 { + // var operatorIsTrueCont modelskpi.OperatorIsTrue + // operatorIsTrueCont.OrderId = uuId //订单ID"` + // operatorIsTrueCont.Step = 1 //审批到第几步"` + // operatorIsTrueCont.State = 1 //:状态:1:可操作;2:不可操作"` + // operatorIsTrueCont.Time = addTime //操作时间"` + // operatorIsTrueCont.Msgid = callData.Msgid //:消息id,用于撤回应用消息"` + // operatorIsTrueCont.ResponseCode = callData.ResponseCode //仅消息类型为“按钮交互型”,“投票选择型”和“多项选择型”的模板卡片消息返回,应用可使用response_code调用更新模版卡片消息接口,24小时内有效,且只能使用一次"` + // operatorIsTrueCont.Stepper = 1 + // overall.CONSTANT_DB_KPI.Create(&operatorIsTrueCont) + + var openAppChangeLog modelskpi.OpenApprovalChangeLog + openAppChangeLog.Type = 2 + openAppChangeLog.Title = "创建申请" + openAppChangeLog.Operator = context.Key + openAppChangeLog.OrderId = uuId // 审批单ID"` + openAppChangeLog.OperatorTime = addTime + openAppChangeLog.Step = 1 + openAppChangeLog.OperatorType = 2 + openAppChangeLog.Msgid = callData.Msgid //:消息id,用于撤回应用消息"` + openAppChangeLog.ResponseCode = callData.ResponseCode //仅消息类型为“按钮交互型”,“投票选择型”和“多项选择型”的模板卡片消息返回,应用可使用response_code调用更新模版卡片消息接口,24小时内有效,且只能使用一次"` + openAppChangeLog.Stepper = 1 + openAppChangeLog.ChangeIsTrue = 1 //是否可变更(1:可变更;2:不可变更)"` + overall.CONSTANT_DB_KPI.Create(&openAppChangeLog) + + } + } + // jsonstr, _ := json.Marshal(callData) + // fmt.Printf("callData------>%v--------err--------->%v--------->%v\n", callData, err, string(jsonstr)) + } } else { addErr := gormDbAffair.Rollback().Error publicmethod.Result(104, addErr, c) diff --git a/apirouter/entry.go b/apirouter/entry.go index c1cd388..ee086a9 100644 --- a/apirouter/entry.go +++ b/apirouter/entry.go @@ -11,6 +11,7 @@ import ( "key_performance_indicators/apirouter/v1/systempower" "key_performance_indicators/apirouter/verifyLogin" "key_performance_indicators/apirouter/wechaturl" + "key_performance_indicators/apirouter/workflowchart" // "key_performance_indicators/v1" ) @@ -26,6 +27,7 @@ type RouterGroup struct { SystemPowerRouter systempower.ApiRouter Empowerouter empowerrouter.ApiRouter WechatRouter wechaturl.ApiRouter + WorkFlowRouter workflowchart.ApiRouter } var RouterGroupEntry = new(RouterGroup) diff --git a/apirouter/wechaturl/wechatrouter.go b/apirouter/wechaturl/wechatrouter.go index a16fe76..8017ecf 100644 --- a/apirouter/wechaturl/wechatrouter.go +++ b/apirouter/wechaturl/wechatrouter.go @@ -12,8 +12,9 @@ func (a *ApiRouter) RouterGroup(router *gin.RouterGroup) { var methodBinding = wechatapp.WechatAppApi.WechatCallBackApi { - apiRouter.GET("", methodBinding.Index) //入口 - apiRouter.POST("", methodBinding.Index) //入口 - apiRouter.GET("callback_message_api", methodBinding.CallbackMessageApi) //回调入口 + apiRouter.GET("", methodBinding.Index) //入口 + apiRouter.POST("", methodBinding.Index) //入口 + apiRouter.GET("callback_message_api", methodBinding.CallbackMessageApi) //回调入口 + apiRouter.POST("callback_message_api", methodBinding.CallbackMessageApi) //回调入口 } } diff --git a/apirouter/workflowchart/entry.go b/apirouter/workflowchart/entry.go new file mode 100644 index 0000000..2df91d7 --- /dev/null +++ b/apirouter/workflowchart/entry.go @@ -0,0 +1,12 @@ +package workflowchart + +/** +@ 作者: 秦东 +@ 时间: 2022-09-30 09:49:37 +@ 功能: 工作流路由 +@ 参数 + # +@ 返回值 + # +*/ +type ApiRouter struct{} diff --git a/apirouter/workflowchart/flowes.go b/apirouter/workflowchart/flowes.go new file mode 100644 index 0000000..dc0c8b5 --- /dev/null +++ b/apirouter/workflowchart/flowes.go @@ -0,0 +1,19 @@ +package workflowchart + +import ( + "key_performance_indicators/api/version1" + + "github.com/gin-gonic/gin" +) + +// 工作流 +func (a *ApiRouter) RouterGroup(router *gin.RouterGroup) { + apiRouter := router.Group("workflow") + + var workFlow = version1.AppApiEntry.WorkFlowChat + { + apiRouter.GET("", workFlow.Index) //入口 + apiRouter.POST("", workFlow.Index) //入口 + apiRouter.POST("review_workflow", workFlow.ReviewWorkFlow) //生成审批流程流 + } +} diff --git a/initialization/route/initRoute.go b/initialization/route/initRoute.go index 96837f6..a1e0c5f 100644 --- a/initialization/route/initRoute.go +++ b/initialization/route/initRoute.go @@ -51,6 +51,7 @@ func InitialRouter() *gin.Engine { { wechaturlApi.RouterGroup(appLoadRouterGroup) } + } //验证身份接口 鉴权Url(主要应用端使用) @@ -93,6 +94,9 @@ func InitialRouter() *gin.Engine { //系统授权 systemAuthorizingApi := apirouter.RouterGroupEntry.Empowerouter systemAuthorizingApi.RouterGroup(VerifyIdentityWeb) //系统授权 + //工作流 + workFlowApiRouter := apirouter.RouterGroupEntry.WorkFlowRouter + workFlowApiRouter.RouterGroup(VerifyIdentityWeb) //工作流 } //Token身份验证 VerifyIdentityToken := router.Group("") diff --git a/middleware/wechatapp/wechatcallback/event_processing.go b/middleware/wechatapp/wechatcallback/event_processing.go new file mode 100644 index 0000000..e735b72 --- /dev/null +++ b/middleware/wechatapp/wechatcallback/event_processing.go @@ -0,0 +1,150 @@ +package wechatcallback + +import ( + "encoding/json" + "encoding/xml" + "fmt" + "key_performance_indicators/middleware/wechatapp/wechatsendmsg" + "key_performance_indicators/models/modelskpi" + "key_performance_indicators/overall" + "strconv" + "strings" + + "github.com/gin-gonic/gin" +) + +// 事件处理 +func EventProcessing(msg []byte, c *gin.Context) { + //通用类型判断是回调的什么事件 + var commonType CurrencyMessage + xml.Unmarshal(msg, &commonType) + switch commonType.Event { + case "subscribe": //关注 + case "unsubscribe": //取消关注 + case "enter_agent": //本事件在成员进入企业微信的应用时触发 + case "LOCATION": //上报地理位置 + GeographicalPosition(msg) + case "batch_job_result": //异步任务完成事件推送 + case "change_contact": //通讯录变更事件 + // WorkWechatMailList(msgContent.ChangeType, decryptMsg) + case "click": //点击菜单拉取消息的事件推送 + case "view": //点击菜单跳转链接的事件推送 + case "scancode_push": //扫码推事件的事件推送 + case "scancode_waitmsg": //扫码推事件且弹出“消息接收中”提示框的事件推送 + case "pic_sysphoto": //弹出系统拍照发图的事件推送 + case "pic_photo_or_album": //弹出拍照或者相册发图的事件推送 + case "pic_weixin": //弹出微信相册发图器的事件推送 + case "location_select": //弹出地理位置选择器的事件推送 + case "open_approval_change": //审批状态通知事件 自建应用 + // OpenApprovalChange(decryptMsg) + case "sys_approval_change": //系统审批应用 + case "share_agent_change": //企业互联共享应用事件回调 + case "share_chain_change": //上下游共享应用事件回调 + case "template_card_event": //模板卡片事件推送 + TemplateEvent(msg) + case "template_card_menu_event": //通用模板卡片右上角菜单事件推送 + default: + } +} + +// 模板事件处理 +func TemplateEvent(msg []byte) { + var msgCont ButtonEventQuestion + err := xml.Unmarshal(msg, &msgCont) + if err != nil { + return + } + eventKeyAry := strings.Split(msgCont.EventKey, "_") + buttionLen := len(eventKeyAry) + if buttionLen >= 5 { + // for i, v := range eventKeyAry { + + // fmt.Printf("eventKeyAry:%v====================>%v==================>%v\n", i, v, eventKeyAry[i]) + // } + switch eventKeyAry[0] { + case "school": + default: //默认系统 + if eventKeyAry[1] == "post" { + //岗位考核 + } else { + //部门考核 + } + } + } else { + jsonStr, _ := json.Marshal(msgCont) + fmt.Printf("TemplateEvent======>%v\n", string(jsonStr)) + } +} + +/* +* +@ 作者: 秦东 +@ 时间: 2022-10-05 15:46:05 +@ 功能: 岗位按钮模板回调处理 +@ 参数 + + #orderId 流程Key + #clickEnter 1:同意;2:驳回 + #systemApp 系统 + #step 步进位 + +@ 返回值 + + # +*/ +func (b *ButtonEventQuestion) PostTemolateCallBack(orderId, clickEnter, systemApp, step string) { + //1、判断当前流程状态 + var flowCont modelskpi.PostWorkflowOrders + err := flowCont.GetCont(map[string]interface{}{"`order_id`": orderId}) + if err != nil { + var sendMsgText wechatsendmsg.SendTextCard + sendMsgText.Touser = b.FromUsername + sendMsgText.Msgtype = "textcard" + agentIdInt, _ := strconv.ParseInt(overall.CONSTANT_CONFIG.WechatKpi.Agentid, 10, 64) + sendMsgText.Agentid = agentIdInt + sendMsgText.EnableDuplicateCheck = 0 + sendMsgText.DuplicateCheckInterval = 1800 + sendMsgText.EnableIdTrans = 0 + sendMsgText.MsgBody.Title = "流程关闭" + sendMsgText.MsgBody.Description = "此审批流程已经关闭!请联系发起人!" + jumpUrl := fmt.Sprintf("http://new.hxgk.group/#/responsible?id=%v", orderId) + sendMsgText.MsgBody.URL = jumpUrl + sendMsgText.MsgBody.BtnTxt = "" + sendMsgText.SendMsg(systemApp) + return + } else { + var sendMsgText wechatsendmsg.SendTextCard + sendMsgText.Touser = b.FromUsername + sendMsgText.Msgtype = "textcard" + agentIdInt, _ := strconv.ParseInt(overall.CONSTANT_CONFIG.WechatKpi.Agentid, 10, 64) + sendMsgText.Agentid = agentIdInt + sendMsgText.EnableDuplicateCheck = 0 + sendMsgText.DuplicateCheckInterval = 1800 + sendMsgText.EnableIdTrans = 0 + + jumpUrl := fmt.Sprintf("http://new.hxgk.group/#/responsible?id=%v", orderId) + sendMsgText.MsgBody.URL = jumpUrl + sendMsgText.MsgBody.BtnTxt = "查看详情" + switch flowCont.State { + case 4: + sendMsgText.MsgBody.Title = "流程归档" + sendMsgText.MsgBody.Description = "此审批流程已经归档!不可继续操作!" + sendMsgText.SendMsg(systemApp) + return + case 5: + sendMsgText.MsgBody.Title = "流程废弃" + sendMsgText.MsgBody.Description = "此审批流程已经废弃!不可继续操作!" + sendMsgText.SendMsg(systemApp) + return + case 6: + sendMsgText.MsgBody.Title = "流程不存在" + sendMsgText.MsgBody.Description = "此审批流程不存在!请联系发起人!" + sendMsgText.SendMsg(systemApp) + return + default: + } + } + //判断当前步进位是否已经被操作 + var operatorIsTreu modelskpi.OpenApprovalChangeLog + err = operatorIsTreu.GetCont(map[string]interface{}{"`orderid`": orderId, `stepper`: step}) +} diff --git a/middleware/wechatapp/wechatcallback/geographical_position.go b/middleware/wechatapp/wechatcallback/geographical_position.go new file mode 100644 index 0000000..ddf041a --- /dev/null +++ b/middleware/wechatapp/wechatcallback/geographical_position.go @@ -0,0 +1,64 @@ +package wechatcallback + +import ( + "encoding/json" + "encoding/xml" + "fmt" + "key_performance_indicators/middleware/grocerystore" + "key_performance_indicators/overall" + "key_performance_indicators/overall/publicmethod" + "time" +) + +func GeographicalPosition(eventMsg []byte) { //进入应用上报地址位置 + var msgContent GeographicalPositionType + err := xml.Unmarshal(eventMsg, &msgContent) + if nil != err { + fmt.Println("***********Unmarshal fail") + } + userAddress := publicmethod.MapOut[string]() + userAddress["userid"] = msgContent.FromUsername //userID + userAddress["latitude"] = msgContent.Latitude //地理位置纬度 + userAddress["longitude"] = msgContent.Longitude //地理位置经度 + userAddress["precision"] = msgContent.Precision //地理位置精度 + userAddress["time"] = time.Now().Unix() + + marshal, err := json.Marshal(userAddress) + if err != nil { + marshal = []byte{} + } + + redisPrefix := "Location:GeographicalPosition_" + overall.CONSTANT_CONFIG.RedisPrefixStr.PreFix + ":userId_" + msgContent.FromUsername //redis KEY + // redisClient := redishandel.RunRedis() + redisClient := grocerystore.RunRedis(overall.CONSTANT_REDIS1) + // fmt.Printf("button===101===>%v\n", redisClient) + locationJson, locationErr := redisClient.Lindex(redisPrefix, 0) + + // fmt.Printf("button===102===>%v===>%v\n", locationJson, locationErr) + + if locationErr != nil { + redisClient.Lpush(redisPrefix, string(marshal)) + // fmt.Printf("button===1===>%v\n", marshal) + } else { + var geographicalPositionRedis GeographicalPositionRedis + jsonErr := json.Unmarshal([]byte(locationJson), &geographicalPositionRedis) + + // fmt.Printf("button===2111===>%v===>%v\n", jsonErr, geographicalPositionRedis) + if jsonErr != nil { + redisClient.Lpush(redisPrefix, string(marshal)) + // fmt.Printf("button===2===>%v===>%v\n", jsonErr, locationJson) + } else { + timeVal := geographicalPositionRedis.Time + if time.Now().Unix()-timeVal >= 300 { + redisClient.Lpush(redisPrefix, string(marshal)) + // fmt.Printf("button===4===>%v\n", marshal) + } else { + // fmt.Printf("button===412===>%v===>%v\n", timeVal, time.Now().Unix()-timeVal) + } + } + } + // longFloat, _ := strconv.ParseFloat(msgContent.Longitude, 64) + // latFloat, _ := strconv.ParseFloat(msgContent.Latitude, 64) + // long, latg := commonus.GCJ02toBD09(longFloat, latFloat) + // fmt.Printf("button======>%v======>%v======>%v\n", msgContent, long, latg) +} diff --git a/middleware/wechatapp/wechatcallback/response.go b/middleware/wechatapp/wechatcallback/response.go index a160bff..4d9716a 100644 --- a/middleware/wechatapp/wechatcallback/response.go +++ b/middleware/wechatapp/wechatcallback/response.go @@ -1,13 +1,10 @@ package wechatcallback import ( + "encoding/xml" "fmt" "key_performance_indicators/middleware/wechatapp/wechatstatice" - "key_performance_indicators/models/wechatcallback" - "key_performance_indicators/overall" "key_performance_indicators/overall/publicmethod" - "strconv" - "time" "github.com/gin-gonic/gin" ) @@ -65,7 +62,52 @@ func (a *ApiRouter) CallbackMessageApi(c *gin.Context) { c.String(200, msgStr) } else { //回调事件 - fmt.Printf("回调事件") + fmt.Printf("回调事件\n") + var callBackXmlMsg XmlMsgCont + xmlErr := c.ShouldBindXML(&callBackXmlMsg) + if xmlErr != nil { + fmt.Printf("回调事件失败!%v\n", xmlErr) + return + } + var jieMiCont DecryptMsgCont + jieMiCont.MsgSignature = MsgSignature + jieMiCont.Timestamp = Timestamp + jieMiCont.Nonce = Nonce + jieMiCont.ToUsername = callBackXmlMsg.ToUsername + jieMiCont.Agentid = callBackXmlMsg.Agentid + jieMiCont.Encrypt = callBackXmlMsg.Encrypt + decryptMsgCont, jsonErr := jieMiCont.DecryptMsgInfo() + fmt.Printf("Xml----->%v\n\n", string(decryptMsgCont)) + if jsonErr != nil { + fmt.Printf("回调事件失败!%v\n", jsonErr) + return + } + var msgCont MsgContentXml + errXml := xml.Unmarshal(decryptMsgCont, &msgCont) + if errXml != nil { + fmt.Printf("回调事件失败!%v\n", errXml) + return + } + fmt.Printf("XmlCont----->%v\nwxcptJson----->%v\n", string(decryptMsgCont), msgCont) + switch msgCont.MsgType { + /*消息格式类型 + */ + case "text": //文本 + case "image": //图片 + case "voice": //语音 + case "video": //视频 + case "location": //位置 + GeographicalPosition(decryptMsgCont) + case "link": //链接 + /*事件格式类型*/ + case "event": + /* + 事件附属格式 + */ + EventProcessing(decryptMsgCont, c) + // return + default: + } } // fmt.Printf("(3)CallbackMessageApi---------->%v------------------->%v\n", msgStr, basicValueCallback) @@ -74,52 +116,62 @@ func (a *ApiRouter) CallbackMessageApi(c *gin.Context) { // 验证URL func (c *CallBackData) VerificationUrl() (msg string) { - // wecahtCpt := WechatVerification() - // timestampStr := strconv.FormatInt(c.Timestamp, 10) - // echoStr, cryptErr := wecahtCpt.VerifyURL(c.MsgSignature, timestampStr, c.Nonce, c.Echostr) - - // if nil != cryptErr { - // fmt.Println("verifyUrl fail", cryptErr) - // } - // msg = string(echoStr) - // jsonk, _ := json.Marshal(c) - // fmt.Printf("json--------->%v\n", string(jsonk)) + switch c.DataType { case "json": wxcptJson := wechatstatice.WechatDecryptJson(c.SystemApp) echoStr, cryptErr := wxcptJson.VerifyURL(c.MsgSignature, c.Timestamp, c.Nonce, c.Echostr) - fmt.Printf("(2)wxcptJson---------->%v------------echoStr------->%v----cryptErr---->%v-----MsgSignature--->%v----Timestamp---->%v-----Nonce--->%v-----Echostr--->%v\n", wxcptJson, string(echoStr), cryptErr, c.MsgSignature, c.Timestamp, c.Nonce, c.Echostr) + // fmt.Printf("(2)wxcptJson---------->%v-----MsgSignature--->%v----Timestamp---->%v-----Nonce--->%v-----c.Echostr--->%v------------echoStr------->%v----cryptErr---->%v\n", wxcptJson, c.MsgSignature, c.Timestamp, c.Nonce, c.Echostr, string(echoStr), cryptErr) msg = string(echoStr) - - var callbackLog wechatcallback.CallbackLog - callbackLog.MsgSignature = c.MsgSignature - TimestampInt, _ := strconv.ParseInt(c.Timestamp, 10, 64) - callbackLog.TimeStamp = TimestampInt - callbackLog.Nonce = c.Nonce - callbackLog.Echostr = c.Echostr - callbackLog.Xmlstr = string(echoStr) - // callbackLog.Reqdata = string(reqData) - callbackLog.AddTime = time.Now().Unix() - overall.CONSTANT_DB_WECHAT_LOG.Create(&callbackLog) + if cryptErr != nil { + fmt.Println("verifyUrl fail", cryptErr) + } + // var callbackLog wechatcallback.CallbackLog + // callbackLog.MsgSignature = c.MsgSignature + // TimestampInt, _ := strconv.ParseInt(c.Timestamp, 10, 64) + // callbackLog.TimeStamp = TimestampInt + // callbackLog.Nonce = c.Nonce + // callbackLog.Echostr = c.Echostr + // callbackLog.Xmlstr = string(echoStr) + // // callbackLog.Reqdata = string(reqData) + // callbackLog.AddTime = time.Now().Unix() + // overall.CONSTANT_DB_WECHAT_LOG.Create(&callbackLog) default: wxcptXml := wechatstatice.WechatDecryptXml(c.SystemApp) echoStr, cryptErr := wxcptXml.VerifyURL(c.MsgSignature, c.Timestamp, c.Nonce, c.Echostr) - fmt.Printf("wxcptXml---------->%v------------echoStr------->%v----cryptErr---->%v-----MsgSignature--->%v----Timestamp---->%v-----Nonce--->%v-----Echostr--->%v\n", wxcptXml, string(echoStr), cryptErr, c.MsgSignature, c.Timestamp, c.Nonce, c.Echostr) + // fmt.Printf("wxcptXml---------->%v------------echoStr------->%v----cryptErr---->%v-----MsgSignature--->%v----Timestamp---->%v-----Nonce--->%v-----Echostr--->%v\n", wxcptXml, string(echoStr), cryptErr, c.MsgSignature, c.Timestamp, c.Nonce, c.Echostr) msg = string(echoStr) - var callbackLog wechatcallback.CallbackLog - callbackLog.MsgSignature = c.MsgSignature - TimestampInt, _ := strconv.ParseInt(c.Timestamp, 10, 64) - callbackLog.TimeStamp = TimestampInt - callbackLog.Nonce = c.Nonce - callbackLog.Echostr = c.Echostr - callbackLog.Xmlstr = string(echoStr) - // callbackLog.Reqdata = string(reqData) - callbackLog.AddTime = time.Now().Unix() - overall.CONSTANT_DB_WECHAT_LOG.Create(&callbackLog) + if cryptErr != nil { + fmt.Println("verifyUrl fail", cryptErr) + } + // var callbackLog wechatcallback.CallbackLog + // callbackLog.MsgSignature = c.MsgSignature + // TimestampInt, _ := strconv.ParseInt(c.Timestamp, 10, 64) + // callbackLog.TimeStamp = TimestampInt + // callbackLog.Nonce = c.Nonce + // callbackLog.Echostr = c.Echostr + // callbackLog.Xmlstr = string(echoStr) + // // callbackLog.Reqdata = string(reqData) + // callbackLog.AddTime = time.Now().Unix() + // overall.CONSTANT_DB_WECHAT_LOG.Create(&callbackLog) } return - // fmt.Println(string(echoStr)) - // fmt.Print(string(echoStr)) } + +// 解密文档 +func (d *DecryptMsgCont) DecryptMsgInfo() (msg []byte, err error) { + decryptStr := fmt.Sprintf(`{"tousername":"%v","encrypt":"%v","agentid":"%v"}`, d.ToUsername, d.Encrypt, d.Agentid) + + reqData := []byte(decryptStr) + + wxcptJson := wechatstatice.WechatDecryptJson(d.SystemApp) + + msg, cryptErr := wxcptJson.DecryptMsg(d.MsgSignature, d.Timestamp, d.Nonce, reqData) + if cryptErr != nil { + err = fmt.Errorf("解密失败1") + } + // fmt.Printf("msg:-----------%v\n cryptErr:-----------%v----->all\n\n", string(msg), cryptErr) + return +} diff --git a/middleware/wechatapp/wechatcallback/type.go b/middleware/wechatapp/wechatcallback/type.go index 2e07a5d..bcf0f21 100644 --- a/middleware/wechatapp/wechatcallback/type.go +++ b/middleware/wechatapp/wechatcallback/type.go @@ -25,3 +25,106 @@ type MsgContent struct { Msgid uint64 `json:"MsgId"` Agentid uint32 `json:"AgentId"` } + +//XML 格式回调 +type XmlMsgCont struct { + ToUsername string `xml:"ToUserName"` + Agentid uint32 `xml:"AgentID"` + Encrypt string `json:"encrypt"` +} + +//通用更新切片 +type XmlMsgUpdateCont struct { + ToUsername string `xml:"ToUserName"` + FromUsername string `xml:"FromUserName"` + CreateTime uint32 `xml:"CreateTime"` + MsgType string `xml:"MsgType"` + Agentid uint32 `xml:"AgentID"` + Event string `xml:"Event"` + EventKey string `xml:"EventKey"` +} + +//XML数据解密 +type MsgContentXml struct { + XmlMsgUpdateCont + Content string `xml:"Content"` + Msgid string `xml:"MsgId"` +} + +//返回消息体解密 +type DecryptMsgCont struct { + MsgSignature string `json:"msg_signature"` + Timestamp string `json:"timestamp"` + Nonce string `json:"nonce"` + SystemApp string `json:"systemapp"` + jsonMsgCont +} +type jsonMsgCont struct { + ToUsername string `json:"ToUserName"` + Agentid uint32 `json:"AgentID"` + Encrypt string `json:"encrypt"` +} + +//上报地理位置 +type GeographicalPositionType struct { + CurrencyMessage + Latitude string `xml:"Latitude"` + Longitude string `xml:"Longitude"` + Precision string `xml:"Precision"` + AppType string `xml:"AppType"` +} + +//通用更新切片 +type CurrencyMessage struct { + ToUsername string `xml:"ToUserName"` + FromUsername string `xml:"FromUserName"` + CreateTime uint32 `xml:"CreateTime"` + MsgType string `xml:"MsgType"` + Agentid uint32 `xml:"AgentID"` + Event string `xml:"Event"` + EventKey string `xml:"EventKey"` + // TaskId string `xml:"TaskId"` +} + +//上报地理位置Redis +type GeographicalPositionRedis struct { + UserId string `json:"userid"` + Latitude string `json:"latitude"` + Longitude string `json:"longitude"` + Precision string `json:"precision"` + Time int64 `json:"time"` + LatitudeBaiDu float64 `json:"latitudebaidu"` + LongitudeBaiDu float64 `json:"longitudebaidu"` +} + +//模板卡片事件推送 通用 +type ButtonEvent struct { + ToUsername string `json:"ToUserName"` + FromUsername string `json:"FromUserName"` + CreateTime uint32 `json:"CreateTime"` + MsgType string `json:"MsgType"` + Event string `xml:"Event"` + EventKey string `xml:"EventKey"` + TaskId string `xml:"TaskId"` + CardType string `xml:"CardType"` + ResponseCode string `xml:"ResponseCode"` + Agentid uint32 `xml:"AgentID"` +} + +//模板卡片事件推送 问题列表 +type ButtonEventQuestion struct { + ButtonEvent + SelectedItems []SelectedItemsList `xml:"SelectedItems"` //问题列表 +} + +//问题列表 +type SelectedItemsList struct { + SelectedItem []SelectedItemList `xml:"SelectedItem"` +} +type SelectedItemList struct { + QuestionKey string `xml:"QuestionKey"` + OptionIds []OptionIdsStr `xml:"OptionIds"` +} +type OptionIdsStr struct { + OptionId string `xml:"OptionId"` +} diff --git a/middleware/wechatapp/wechatsendmsg/send_applets_type.go b/middleware/wechatapp/wechatsendmsg/send_applets_type.go new file mode 100644 index 0000000..a773f19 --- /dev/null +++ b/middleware/wechatapp/wechatsendmsg/send_applets_type.go @@ -0,0 +1,23 @@ +package wechatsendmsg + +import "key_performance_indicators/middleware/wechatapp/wechatstatice" + +//发送markdown消息 +type SendMiniprogramNotice struct { + wechatstatice.PublicSendMsgSmaillSub + MsgBody MiniprogramNoticeCont `json:"miniprogram_notice"` + + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 + wechatstatice.PublicSendMsgBootem +} +type MiniprogramNoticeCont struct { + Appid string `json:"appid"` //小程序appid,必须是与当前应用关联的小程序,appid和pagepath必须同时填写,填写后会忽略url字段 + Page string `json:"page"` //点击消息卡片后的小程序页面,最长1024个字节,仅限本小程序内的页面。该字段不填则消息点击后不跳转。 + PublicTextCont + EmphasisFirstItem bool `json:"emphasis_first_item"` //是否放大第一个content_item + ContentItem []ContentItemCont `json:"content_item"` //消息内容键值对,最多允许10个item +} +type ContentItemCont struct { + Key string `json:"key"` //长度10个汉字以内 + Calue string `json:"value"` //长度30个汉字以内(支持id转译) +} diff --git a/middleware/wechatapp/wechatsendmsg/send_ordinary_msg.go b/middleware/wechatapp/wechatsendmsg/send_ordinary_msg.go new file mode 100644 index 0000000..3a61520 --- /dev/null +++ b/middleware/wechatapp/wechatsendmsg/send_ordinary_msg.go @@ -0,0 +1,301 @@ +package wechatsendmsg + +import ( + "encoding/json" + "key_performance_indicators/middleware/wechatapp/wechatstatice" + "key_performance_indicators/overall/publicmethod" +) + +// 发送文本消息 +func (s *SendTextMsg) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 发送语音信息 +func (s *SendVoiceMsg) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 发送图片信息 +func (s *SendImage) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 发送视频信息 +func (s *SendVideo) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 发送文件消息 +func (s *SendFile) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 发送文本卡片消息 +func (s *SendTextCard) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 发送图文消息 +func (s *SendNews) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 发送图文消息(mpnews) +func (s *SendMpNews) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 发送图文消息(mpnews) +func (s *SendMarkDown) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 发送小程序通知消息 +func (s *SendMiniprogramNotice) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 发送文本通知型消息(All) +func (s *SendTextNoticeAll) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 发送文本通知型(一级标题+二级文本+发送人) +func (s *SendTextNoticeOneAndTwoTitleMan) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 发送文本通知型(引用文献+发送人) +func (s *SendTextNoticeQuoteMan) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 发送图文展示型(All) +func (s *SendImageNoticeAll) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 图文展示型(一级标题+图片) +func (s *SendImageNoticeOneImg) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 图文展示型(卡片二级垂直内容+图片) +func (s *SendImageNoticeImgVer) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 图文展示型(左图右文样式) +func (s *SendImageNoticeLImgRText) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 按钮交互型(All) +func (s *SendButtonInteractionAll) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 按钮交互型(simplify) +func (s *SendButtonInteractionSimplify) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 投票选择型 +func (s *SendVoteInteraction) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} + +// 多项选择型 +func (s *SendMultipleInteraction) SendMsg(systemApp string) (callBackCont wechatstatice.SendCallBackMsg, err error) { + sendUrl, token, err := wechatstatice.GetSendMsgTokenUrl(systemApp, "send") + if err != nil { + callBackCont.Unlicenseduser = sendUrl + callBackCont.Msgid = token + return + } + sendDate, _ := json.Marshal(s) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &callBackCont) + return +} diff --git a/middleware/wechatapp/wechatsendmsg/send_template_card_type.go b/middleware/wechatapp/wechatsendmsg/send_template_card_type.go new file mode 100644 index 0000000..2cb8d98 --- /dev/null +++ b/middleware/wechatapp/wechatsendmsg/send_template_card_type.go @@ -0,0 +1,303 @@ +package wechatsendmsg + +import "key_performance_indicators/middleware/wechatapp/wechatstatice" + +type PublicSource struct { + IconUrl string `json:"icon_url"` + Desc string `json:"desc"` +} +type SmaillSub struct { + Appid string `json:"appid"` //小程序appid,必须是与当前应用关联的小程序,appid和pagepath必须同时填写,填写后会忽略url字段 + PagePath string `json:"pagepath"` //点击消息卡片后的小程序页面,最长128字节,仅限本小程序内的页面。appid和pagepath必须同时填写,填写后会忽略url字段 +} + +//文本通知型 +type SendTextNoticeAll struct { + wechatstatice.PublicSendMsg + TemplateCard TemplateCardContText `json:"template_card"` + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} + +type TemplateCardContText struct { + CardType string `json:"card_type"` //模板卡片类型 + Source SourceText `json:"source"` //卡片来源样式信息,不需要来源样式可不填写 + ActionMenu ActionMenuCont `json:"action_menu"` //卡片右上角更多操作按钮 + TaskId string `json:"task_id"` //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填 + MainTitle MainTitleCont `json:"main_title"` //一级标题 + QuoteArea QuoteAreaCont `json:"quote_area"` //引用文献样式 + EmphasisContent EmphasisContentInfo `json:"emphasis_content"` //关键数据样式 + SubTitleText string `json:"sub_title_text"` //二级普通文本,建议不超过160个字,(支持id转译) + HorizontalContentList []HorizontalContentListInfo `json:"horizontal_content_list"` //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6 + JumpList []JumpListCont `json:"jump_list"` //跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3 + CardAction CardActionCont `json:"card_action"` //整体卡片的点击跳转事件,text_notice必填本字段 +} + +type SourceText struct { + PublicSource + DescColor int `json:"desc_color"` //来源文字的颜色,目前支持:0(默认) 灰色,1 黑色,2 红色,3 绿色 +} +type ActionMenuCont struct { + Desc string `json:"desc"` //更多操作界面的描述 + ActionList []ActionListCont `json:"action_list"` //操作列表,列表长度取值范围为 [1, 3] +} +type ActionListCont struct { + Key string `json:"key"` //操作key值,用户点击后,会产生回调事件将本参数作为EventKey返回,回调事件会带上该key值,最长支持1024字节,不可重复 + Text string `json:"text"` //操作的描述文案 +} +type MainTitleCont struct { + Title string `json:"title"` //标题,建议不超过36个字,文本通知型卡片本字段非必填 + Desc string `json:"desc"` //标题辅助信息,建议不超过44个字 +} +type QuoteAreaCont struct { + Type int `json:"type"` //引用文献样式区域点击事件,0或不填代表没有点击事件,1 代表跳转url,2 代表跳转小程序 + Url string `json:"url"` //点击跳转的url,quote_area.type是1时必填 + Title string `json:"title"` //引用文献样式的标题 + QuoteText string `json:"quote_text"` //引用文献样式的引用文案 + SmaillSub +} +type EmphasisContentInfo struct { + MainTitleCont +} +type HorizontalContentListInfo struct { + Type int `json:"type"` //链接类型,0或不填代表不是链接,1 代表跳转url,2 代表下载附件,3 代表点击跳转成员详情 + KeyName string `json:"keyname"` //二级标题,建议不超过5个字 + Value string `json:"value"` //二级文本,如果horizontal_content_list.type是2,该字段代表文件名称(要包含文件类型),建议不超过30个字,(支持id转译) + Url string `json:"url"` //链接跳转的url,horizontal_content_list.type是1时必填 + MediaIdCont //附件的media_id,horizontal_content_list.type是2时必填 + Userid string `json:"userid"` //成员详情的userid,horizontal_content_list.type是3时必填 +} +type JumpListCont struct { + Title string `json:"title"` //跳转链接样式的文案内容,建议不超过18个字 + CardActionCont +} + +type CardActionCont struct { + Type int `json:"type"` //跳转事件类型,1 代表跳转url,2 代表打开小程序。text_notice卡片模版中该字段取值范围为[1,2] + Url string `json:"url"` //跳转事件的url,card_action.type是1时必填 + SmaillSub +} + +//文本通知型(引用文献+发送人) +type SendTextNoticeQuoteMan struct { + wechatstatice.PublicSendMsg + TemplateCard TemplateCardQuoteMan `json:"template_card"` + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} +type TemplateCardQuoteMan struct { + CardType string `json:"card_type"` //模板卡片类型 + Source SourceText `json:"source"` //卡片来源样式信息,不需要来源样式可不填写 + TaskId string `json:"task_id"` //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填 + MainTitle MainTitleCont `json:"main_title"` //一级标题 + QuoteArea QuoteAreaCont `json:"quote_area"` //引用文献样式 + HorizontalContentList []HorizontalContentListInfo `json:"horizontal_content_list"` //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6 + JumpList []JumpListCont `json:"jump_list"` //跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3 + CardAction CardActionCont `json:"card_action"` //整体卡片的点击跳转事件,text_notice必填本字段 +} + +//文本通知型(一级标题+二级文本+发送人) +type SendTextNoticeOneAndTwoTitleMan struct { + wechatstatice.PublicSendMsg + TemplateCard TemplateCardOneAndTwoMan `json:"template_card"` + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} +type TemplateCardOneAndTwoMan struct { + CardType string `json:"card_type"` //模板卡片类型 + Source SourceText `json:"source"` //卡片来源样式信息,不需要来源样式可不填写 + TaskId string `json:"task_id"` //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填 + MainTitle MainTitleCont `json:"main_title"` //一级标题 + SubTitleText string `json:"sub_title_text"` //二级普通文本,建议不超过160个字,(支持id转译) + HorizontalContentList []HorizontalContentListInfo `json:"horizontal_content_list"` //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6 + JumpList []JumpListCont `json:"jump_list"` //跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3 + CardAction CardActionCont `json:"card_action"` //整体卡片的点击跳转事件,text_notice必填本字段 +} + +//图文展示型(All) +type SendImageNoticeAll struct { + wechatstatice.PublicSendMsg + TemplateCard TemplateCardContImage `json:"template_card"` + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} +type TemplateCardContImage struct { + CardType string `json:"card_type"` //模板卡片类型 + Source SourceText `json:"source"` //卡片来源样式信息,不需要来源样式可不填写 + ActionMenu ActionMenuCont `json:"action_menu"` //卡片右上角更多操作按钮 + TaskId string `json:"task_id"` //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填 + MainTitle MainTitleCont `json:"main_title"` //一级标题 + QuoteArea QuoteAreaCont `json:"quote_area"` //引用文献样式 + + ImageTextArea ImageTextAreaCont `json:"image_text_area"` //左图右文样式,news_notice类型的卡片,card_image和image_text_area两者必填一个字段,不可都不填 + CardImage CardImageCont `json:"card_image"` //图片样式,news_notice类型的卡片,card_image和image_text_area两者必填一个字段,不可都不填 + VerticalContentList VerticalContentListCont `json:"vertical_content_list"` //卡片二级垂直内容,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过4 + + HorizontalContentList []HorizontalContentListInfo `json:"horizontal_content_list"` //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6 + JumpList []JumpListCont `json:"jump_list"` //跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3 + CardAction CardActionCont `json:"card_action"` //整体卡片的点击跳转事件,text_notice必填本字段 +} +type ImageTextAreaCont struct { + Type int `json:"type"` //左图右文样式区域点击事件,0或不填代表没有点击事件,1 代表跳转url,2 代表跳转小程序 + Url string `json:"url"` //点击跳转的url,image_text_area.type是1时必填 + Title string `json:"title"` //左图右文样式的标题 + Desc string `json:"desc"` //左图右文样式的描述 + ImageUrl string `json:"image_url"` //左图右文样式的图片url +} +type CardImageCont struct { + Url string `json:"url"` //图片的url + AspectRatio float64 `json:"aspect_ratio"` //图片的宽高比,宽高比要小于2.25,大于1.3,不填该参数默认1.3 +} +type VerticalContentListCont struct { + Title string `json:"title"` //卡片二级标题,建议不超过38个字 + Desc string `json:"desc"` //二级普通文本,建议不超过160个字 +} + +//图文展示型(一级标题+图片) +type SendImageNoticeOneImg struct { + wechatstatice.PublicSendMsg + TemplateCard TemplateCardOneImg `json:"template_card"` + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} +type TemplateCardOneImg struct { + CardType string `json:"card_type"` //模板卡片类型 + Source SourceText `json:"source"` //卡片来源样式信息,不需要来源样式可不填写 + TaskId string `json:"task_id"` //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填 + MainTitle MainTitleCont `json:"main_title"` //一级标题 + QuoteArea QuoteAreaCont `json:"quote_area"` //引用文献样式 + CardImage CardImageCont `json:"card_image"` //图片样式,news_notice类型的卡片,card_image和image_text_area两者必填一个字段,不可都不填 + HorizontalContentList []HorizontalContentListInfo `json:"horizontal_content_list"` //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6 + JumpList []JumpListCont `json:"jump_list"` //跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3 + CardAction CardActionCont `json:"card_action"` //整体卡片的点击跳转事件,text_notice必填本字段 +} + +//图文展示型(卡片二级垂直内容+图片) +type SendImageNoticeImgVer struct { + wechatstatice.PublicSendMsg + TemplateCard TemplateCardImgVer `json:"template_card"` + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} +type TemplateCardImgVer struct { + CardType string `json:"card_type"` //模板卡片类型 + Source SourceText `json:"source"` //卡片来源样式信息,不需要来源样式可不填写 + TaskId string `json:"task_id"` //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填 + QuoteArea QuoteAreaCont `json:"quote_area"` //引用文献样式 + CardImage CardImageCont `json:"card_image"` //图片样式,news_notice类型的卡片,card_image和image_text_area两者必填一个字段,不可都不填 + VerticalContentList VerticalContentListCont `json:"vertical_content_list"` //卡片二级垂直内容,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过4 + HorizontalContentList []HorizontalContentListInfo `json:"horizontal_content_list"` //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6 + JumpList []JumpListCont `json:"jump_list"` //跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3 + CardAction CardActionCont `json:"card_action"` //整体卡片的点击跳转事件,text_notice必填本字段 + MainTitle MainTitleCont `json:"main_title"` //一级标题 +} + +//图文展示型(左图右文样式) +type SendImageNoticeLImgRText struct { + wechatstatice.PublicSendMsg + TemplateCard TemplateCardLImgRText `json:"template_card"` + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} +type TemplateCardLImgRText struct { + CardType string `json:"card_type"` //模板卡片类型 + Source SourceText `json:"source"` //卡片来源样式信息,不需要来源样式可不填写 + TaskId string `json:"task_id"` //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填 + + MainTitle MainTitleCont `json:"main_title"` //一级标题 + CardImage CardImageCont `json:"card_image"` //图片样式,news_notice类型的卡片,card_image和image_text_area两者必填一个字段,不可都不填 + ImageTextArea ImageTextAreaCont `json:"image_text_area"` //左图右文样式,news_notice类型的卡片,card_image和image_text_area两者必填一个字段,不可都不填 + + HorizontalContentList []HorizontalContentListInfo `json:"horizontal_content_list"` //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6 + JumpList []JumpListCont `json:"jump_list"` //跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3 + CardAction CardActionCont `json:"card_action"` //整体卡片的点击跳转事件,text_notice必填本字段 +} + +//按钮交互型(All) +type SendButtonInteractionAll struct { + wechatstatice.PublicSendMsg + TemplateCard TemplateButtonInteraction `json:"template_card"` + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} +type TemplateButtonInteraction struct { + CardType string `json:"card_type"` //模板卡片类型 + Source SourceText `json:"source"` //卡片来源样式信息,不需要来源样式可不填写 + ActionMenu ActionMenuCont `json:"action_menu"` //卡片右上角更多操作按钮 + TaskId string `json:"task_id"` //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填 + MainTitle MainTitleCont `json:"main_title"` //一级标题 + QuoteArea QuoteAreaCont `json:"quote_area"` //引用文献样式 + + SubTitleText string `json:"sub_title_text"` //二级普通文本,建议不超过160个字,(支持id转译) + + ButtonSelection ButtonSelectionCont `json:"button_selection"` + ButtonList []ButtonListCont `json:"button_list"` + + HorizontalContentList []HorizontalContentListInfo `json:"horizontal_content_list"` //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6 + CardAction CardActionCont `json:"card_action"` //整体卡片的点击跳转事件,text_notice必填本字段 +} + +type ButtonSelectionCont struct { + QuestionKey string `json:"question_key"` + Title string `json:"title"` //标题,建议不超过36个字,文本通知型卡片本字段非必填 + SelectedId string `json:"selected_id"` + OptionList []OptionListCont `json:"option_list"` +} +type OptionListCont struct { + Id string `json:"id"` + Text string `json:"text"` +} +type ButtonListCont struct { + Text string `json:"text"` + Style int `json:"style"` + Key string `json:"key"` +} + +//按钮交互型(simplify) +type SendButtonInteractionSimplify struct { + wechatstatice.PublicSendMsg + TemplateCard TemplateButtonInteractionSimplify `json:"template_card"` + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} +type TemplateButtonInteractionSimplify struct { + CardType string `json:"card_type"` //模板卡片类型 + Source SourceText `json:"source"` //卡片来源样式信息,不需要来源样式可不填写 + TaskId string `json:"task_id"` //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填 + MainTitle MainTitleCont `json:"main_title"` //一级标题 + SubTitleText string `json:"sub_title_text"` //二级普通文本,建议不超过160个字,(支持id转译) + QuoteArea QuoteAreaCont `json:"quote_area"` //引用文献样式 + ButtonList []ButtonListCont `json:"button_list"` + HorizontalContentList []HorizontalContentListInfo `json:"horizontal_content_list"` //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6 + CardAction CardActionCont `json:"card_action"` //整体卡片的点击跳转事件,text_notice必填本字段 +} + +//投票选择型 +type SendVoteInteraction struct { + wechatstatice.PublicSendMsg + TemplateCard TemplateVoteInteraction `json:"template_card"` + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} +type TemplateVoteInteraction struct { + CardType string `json:"card_type"` //模板卡片类型 + Source SourceText `json:"source"` //卡片来源样式信息,不需要来源样式可不填写 + MainTitle MainTitleCont `json:"main_title"` //一级标题 + TaskId string `json:"task_id"` //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填 + CheckBox CheckBoxCont `json:"checkbox"` + SubmitButton ActionListCont `json:"submit_button"` +} +type CheckBoxCont struct { + QuestionKey string `json:"question_key"` //选择题key值,用户提交选项后,会产生回调事件,回调事件会带上该key值表示该题,最长支持1024字节 + OptionList []OptionListContCheckBox `json:"option_list"` //选项list,选项个数不超过 20 个,最少1个 + Mode int `json:"mode"` // 选择题模式,单选:0,多选:1,不填默认0 +} +type OptionListContCheckBox struct { + OptionListCont + IsChecked bool `json:"is_checked"` //该选项是否要默认选中 +} + +//多项选择型 +type SendMultipleInteraction struct { + wechatstatice.PublicSendMsg + TemplateCard TemMultipleInteraction `json:"template_card"` + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} +type TemMultipleInteraction struct { + CardType string `json:"card_type"` //模板卡片类型 + Source SourceText `json:"source"` //卡片来源样式信息,不需要来源样式可不填写 + MainTitle MainTitleCont `json:"main_title"` //一级标题 + TaskId string `json:"task_id"` //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填 + SelectList []ButtonSelectionCont `json:"select_list"` + SubmitButton ActionListCont `json:"submit_button"` +} diff --git a/middleware/wechatapp/wechatsendmsg/type.go b/middleware/wechatapp/wechatsendmsg/type.go index 40f7e22..9570c81 100644 --- a/middleware/wechatapp/wechatsendmsg/type.go +++ b/middleware/wechatapp/wechatsendmsg/type.go @@ -1,4 +1,116 @@ package wechatsendmsg +import "key_performance_indicators/middleware/wechatapp/wechatstatice" + //企业微信发送消息 type ApiRouter struct{} + +//通用文本信息 +type PublicTextCont struct { + Title string `json:"title"` //消息的标题,不超过128个字节,超过会自动截断 + Description string `json:"description"` //消息的描述,不超过512个字节,超过会自动截断 +} + +//消息内容结构体 +type TextMsgCont struct { + Content string `json:"content"` //消息内容,最长不超过2048个字节,超过将截断(支持id转译) +} + +type MediaIdCont struct { + MediaId string `json:"media_id"` //文件id,可以调用上传临时素材接口获取 +} + +//发送文本消息求情结构体 +type SendTextMsg struct { + wechatstatice.PublicSendMsg + MsgBody TextMsgCont `json:"text"` + Safe int `json:"safe"` //表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0 + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} + +//发送语音消息 +type SendVoiceMsg struct { + wechatstatice.PublicSendMsg + Voice MediaIdCont `json:"voice"` +} + +//发送图片信息 +type SendImage struct { + wechatstatice.PublicSendMsg + MsgBody MediaIdCont `json:"image"` + Safe int `json:"safe"` //表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0 +} + +//发送视频信息 +type SendVideo struct { + wechatstatice.PublicSendMsg + MsgBody VideoContSend `json:"video"` + Safe int `json:"safe"` //表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0 +} +type VideoContSend struct { + MediaIdCont + PublicTextCont +} + +//发送文件消息 +type SendFile struct { + wechatstatice.PublicSendMsg + MsgBody MediaIdCont `json:"file"` + Safe int `json:"safe"` //表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0 +} + +//发送文本卡片消息 +type SendTextCard struct { + wechatstatice.PublicSendMsg + MsgBody TextCardCont `json:"textcard"` + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} +type TextCardCont struct { + PublicTextCont + URL string `json:"url"` //点击后跳转的链接。最长2048字节,请确保包含了协议头(http/https) + BtnTxt string `json:"btntxt"` //按钮文字。 默认为“详情”, 不超过4个文字,超过自动截断。 +} + +//发送图文消息 +type SendNews struct { + wechatstatice.PublicSendMsg + MsgBody NewsArticles `json:"news"` + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} + +type NewsArticles struct { + Articles []ArticlesList `json:"articles"` //图文消息,一个图文消息支持1到8条图文 +} +type ArticlesList struct { + PublicTextCont + URL string `json:"url"` //点击后跳转的链接。最长2048字节,请确保包含了协议头(http/https) + PicURL string `json:"picurl"` //图文消息的图片链接,最长2048字节,支持JPG、PNG格式,较好的效果为大图 1068*455,小图150*150。 + Appid string `json:"appid"` //小程序appid,必须是与当前应用关联的小程序,appid和pagepath必须同时填写,填写后会忽略url字段 + PagePath string `json:"pagepath"` //点击消息卡片后的小程序页面,最长128字节,仅限本小程序内的页面。appid和pagepath必须同时填写,填写后会忽略url字段 + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} + +//发送图文消息(mpnews) +type SendMpNews struct { + wechatstatice.PublicSendMsg + MsgBody NewsArticlesMp `json:"mpnews"` + Safe int `json:"safe"` //表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0 + EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。 +} +type NewsArticlesMp struct { + Articles []ArticlesListMp `json:"articles"` //图文消息,一个图文消息支持1到8条图文 +} +type ArticlesListMp struct { + Title string `json:"title"` //消息的标题,不超过128个字节,超过会自动截断 + ThumbMediaId string `json:"thumb_media_id"` + Author string `json:"author"` + ContentSourceUrl string `json:"content_source_url"` + Content string `json:"content"` + Digest string `json:"digest"` +} + +//发送markdown消息 +type SendMarkDown struct { + wechatstatice.PublicSendMsg + MsgBody TextMsgCont `json:"markdown"` +} diff --git a/middleware/wechatapp/wechatstatice/method.go b/middleware/wechatapp/wechatstatice/method.go index d3cebb8..ef1471f 100644 --- a/middleware/wechatapp/wechatstatice/method.go +++ b/middleware/wechatapp/wechatstatice/method.go @@ -31,6 +31,7 @@ func GetWechatToken(systemApp string) (token string, err error) { } isTrue, token := redisClient.Get(redisFileKey) if isTrue == true { + err = nil return } //重新获取token @@ -104,7 +105,7 @@ func WechatDecryptJson(systemApp string) (wxcpt *wxbizjsonmsgcrypt.WXBizMsgCrypt token = overall.CONSTANT_CONFIG.WechatSchool.Token encodingAesKey = overall.CONSTANT_CONFIG.WechatSchool.Encodingaeskey } - fmt.Printf("WechatDecryptJson------->%v------->%v------->%v\n", token, overall.CONSTANT_CONFIG.WechatCompany.CompanyId, encodingAesKey) + // fmt.Printf("WechatDecryptJson------->%v------->%v------->%v\n", token, overall.CONSTANT_CONFIG.WechatCompany.CompanyId, encodingAesKey) wxcpt = wxbizjsonmsgcrypt.NewWXBizMsgCrypt(token, encodingAesKey, overall.CONSTANT_CONFIG.WechatCompany.CompanyId, wxbizjsonmsgcrypt.JsonType) return } @@ -134,7 +135,20 @@ func WechatDecryptXml(systemApp string) (wxcpt *wxbizmsgcrypt.WXBizMsgCrypt) { token = overall.CONSTANT_CONFIG.WechatSchool.Token encodingAesKey = overall.CONSTANT_CONFIG.WechatSchool.Encodingaeskey } - fmt.Printf("WechatDecryptXml------->%v------->%v------->%v\n", token, overall.CONSTANT_CONFIG.WechatCompany.CompanyId, encodingAesKey) + // fmt.Printf("WechatDecryptXml------->%v------->%v------->%v\n", token, overall.CONSTANT_CONFIG.WechatCompany.CompanyId, encodingAesKey) wxcpt = wxbizmsgcrypt.NewWXBizMsgCrypt(token, encodingAesKey, overall.CONSTANT_CONFIG.WechatCompany.CompanyId, wxbizmsgcrypt.XmlType) return } + +// 撤回应用消息 +func (r *RevokeMsgSend) RevokeMsgSendCont(systemApp string) (revokeCont RevokeMsgSendCallBack, err error) { + sendUrl, _, err := GetSendMsgTokenUrl(systemApp, "recall") + if err != nil { + revokeCont.Errcode = 5000 + return + } + sendDate, _ := json.Marshal(r) + callBackByte := publicmethod.CurlPostJosn(sendUrl, sendDate) + err = json.Unmarshal(callBackByte, &revokeCont) + return +} diff --git a/middleware/wechatapp/wechatstatice/type.go b/middleware/wechatapp/wechatstatice/type.go index 4ac4ced..1616d94 100644 --- a/middleware/wechatapp/wechatstatice/type.go +++ b/middleware/wechatapp/wechatstatice/type.go @@ -2,9 +2,50 @@ package wechatstatice //组织架构返回统类 type weChatCallBack struct { - Errcode int `json:"errcode"` - Errmsg string `json:"errmsg"` + RevokeMsgSendCallBack Accesstoken string `json:"access_token"` Expiresin int64 `json:"expires_in"` Ticket string `json:"ticket"` } + +//发送消息公共结构体 +type PublicSendMsgSmaillSub struct { + Touser string `json:"touser"` //指定接收消息的成员,成员ID列表;特殊情况:指定为"@all",则向该企业应用的全部成员发送;最多支持1000个 + Toparty string `json:"toparty"` //指定接收消息的部门,部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为"@all"时忽略本参数 + Totag string `json:"totag"` //指定接收消息的标签,标签ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为"@all"时忽略本参数 + Msgtype string `json:"msgtype"` //消息类型 +} + +//通用 +type PublicSendMsg struct { + PublicSendMsgSmaillSub + Agentid int64 `json:"agentid"` //企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值 + + PublicSendMsgBootem +} + +//底部参数 +type PublicSendMsgBootem struct { + EnableDuplicateCheck int `json:"enable_duplicate_check"` //表示是否开启重复消息检查,0表示否,1表示是,默认0 + DuplicateCheckInterval int `json:"duplicate_check_interval"` //表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时 +} + +//返回通用结构体 +type SendCallBackMsg struct { + RevokeMsgSendCallBack + Invaliduser string `json:"invaliduser"` //不合法的userid,不区分大小写,统一转为小写 + Invalidparty string `json:"invalidparty"` //不合法的partyid + Invalidtag string `json:"invalidtag"` //不合法的标签id + Unlicenseduser string `json:"unlicenseduser"` //没有基础接口许可(包含已过期)的userid + Msgid string `json:"msgid"` // 消息id,用于撤回应用消息 + ResponseCode string `json:"response_code"` //仅消息类型为“按钮交互型”,“投票选择型”和“多项选择型”的模板卡片消息返回,应用可使用response_code调用更新模版卡片消息接口,24小时内有效,且只能使用一次 +} + +//消息ID。从应用发送消息接口处获得。 +type RevokeMsgSend struct { + Msgid string `json:"msgid"` // 消息id,用于撤回应用消息 +} +type RevokeMsgSendCallBack struct { + Errcode int `json:"errcode"` //返回码 + Errmsg string `json:"errmsg"` //对返回码的文本描述内容 +} diff --git a/models/modelskpi/open_approval_change_log.go b/models/modelskpi/open_approval_change_log.go new file mode 100644 index 0000000..35be927 --- /dev/null +++ b/models/modelskpi/open_approval_change_log.go @@ -0,0 +1,73 @@ +package modelskpi + +import ( + "key_performance_indicators/overall" + "strings" +) + +// 审批记录 +type OpenApprovalChangeLog struct { + Id int64 `json:"id" gorm:"primaryKey;column:id;type:bigint(20) unsigned;not null;comment:Id;index"` + Type int `json:"type" gorm:"column:type;type:int(1) unsigned;default:1;not null;comment:类型(1:部门;2:岗位)"` + Title string `json:"title" gorm:"column:title;type:varchar(255);comment:节点名称"` + Operator int64 `json:"operator" gorm:"column:operator;type:bigint(20);comment:操作人"` + OrderId int64 `json:"orderid" gorm:"column:orderid;type:bigint(20) unsigned;default:0;not null;comment:订单ID"` + OperatorTime int64 `json:"operatortime" gorm:"column:operatortime;type:bigint(20) unsigned;default:0;not null;comment:操作时间"` + Step int `json:"step" gorm:"column:step;type:int(5) unsigned;default:1;not null;comment:操作第几步"` + OperatorType int `json:"operatortype" gorm:"column:operatortype;type:int(1) unsigned;default:1;not null;comment:操作状态(1:位操作;2:已操作)"` + Msgid string `json:"msgid" gorm:"column:msgid;type:varchar(255);comment:消息id,用于撤回应用消息"` + ResponseCode string `json:"responsecode" gorm:"column:response_code;type:varchar(255);comment:仅消息类型为“按钮交互型”,“投票选择型”和“多项选择型”的模板卡片消息返回,应用可使用response_code调用更新模版卡片消息接口,24小时内有效,且只能使用一次"` + Stepper int `json:"stepper" gorm:"column:stepper;type:int(5) unsigned;default:1;not null;comment:步进器"` + ChangeIsTrue int `json:"changeistrue" gorm:"column:change_is_true;type:int(1) unsigned;default:1;not null;comment:是否可变更(1:可变更;2:不可变更)"` +} + +func (OpenApprovalChangeLog *OpenApprovalChangeLog) TableName() string { + return "open_approval_change_log" +} + +// 编辑内容 +func (cont *OpenApprovalChangeLog) EiteCont(whereMap interface{}, saveData interface{}) (err error) { + err = overall.CONSTANT_DB_KPI.Model(&cont).Where(whereMap).Updates(saveData).Error + return +} + +// 获取内容 +func (cont *OpenApprovalChangeLog) 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 *OpenApprovalChangeLog) CountCont(whereMap interface{}) (countId int64) { + overall.CONSTANT_DB_KPI.Model(&cont).Where(whereMap).Count(&countId) + return +} + +// 读取全部信息 +func (cont *OpenApprovalChangeLog) ContMap(whereMap interface{}, field ...string) (countAry []OpenApprovalChangeLog, 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 *OpenApprovalChangeLog) DelCont(whereMap interface{}) (err error) { + err = overall.CONSTANT_DB_KPI.Where(whereMap).Delete(&cont).Error + return +} + +// 添加记录 +func (cont *OpenApprovalChangeLog) AddCont() (err error) { + err = overall.CONSTANT_DB_KPI.Create(&cont).Error + return +} diff --git a/models/modelskpi/operator_is_true.go b/models/modelskpi/operator_is_true.go new file mode 100644 index 0000000..e66eb46 --- /dev/null +++ b/models/modelskpi/operator_is_true.go @@ -0,0 +1,69 @@ +package modelskpi + +import ( + "key_performance_indicators/overall" + "strings" +) + +// 当前节点是否可操作 +type OperatorIsTrue struct { + Id int64 `json:"id" gorm:"primaryKey;column:id;type:bigint(20) unsigned;not null;comment:Id;index"` + OrderId int64 `json:"orderid" gorm:"column:orderid;type:bigint(20) unsigned;default:0;not null;comment:订单ID"` + Step int `json:"step" gorm:"column:step;type:int(5) unsigned;default:1;not null;comment:审批到第几步"` + State int `json:"state" gorm:"column:state;type:int(1) unsigned;default:1;not null;comment:状态:1:可操作;2:不可操作"` + Time int64 `json:"time" gorm:"column:time;type:bigint(20) unsigned;default:0;not null;comment:操作时间"` + Msgid string `json:"msgid" gorm:"column:msgid;type:varchar(255);comment:消息id,用于撤回应用消息"` + ResponseCode string `json:"responsecode" gorm:"column:response_code;type:varchar(255);comment:仅消息类型为“按钮交互型”,“投票选择型”和“多项选择型”的模板卡片消息返回,应用可使用response_code调用更新模版卡片消息接口,24小时内有效,且只能使用一次"` + Stepper int `json:"stepper" gorm:"column:stepper;type:int(5) unsigned;default:1;not null;comment:步进器"` +} + +func (OperatorIsTrue *OperatorIsTrue) TableName() string { + return "operator_is_true" +} + +// 编辑内容 +func (cont *OperatorIsTrue) EiteCont(whereMap interface{}, saveData interface{}) (err error) { + err = overall.CONSTANT_DB_KPI.Model(&cont).Where(whereMap).Updates(saveData).Error + return +} + +// 获取内容 +func (cont *OperatorIsTrue) 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 *OperatorIsTrue) CountCont(whereMap interface{}) (countId int64) { + overall.CONSTANT_DB_KPI.Model(&cont).Where(whereMap).Count(&countId) + return +} + +// 读取全部信息 +func (cont *OperatorIsTrue) ContMap(whereMap interface{}, field ...string) (countAry []OperatorIsTrue, 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 *OperatorIsTrue) DelCont(whereMap interface{}) (err error) { + err = overall.CONSTANT_DB_KPI.Where(whereMap).Delete(&cont).Error + return +} + +// 添加记录 +func (cont *OperatorIsTrue) AddCont() (err error) { + err = overall.CONSTANT_DB_KPI.Create(&cont).Error + return +} diff --git a/models/modelskpi/post_target.go b/models/modelskpi/post_target.go index 56917de..ba89077 100644 --- a/models/modelskpi/post_target.go +++ b/models/modelskpi/post_target.go @@ -1,6 +1,7 @@ package modelskpi import ( + "fmt" "key_performance_indicators/overall" "strings" ) @@ -40,11 +41,15 @@ func (cont *PostTarget) EiteCont(whereMap interface{}, saveData interface{}) (er func (cont *PostTarget) 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) + // fieldStr := strings.Join(field, ",") + // gormDb = gormDb.Select(fieldStr) + for _, v := range field { + gormDb = gormDb.Select(v) + } } gormDb = gormDb.Where(whereMap) err = gormDb.First(&cont).Error + fmt.Printf("GetCont---------->%v------->%v\n", err, cont) return } diff --git a/models/modelskpi/qualitative_evaluation_scheme.go b/models/modelskpi/qualitative_evaluation_scheme.go index e36bf2b..c76ba24 100644 --- a/models/modelskpi/qualitative_evaluation_scheme.go +++ b/models/modelskpi/qualitative_evaluation_scheme.go @@ -32,6 +32,7 @@ type QualitativeEvaluationScheme struct { Punishmode int `json:"punishmode" gorm:"column:punishmode;type:tinyint(1) unsigned;default:1;not null;comment:处罚方式 1:扣分;2:现金处罚;3:扣分加现金"` Maxmoney int64 `json:"maxmoney" gorm:"column:maxmoney;type:bigint(20) unsigned;default:0;not null;comment:最高罚款*100保存"` Minmoney int64 `json:"minmoney" gorm:"column:minmoney;type:bigint(20) unsigned;default:0;not null;comment:最低罚款*100保存"` + AddReduce int `json:"add_reduce" gorm:"column:add_reduce;type:int(1) unsigned;default:0;not null;comment:1:减少;2:增加;3:无属性,现场确认加或减"` } func (QualitativeEvaluationScheme *QualitativeEvaluationScheme) TableName() string { diff --git a/models/modelsschool/step_role_group.go b/models/modelsschool/step_role_group.go index 54dd410..c77e5a8 100644 --- a/models/modelsschool/step_role_group.go +++ b/models/modelsschool/step_role_group.go @@ -1,8 +1,11 @@ package modelsschool -import "key_performance_indicators/overall" +import ( + "key_performance_indicators/overall" + "strings" +) -//角色组(审批流程使用) +// 角色组(审批流程使用) type RoleGroup struct { Id int64 `json:"id" gorm:"primaryKey;column:srg_id;type:bigint(20) unsigned;not null;comment:Id;index"` Title string `json:"title" gorm:"column:srg_name;type:text;comment:角色名称"` @@ -17,19 +20,28 @@ func (RoleGroup *RoleGroup) TableName() string { return "step_role_group" } -//获取详情 +// 获取详情 func (cont *RoleGroup) GetCont(where interface{}, filed ...string) error { - gormDb := overall.CONSTANT_DB_Master.Where(where) + // gormDb := overall.CONSTANT_DB_Master.Where(where) + // if len(filed) > 0 { + // fieldStr := strings.Join(filed, ",") + // gormDb = gormDb.Select(fieldStr) + // } + // err := gormDb.First(&cont).Error + // return err + // fmt.Println("败笔") + gormDb := overall.CONSTANT_DB_Master.Model(&cont) if len(filed) > 0 { - for _, v := range filed { - gormDb = gormDb.Select(v) - } + fieldStr := strings.Join(filed, ",") + gormDb = gormDb.Select(fieldStr) } + gormDb = gormDb.Where(where) err := gormDb.First(&cont).Error + // fmt.Println("败笔", cont) return err } -//编辑内容 +// 编辑内容 func (cont *RoleGroup) EiteCont(whereMap interface{}, saveData interface{}) (err error) { err = overall.CONSTANT_DB_Master.Model(&cont).Where(whereMap).Updates(saveData).Error return diff --git a/overall/publicmethod/technique.go b/overall/publicmethod/technique.go index 86aa8ab..d0386c7 100644 --- a/overall/publicmethod/technique.go +++ b/overall/publicmethod/technique.go @@ -1152,3 +1152,93 @@ func GetPostOfUsEmpowerCont(orgId, postId int64, systemName string) (sysPowerCon } return } + +// 步骤名称 +func GetSetpName(setId int) (setpName string) { + switch setId { + case 1: + setpName = "创建申请" + case 2: + setpName = "审核确认" + case 3: + setpName = "责任划分" + case 4: + setpName = "整改措施" + case 5: + setpName = "整改验收" + case 6: + setpName = "抄送" + case 7: + // setpName = "部门负责人" + setpName = "审核确认" + default: + setpName = "创建申请" + } + return +} + +/* +* +@ 作者: 秦东 +@ 时间: 2022-10-01 10:44:41 +@ 功能: 获取企业微信审批组相关负责人 +@ 参数 + + #wechatTeamId 审批数据库节点ID + #departmentId 部门ID + +@ 返回值 + + #userStrList 微信Openid + #err cuo +*/ +func GetRefereeTeamWorkWechat(wechatTeamId, departmentId int64) (userStrList []string, err error) { + var orgCont modelshr.AdministrativeOrganization + err = orgCont.GetCont(map[string]interface{}{"`id`": departmentId}, "`wechat_organization_id`") + // fmt.Printf("orgCont------------>%v\n", err) + if err != nil { + return + } + //获取角色组数据 + var roleCont modelsschool.RoleGroup + err = roleCont.GetCont(map[string]interface{}{"`srg_id`": wechatTeamId}, "`srg_extatry`", "`srg_type`") + // fmt.Printf("orgCont:%v------------>roleCont:%v\n", err, roleCont) + if err != nil { + return + } + var roleUser []roleGroupBodyAry + if roleCont.Type == 1 { + //矩阵 + roleList := MapOut[string]() + err = json.Unmarshal([]byte(roleCont.Contentes), &roleList) + + if err != nil { + return + } + departmentIdStr := strconv.FormatInt(orgCont.WechatOrganizationId, 10) + // fmt.Printf("roleList------矩阵------>%v------>%v\n", roleList, departmentIdStr) + for i, v := range roleList { + if i == departmentIdStr { + jsonMAp, _ := json.Marshal(v) + json.Unmarshal(jsonMAp, &roleUser) + } + + } + + } else { + //个人 + err = json.Unmarshal([]byte(roleCont.Contentes), &roleUser) + } + if len(roleUser) < 1 { + err = fmt.Errorf("没有数据!") + } + // fmt.Printf("roleUser------------>%v\n", roleUser) + for _, v := range roleUser { + if IsInTrue[string](v.Id, userStrList) == false { + userStrList = append(userStrList, v.Id) + } + } + return +} + +//传教审批记录 diff --git a/overall/publicmethod/type.go b/overall/publicmethod/type.go index 74639d5..a615949 100644 --- a/overall/publicmethod/type.go +++ b/overall/publicmethod/type.go @@ -147,3 +147,53 @@ type AuthenticationPower struct { PointIdList []string `json:"point_id_list"` OrganizationList []string `json:"organization"` } + +// 流程结构体 +type FlowChartList struct { + Step int `json:"step"` //步伐 + NodeName string `json:"nodename"` //节点名称 + State int `json:"state"` //状态 1、不点亮;2、点亮 + Class int `json:"class"` //节点类型 1、普通节点;2、运行中指定节点 + RunType int `json:"runtype"` //运行状态(1:开始;2:操作点;3:结束) + UserList []UserListFlowAll `json:"userlist"` //节点操作人 +} + +// 节点操作人 +type UserListFlowAll struct { + Id string `json:"id"` //操作人ID + Name string `json:"name"` //操作人姓名 + Icon string `json:"icon"` //操作人头像 + Wechat string `json:"wechat"` //微信Openid + Company int64 `json:"company"` //公司 + CompanyName string `json:"companyname"` //公司名称 + DepartmentId int64 `json:"departmentid"` //分厂Id + DepartmentName string `json:"departmentname"` //分厂名称 + WorkshopId int64 `json:"workshopid"` //工段Id + WorkshopName string `json:"workshopname"` //工段名称 + 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 FlowNodePeopleInfo struct { + EvalCont UserListFlowAll `json:"evalcont"` + DutyCont UserListFlowAll `json:"dutycont"` +} + +type roleGroupBodyAry struct { + Id string `json:"open_id"` + WechatName string `json:"wechat_name"` + Prentid string `json:"prentid"` + Bfid string `json:"bf_id"` + Icons string `json:"icons"` +}