Browse Source

处理工作流发送信息

li_v1
hreenshan112 1 year ago
parent
commit
1cd4e99220
  1. 2
      api/personalityTest/entry.go
  2. 2
      api/personalityTest/rongXinPage/controller.go
  3. 33
      api/personalityTest/rongXinPage/downLoad.go
  4. 296
      api/personalityTest/rongXinPage/testCaput.go
  5. 11
      api/personalityTest/rongXinPage/type.go
  6. 6
      api/shiyan/maptostruct/shiyan.go
  7. 154
      api/version1/customerApp/runAppControll.go
  8. 17
      api/version1/customerApp/type.go
  9. 58
      api/version1/customerform/formTable.go
  10. 8
      api/version1/customerform/formTableView.go
  11. 5
      api/version1/customerform/type.go
  12. 2
      api/version1/entry.go
  13. 5
      api/version1/publicapi/api.go
  14. 31
      api/version1/taskplatform/taskmanagement/flowType.go
  15. 39
      api/version1/taskplatform/taskmanagement/runTaskFlow.go
  16. 99
      api/version1/taskplatform/taskmanagement/runWorkFlow.go
  17. 272
      api/version1/taskplatform/taskmanagement/sendWechatMsg.go
  18. 1061
      api/version1/workFlow/common.go
  19. 341
      api/version1/workFlow/flow.go
  20. 189
      api/version1/workFlow/flowNode.go
  21. 41
      api/version1/workFlow/flowType.go
  22. 8
      api/version1/workFlow/type.go
  23. 662
      api/version1/workWechat/msgMap.go
  24. 529
      api/version1/workWechat/msgMethod.go
  25. 278
      api/version1/workWechat/sendMsg.go
  26. 421
      api/version1/workWechat/workMsgType.go
  27. 2
      apirouter/v1/customerformrouter/router.go
  28. 20
      apirouter/v1/taskrouter/workFlow.go
  29. 1
      apirouter/v1/workWechatRouter/router.go
  30. 5
      initialization/route/initRoute.go
  31. 1
      models/customerForm/taskrecord.go
  32. 40
      overall/publicmethod/technique.go

2
api/personalityTest/entry.go

@ -1,6 +1,6 @@
package personalityTest
import rongxin "appPlatform/api/personalityTest/rongXin"
import rongxin "appPlatform/api/personalityTest/rongXinPage"
//性格测试相关
type ApiEntry struct {

2
api/personalityTest/rongXin/controller.go → api/personalityTest/rongXinPage/controller.go

@ -1,4 +1,4 @@
package rongxin
package rongXinPage
import (
"appPlatform/models/modelshr"

33
api/personalityTest/rongXin/downLoad.go → api/personalityTest/rongXinPage/downLoad.go

@ -1,4 +1,4 @@
package rongxin
package rongXinPage
import (
"appPlatform/models/modelshr"
@ -318,6 +318,9 @@ func (a *ApiMethod) StatisticsPersonality(c *gin.Context) {
adminorg := c.Query("org")
typekey := c.Query("typekey")
types := c.Query("types")
if typekey != "" {
requestData.Typekey = typekey
}
typesInt, _ := strconv.Atoi(types)
@ -349,12 +352,27 @@ func (a *ApiMethod) StatisticsPersonality(c *gin.Context) {
builder.WriteString("\xEF\xBB\xBF") //写入UTF-8 BOM 防止乱码
writer := csv.NewWriter(&builder)
if typesInt == 2 {
// fmt.Printf("Typekey: %v\n", requestData.Typekey)
writer.Write([]string{"已完成测试人员名单"})
switch requestData.Typekey {
case "10000001": //性格色彩
writer.Write([]string{"序号", "工号", "姓名", "行政组织", "性格色彩解析"})
// fmt.Printf("Typekey----1------>: %v\n", requestData.Typekey)
case "10000002": //DISC性格特质
writer.Write([]string{"序号", "工号", "姓名", "行政组织", "DISC性格解析"})
// fmt.Printf("Typekey----2------>: %v\n", requestData.Typekey)
case "10000003": //九型人格特质
writer.Write([]string{"序号", "工号", "姓名", "行政组织", "第一角色", "第二角色", "第三角色", "第四角色"})
// fmt.Printf("Typekey----3------>: %v\n", requestData.Typekey)
default:
writer.Write([]string{"序号", "工号", "姓名", "行政组织"})
// fmt.Printf("Typekey----4------>: %v\n", requestData.Typekey)
}
} else {
writer.Write([]string{"未完成测试人员名单"})
writer.Write([]string{"序号", "工号", "姓名", "行政组织"})
}
writer.Write([]string{"序号", "工号", "姓名", "行政组织"})
jibuqi := 0
for _, v := range peopleList {
if typesInt == 2 {
@ -366,6 +384,16 @@ func (a *ApiMethod) StatisticsPersonality(c *gin.Context) {
scvBody = append(scvBody, v.Number)
scvBody = append(scvBody, v.Name)
scvBody = append(scvBody, jisuanOrg(v.Company, v.MainDeparment, v.AdminOrg))
switch requestData.Typekey {
case "10000001": //性格色彩
scvBody = append(scvBody, TallyColor(v))
case "10000002": //DISC性格特质
scvBody = append(scvBody, TallDiscCaput(v))
case "10000003": //九型人格特质
scvBody = append(scvBody, TallyNineCaput(v)...)
default:
}
writer.Write(scvBody)
}
} else {
@ -388,6 +416,7 @@ func (a *ApiMethod) StatisticsPersonality(c *gin.Context) {
if typesInt == 2 {
fileName = fmt.Sprintf("已完成测试人员名单_%v.csv", publicmethod.GetUUid(1))
}
// fmt.Printf("fileName: %v\n", fileName)
c.Writer.Header().Add("Content-type", "application/octet-stream")
c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
c.Header("Content-Disposition", "attachment; filename="+url.PathEscape(fileName))

296
api/personalityTest/rongXinPage/testCaput.go

@ -0,0 +1,296 @@
package rongXinPage
import (
"appPlatform/models/modelshr"
personalitycolor "appPlatform/models/personalityColor"
"appPlatform/overall"
"appPlatform/overall/publicmethod"
"encoding/json"
"fmt"
"sort"
"strconv"
"strings"
)
/*
*
@ 作者: 秦东
@ 时间: 2024-12-12 10:07:32
@ 功能: TallDisc测试
*/
func TallDiscCaput(user modelshr.PersonArchives) string {
var cesiJieguo []string
var colorInfo personalitycolor.Charcolortest
colorInfo.GetCont(map[string]interface{}{"`c_states`": 1, "`c_number`": user.Number, "`c_class`": 10000002}, "`c_test_json`")
if colorInfo.TestJson != "" {
var testPage JieShouDaan
json.Unmarshal([]byte(colorInfo.TestJson), &testPage)
d := 0
i := 0
s := 0
cVal := 0
for _, v := range testPage.List {
switch v.Pick {
case "D":
d++
case "I":
i++
case "S":
s++
case "C":
cVal++
default:
}
}
// disc := []string{"支配型", "影响型", "稳定型", "服从型"}
discVal := []int{d, i, s, cVal}
maxVal := 0
for _, mv := range discVal {
if maxVal <= mv {
maxVal = mv
}
}
if d == maxVal {
cesiJieguo = append(cesiJieguo, "支配型")
}
if i == maxVal {
cesiJieguo = append(cesiJieguo, "影响型")
}
if s == maxVal {
cesiJieguo = append(cesiJieguo, "稳定型")
}
if cVal == maxVal {
cesiJieguo = append(cesiJieguo, "服从型")
}
}
return strings.Join(cesiJieguo, ",")
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-12 09:20:36
@ 功能: 计算九型人格
*/
func TallyNineCaput(user modelshr.PersonArchives) []string {
var xgAry personalitycolor.Charcolortest
overall.CONSTANT_DB_Color.Model(&personalitycolor.Charcolortest{}).Where("`c_states` = 1 AND `c_class` = ? AND `c_number` = ?", 10000003, user.Number).First(&xgAry)
var jieguo []string
if xgAry.TestJson != "" {
var testPage JieShouDaaning
err := json.Unmarshal([]byte(xgAry.TestJson), &testPage)
if err == nil {
scoreForEachItem := CalculateScoresForEachItem(testPage)
sort.Slice(scoreForEachItem, func(i, j int) bool {
return scoreForEachItem[i].Value > scoreForEachItem[j].Value
})
for i, v := range scoreForEachItem {
if i < 4 {
jieguo = append(jieguo, v.Attribute)
}
}
}
}
return jieguo
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-12 09:48:23
@ 功能: 计算性格色彩
*/
func TallyColor(user modelshr.PersonArchives) string {
var colorMax []string
var myColor personalitycolor.Charcolortest
err := myColor.GetCont(map[string]interface{}{"`c_states`": 1, "`c_class`": 10000001, "`c_number`": user.Number})
if err != nil {
return strings.Join(colorMax, ",")
}
GetColorVal := make(map[string]int)
if myColor.TestJson != "" {
var testPage []TestPageColor
errJson := json.Unmarshal([]byte(myColor.TestJson), &testPage)
if errJson != nil {
var testPageStr []TestPageColorStr
json.Unmarshal([]byte(myColor.TestJson), &testPageStr)
GetColorVal = JiSuanColorStr(testPageStr)
} else {
GetColorVal = JiSuanColor(testPage)
}
}
var colorAry []int
colorAry = append(colorAry, GetColorVal["RedColor"])
colorAry = append(colorAry, GetColorVal["BlueColor"])
colorAry = append(colorAry, GetColorVal["YellowColor"])
colorAry = append(colorAry, GetColorVal["GreenColor"])
MaxColor := publicmethod.GetMaxNum[int](colorAry)
if GetColorVal["RedColor"] == MaxColor {
colorMax = append(colorMax, "红色")
}
if GetColorVal["BlueColor"] == MaxColor {
colorMax = append(colorMax, "蓝色")
}
if GetColorVal["YellowColor"] == MaxColor {
colorMax = append(colorMax, "黄色")
}
if GetColorVal["GreenColor"] == MaxColor {
colorMax = append(colorMax, "绿色")
}
return strings.Join(colorMax, ",")
}
// 计算颜色
func JiSuanColor(testPage []TestPageColor) map[string]int {
if len(testPage) < 1 {
sendDataw := make(map[string]int)
sendDataw["RedColor"] = 0
sendDataw["BlueColor"] = 0
sendDataw["YellowColor"] = 0
sendDataw["GreenColor"] = 0
return sendDataw
}
A_front_count := 0
B_front_count := 0
C_front_count := 0
D_front_count := 0
A_after_count := 0
B_after_count := 0
C_after_count := 0
D_after_count := 0
// fmt.Printf("testPage:%v\n", testPage)
for _, v := range testPage {
// testNumInt, _ := strconv.Atoi(v.TestNumber)
// checkedValInt, _ := strconv.Atoi(v.CheckedVal)
testNumInt := v.TestNumber
checkedValInt := v.CheckedVal
if testNumInt <= 15 {
switch checkedValInt {
case 2:
B_front_count++
case 3:
C_front_count++
case 4:
D_front_count++
default:
A_front_count++
}
} else {
switch checkedValInt {
case 2:
B_after_count++
case 3:
C_after_count++
case 4:
D_after_count++
default:
A_after_count++
}
}
}
fmt.Printf("A_front_count: %v, B_front_count: %v, C_front_count: %v, D_front_count: %v\n", A_front_count, B_front_count, C_front_count, D_front_count)
fmt.Printf("A_after_count: %v, B_after_count: %v, C_after_count: %v, D_after_count: %v\n", A_after_count, B_after_count, C_after_count, D_after_count)
RedColor := A_front_count + D_after_count
BlueColor := B_front_count + C_after_count
YellowColor := C_front_count + B_after_count
GreenColor := D_front_count + A_after_count
// fmt.Printf("A_front_count: %v, D_after_count: %v, B_front_count: %v, BlueColor: %v\n", A_front_count, D_after_count, B_front_count, C_after_count)
// fmt.Printf("RedColor: %v, GreenColor: %v, YellowColor: %v, BlueColor: %v\n", RedColor, GreenColor, YellowColor, BlueColor)
sendData := make(map[string]int)
sendData["RedColor"] = RedColor
sendData["BlueColor"] = BlueColor
sendData["YellowColor"] = YellowColor
sendData["GreenColor"] = GreenColor
sendData["A_front_count"] = A_front_count
sendData["B_front_count"] = B_front_count
sendData["C_front_count"] = C_front_count
sendData["D_front_count"] = D_front_count
sendData["A_after_count"] = A_after_count
sendData["B_after_count"] = B_after_count
sendData["C_after_count"] = C_after_count
sendData["D_after_count"] = D_after_count
return sendData
}
// 计算颜色
func JiSuanColorStr(testPage []TestPageColorStr) map[string]int {
if len(testPage) < 1 {
sendDataw := make(map[string]int)
sendDataw["RedColor"] = 0
sendDataw["BlueColor"] = 0
sendDataw["YellowColor"] = 0
sendDataw["GreenColor"] = 0
return sendDataw
}
A_front_count := 0
B_front_count := 0
C_front_count := 0
D_front_count := 0
A_after_count := 0
B_after_count := 0
C_after_count := 0
D_after_count := 0
// fmt.Printf("testPage:%v\n", testPage)
for _, v := range testPage {
testNumInt, _ := strconv.Atoi(v.TestNumber)
checkedValInt, _ := strconv.Atoi(v.CheckedVal)
// testNumInt := v.TestNumber
// checkedValInt := v.CheckedVal
if testNumInt <= 15 {
switch checkedValInt {
case 2:
B_front_count++
case 3:
C_front_count++
case 4:
D_front_count++
default:
A_front_count++
}
} else {
switch checkedValInt {
case 2:
B_after_count++
case 3:
C_after_count++
case 4:
D_after_count++
default:
A_after_count++
}
}
}
fmt.Printf("A_front_count: %v, B_front_count: %v, C_front_count: %v, D_front_count: %v\n", A_front_count, B_front_count, C_front_count, D_front_count)
fmt.Printf("A_after_count: %v, B_after_count: %v, C_after_count: %v, D_after_count: %v\n", A_after_count, B_after_count, C_after_count, D_after_count)
RedColor := A_front_count + D_after_count
BlueColor := B_front_count + C_after_count
YellowColor := C_front_count + B_after_count
GreenColor := D_front_count + A_after_count
// fmt.Printf("A_front_count: %v, D_after_count: %v, B_front_count: %v, BlueColor: %v\n", A_front_count, D_after_count, B_front_count, C_after_count)
// fmt.Printf("RedColor: %v, GreenColor: %v, YellowColor: %v, BlueColor: %v\n", RedColor, GreenColor, YellowColor, BlueColor)
sendData := make(map[string]int)
sendData["RedColor"] = RedColor
sendData["BlueColor"] = BlueColor
sendData["YellowColor"] = YellowColor
sendData["GreenColor"] = GreenColor
sendData["A_front_count"] = A_front_count
sendData["B_front_count"] = B_front_count
sendData["C_front_count"] = C_front_count
sendData["D_front_count"] = D_front_count
sendData["A_after_count"] = A_after_count
sendData["B_after_count"] = B_after_count
sendData["C_after_count"] = C_after_count
sendData["D_after_count"] = D_after_count
return sendData
}

11
api/personalityTest/rongXin/type.go → api/personalityTest/rongXinPage/type.go

@ -1,4 +1,4 @@
package rongxin
package rongXinPage
import (
"appPlatform/overall/publicmethod"
@ -113,3 +113,12 @@ type CharacterStatis struct {
Keywords string `json:"keywords"`
Typekey string `json:"typekey"`
}
type TestPageColor struct {
TestNumber int `json:"testnumber"` //题号
CheckedVal int `json:"checkedval"` //选项
}
type TestPageColorStr struct {
TestNumber string `json:"testnumber"` //题号
CheckedVal string `json:"checkedval"` //选项
}

6
api/shiyan/maptostruct/shiyan.go

@ -411,15 +411,17 @@ func (a *ApiMethod) TestTable(c *gin.Context) {
if requestData.Name == "" {
requestData.Name = "shi_yang"
}
masterFormCont := publicmethod.MapOut[string]()
// masterFormCont := publicmethod.MapOut[string]()
var masterFormCont []map[string]interface{}
err = overall.CONSTANT_DB_CustomerForm.Table(requestData.Name).Find(&masterFormCont).Error
if err != nil {
publicmethod.Result(107, err, c)
return
}
for k, v := range masterFormCont {
fmt.Printf("%v => %T\n", k, v)
fmt.Printf("%v => %T => %v\n", k, v, v)
}
// fmt.Printf("%v => %T\n", masterFormCont, masterFormCont)
}
/*

154
api/version1/customerApp/runAppControll.go

@ -537,3 +537,157 @@ func (x *XiechengApp) GainAppList(id int64) {
}
}
/*
*
@ 作者: 秦东
@ 时间: 2024-11-27 08:41:06
@ 功能: 按菜单顶级分组和表单
@ 参数
#
@ 返回值
#
@ 方法原型
#
*/
func (a *ApiMethod) GainMenuGroupForm(c *gin.Context) {
var requestData AppIdType
c.ShouldBindJSON(&requestData)
if requestData.Id == "" {
publicmethod.Result(1021, requestData, c)
return
}
var topIdAry []modelAppPlatform.Appmenus
gormDb := overall.CONSTANT_DB_AppPlatform.Model(&modelAppPlatform.Appmenus{}).Select("`id`,`label`").Where("`state` = 1 AND `type` = 1 AND `isLock` = 2 AND `appkey` = ? AND `parent` = ?", requestData.Id, requestData.Id)
if requestData.Types == 2 {
gormDb = gormDb.Where("`wapIsShow` = ?", 1)
} else {
gormDb = gormDb.Where("`pcIsShow` = ?", 1)
}
err := gormDb.Order("`sort` DESC").Find(&topIdAry).Error
if err != nil || len(topIdAry) < 1 {
publicmethod.Result(10001, topIdAry, c)
return
}
appKey, _ := strconv.ParseInt(requestData.Id, 10, 64)
var appMenu AppMenuList
for _, v := range topIdAry {
syncSeting.Add(1)
go appMenu.AppMenuContent(appKey, v)
}
syncSeting.Wait()
var sendData []MenuGroupList
for _, sv := range appMenu.List {
var sendInfo MenuGroupList
sendInfo.MenuAppId = sv.MenuAppId
sendInfo.MenuAppTitle = sv.MenuAppTitle
sendInfo.List = append(sendInfo.List, GainTableList(sv.SunId, requestData.Types)...)
sendData = append(sendData, sendInfo)
}
var otherIdAry []SendAppForm
gormDbOther := overall.CONSTANT_DB_AppPlatform.Model(&modelAppPlatform.Appmenus{}).Select("`id`,`label`").Where("`state` = 1 AND `type` = 2 AND `isLock` = 2 AND `appkey` = ? AND `parent` = ?", requestData.Id, requestData.Id)
if requestData.Types == 2 {
gormDbOther = gormDbOther.Where("`wapIsShow` = ?", 1)
} else {
gormDbOther = gormDbOther.Where("`pcIsShow` = ?", 1)
}
gormDbOther.Order("`sort` DESC").Find(&otherIdAry)
if len(otherIdAry) > 0 {
for i, v := range otherIdAry {
otherIdAry[i].IdStr = strconv.FormatInt(v.Id, 10)
otherIdAry[i].AppkStr = strconv.FormatInt(v.Appkey, 10)
otherIdAry[i].ParentStr = strconv.FormatInt(v.Parent, 10)
otherIdAry[i].CreaterStr = strconv.FormatInt(v.Creater, 10)
var tableFormInfo modelAppPlatform.CustomerFormView
err := tableFormInfo.GetCont(map[string]interface{}{"`status`": 1, "`signCode`": v.Id}, "`id`", "`cfid`", "`time`", "`icon`", "`listjson`")
if err == nil {
if tableFormInfo.ListJson != "" {
otherIdAry[i].IsList = true
} else {
otherIdAry[i].IsList = false
}
otherIdAry[i].VersionId = strconv.FormatInt(tableFormInfo.Id, 10)
otherIdAry[i].TableId = strconv.FormatInt(tableFormInfo.CfId, 10)
var usInfo modelshr.PersonArchives //获取创建人
usInfo.GetCont(map[string]interface{}{"`key`": v.Creater}, "`name`", "`number`")
otherIdAry[i].Founder = fmt.Sprintf("%v(%v)", usInfo.Name, usInfo.Number)
otherIdAry[i].CreateDate = publicmethod.UnixTimeToDay(tableFormInfo.CreaterTime, 14)
otherIdAry[i].Icon = tableFormInfo.Icon
}
}
var sendInfo MenuGroupList
sendInfo.MenuAppId = requestData.Id
sendInfo.MenuAppTitle = "默认分组"
sendInfo.List = append(sendInfo.List, otherIdAry...)
sendData = append(sendData, sendInfo)
}
publicmethod.Result(0, sendData, c)
}
/*
*
@ 作者: 秦东
@ 时间: 2024-11-27 10:22:16
@ 功能: 获取操作表
*/
func GainTableList(parent []int64, types int) []SendAppForm {
var appMenusList []SendAppForm
gormDb := overall.CONSTANT_DB_AppPlatform.Model(&modelAppPlatform.Appmenus{}).Where("`state` = 1 AND `type` = 2 AND `isLock` = 2 AND `parent` IN ?", parent)
if types == 2 {
gormDb = gormDb.Where("`wapIsShow` = ?", 1)
} else {
gormDb = gormDb.Where("`pcIsShow` = ?", 1)
}
gormDb.Order("`sort` DESC").Find(&appMenusList)
for i, v := range appMenusList {
appMenusList[i].IdStr = strconv.FormatInt(v.Id, 10)
appMenusList[i].AppkStr = strconv.FormatInt(v.Appkey, 10)
appMenusList[i].ParentStr = strconv.FormatInt(v.Parent, 10)
appMenusList[i].CreaterStr = strconv.FormatInt(v.Creater, 10)
var tableFormInfo modelAppPlatform.CustomerFormView
err := tableFormInfo.GetCont(map[string]interface{}{"`status`": 1, "`signCode`": v.Id}, "`id`", "`cfid`", "`time`", "`icon`", "`listjson`")
if err == nil {
if tableFormInfo.ListJson != "" {
appMenusList[i].IsList = true
} else {
appMenusList[i].IsList = false
}
appMenusList[i].VersionId = strconv.FormatInt(tableFormInfo.Id, 10)
appMenusList[i].TableId = strconv.FormatInt(tableFormInfo.CfId, 10)
var usInfo modelshr.PersonArchives //获取创建人
usInfo.GetCont(map[string]interface{}{"`key`": v.Creater}, "`name`", "`number`")
appMenusList[i].Founder = fmt.Sprintf("%v(%v)", usInfo.Name, usInfo.Number)
appMenusList[i].CreateDate = publicmethod.UnixTimeToDay(tableFormInfo.CreaterTime, 14)
appMenusList[i].Icon = tableFormInfo.Icon
}
}
return appMenusList
}
/*
*
@ 作者: 秦东
@ 时间: 2024-11-27 09:27:51
@ 功能: 获取所有子类
*/
func (a *AppMenuList) AppMenuContent(appKey int64, menuInfo modelAppPlatform.Appmenus) {
defer syncSeting.Done()
var menuCont AppMenuListInfo
menuCont.MenuAppId = strconv.FormatInt(menuInfo.Id, 10)
menuCont.MenuAppTitle = menuInfo.Label
var menuSun publicmethod.GetOrgAllParent
menuSun.GetAppMenuSun(appKey, menuInfo.Id)
menuCont.SunId = append(menuCont.SunId, menuInfo.Id)
menuCont.SunId = append(menuCont.SunId, menuSun.Id...)
a.List = append(a.List, menuCont)
fmt.Printf("获取所有子类:%v\n", a)
}

17
api/version1/customerApp/type.go

@ -250,3 +250,20 @@ type AppListCont struct {
modelAppPlatform.CustomerForm
SignCodeStr string `json:"signCodeStr" gorm:"-"`
}
type AppMenuList struct {
List []AppMenuListInfo `json:"list"`
}
type AppMenuListInfo struct {
MenuAppId string `json:"menuAppId"`
MenuAppTitle string `json:"menuAppTitle"`
SunId []int64 `json:"sunId"`
}
// 输出菜单分组及表单
type MenuGroupList struct {
MenuAppId string `json:"id"`
MenuAppTitle string `json:"title"`
List []SendAppForm `json:"list"`
}

58
api/version1/customerform/formTable.go

@ -443,7 +443,18 @@ func MakeSql(tablename string, fieldCont AnalysisFormSubUnitClass, fieldList []R
for _, v := range fieldList {
if v.Field == fieldCont.WordName {
isNew = false
sql = append(sql, fmt.Sprintf("ALTER TABLE `%v` MODIFY COLUMN %v %v COMMENT '%v'", tablename, fieldCont.WordName, v.Type, fieldCont.Describe))
if fieldCont.FieldType == "bigint" {
if fieldCont.ValIsAry {
sql = append(sql, fmt.Sprintf("ALTER TABLE `%v` ADD COLUMN `%v` %v(%v) %v NOT NULL DEFAULT %v COMMENT '%v'", tablename, fieldCont.WordName, fieldCont.FieldType, fieldCont.MaxVal, unsigned, fieldCont.MinVal, "开始日期"))
endField := fmt.Sprintf("%v_end", fieldCont.WordName)
sql = append(sql, fmt.Sprintf("ALTER TABLE `%v` ADD COLUMN `%v` %v(%v) %v NOT NULL DEFAULT %v COMMENT '%v'", tablename, endField, fieldCont.FieldType, fieldCont.MaxVal, unsigned, fieldCont.MinVal, "结束日期"))
} else {
sql = append(sql, fmt.Sprintf("ALTER TABLE `%v` ADD COLUMN `%v` %v(%v) %v NOT NULL DEFAULT %v COMMENT '%v'", tablename, fieldCont.WordName, fieldCont.FieldType, fieldCont.MaxVal, unsigned, fieldCont.MinVal, fieldCont.Describe))
}
} else {
sql = append(sql, fmt.Sprintf("ALTER TABLE `%v` MODIFY COLUMN %v %v COMMENT '%v'", tablename, fieldCont.WordName, v.Type, fieldCont.Describe))
}
}
}
} else {
@ -454,10 +465,13 @@ func MakeSql(tablename string, fieldCont AnalysisFormSubUnitClass, fieldList []R
case "int":
sql = append(sql, fmt.Sprintf("ALTER TABLE `%v` ADD COLUMN `%v` %v(%v) %v NOT NULL DEFAULT %v COMMENT '%v'", tablename, fieldCont.WordName, fieldCont.FieldType, fieldCont.MaxVal, unsigned, fieldCont.MinVal, fieldCont.Describe))
case "bigint":
sql = append(sql, fmt.Sprintf("ALTER TABLE `%v` ADD COLUMN `%v` %v(%v) %v NOT NULL DEFAULT %v COMMENT '%v'", tablename, fieldCont.WordName, fieldCont.FieldType, fieldCont.MaxVal, unsigned, fieldCont.MinVal, fieldCont.Describe))
if fieldCont.ValIsAry {
sql = append(sql, fmt.Sprintf("ALTER TABLE `%v` ADD COLUMN `%v` %v(%v) %v NOT NULL DEFAULT %v COMMENT '%v'", tablename, fieldCont.WordName, fieldCont.FieldType, fieldCont.MaxVal, unsigned, fieldCont.MinVal, "开始日期"))
endField := fmt.Sprintf("%v_end", fieldCont.WordName)
sql = append(sql, fmt.Sprintf("ALTER TABLE `%v` ADD COLUMN `%v` %v(%v) %v NOT NULL DEFAULT %v COMMENT '%v'", tablename, endField, fieldCont.FieldType, fieldCont.MaxVal, unsigned, fieldCont.MinVal, fieldCont.Describe))
sql = append(sql, fmt.Sprintf("ALTER TABLE `%v` ADD COLUMN `%v` %v(%v) %v NOT NULL DEFAULT %v COMMENT '%v'", tablename, endField, fieldCont.FieldType, fieldCont.MaxVal, unsigned, fieldCont.MinVal, "结束日期"))
} else {
sql = append(sql, fmt.Sprintf("ALTER TABLE `%v` ADD COLUMN `%v` %v(%v) %v NOT NULL DEFAULT %v COMMENT '%v'", tablename, fieldCont.WordName, fieldCont.FieldType, fieldCont.MaxVal, unsigned, fieldCont.MinVal, fieldCont.Describe))
}
case "float":
sql = append(sql, fmt.Sprintf("ALTER TABLE `%v` ADD COLUMN `%v` %v(%v,%v) %v NOT NULL DEFAULT 0 COMMENT '%v'", tablename, fieldCont.WordName, fieldCont.FieldType, fieldCont.MaxVal, fieldCont.MinVal, unsigned, fieldCont.Describe))
@ -717,8 +731,10 @@ func (a *ApiMethod) GainFormTableField(c *gin.Context) {
masterTable = append(masterTable, myKeyWord)
}
}
masterTableAll, err := GainFormTableField(customerFormMaster.TableKey)
masterTable = append(masterTable, masterTableAll...)
if err != nil {
publicmethod.Result(1, err, c, "未知表单!无法获取字段!")
return
@ -734,8 +750,11 @@ func (a *ApiMethod) GainFormTableField(c *gin.Context) {
if listAry, ok := list.([]interface{}); ok {
formFieldAry.AnalyzingFormJson("", listAry)
// publicmethod.Result(0, listAry, c)
// return
}
}
sendTableList := publicmethod.MapOut[string]()
if len(formFieldAry.MasterInfo) > 0 {
sendTableList["masterTable"] = TableFieldCompare(masterTable, formFieldAry.MasterInfo)
@ -823,12 +842,12 @@ func GainSunFormTableField(tableName string, SunFormInfo []SunFormFieldInfoList)
*/
func TableFieldCompare(tableFieldList []Result, jsonFieldList []FormFieldInfo) (fieldList []FormFieldInfo) {
tableFieldListsdf, _ := json.Marshal(tableFieldList)
jsonFieldListsdf, _ := json.Marshal(jsonFieldList)
fmt.Printf("\n=====================================================\n")
fmt.Printf("tableFieldListsdf:%v\n", string(tableFieldListsdf))
fmt.Printf("jsonFieldListsdf:%v\n", string(jsonFieldListsdf))
fmt.Printf("\n=====================================================\n")
// tableFieldListsdf, _ := json.Marshal(tableFieldList)
// jsonFieldListsdf, _ := json.Marshal(jsonFieldList)
// fmt.Printf("\n=====================================================\n")
// fmt.Printf("tableFieldListsdf:%v\n", string(tableFieldListsdf))
// fmt.Printf("jsonFieldListsdf:%v\n", string(jsonFieldListsdf))
// fmt.Printf("\n=====================================================\n")
if len(tableFieldList) > 0 {
for _, v := range tableFieldList {
@ -933,6 +952,7 @@ func (f *FormJsonFieldInfo) AnalyzingFormJson(tableName string, unitList []inter
if len(unitList) > 0 {
var fieldInfo []FormFieldInfo
for _, listVal := range unitList {
// fmt.Printf("listVal------------------>%v\n", listVal)
if listInfo, ok := listVal.(map[string]interface{}); ok {
if unitType, ok := listInfo["type"]; ok {
var unitInfo FormFieldInfo
@ -1049,10 +1069,20 @@ func (f *FormJsonFieldInfo) AnalyzingFormJson(tableName string, unitList []inter
optInfo.Label = labelValStr
}
}
if valueVal, ok := optvMap["value"]; ok {
if valueValStr, ok := valueVal.(string); ok {
optInfo.Value = valueValStr
}
optInfo.Value = valueVal
// if valueValStr, ok := valueVal.(string); ok {
// optInfo.Value = valueValStr
// } else {
// intVal, _ := publicmethod.StringToInt64(valueVal)
// optInfo.Value = intVal
// }
}
if chiVal, ok := optvMap["children"]; ok {
// fmt.Printf("unitInfo--3->:%v---->%T\n", chiVal, chiVal)
optInfo.Children = chiVal
}
unitInfo.Options = append(unitInfo.Options, optInfo)
}
@ -1510,7 +1540,9 @@ func (l *ListPageFields) BaseTableAttrField(key string, val interface{}) interfa
if len(checkboxAry) > 0 {
var jieGuo []string
for _, ov := range v.Options {
if publicmethod.IsInTrue[string](ov.Value, checkboxAry) {
intVal, _ := publicmethod.StringToInt64(ov.Value)
intValStr := strconv.FormatInt(intVal, 10)
if publicmethod.IsInTrue[string](intValStr, checkboxAry) {
jieGuo = append(jieGuo, ov.Label)
}
}

8
api/version1/customerform/formTableView.go

@ -566,7 +566,9 @@ func (l *ListPageFields) BaseTableAttrViewField(key string, val interface{}, lis
if len(checkboxAry) > 0 {
var jieGuo []string
for _, ov := range v.Options {
if publicmethod.IsInTrue[string](ov.Value, checkboxAry) {
intVal, _ := publicmethod.StringToInt64(ov.Value)
intValStr := strconv.FormatInt(intVal, 10)
if publicmethod.IsInTrue[string](intValStr, checkboxAry) {
jieGuo = append(jieGuo, ov.Label)
}
}
@ -1134,7 +1136,7 @@ func (a *ApiMethod) GainFormPageMapCont(c *gin.Context) {
func TableFormAttribute(formField Result, tableFieldList []FormFieldInfo) (fieldInfo FormFieldInfo, isTrue bool) {
if len(tableFieldList) > 0 {
fieldAry := strings.Split(formField.Field, "_end")
fmt.Printf("字段数组----->%v----->%v\n", len(fieldAry), fieldAry)
// fmt.Printf("字段数组----->%v----->%v\n", len(fieldAry), fieldAry)
if len(fieldAry) >= 1 {
isWrite := true
for _, v := range tableFieldList {
@ -1182,7 +1184,7 @@ func TableFormAttribute(formField Result, tableFieldList []FormFieldInfo) (field
// if len(patternInfo) >= 1 {
// fieldInfo.Pattern = patternInfo[0]
// }
fmt.Printf("字段数组---12-->%v----->%v\n", isWrite, formField)
// fmt.Printf("字段数组---12-->%v----->%v\n", isWrite, formField)
switch formField.Field {
case "_lableTitle":
fieldInfo.Id = formField.Field

5
api/version1/customerform/type.go

@ -456,8 +456,9 @@ type ControlType struct {
}
type OptionsInfo struct {
Label string `json:"label"`
Value string `json:"value"`
Label string `json:"label"`
Value interface{} `json:"value"`
Children interface{} `json:"children"`
}
// 分析表单Json字段

2
api/version1/entry.go

@ -16,6 +16,7 @@ import (
"appPlatform/api/version1/taskplatform/taskmanagement"
"appPlatform/api/version1/user"
webstocetmsg "appPlatform/api/version1/webStocetmsg"
workflow "appPlatform/api/version1/workFlow"
"appPlatform/api/version1/workWechat"
)
@ -36,6 +37,7 @@ type ApiEntry struct {
DataCenterApi datacenter.ApiMethod //数据中台
CustomerAppApi customerApp.ApiMethod //自定App
WebSocketApi webstocetmsg.ApiMethod //webSocket通讯相关
WorkFlowApi workflow.ApiMethod //工作流相关
}
var AppApiEntry = new(ApiEntry)

5
api/version1/publicapi/api.go

@ -358,7 +358,7 @@ func (a *ApiMethod) GainNumber(c *gin.Context) {
var requestData GainRulsNumner
c.ShouldBindJSON(&requestData)
uuid := strconv.FormatInt(publicmethod.GetUUid(1), 10)
// fmt.Printf("uuidAry---->%v\n", uuid)
// fmt.Printf("uuidAry---->%v\n", requestData)
if requestData.Automatic {
uuid = requestData.GainUniqueNumber(uuid)
}
@ -385,6 +385,8 @@ func (a *ApiMethod) GainNumber(c *gin.Context) {
*/
func (g *GainRulsNumner) GainUniqueNumber(uuid string) string {
var uuidAry []string
// fmt.Printf("获取唯一编号%v\n", g)
// fmt.Printf("uuidAry---->%v\n", uuid)
if len(g.CustomRules) > 0 {
for _, v := range g.CustomRules {
switch v.Types {
@ -470,6 +472,7 @@ func (g *GainRulsNumner) GainUniqueNumber(uuid string) string {
}
g.GainUniqueNumber(uuid)
}
return uuid
}

31
api/version1/taskplatform/taskmanagement/flowType.go

@ -11,17 +11,26 @@ type StartWorkFlow struct {
// 流程执行
type RunWorkFlow struct {
Step int //执行哪一步
NextStep int //下一步
TotalSteps int //总步数
FlowList []RunFlow //流程
Participant []string //参与人
MakeCopy []string //抄送人
NewFlowList []RunFlow //流程
Uuid int64 //
RunUid int64 //执行Uid
IsRun bool //是否结束执行
Msg string //执行说明
Step int //执行哪一步
NextStep int //下一步
TotalSteps int //总步数
FlowList []RunFlow //流程
Participant []string //参与人
MakeCopy []string //抄送人
NewFlowList []RunFlow //流程
Uuid int64 //
RunUid int64 //执行Uid
IsRun bool //是否结束执行
Msg string //执行说明
SendWecharMsg SendWecharMsgMap
}
type SendWecharMsgMap struct {
MastersKey int64
TableKey int64
AppKey int64
RunFlowId int64
Creater int64
}
type SubmitAppResults struct {
publicmethod.PublicId

39
api/version1/taskplatform/taskmanagement/runTaskFlow.go

@ -75,6 +75,9 @@ func (a *ApiMethod) RunTaskFlow(c *gin.Context) {
context, _ := c.Get(overall.MyContJwt)
var userCont modelshr.ManCont
userCont.GetLoginCont(context) //当前操作人
var taskInfo customerForm.TaskRecord
taskInfo.GetCont(map[string]interface{}{"`runFlowId`": requestData.Id}, "`title`", "`creater`", `masters_key`, "`version_id`", "`flow_key`", "`flow_run_sing`", "`tableKey`", "`appKey`", "`runFlowId`")
//执行流程
var runFlow RunWorkFlow
runFlow.Step = flowInfo.NextStep
@ -83,6 +86,13 @@ func (a *ApiMethod) RunTaskFlow(c *gin.Context) {
runFlow.RunUid = flowInfo.RunKey
runFlow.Participant = strings.Split(flowInfo.Participants, ",")
runFlow.FlowList = requestData.FlowList
runFlow.SendWecharMsg.AppKey = taskInfo.AppKey
runFlow.SendWecharMsg.Creater = taskInfo.Creater
runFlow.SendWecharMsg.MastersKey = taskInfo.MastersKey
runFlow.SendWecharMsg.TableKey = taskInfo.TableKey
runFlow.SendWecharMsg.RunFlowId = taskInfo.RunFlowId
runFlow.RunNodeHandle(userCont.Key, requestData.AgreeOrRefuse, requestData.Suggest)
if runFlow.IsRun {
publicmethod.Result(1, err, c, runFlow.Msg)
@ -191,7 +201,7 @@ func (r *RunWorkFlow) RunNodeHandle(userKey int64, AgreeToRefuse int, Suggest st
return
}
userKeyStr := strconv.FormatInt(userKey, 10) //当前操作人识别符转字符类型
// fmt.Printf("执行节点处理--->%v------>%v\n", r.Step, r.NextStep)
fmt.Printf("执行节点处理--->%v------>%v\n", r.Step, r.NextStep)
//遍历流程判断当前要执行的步骤
for i := 0; i < r.TotalSteps; i++ {
if r.FlowList[i].Step == r.Step { //获取当前操作节点
@ -205,10 +215,12 @@ func (r *RunWorkFlow) RunNodeHandle(userKey int64, AgreeToRefuse int, Suggest st
FlowRunLog(r.Uuid, userkIntId, AgreeToRefuse, r.FlowList[i].NodeKey, title, "")
// fmt.Printf("抄送人---->%v---->%v\n", userkIntId, title)
}
r.SendWecharMsgTopct(userKeyStr, r.Step)
r.Step = currentStep
r.NextStep = nextStep
if nextStep > 0 {
if JudgeRunNode(nextStep, r.FlowList) {
// if JudgeRunNode(nextStep, r.FlowList) {
if r.ToNextNodeRunOrClose(userKeyStr, nextStep) {
r.Step = nextStep
r.RunNodeHandle(userKey, AgreeToRefuse, Suggest)
}
@ -224,6 +236,7 @@ func (r *RunWorkFlow) RunNodeHandle(userKey int64, AgreeToRefuse int, Suggest st
r.FlowList[i].Operator = operatorAry
r.Participant = append(r.Participant, nodeUser...)
r.RejectNode(r.FlowList[i].GoBackNode)
r.SendWecharMsgTextCard(r.Step, "驳回", Suggest)
return
} else {
currentStep, nextStep := PaceStep(r.RunUid, r.Step, r.TotalSteps, r.FlowList[i])
@ -234,23 +247,32 @@ func (r *RunWorkFlow) RunNodeHandle(userKey int64, AgreeToRefuse int, Suggest st
r.Participant = append(r.Participant, nodeUser...)
switch r.FlowList[i].Types {
case 0:
if r.Step != currentStep {
r.SendWecharMsgTopct(userKeyStr, currentStep)
}
r.Step = currentStep
r.NextStep = nextStep
FlowRunLog(r.Uuid, userKey, 2, r.FlowList[i].NodeKey, "发起流程", "")
if JudgeRunNode(nextStep, r.FlowList) {
// if JudgeRunNode(nextStep, r.FlowList) {
if r.ToNextNodeRunOrClose(userKeyStr, nextStep) {
r.Step = nextStep
r.FlowStepRun(userKey, AgreeToRefuse, Suggest)
}
return
case 1:
if r.Step != currentStep {
r.SendWecharMsgTopct(userKeyStr, currentStep)
}
r.Step = currentStep
r.NextStep = nextStep
// fmt.Printf("判断是否继续执行---->%v\n", JudgeRunNode(nextStep, r.FlowList))
FlowRunLog(r.Uuid, userKey, 2, r.FlowList[i].NodeKey, Suggest, "")
if JudgeRunNode(nextStep, r.FlowList) {
if r.ToNextNodeRunOrClose(userKeyStr, nextStep) {
// if JudgeRunNode(nextStep, r.FlowList) {
r.Step = nextStep
r.RunNodeHandle(userKey, AgreeToRefuse, Suggest)
}
return
case 2:
if currentStep+1 < r.TotalSteps {
r.Step = currentStep + 1
@ -269,14 +291,21 @@ func (r *RunWorkFlow) RunNodeHandle(userKey int64, AgreeToRefuse int, Suggest st
title := fmt.Sprintf("向%v发送抄送数据", op.Name)
FlowRunLog(r.Uuid, userkIntId, AgreeToRefuse, r.FlowList[i].NodeKey, title, "")
}
r.SendWecharMsgTopct(userKeyStr, r.Step)
return
case 3:
if r.Step != currentStep {
r.SendWecharMsgTopct(userKeyStr, currentStep)
}
r.Step = currentStep
r.NextStep = nextStep
FlowRunLog(r.Uuid, userKey, 2, r.FlowList[i].NodeKey, Suggest, "")
if JudgeRunNode(nextStep, r.FlowList) {
if r.ToNextNodeRunOrClose(userKeyStr, nextStep) {
// if JudgeRunNode(nextStep, r.FlowList) {
r.Step = nextStep
r.RunNodeHandle(userKey, AgreeToRefuse, Suggest)
}
return
default:
}

99
api/version1/taskplatform/taskmanagement/runWorkFlow.go

@ -41,14 +41,15 @@ func (a *ApiMethod) StartRunWorkFlow(c *gin.Context) {
publicmethod.Result(10001, err, c, "未知进程!不可执行")
return
}
var taskInfo customerForm.TaskRecord
if requestData.Id == "" {
var taskInfo customerForm.TaskRecord
taskInfo.EiteCont(map[string]interface{}{"`masters_key`": requestData.Id}, map[string]interface{}{"`status`": 1})
//获取当前任务内容
// taskInfo.EiteCont(map[string]interface{}{"`masters_key`": requestData.Id}, map[string]interface{}{"`status`": 1})
publicmethod.Result(10001, err, c, "未知进程!不可执行")
return
}
if len(requestData.FlowList) < 1 {
var taskInfo customerForm.TaskRecord
//获取当前任务内容
taskInfo.EiteCont(map[string]interface{}{"`masters_key`": requestData.Id}, map[string]interface{}{"`status`": 1})
publicmethod.Result(10001, err, c, "未知进程!不可执行")
return
@ -60,8 +61,8 @@ func (a *ApiMethod) StartRunWorkFlow(c *gin.Context) {
var userCont modelshr.ManCont
userCont.GetLoginCont(context) //当前操作人
creetTime := time.Now().Unix() //当前时间
//获取当前任务内容
var taskInfo customerForm.TaskRecord
// //获取当前任务内容
// var taskInfo customerForm.TaskRecord
taskInfo.GetCont(map[string]interface{}{"`masters_key`": requestData.Id}, "`flow_key`", "`flow_run_sing`")
//获取流程详情
var flowVersionInfo modelAppPlatform.WorkFlowVersion
@ -283,6 +284,86 @@ func JudgeRunNode(step int, FlowList []RunFlow) (isRun bool) {
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-13 11:26:32
@ 功能: 判断下一个节点是否继续执行
@ 参数
#userKey 当前执行人
#nextStep 下一个节点
@ 返回值
#
@ 方法原型
#
*/
func (r *RunWorkFlow) ToNextNodeRunOrClose(userKey string, nextStep int) (isRun bool) {
isRun = false
if nextStep == 0 {
return isRun
}
runIdStr := strconv.FormatInt(r.RunUid, 10)
fmt.Printf("判断下一个节点是否继续执行:userKey:%v------->nextStep:%v\n", userKey, nextStep)
for _, v := range r.FlowList {
if nextStep == v.Step {
fmt.Printf("判断下一个节点是否继续执行:v.Step:%v----1--->v.Types:%v\n", v.Step, v.Types)
switch v.Types {
case 1, 3:
isMyTrue := false
optUserCount := len(v.Operator)
allPick := 0
for _, ov := range v.Operator {
if ov.Id == userKey {
isMyTrue = true
}
for _, ol := range ov.LogList {
if runIdStr == ol.UID {
allPick++
}
}
}
if isMyTrue {
if optUserCount > 1 {
switch v.ExamineMode {
case 1, 2:
if allPick == 0 {
isRun = true
} else {
if allPick == optUserCount {
isRun = true
} else {
isRun = false
}
}
default:
isRun = true
}
} else {
if optUserCount == 1 {
isRun = true
} else {
isRun = false
}
}
// isRun = true
}
fmt.Printf("判断下一个节点是否继续执行:isMyTrue:%v----3--->isRun:%v\n----3--->optUserCount:%v\n----3--->v.ExamineMode:%v\n", isMyTrue, isRun, optUserCount, v.ExamineMode)
case 2:
isRun = true
default:
isRun = false
}
}
}
return isRun
}
/*
*
@ 作者: 秦东
@ -1571,15 +1652,23 @@ func JudgeOperUser(userKey, runId int64, Operator []OperatorList) (bool, string)
}
caoZuoQuanXian := true
for _, v := range Operator {
if v.Id == strconv.FormatInt(userKey, 10) {
js, _ := json.Marshal(v)
fmt.Printf("判断操作人是否已经操作过\n userKey:%v====runId:%v=========v.Id=>%v\n\n\n%v\n\n\n", userKey, runId, v.Id, string(js))
caoZuoQuanXian = false
if len(v.LogList) > 0 {
for _, m := range v.LogList {
if m.UID == strconv.FormatInt(runId, 10) {
fmt.Printf("判断操作人\n\n\n userKey:%v====runId:%v=========v.Id=>%v\n\n\n%v\n\n\n", userKey, runId, m.UID, m)
return true, "您已经操作过此节点!请不要重复提交!"
}
}
} else {
caoZuoQuanXian = false
}
jsLog, _ := json.Marshal(v.LogList)
fmt.Printf("是否已经操作过\n userKey:%v====runId:%v=========caoZuoQuanXian=>%v\n\n\n%v\n\n\n", userKey, runId, caoZuoQuanXian, string(jsLog))
}
}
if caoZuoQuanXian {

272
api/version1/taskplatform/taskmanagement/sendWechatMsg.go

@ -0,0 +1,272 @@
package taskmanagement
import (
"appPlatform/api/version1/customerform"
"appPlatform/api/version1/workWechat"
"appPlatform/models/modelAppPlatform"
"appPlatform/models/modelshr"
"appPlatform/overall"
"appPlatform/overall/publicmethod"
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
)
/*
*
@ 作者: 秦东
@ 时间: 2024-12-13 13:38:52
@ 功能: 向下一个节点人员发送消息
@ 参数
#
@ 返回值
#
@ 方法原型
#
*/
func (r *RunWorkFlow) SendWecharMsgTopct(userKey string, nextStep int) {
if nextStep > 0 {
var sendUserAry []string
nodeTitle := ""
for _, v := range r.FlowList {
if nextStep == v.Step {
nodeTitle = v.NodeName
if v.ExamineMode != 1 {
for _, ov := range v.Operator {
if userKey != "" {
if ov.Id != userKey && ov.Wechat != "" {
sendUserAry = append(sendUserAry, ov.Wechat)
}
} else {
if ov.Wechat != "" {
sendUserAry = append(sendUserAry, ov.Wechat)
}
}
}
} else {
uuidStr := strconv.FormatInt(r.Uuid, 10)
for _, ov := range v.Operator {
for _, lv := range ov.LogList {
if lv.UID != uuidStr {
if userKey != "" {
if ov.Id != userKey && ov.Wechat != "" {
sendUserAry = append(sendUserAry, ov.Wechat)
}
} else {
if ov.Wechat != "" {
sendUserAry = append(sendUserAry, ov.Wechat)
}
}
}
}
}
}
}
}
if len(sendUserAry) > 0 {
taskId := publicmethod.GetUUid(1)
tableName, qouteTitle, contList := r.GainTitleAndCreate()
var sendMsg workWechat.SendMessage
sendMsg.Touser = strings.Join(sendUserAry, "|")
sendMsg.TemplateCard.Source.Desc = nodeTitle
sendMsg.TemplateCard.MainTitle.Title = tableName
sendMsg.TemplateCard.TaskId = strconv.FormatInt(taskId, 10)
sendMsg.TemplateCard.QuoteArea.Quote_text = qouteTitle
sendMsg.TemplateCard.HorizontalContentList = append(sendMsg.TemplateCard.HorizontalContentList, contList...)
var jumpInfo workWechat.Jump_list
jumpInfo.Title = "前往处理"
jumpInfo.Url = "wap.gyhlw.group"
jumpInfo.Type = 1
sendMsg.TemplateCard.JumpList = append(sendMsg.TemplateCard.JumpList, jumpInfo)
sendMsg.TemplateCard.CardAction.Type = 1
sendMsg.TemplateCard.CardAction.Url = "wap.gyhlw.group"
sendMsg.SendMsg("stzl", 1)
}
}
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-17 15:53:24
@ 功能: 发送文本卡片消息
@ 参数
#userKey 接收人
@ 返回值
#
@ 方法原型
#
*/
func (r *RunWorkFlow) SendWecharMsgTextCard(runStep int, nodeTitle, content string) {
if runStep == 0 {
runStep = 1
}
if runStep > len(r.FlowList) {
runStep = len(r.FlowList)
}
var sendUser []string
for _, v := range r.FlowList {
if v.Step == runStep {
for _, lv := range v.Operator {
if lv.Wechat != "" && !publicmethod.IsInTrue[string](lv.Wechat, sendUser) {
sendUser = append(sendUser, lv.Wechat)
}
}
}
}
// fmt.Printf("驳回数据接收人:%v", sendUser)
if len(sendUser) > 0 {
tableName, qouteTitle, _ := r.GainTitleAndCreate()
var sendMsg workWechat.SendMessage
sendMsg.Touser = strings.Join(sendUser, "|")
sendMsg.Msgtype = "textcard"
sendMsg.Textcard.Title = nodeTitle
sendMsg.Textcard.Description = fmt.Sprintf("<div class='gray'>%v</div> <div class='normal'>%v</div><div class='gray'>%v</div><div class='highlight'>驳回原因:%v</div>", publicmethod.UnixTimeToDay(time.Now().Unix(), 11), tableName, qouteTitle, content)
sendMsg.Textcard.Url = "wap.gyhlw.group"
sendMsg.Textcard.Btntxt = "前往查看"
fmt.Printf("驳回数据接收人2:%v", sendMsg)
sendMsg.SendMsg("stzl", 1)
}
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-13 15:38:55
@ 功能: 获取指定标题和申请人相关信息
#tableName 一级标题
#qouteTitle 引用文件
#peopleInfoAry 发起人
*/
func (r *RunWorkFlow) GainTitleAndCreate() (tableName, qouteTitle string, peopleInfoAry []workWechat.Horizontal_content_list) {
var tableInFor modelAppPlatform.CustomerForm
tableInFor.GetCont(map[string]interface{}{"`signCode`": r.SendWecharMsg.TableKey}, "`name`", "`tablename`", "`listjson`")
tableName = tableInFor.Name
qouteTitle = tableInFor.Name
var ceraterInfo modelshr.PersonArchives
ceraterInfo.GetCont(map[string]interface{}{"`key`": r.SendWecharMsg.Creater}, "`name`", "`number`", "`wechat`", "`work_wechat`")
var peopleInfo workWechat.Horizontal_content_list
peopleInfo.Keyname = "申请人"
peopleInfo.Value = fmt.Sprintf("%v(%v)", ceraterInfo.Name, ceraterInfo.Number)
if ceraterInfo.WorkWechat != "" {
peopleInfo.Type = 3
peopleInfo.UserId = ceraterInfo.WorkWechat
} else if ceraterInfo.Wechat != "" {
peopleInfo.Type = 3
peopleInfo.UserId = ceraterInfo.Wechat
}
peopleInfoAry = append(peopleInfoAry, peopleInfo)
if tableInFor.ListJson != "" {
var listInfo customerform.ListPageFields
json.Unmarshal([]byte(tableInFor.ListJson), &listInfo)
if listView, isOk := listInfo.View["list"]; isOk {
if len(listView.Form.Title) > 0 {
tableForm := publicmethod.MapOut[string]()
overall.CONSTANT_DB_CustomerForm.Table(tableInFor.TableNames).Where("`masters_key` = ?", r.SendWecharMsg.MastersKey).Find(&tableForm)
var qouteTitleAry []string
// fmt.Printf("list表单:%v\n\n\n%v\n\n\n", listView.Form.Title, tableForm)
for _, v := range listView.Form.Title {
if formVal, isOk := tableForm[v]; isOk {
// fmt.Printf("list表单-----v----->:%v\n\n\n%v\n\n\n", formVal, publicmethod.TypeToInterface(formVal))
qouteTitleAry = append(qouteTitleAry, publicmethod.TypeToInterface(formVal))
}
}
if len(qouteTitleAry) > 0 {
qouteTitle = strings.Join(qouteTitleAry, "-")
}
}
} else if dateView, isOk := listInfo.View["date"]; isOk {
if len(dateView.Form.Title) > 0 {
tableForm := publicmethod.MapOut[string]()
overall.CONSTANT_DB_CustomerForm.Table(tableInFor.TableNames).Where("`masters_key` = ?", r.SendWecharMsg.MastersKey).Find(&tableForm)
var qouteTitleAry []string
// fmt.Printf("date表单:%v\n\n\n%v\n\n\n", dateView.Form.Title, tableForm)
for _, v := range dateView.Form.Title {
if formVal, isOk := tableForm[v]; isOk {
qouteTitleAry = append(qouteTitleAry, publicmethod.TypeToInterface(formVal))
}
}
if len(qouteTitleAry) > 0 {
qouteTitle = strings.Join(qouteTitleAry, "-")
}
}
} else if timeView, isOk := listInfo.View["time"]; isOk {
if len(timeView.Form.Title) > 0 {
tableForm := publicmethod.MapOut[string]()
overall.CONSTANT_DB_CustomerForm.Table(tableInFor.TableNames).Where("`masters_key` = ?", r.SendWecharMsg.MastersKey).Find(&tableForm)
var qouteTitleAry []string
// fmt.Printf("time表单:%v\n\n\n%v\n\n\n", timeView.Form.Title, tableForm)
for _, v := range timeView.Form.Title {
if formVal, isOk := tableForm[v]; isOk {
qouteTitleAry = append(qouteTitleAry, publicmethod.TypeToInterface(formVal))
}
}
if len(qouteTitleAry) > 0 {
qouteTitle = strings.Join(qouteTitleAry, "-")
}
}
} else if ganttView, isOk := listInfo.View["gantt"]; isOk {
if len(ganttView.Form.Title) > 0 {
tableForm := publicmethod.MapOut[string]()
overall.CONSTANT_DB_CustomerForm.Table(tableInFor.TableNames).Where("`masters_key` = ?", r.SendWecharMsg.MastersKey).Find(&tableForm)
var qouteTitleAry []string
// fmt.Printf("gantt表单:%v\n\n\n%v\n\n\n", ganttView.Form.Title, tableForm)
for _, v := range ganttView.Form.Title {
if formVal, isOk := tableForm[v]; isOk {
qouteTitleAry = append(qouteTitleAry, publicmethod.TypeToInterface(formVal))
}
}
if len(qouteTitleAry) > 0 {
qouteTitle = strings.Join(qouteTitleAry, "-")
}
}
} else if mapView, isOk := listInfo.View["map"]; isOk {
if len(mapView.Form.Title) > 0 {
tableForm := publicmethod.MapOut[string]()
overall.CONSTANT_DB_CustomerForm.Table(tableInFor.TableNames).Where("`masters_key` = ?", r.SendWecharMsg.MastersKey).Find(&tableForm)
var qouteTitleAry []string
// fmt.Printf("map表单:%v\n\n\n%v\n\n\n", mapView.Form.Title, tableForm)
for _, v := range mapView.Form.Title {
if formVal, isOk := tableForm[v]; isOk {
qouteTitleAry = append(qouteTitleAry, publicmethod.TypeToInterface(formVal))
}
}
if len(qouteTitleAry) > 0 {
qouteTitle = strings.Join(qouteTitleAry, "-")
}
}
} else if cardView, isOk := listInfo.View["card"]; isOk {
if len(cardView.Form.Title) > 0 {
tableForm := publicmethod.MapOut[string]()
overall.CONSTANT_DB_CustomerForm.Table(tableInFor.TableNames).Where("`masters_key` = ?", r.SendWecharMsg.MastersKey).Find(&tableForm)
var qouteTitleAry []string
// fmt.Printf("card表单:%v\n\n\n%v\n\n\n", cardView.Form.Title, tableForm)
for _, v := range cardView.Form.Title {
if formVal, isOk := tableForm[v]; isOk {
qouteTitleAry = append(qouteTitleAry, publicmethod.TypeToInterface(formVal))
}
}
if len(qouteTitleAry) > 0 {
qouteTitle = strings.Join(qouteTitleAry, "-")
}
}
}
}
// fmt.Printf("qouteTitle表单:%v\n\n\n", qouteTitle)
return
}

1061
api/version1/workFlow/common.go

File diff suppressed because it is too large

341
api/version1/workFlow/flow.go

@ -0,0 +1,341 @@
package workflow
import (
"appPlatform/api/version1/taskplatform/taskmanagement"
"appPlatform/models/customerForm"
"appPlatform/models/modelAppPlatform"
"appPlatform/models/modelshr"
"appPlatform/overall"
"appPlatform/overall/publicmethod"
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
)
/*
*
@ 作者: 秦东
@ 时间: 2024-12-12 14:37:41
@ 功能: 启动流程
@ 参数
#
@ 返回值
#
@ 方法原型
#
*/
func (a *ApiMethod) StartProcess(c *gin.Context) {
var requestData StartWorkFlow
err := c.ShouldBindJSON(&requestData)
if err != nil {
publicmethod.Result(10001, err, c, "未知进程!不可执行")
return
}
if requestData.Id == "" {
publicmethod.Result(10001, err, c, "未知进程!不可执行")
return
}
if requestData.State == 0 {
requestData.State = 3
}
var taskInfo customerForm.TaskRecord
taskInfo.GetCont(map[string]interface{}{"`masters_key`": requestData.Id}, "`title`", "`creater`", `masters_key`, "`version_id`", "`flow_key`", "`flow_run_sing`", "`tableKey`", "`appKey`", "`runFlowId`")
if len(requestData.FlowList) < 1 {
taskInfo.EiteCont(map[string]interface{}{"`masters_key`": requestData.Id}, map[string]interface{}{"`status`": 1})
if taskInfo.RunFlowId != 0 {
var runFlowInfo customerForm.RunWorkflow
runFlowInfo.EiteCont(map[string]interface{}{"`id`": taskInfo.RunFlowId}, map[string]interface{}{"`status`": 1})
}
publicmethod.Result(10001, err, c, "未知进程!不可执行")
return
}
//获取当前操作参数
context, _ := c.Get(overall.MyContJwt)
var userCont modelshr.ManCont
userCont.GetLoginCont(context) //当前操作人
startCreaterKey := strconv.FormatInt(userCont.Key, 10) //当前操作人
creetTime := time.Now().Unix() //当前时间
//获取流程详情
var flowVersionInfo modelAppPlatform.WorkFlowVersion
flowVersionInfo.GetCont(map[string]interface{}{"`id`": taskInfo.FlowRunSing}, "`content`")
uuid := publicmethod.GetUUid(1)
runUuId := publicmethod.GetUUid(6)
//工作流执行主体
var workFlowInfo customerForm.RunWorkflow
workFlowInfo.Id = uuid
workFlowInfo.FlowKey = taskInfo.FlowKey //统一识别符(任务标识符)
workFlowInfo.Version = strconv.FormatInt(taskInfo.FlowRunSing, 10) //工作流版本
workFlowInfo.VersionCont = flowVersionInfo.Content //当前工作流内容
workFlowInfo.Creater = userCont.Key //流程发起人
workFlowInfo.Status = requestData.State //状态:1、草稿;2:驳回;3:审批中;4:归档;5:删除
workFlowInfo.StartTime = creetTime //开始时间
workFlowInfo.UpdateTime = creetTime //更新时间
workFlowInfo.RunKey = runUuId //当前执行识别符
//流程结构体
var executeWorkflow RunWorkFlow
executeWorkflow.Step = 1 //执行第1部 发起流程。当前为第一步
executeWorkflow.FlowList = requestData.FlowList //工作流主体
executeWorkflow.Participant = append(executeWorkflow.Participant, startCreaterKey) //当前操作人
executeWorkflow.TotalSteps = len(requestData.FlowList) //流程总长度
executeWorkflow.Uuid = uuid //流程唯一识别符
executeWorkflow.RunUid = runUuId //执行Uid
executeWorkflow.SendWecharMsg.AppKey = taskInfo.AppKey
executeWorkflow.SendWecharMsg.Creater = taskInfo.Creater
executeWorkflow.SendWecharMsg.MastersKey = taskInfo.MastersKey
executeWorkflow.SendWecharMsg.TableKey = taskInfo.TableKey
executeWorkflow.SendWecharMsg.RunFlowId = taskInfo.RunFlowId
if requestData.State == 3 {
workFlowInfo.CurrentStep, workFlowInfo.NextStep = executeWorkflow.GainRunNodeNew(startCreaterKey, 1, 2, "发起审批")
} else {
workFlowInfo.CurrentStep, workFlowInfo.NextStep = executeWorkflow.GainRunNodeNew(startCreaterKey, 1, 1, "")
}
fmt.Printf("获取得步骤:workFlowInfo.CurrentStep :%v\n workFlowInfo.NextStep :%v\n", workFlowInfo.CurrentStep, workFlowInfo.NextStep)
flowJsonCont, _ := json.Marshal(executeWorkflow.FlowList) //将步进流转化成json流
workFlowInfo.FlowCont = string(flowJsonCont) //流程执行体
if requestData.State == 3 {
// workFlowInfo.CurrentStep = executeWorkflow.Step
// workFlowInfo.NextStep = executeWorkflow.NextStep
//参与人去重
var parUser []string
for _, v := range executeWorkflow.Participant {
if !publicmethod.IsInTrue[string](v, parUser) {
parUser = append(parUser, v)
}
}
workFlowInfo.Participants = strings.Join(parUser, ",")
nextNodeRunUser := executeWorkflow.NextNodePeople()
workFlowInfo.NextExecutor = strings.Join(nextNodeRunUser, ",")
if executeWorkflow.NextStep <= 0 {
workFlowInfo.Status = 4
}
}
err = workFlowInfo.WriteCont() //写入执行工作流
if err != nil {
var taskInfo customerForm.TaskRecord
taskInfo.EiteCont(map[string]interface{}{"`masters_key`": requestData.Id}, map[string]interface{}{"`status`": 1})
publicmethod.Result(10001, err, c, "流程写入失败!请重新发起")
return
}
if executeWorkflow.NextStep <= 0 {
var taskCont customerForm.TaskRecord
taskCont.EiteCont(map[string]interface{}{"`masters_key`": requestData.Id}, map[string]interface{}{"`status`": 4, "`runFlowId`": uuid})
} else {
var taskCont customerForm.TaskRecord
taskCont.EiteCont(map[string]interface{}{"`masters_key`": requestData.Id}, map[string]interface{}{"`status`": requestData.State, "`runFlowId`": uuid})
}
publicmethod.Result(0, err, c)
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-17 10:40:52
@ 功能: 执行工作流
@ 参数
#
@ 返回值
#
@ 方法原型
#
*/
func (a *ApiMethod) RunTaskWorkFlow(c *gin.Context) {
var requestData SubmitAppResults
err := c.ShouldBindJSON(&requestData)
if err != nil {
publicmethod.Result(100, err, c)
return
}
if requestData.Id == "" {
publicmethod.Result(100, err, c)
return
}
if requestData.AgreeOrRefuse == 0 {
requestData.AgreeOrRefuse = 2
}
//step 1:获取流程执行情况
var flowInfo customerForm.RunWorkflow
err = flowInfo.GetCont(map[string]interface{}{"`id`": requestData.Id})
if err != nil {
publicmethod.Result(107, err, c)
return
}
if flowInfo.NextStep == 0 || flowInfo.Status != 3 {
publicmethod.Result(1, err, c, "此流程在不可审批状态!您的提交无效")
return
}
if len(requestData.FlowList) < 1 { //判断流程是否因表单条件而变化
if flowInfo.FlowCont != "" {
err = json.Unmarshal([]byte(flowInfo.FlowCont), &requestData.FlowList)
if err != nil {
publicmethod.Result(1, err, c, "流程异常!您的提交无效")
return
}
} else {
publicmethod.Result(1, err, c, "流程异常!您的提交无效")
return
}
}
//step 2:获取操作人
context, _ := c.Get(overall.MyContJwt)
var userCont modelshr.ManCont
userCont.GetLoginCont(context)
var taskInfo customerForm.TaskRecord
taskInfo.GetCont(map[string]interface{}{"`runFlowId`": requestData.Id}, "`title`", "`creater`", `masters_key`, "`version_id`", "`flow_key`", "`flow_run_sing`", "`tableKey`", "`appKey`", "`runFlowId`", "`participant`")
//step 3:执行流程
var runFlow RunWorkFlow
runFlow.Step = flowInfo.NextStep
runFlow.TotalSteps = len(requestData.FlowList) //流程总长度
runFlow.Uuid = flowInfo.FlowKey
runFlow.RunUid = flowInfo.RunKey
runFlow.Participant = strings.Split(flowInfo.Participants, ",")
runFlow.FlowList = requestData.FlowList
runFlow.SendWecharMsg.AppKey = taskInfo.AppKey
runFlow.SendWecharMsg.Creater = taskInfo.Creater
runFlow.SendWecharMsg.MastersKey = taskInfo.MastersKey
runFlow.SendWecharMsg.TableKey = taskInfo.TableKey
runFlow.SendWecharMsg.RunFlowId = taskInfo.RunFlowId
runFlow.RunNodeHandle(userCont.Key, requestData.AgreeOrRefuse, requestData.Suggest)
if runFlow.IsRun {
publicmethod.Result(1, err, c, runFlow.Msg)
return
}
flowJsonCont, _ := json.Marshal(runFlow.FlowList) //将步进流转化成json流
saveFlowInfo := publicmethod.MapOut[string]() //修改工作流
saveFlowInfo["`flow_cont`"] = flowJsonCont
saveFlowInfo["`current_step`"] = runFlow.Step
saveFlowInfo["`next_step`"] = runFlow.NextStep
if flowInfo.Participants != "" {
oldUser := strings.Split(flowInfo.Participants, ",")
runFlow.Participant = append(runFlow.Participant, oldUser...)
}
//参与人去重
var parUser []string
for _, v := range runFlow.Participant {
if !publicmethod.IsInTrue[string](v, parUser) {
parUser = append(parUser, v)
}
}
saveFlowInfo["`participants`"] = strings.Join(parUser, ",")
saveTaskInfo := publicmethod.MapOut[string]() //修改任务
//参与人去重
if len(parUser) > 0 {
oldTaskUser := strings.Split(taskInfo.Participant, ",")
for _, v := range parUser {
if !publicmethod.IsInTrue[string](v, oldTaskUser) {
oldTaskUser = append(oldTaskUser, v)
}
}
saveTaskInfo["`participant`"] = strings.Join(parUser, ",")
}
//抄送人
if flowInfo.MakeCopy != "" {
oldCopyUser := strings.Split(flowInfo.MakeCopy, ",")
runFlow.MakeCopy = append(runFlow.MakeCopy, oldCopyUser...)
}
//抄送人 去重
var copyMan []string
for _, v := range runFlow.MakeCopy {
if !publicmethod.IsInTrue[string](v, copyMan) {
copyMan = append(copyMan, v)
}
}
saveFlowInfo["`makeCopy`"] = strings.Join(copyMan, ",")
//下一步执行人
nextRunUser := runFlow.GainNextStepUser(runFlow.NextStep)
saveFlowInfo["`next_executor`"] = strings.Join(nextRunUser, ",")
saveFlowInfo["`update_time`"] = time.Now().Unix()
if requestData.AgreeOrRefuse == 1 {
if runFlow.NextStep != 0 {
saveFlowInfo["`status`"] = 3
saveTaskInfo["`status`"] = 3
} else {
saveFlowInfo["`status`"] = 4
saveTaskInfo["`status`"] = 4
taskmanagement.JudgeEditFlow(flowInfo.FlowKey)
}
} else {
saveFlowInfo["`runKey`"] = publicmethod.GetUUid(6)
if runFlow.Step != 1 {
saveFlowInfo["`status`"] = 3
} else {
saveFlowInfo["`status`"] = 2
saveTaskInfo["`status`"] = 1
}
}
saveTaskInfo["`edit_time`"] = time.Now().Unix()
gordb := overall.CONSTANT_DB_CustomerForm.Begin()
flowErr := gordb.Model(&customerForm.RunWorkflow{}).Where(map[string]interface{}{"`id`": requestData.Id}).Updates(saveFlowInfo).Error
taskErr := gordb.Model(&customerForm.TaskRecord{}).Where("`runFlowId` = ?", requestData.Id).Updates(saveTaskInfo).Error
if flowErr != nil || taskErr != nil {
gordb.Rollback()
publicmethod.Result(100, err, c, "数据提交失败!请重新提交!")
return
}
gordb.Commit()
publicmethod.Result(0, err, c)
// sendMap := publicmethod.MapOut[string]()
// sendMap["runFlow"] = runFlow
// sendMap["saveFlowInfo"] = saveFlowInfo
// sendMap["saveTaskInfo"] = saveTaskInfo
// sendMap["nextStep"] = runFlow.NextStep
// publicmethod.Result(1, sendMap, c, runFlow.Msg)
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-19 10:01:12
@ 功能: 获取指定节点执行人
@ 参数
#
@ 返回值
#
@ 方法原型
#
*/
func (r *RunWorkFlow) GainNextStepUser(stepNode int) (userAry []string) {
if stepNode <= 0 {
return
}
for _, v := range r.FlowList {
if v.Step == stepNode {
for _, op := range v.Operator {
if !publicmethod.IsInTrue[string](op.Id, userAry) {
userAry = append(userAry, op.Id)
}
}
}
}
return
}

189
api/version1/workFlow/flowNode.go

@ -0,0 +1,189 @@
package workflow
import "appPlatform/overall/publicmethod"
/**
@ 作者: 秦东
@ 时间: 2024-04-09 10:56:48
@ 功能: 工作流结构主体
*/
type FlowMainBody struct {
TableId string `json:"tableId"` //工作流识别吗
WorkFlowDef WorkFlowDefInfo `json:"workFlowDef"` //工作流主体属性
DirectorMaxLevel int `json:"directorMaxLevel"` //审批主管最大层级
FlowPermission []FlowPermissionInfo `json:"flowPermission"` //流程发起人
NodeConfig NodePublicInfo `json:"nodeConfig"` //节点信息内容
}
//工作流主体属性
type WorkFlowDefInfo struct {
FormKey string `json:"formKey"` //关联操作ID
publicmethod.PublicName //姓名
}
//流程节点
type NodePublicInfo struct {
NodePublicInfoES
Settype int `json:"settype"` // 审批人设置 1:指定成员; 2:主管;3:行政岗位; 4:发起人自选; 5:发起人自己;6:连续多级主管;7:指定前置审批为本节点设置审批人;8:表单字段;9:权限矩阵
SelectMode int `json:"selectMode"` //审批人数 1选一个人 2选多个人
SelectRange int `json:"selectRange"` //选择范围 1.全公司 2指定成员 3指定角色
DirectorLevel int `json:"directorLevel"` //审批终点 最高层主管数
ExamineMode int `json:"examineMode"` //多人审批时采用的审批方式 1:依次审批; 2:会签;3:非会签
NoHanderAction int `json:"noHanderAction"` //审批人为空时 1自动审批通过/不允许发起 2转交给审核管理员
ExamineEndDirectorLevel int `json:"examineEndDirectorLevel"` //审批终点 第n层主管
SendBackNode string `json:"sendBackNode"` //退回哪个节点
CustomNode string `json:"customNode"` //指定前置审批为本节点设置审批人
ConditionNodes []NodePublicInfoES `json:"conditionNodes"` //判断条件,当节点是路由时有效
Executionaddress string `json:"executionaddress"` //第三方执行地址
ChildNode *NodePublicInfo `json:"childNode"` //子节点
Matrix MatrixInfo `json:"matrix"` //
OrgList []int64 `json:"orgList"` //指定行政组织,由其负责人审批
HelpTips string `json:"helpTips"` //节点帮助说明
}
type NodePublicInfoES struct {
NodeNumber string `json:"nodeNumber"` //节点识别符
NodeName string `json:"nodeName"` //节点名称
Types int `json:"type"` //0:发起人;1:审批;2:抄送;3:执行人;4:条件;5:路由
FromNode string `json:"fromNode"` //来源节点
GotoNode []string `json:"gotoNode"` //流向节点
PriorityLevel int `json:"priorityLevel"` // 条件优先级
Attribute int `json:"attribute"` //属性 1:申请人为基线;2:目标人为基线
Errors bool `json:"error"` //当前审批是否通过校验
CcSelfSelectFlag int `json:"ccSelfSelectFlag"` //允许发起人自选抄送人(0:不允许;1:允许)
NodeUserList []NodeUserListInfo `json:"nodeUserList"` //操作人
ConditionList []ConditionListInfo `json:"conditionList"` //判断条件主体
ChildNode *NodePublicInfo `json:"childNode"` //子节点
}
//节点执行人
type NodeUserListInfo struct {
FlowPermissionInfo
publicmethod.CommonId[string]
publicmethod.PublicName
Options []OptionsInfo `json:"options"` //可选项(用于关联表单使用)
IsCheckbox bool `json:"isCheckbox"` //结果值多选
}
//人员;角色;行政组织;职务通用结构体
type FlowPermissionInfo struct {
Types int `json:"type"` //1:人员;2:角色;3:行政组织;4:职务
TargetId string `json:"targetId"` //相关内容识别符
publicmethod.PublicName //相关内容名称
Icon string `json:"icon"` //头像
IconToBase64 string `json:"iconToBase64"` //头像Base64
}
//矩阵信息
type MatrixInfo struct {
MatrixId int64 `json:"matrixid"`
FactorId int64 `json:"factorid"`
OutcomeId int64 `json:"outcomeid"`
MatrixName string `json:"matrixName"`
FactorName string `json:"factorName"`
OutcomeName string `json:"outcomeName"`
}
//判断条件主体
type ConditionListInfo struct {
publicmethod.CommonId[int] //条件顺序
publicmethod.PublicName //条件名称
Factorid string `json:"factorid"` //条件识别字段
Types int `json:"type"` //条件类型:1:人员、行政组织、角色;2:自定义字段;3:关联表单字段;
Isok bool `json:"isok"` //页面渲染使用
IsCheckbox bool `json:"isCheckbox"` //结果值多选
Options []OptionsInfo `json:"options"` //可选项(用于关联表单使用)
Oneanswer string `json:"oneanswer"` //可选项锚定值(用于关联表单使用)
Answers []string `json:"answers"` //可选项锚定值(用于关联表单使用)
CustomFields []CustomFieldsInfo `json:"customFields"` //自定义字段条件主体
NodeUserList []FlowPermissionInfo `json:"nodeUserList"` //人员、行政组织、角色为条件主体
}
//可选项(用于关联表单使用)
type OptionsInfo struct {
Label string `json:"label"` //名称
Value string `json:"value"` //值
}
//自定义字段条件主体
type CustomFieldsInfo struct {
Wordfield string `json:"wordfield"` //判断字段
OptType string `json:"optType"` //判定方法(1:小于;2:大于;3:小于等于;4:等于;5:大于等于;6:介于两数之间;7:包含;8:不包含)
LeftVal string `json:"leftval"` //左侧值
LeftOptType string `json:"leftoptType"` //OptType值为6时;左侧判定方法
RightOptType string `json:"rightoptType"` //OptType值为6时;右侧判定方法
RightVal string `json:"rightval"` //OptType值为6时;右侧值
}
//输出工作流相关操作
type SendFlowInfo struct {
Step int `json:"Step"` //当前执行第几步
NodeKey string `json:"nodeKey"` //当前节点标识
NextStep int `json:"nextStep"` //下一步执行第几步
FlowList []RunFlow `json:"flowList"` //流程主体
}
/**
@ 作者: 秦东
@ 时间: 2023-11-01 09:12:18
@ 功能: 流程执行体
*/
type RunFlow struct {
Step int `json:"step"` //步骤
Types int `json:"type"` //0:发起节点;1:审批节点;2:抄送;3:执行节点
NodeKey string `json:"nodeKey"` //节点识别符
NodeName string `json:"nodeName"` //节点名称
Status int `json:"status"` //1:未到达;2:已审批;3:已驳回;4:再次审批
FromNode string `json:"fromnode"` //来至哪个节点
ArriveNode string `json:"arrivenode"` //到哪个节点
GoBackNode string `json:"gobacknode"` //驳回返回节点
ExamineMode int `json:"examinemode"` //多人审批时采用的审批方式。0:无操作 1依次审批 2会签 3:非会签
NoHanderAction int `json:"nohanderaction"` //审批人为空时 1自动审批通过/不允许发起 2转交给审核管理员
CustomNode string `json:"customNode"` //由哪个节点指定本节点审批人
JudgeList bool `json:"judgelist"` //是否可自己选中操作人
Operator []OperatorList `json:"operator"` //操作人
PendPers []OperatorList `json:"pendpers"` //操作人ssss
RunType int `json:"runtype"` //运行时选择 0:禁闭;1:发起人自选,2:发起人自己,3:有选中得节点指定,4:抄送节点
RunScope int `json:"runscope"` //运行时选择范围 0:不可选,1:本公司;2:本部门;当RunType = 4时:1:自选;非1:不可自选
// Operational bool `json:"operational"` //是否可提交审批意见
HelpTips string `json:"helpTips"` //节点帮助说明
}
//操作人
type OperatorList struct {
Id string `json:"id"` //操作人ID
Types int `json:"type"` //1:人员;2:角色;3:行政组织
Name string `json:"name"` //操作人姓名
Number string `json:"number"` //操作人工号
Icon string `json:"icon"` //操作人头像
IconBase64 string `json:"iconbase64"` //操作人头像
Wechat string `json:"wechat"` //微信Openid
DepartmentId int64 `json:"departmentid"` //分厂Id
DepartmentName string `json:"departmentname"` //分厂名称
PostId int64 `json:"postid"` //职务Id
PostName string `json:"postname"` //职务名称
Tema int64 `json:"tema"` //班组Id
TemaName string `json:"temaname"` //班组名称
LogList []LogList `json:"log"` //操作记录
NoEdit bool `json:"noedit"` //不可删除
Tel string `json:"tel"` //电话
CompanyName string `json:"companyName"` //公司
}
// 节点操作人操作记录
type LogList struct {
State int `json:"state"` //状态 1、未操作;2、通过;3、驳回;4、已查看
TimeVal string `json:"time"`
Cause string `json:"cause"` //审批意见
Enclosure []EnclosureFormat `json:"enclosure"` //附件
UID string `json:"uid"` //当前执行识别符
}
// 附件格式
type EnclosureFormat struct {
FileName string `json:"filename"` //附件名称
FilePath string `json:"filepath"` //附件地址
Type int `json:"type"` //附件类型
}

41
api/version1/workFlow/flowType.go

@ -0,0 +1,41 @@
package workflow
import "appPlatform/overall/publicmethod"
// 启动流程
type StartWorkFlow struct {
publicmethod.PublicId
FlowList []RunFlow `json:"flowList"` //流程主体
State int `json:"state"` //状态状态:1、草稿;2:驳回;3:审批中;4:归档;5:删除
}
// 流程执行
type RunWorkFlow struct {
Step int //执行哪一步
NextStep int //下一步
TotalSteps int //总步数
FlowList []RunFlow //流程
Participant []string //参与人
MakeCopy []string //抄送人
NewFlowList []RunFlow //流程
Uuid int64 //
RunUid int64 //执行Uid
IsRun bool //是否结束执行
Msg string //执行说明
SendWecharMsg SendWecharMsgMap
}
type SendWecharMsgMap struct {
MastersKey int64
TableKey int64
AppKey int64
RunFlowId int64
Creater int64
}
type SubmitAppResults struct {
publicmethod.PublicId
AgreeOrRefuse int `json:"agreeOrRefuse"` //1:同意;2:驳回
Suggest string `json:"suggest"` //审批意见
FlowList []RunFlow `json:"flowlist"` //执行流程
}

8
api/version1/workFlow/type.go

@ -0,0 +1,8 @@
package workflow
import "sync"
// 协程设置
var syncSeting = sync.WaitGroup{}
type ApiMethod struct{}

662
api/version1/workWechat/msgMap.go

@ -0,0 +1,662 @@
package workWechat
import (
"appPlatform/overall/publicmethod"
"errors"
)
// 卡片来源样式信息,不需要来源样式可不填写
func (s *Source) Source() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
if s.IconUrl != "" {
mapAryCont["icon_url"] = s.IconUrl
}
if s.Desc != "" {
mapAryCont["desc"] = s.Desc
}
if s.DescColor != 0 {
mapAryCont["desc_color"] = s.DescColor
}
if len(mapAryCont) > 0 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
return
}
// 发送信息公用头部
func (m *MsgCommon) MsgCommon() (mapAry map[string]interface{}, err error) {
if m.Touser == "" && m.Toparty == "" && m.Totag == "" {
err = errors.New("没有要接收信息的人员!不可发送信息")
return
}
if m.Msgtype == "" {
err = errors.New("未知消息类型!不可发送信息")
return
}
if m.Agentid == 0 {
err = errors.New("未知企业应用的id!不可发送信息")
return
}
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["msgtype"] = m.Msgtype
if m.Msgtype != "" && m.Msgtype != "miniprogram_notice" {
mapAryCont["agentid"] = m.Agentid
}
if m.Touser != "" {
mapAryCont["touser"] = m.Touser
}
if m.Toparty != "" {
mapAryCont["toparty"] = m.Toparty
}
if m.Totag != "" {
mapAryCont["totag"] = m.Totag
}
mapAry = mapAryCont
return
}
// 发送信息公用底部
func (m *MsgCommonFooter) MsgCommonFooter(msgType string) map[string]interface{} {
mapAryCont := publicmethod.MapOut[string]()
switch msgType {
case "text", "mpnews":
mapAryCont["safe"] = m.Safe
mapAryCont["enable_id_trans"] = m.EnableIdTrans
mapAryCont["enable_duplicate_check"] = m.EnableDuplicateCheck
if m.DuplicateCheckInterval == 0 {
mapAryCont["duplicate_check_interval"] = 1800
} else {
mapAryCont["duplicate_check_interval"] = m.DuplicateCheckInterval
}
case "image", "video", "file":
mapAryCont["safe"] = m.Safe
mapAryCont["enable_duplicate_check"] = m.EnableDuplicateCheck
if m.DuplicateCheckInterval == 0 {
mapAryCont["duplicate_check_interval"] = 1800
} else {
mapAryCont["duplicate_check_interval"] = m.DuplicateCheckInterval
}
case "voice", "markdown":
mapAryCont["enable_duplicate_check"] = m.EnableDuplicateCheck
if m.DuplicateCheckInterval == 0 {
mapAryCont["duplicate_check_interval"] = 1800
} else {
mapAryCont["duplicate_check_interval"] = m.DuplicateCheckInterval
}
case "textcard", "news", "miniprogram_notice", "template_card": //文本卡片消息
mapAryCont["enable_id_trans"] = m.EnableIdTrans
mapAryCont["enable_duplicate_check"] = m.EnableDuplicateCheck
if m.DuplicateCheckInterval == 0 {
mapAryCont["duplicate_check_interval"] = 1800
} else {
mapAryCont["duplicate_check_interval"] = m.DuplicateCheckInterval
}
default:
}
return mapAryCont
}
// 卡片右上角更多操作按钮
func (a *Action_menu) ActionMenu() (mapAry map[string]interface{}, isTrue bool) {
var actionList []interface{}
for _, v := range a.ActionList {
mapAry, mapisTrue := v.ActionList()
if mapisTrue {
actionList = append(actionList, mapAry)
}
}
mapAryCont := publicmethod.MapOut[string]()
if a.Desc != "" {
mapAryCont["desc"] = a.Desc
}
if len(actionList) > 0 {
mapAryCont["action_list"] = actionList
}
if len(mapAryCont) > 0 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
return
}
func (a *Action_list) ActionList() (mapAry map[string]interface{}, isTrue bool) {
isTrue = false
if a.Key == "" || a.Text == "" {
return
}
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["key"] = a.Key
mapAryCont["text"] = a.Text
mapAry = mapAryCont
isTrue = true
return
}
// 一级标题
func (m *Main_title) Main_title() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
if m.Title != "" {
mapAryCont["title"] = m.Title
}
if m.Desc != "" {
mapAryCont["desc"] = m.Desc
}
if len(mapAryCont) > 0 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
return
}
// 引用文献样式
func (q *Quote_area) Quote_area() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["type"] = q.Type
if q.Url != "" {
mapAryCont["url"] = q.Url
}
if q.Appid != "" {
mapAryCont["appid"] = q.Type
}
if q.Pagepath != "" {
mapAryCont["pagepath"] = q.Pagepath
}
if q.Title != "" {
mapAryCont["title"] = q.Title
}
if q.Quote_text != "" {
mapAryCont["quote_text"] = q.Quote_text
}
if len(mapAryCont) > 1 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
return
}
// 二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6
func (h *Horizontal_content_list) Horizontal_content_list() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["type"] = h.Type
mapAryCont["keyname"] = h.Keyname
if h.UserId != "" {
mapAryCont["userid"] = h.UserId
}
if h.Value != "" {
mapAryCont["value"] = h.Value
}
if h.Url != "" {
mapAryCont["url"] = h.Url
}
if h.MediaId != "" {
mapAryCont["media_id"] = h.MediaId
}
if len(mapAryCont) > 2 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
switch h.Type {
case 1:
if h.Url == "" {
isTrue = false
}
case 2:
if h.MediaId == "" {
isTrue = false
}
case 3:
if h.UserId == "" {
isTrue = false
}
}
return
}
// 跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3
func (j *Jump_list) Jump_list() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["type"] = j.Type
mapAryCont["title"] = j.Title
if j.Url != "" {
mapAryCont["url"] = j.Url
}
if j.Appid != "" {
mapAryCont["appid"] = j.Appid
}
if j.Pagepath != "" {
mapAryCont["pagepath"] = j.Pagepath
}
if len(mapAryCont) > 2 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
switch j.Type {
case 1:
if j.Url == "" {
isTrue = false
}
case 2:
if j.Appid == "" {
isTrue = false
}
}
return
}
func (c *Card_action) Card_action() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["type"] = c.Type
if c.Url != "" {
mapAryCont["url"] = c.Url
}
if c.Appid != "" {
mapAryCont["appid"] = c.Appid
}
if c.Pagepath != "" {
mapAryCont["pagepath"] = c.Pagepath
}
if len(mapAryCont) > 1 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
switch c.Type {
case 1:
if c.Url == "" {
isTrue = false
}
case 2:
if c.Appid == "" {
isTrue = false
}
}
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-10 14:14:44
@ 功能:
*/
func (e *Emphasis_content) Emphasis_content() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
if e.Title != "" {
mapAryCont["title"] = e.Title
}
if e.Desc != "" {
mapAryCont["desc"] = e.Desc
}
if len(mapAryCont) > 0 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-10 14:39:13
@ 功能:左图右文样式news_notice类型的卡片card_image和image_text_area两者必填一个字段不可都不填
*/
func (i *Image_text_area) Image_text_area() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["type"] = i.Type
mapAryCont["image_url"] = i.ImageUrl
if i.Url != "" {
mapAryCont["url"] = i.Url
}
if i.Title != "" {
mapAryCont["title"] = i.Title
}
if i.Desc != "" {
mapAryCont["desc"] = i.Desc
}
if i.Appid != "" {
mapAryCont["appid"] = i.Type
}
if i.Pagepath != "" {
mapAryCont["pagepath"] = i.Pagepath
}
if len(mapAryCont) > 2 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
switch i.Type {
case 1:
if i.Url == "" {
isTrue = false
}
case 2:
if i.Appid == "" {
isTrue = false
}
}
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-10 14:48:27
@ 功能: 图片样式news_notice类型的卡片card_image和image_text_area两者必填一个字段不可都不填
*/
func (c *Card_image) Card_image() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["url"] = c.Url
if c.AspectRatio != 0 {
mapAryCont["url"] = c.AspectRatio
}
if c.Url == "" {
isTrue = false
return
}
if len(mapAryCont) > 0 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-10 14:54:07
@ 功能: 卡片二级垂直内容该字段可为空数组但有数据的话需确认对应字段是否必填列表长度不超过4
*/
func (v *Vertical_content_list) Vertical_content_list() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["title"] = v.Title
if v.Desc != "" {
mapAryCont["desc"] = v.Desc
}
if v.Title == "" {
isTrue = false
return
}
if len(mapAryCont) > 0 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-10 15:01:33
@ 功能: 下拉式的选择器
*/
func (b *Button_selection) Button_selection() (mapAry map[string]interface{}, isTrue bool) {
isTrue = false
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["question_key"] = b.QuestionKey
if b.Title != "" {
mapAryCont["title"] = b.Title
}
if b.SelectedId != "" {
mapAryCont["selected_id"] = b.SelectedId
}
if len(b.OptionList) > 0 {
var optList []interface{}
for _, v := range b.OptionList {
optVal, optIsOk := v.Option_list()
if optIsOk {
optList = append(optList, optVal)
}
}
if len(optList) > 0 {
isTrue = true
mapAryCont["option_list"] = optList
}
}
if b.QuestionKey == "" {
isTrue = false
}
mapAry = mapAryCont
return
}
// 选项列表,下拉选项不超过 10 个,最少1个
func (o *Option_list) Option_list() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
if o.Id != "" {
mapAryCont["id"] = o.Id
}
if o.Text != "" {
mapAryCont["text"] = o.Text
}
if len(mapAryCont) >= 2 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-10 15:14:04
@ 功能: 按钮列表列表长度不超过6
*/
func (b *Button_list) Button_list() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["type"] = b.Type
mapAryCont["text"] = b.Text
if b.Style != 0 {
mapAryCont["style"] = b.Style
}
if b.Key != "" {
mapAryCont["key"] = b.Key
}
if b.Url != "" {
mapAryCont["url"] = b.Url
}
isTrue = true
if b.Text == "" {
isTrue = false
} else {
if b.Type == 1 && b.Url == "" {
isTrue = false
}
if b.Type == 0 && b.Key == "" {
isTrue = false
}
}
mapAry = mapAryCont
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-10 15:24:41
@ 功能: 选择题样式
*/
func (c *Checkbox) Checkbox() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["mode"] = c.Mode
mapAryCont["question_key"] = c.QuestionKey
if len(c.OptionList) > 0 {
var optList []interface{}
for _, v := range c.OptionList {
optVal, optIsOk := v.OptionList()
if optIsOk {
optList = append(optList, optVal)
}
}
if len(optList) > 0 {
isTrue = true
mapAryCont["option_list"] = optList
}
}
if c.QuestionKey == "" || len(c.OptionList) < 0 {
isTrue = false
} else {
isTrue = true
}
return
}
func (o *OptionList) OptionList() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["id"] = o.Id
mapAryCont["text"] = o.Text
mapAryCont["is_checked"] = o.IsChecked
if o.Id == "" || o.Text == "" {
isTrue = false
} else {
isTrue = true
}
return
}
/**
@ 作者: 秦东
@ 时间: 2024-12-10 15:53:25
@ 功能: 提交按钮样式
*/
func (s *Submit_button) Submit_button() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
if s.Text != "" {
mapAryCont["text"] = s.Text
}
if s.Key != "" {
mapAryCont["key"] = s.Key
}
if len(mapAryCont) >= 2 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 14:19:04
@ 功能: 图文消息一个图文消息支持1到8条图文
*/
func (a *ArticlesList) Articles_list() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
if a.Title != "" {
mapAryCont["title"] = a.Title
if a.Description != "" {
mapAryCont["description"] = a.Description
}
if a.Url != "" {
mapAryCont["url"] = a.Url
}
if a.PicUrl != "" {
mapAryCont["picurl"] = a.PicUrl
}
if a.AppId != "" {
mapAryCont["appid"] = a.AppId
}
if a.Pagepath != "" {
mapAryCont["pagepath"] = a.Pagepath
}
}
if len(mapAryCont) > 0 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 14:28:26
@ 功能:
*/
func (a *ArticlesListMpn) Articles_list_mpn() (mapAry map[string]interface{}, isTrue bool) {
if a.Title == "" && a.ThumbMediaId == "" && a.Content == "" {
isTrue = false
} else {
mapAryCont := publicmethod.MapOut[string]()
mapAryCont["title"] = a.Title
mapAryCont["thumb_media_id"] = a.ThumbMediaId
mapAryCont["pagepath"] = a.Content
if a.Author != "" {
mapAryCont["author"] = a.Author
}
if a.ContentSourceUrl != "" {
mapAryCont["content_source_url"] = a.ContentSourceUrl
}
if a.Digest != "" {
mapAryCont["digest"] = a.Digest
}
if len(mapAryCont) > 0 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
}
return
}
// 循环值
func (c *Content_item) Content_item() (mapAry map[string]interface{}, isTrue bool) {
mapAryCont := publicmethod.MapOut[string]()
if c.Value != "" {
mapAryCont["key"] = c.Value
}
if c.Key != "" {
mapAryCont["url"] = c.Key
}
if len(mapAryCont) > 0 {
isTrue = true
mapAry = mapAryCont
} else {
isTrue = false
}
return
}

529
api/version1/workWechat/msgMethod.go

@ -0,0 +1,529 @@
package workWechat
import (
"appPlatform/overall/publicmethod"
"errors"
)
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 13:17:09
@ 功能: 模板卡片消息
*/
func (s *SendMessage) TemplateCardMethod() (templateCardMap map[string]interface{}, err error) {
templateCard := publicmethod.MapOut[string]() //模版输出
if s.TemplateCard.TemplateCommon.TaskId == "" {
err = errors.New("没有任务id!不可发送信息")
return
} else {
templateCard["task_id"] = s.TemplateCard.TemplateCommon.TaskId //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节
}
sourceMap, sourceIsTrue := s.TemplateCard.TemplateCommon.Source.Source() //卡片来源样式信息,不需要来源样式可不填写
if sourceIsTrue {
sourceMapAry := publicmethod.MapOut[string]()
for i, v := range sourceMap {
sourceMapAry[i] = v
}
templateCard["source"] = sourceMapAry
}
mainTitleMap, mainTitleIsTrue := s.TemplateCard.TemplateCommon.MainTitle.Main_title() //一级标题
if mainTitleIsTrue {
mainTitleMapAry := publicmethod.MapOut[string]()
for i, v := range mainTitleMap {
mainTitleMapAry[i] = v
}
templateCard["main_title"] = mainTitleMapAry
}
templateCard["card_type"] = s.TemplateCard.TemplateCommon.CardType
switch s.TemplateCard.TemplateCommon.CardType {
case "text_notice": //文本类型
actionMenuMap, actionMenuIsTrue := s.TemplateCard.TextTemplate.ActionMenu.ActionMenu() //卡片右上角更多操作按钮
if actionMenuIsTrue {
actionMenuMapAry := publicmethod.MapOut[string]()
for i, v := range actionMenuMap {
actionMenuMapAry[i] = v
}
templateCard["action_menu"] = actionMenuMapAry
}
quoteAreaMap, quoteAreaIsTrue := s.TemplateCard.TextTemplate.QuoteArea.Quote_area() //引用文献样式
if quoteAreaIsTrue {
quoteAreaMapAry := publicmethod.MapOut[string]()
for i, v := range quoteAreaMap {
quoteAreaMapAry[i] = v
}
templateCard["quote_area"] = quoteAreaMapAry
}
if s.TemplateCard.TextTemplate.SubTitleText != "" {
templateCard["sub_title_text"] = s.TemplateCard.TextTemplate.SubTitleText //二级普通文本,建议不超过160个字
}
if len(s.TemplateCard.TextTemplate.HorizontalContentList) > 0 { //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6
var horContList []interface{}
for _, v := range s.TemplateCard.TextTemplate.HorizontalContentList {
horCont, horContIsTrue := v.Horizontal_content_list()
if horContIsTrue {
horContList = append(horContList, horCont)
}
}
if len(horContList) > 0 {
templateCard["horizontal_content_list"] = horContList
}
}
if len(s.TemplateCard.TextTemplate.JumpList) > 0 { //跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3
var jumpListtList []interface{}
for _, v := range s.TemplateCard.TextTemplate.JumpList {
jumpCont, jumpContIsTrue := v.Jump_list()
if jumpContIsTrue {
jumpListtList = append(jumpListtList, jumpCont)
}
}
if len(jumpListtList) > 0 {
templateCard["jump_list"] = jumpListtList
}
}
// fmt.Printf("s.TemplateCard.TextTemplate.CardAction==>%v\n", s.TemplateCard.TextTemplate.CardAction)
//整体卡片的点击跳转事件,text_notice必填本字段
cardMap, cardIsTrue := s.TemplateCard.TextTemplate.CardAction.Card_action() //卡片来源样式信息,不需要来源样式可不填写
if cardIsTrue {
cardMapAry := publicmethod.MapOut[string]()
for i, v := range cardMap {
cardMapAry[i] = v
}
templateCard["card_action"] = cardMapAry
} else {
err = errors.New("没有任务整体卡片的点击跳转事件!不可发送信息")
return
}
empVal, empIsTrue := s.TemplateCard.TextTemplate.EmphasisContent.Emphasis_content()
if empIsTrue {
templateCard["emphasis_content"] = empVal
}
case "news_notice": //图文类型
actionMenuMap, actionMenuIsTrue := s.TemplateCard.ActionMenu.ActionMenu() //卡片右上角更多操作按钮
if actionMenuIsTrue {
actionMenuMapAry := publicmethod.MapOut[string]()
for i, v := range actionMenuMap {
actionMenuMapAry[i] = v
}
templateCard["action_menu"] = actionMenuMapAry
}
quoteAreaMap, quoteAreaIsTrue := s.TemplateCard.QuoteArea.Quote_area() //引用文献样式
if quoteAreaIsTrue {
quoteAreaMapAry := publicmethod.MapOut[string]()
for i, v := range quoteAreaMap {
quoteAreaMapAry[i] = v
}
templateCard["quote_area"] = quoteAreaMapAry
}
if len(s.TemplateCard.HorizontalContentList) > 0 { //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6
var horContList []interface{}
for _, v := range s.TemplateCard.HorizontalContentList {
horCont, horContIsTrue := v.Horizontal_content_list()
if horContIsTrue {
horContList = append(horContList, horCont)
}
}
if len(horContList) > 0 {
templateCard["horizontal_content_list"] = horContList
}
}
if len(s.TemplateCard.JumpList) > 0 { //跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3
var jumpListtList []interface{}
for _, v := range s.TemplateCard.JumpList {
jumpCont, jumpContIsTrue := v.Jump_list()
if jumpContIsTrue {
jumpListtList = append(jumpListtList, jumpCont)
}
}
if len(jumpListtList) > 0 {
templateCard["jump_list"] = jumpListtList
}
}
//整体卡片的点击跳转事件,text_notice必填本字段
cardMap, cardIsTrue := s.TemplateCard.CardAction.Card_action() //卡片来源样式信息,不需要来源样式可不填写
if cardIsTrue {
cardMapAry := publicmethod.MapOut[string]()
for i, v := range cardMap {
cardMapAry[i] = v
}
templateCard["card_action"] = cardMapAry
} else {
err = errors.New("没有任务整体卡片的点击跳转事件!不可发送信息")
return
}
imgAreaMap, imgAreaIsTrue := s.TemplateCard.ImageTemplate.ImageTextArea.Image_text_area() //左图右文样式,news_notice类型的卡片,card_image和image_text_area两者必填一个字段,不可都不填
if imgAreaIsTrue {
imgAreaMapAry := publicmethod.MapOut[string]()
for i, v := range imgAreaMap {
imgAreaMapAry[i] = v
}
templateCard["image_text_area"] = imgAreaMapAry
}
cardImgMap, cardImgIsTrue := s.TemplateCard.ImageTemplate.CardImage.Card_image() //卡片二级垂直内容,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过4
if cardImgIsTrue {
cardImgMapAry := publicmethod.MapOut[string]()
for i, v := range cardImgMap {
cardImgMapAry[i] = v
}
templateCard["card_image"] = cardImgMapAry
}
if len(s.TemplateCard.ImageTemplate.VerticalContentList) > 0 {
var verContList []interface{}
for _, v := range s.TemplateCard.ImageTemplate.VerticalContentList {
verCont, horContIsTrue := v.Vertical_content_list()
if horContIsTrue {
verContList = append(verContList, verCont)
}
}
if len(verContList) > 0 {
templateCard["vertical_content_list"] = verContList
}
}
case "button_interaction": //按钮类型
actionMenuMap, actionMenuIsTrue := s.TemplateCard.ActionMenu.ActionMenu() //卡片右上角更多操作按钮
if actionMenuIsTrue {
actionMenuMapAry := publicmethod.MapOut[string]()
for i, v := range actionMenuMap {
actionMenuMapAry[i] = v
}
templateCard["action_menu"] = actionMenuMapAry
}
quoteAreaMap, quoteAreaIsTrue := s.TemplateCard.QuoteArea.Quote_area() //引用文献样式
if quoteAreaIsTrue {
quoteAreaMapAry := publicmethod.MapOut[string]()
for i, v := range quoteAreaMap {
quoteAreaMapAry[i] = v
}
templateCard["quote_area"] = quoteAreaMapAry
}
if s.TemplateCard.SubTitleText != "" {
templateCard["sub_title_text"] = s.TemplateCard.SubTitleText //二级普通文本,建议不超过160个字
}
if len(s.TemplateCard.HorizontalContentList) > 0 { //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6
var horContList []interface{}
for _, v := range s.TemplateCard.HorizontalContentList {
horCont, horContIsTrue := v.Horizontal_content_list()
if horContIsTrue {
horContList = append(horContList, horCont)
}
}
if len(horContList) > 0 {
templateCard["horizontal_content_list"] = horContList
}
}
//整体卡片的点击跳转事件,text_notice必填本字段
cardMap, cardIsTrue := s.TemplateCard.CardAction.Card_action() //卡片来源样式信息,不需要来源样式可不填写
if cardIsTrue {
cardMapAry := publicmethod.MapOut[string]()
for i, v := range cardMap {
cardMapAry[i] = v
}
templateCard["card_action"] = cardMapAry
} else {
err = errors.New("没有任务整体卡片的点击跳转事件!不可发送信息")
return
}
butVal, butIsTrue := s.TemplateCard.ButtonTemplate.ButtonSelection.Button_selection() //下拉式的选择器
if butIsTrue {
templateCard["button_selection"] = butVal
}
if len(s.TemplateCard.ButtonTemplate.ButtonList) > 0 { //按钮列表,列表长度不超过6
var butListContList []interface{}
for _, v := range s.TemplateCard.ButtonTemplate.ButtonList {
butListCont, butListIsTrue := v.Button_list()
if butListIsTrue {
butListContList = append(butListContList, butListCont)
}
}
if len(butListContList) > 0 {
templateCard["button_list"] = butListContList
}
} else {
err = errors.New("您没有设定操作按钮!不可发送信息")
return
}
case "vote_interaction": //投票类型
cheVal, cheIsTrue := s.TemplateCard.VoteTemplate.CheckBox.Checkbox()
if cheIsTrue {
templateCard["checkbox"] = cheVal
} else {
err = errors.New("您没有设定选择题!不可发送信息")
return
}
subButVal, subButIsTrue := s.TemplateCard.VoteTemplate.SubmitButton.Submit_button()
if subButIsTrue {
templateCard["submit_button"] = subButVal
} else {
err = errors.New("您没有设定提交按钮!不可发送信息")
return
}
case "multiple_interaction": //多项选择型
if len(s.TemplateCard.MultipleTemplate.SelectList) > 0 {
var selectList []interface{}
for _, v := range s.TemplateCard.MultipleTemplate.SelectList {
selListCont, selListIsTrue := v.Button_selection()
if selListIsTrue {
selectList = append(selectList, selListCont)
}
}
if len(selectList) > 0 {
templateCard["select_list"] = selectList
}
} else {
err = errors.New("您没有设定下拉式的选择器列表数据!不可发送信息")
return
}
subButVal, subButIsTrue := s.TemplateCard.SubmitButton.Submit_button()
if subButIsTrue {
templateCard["submit_button"] = subButVal
} else {
err = errors.New("您没有设定提交按钮!不可发送信息")
return
}
default:
err = errors.New("没有选择模板卡片类型!不可发送信息")
return
}
templateCardMap = templateCard
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 13:40:45
@ 功能: 文本消息
*/
func (s *SendMessage) TextMethod() (msgMap map[string]interface{}, err error) {
msgInfo := publicmethod.MapOut[string]() //模版输出
if s.TextMsg.Content != "" {
msgInfo["content"] = s.TextMsg.Content
} else {
err = errors.New("没有要发送的消息内容!不可发送信息")
return
}
msgMap = msgInfo
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 13:40:45
@ 功能: 图片消息
*/
func (s *SendMessage) ImageMethod() (msgMap map[string]interface{}, err error) {
msgInfo := publicmethod.MapOut[string]() //模版输出
if s.ImageMsg.MediaId != "" {
msgInfo["media_id"] = s.ImageMsg.MediaId
} else {
err = errors.New("没有要发送的图片媒体文件id!不可发送信息")
return
}
msgMap = msgInfo
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 13:40:45
@ 功能: 语音消息
*/
func (s *SendMessage) VoiceMethod() (msgMap map[string]interface{}, err error) {
msgInfo := publicmethod.MapOut[string]() //模版输出
if s.VoiceMsg.MediaId != "" {
msgInfo["media_id"] = s.VoiceMsg.MediaId
} else {
err = errors.New("没有要发送的语音文件id!不可发送信息")
return
}
msgMap = msgInfo
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 13:40:45
@ 功能: 视频消息
*/
func (s *SendMessage) VideoMethod() (msgMap map[string]interface{}, err error) {
msgInfo := publicmethod.MapOut[string]() //模版输出
if s.VideoMsg.MediaId != "" {
msgInfo["media_id"] = s.VideoMsg.MediaId
} else {
err = errors.New("没有要发送的视频媒体文件id!不可发送信息")
return
}
if s.VideoMsg.Title != "" {
msgInfo["title"] = s.VideoMsg.Title
}
if s.VideoMsg.Description != "" {
msgInfo["description"] = s.VideoMsg.Description
}
msgMap = msgInfo
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 13:40:45
@ 功能: 文件消息
*/
func (s *SendMessage) FileMethod() (msgMap map[string]interface{}, err error) {
msgInfo := publicmethod.MapOut[string]() //模版输出
if s.FileMsg.MediaId != "" {
msgInfo["media_id"] = s.FileMsg.MediaId
} else {
err = errors.New("没有要发送的文件id!不可发送信息")
return
}
msgMap = msgInfo
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 13:40:45
@ 功能: 文本卡片消息
*/
func (s *SendMessage) TextcardMethod() (msgMap map[string]interface{}, err error) {
msgInfo := publicmethod.MapOut[string]() //模版输出
if s.Textcard.Title != "" && s.Textcard.Description != "" && s.Textcard.Url != "" {
msgInfo["title"] = s.Textcard.Title
msgInfo["description"] = s.Textcard.Description
msgInfo["url"] = s.Textcard.Url
} else {
err = errors.New("发送信息不全!不可发送信息")
return
}
if s.Textcard.Btntxt != "" {
msgInfo["btntxt"] = s.Textcard.Btntxt
}
msgMap = msgInfo
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 13:40:45
@ 功能: 图文消息
*/
func (s *SendMessage) NewsMethod() (msgMap map[string]interface{}, err error) {
msgInfo := publicmethod.MapOut[string]() //模版输出
if len(s.NewsMsg.Articles) > 0 {
var artList []interface{}
for _, v := range s.NewsMsg.Articles {
artMap, artIsOk := v.Articles_list()
if artIsOk {
artList = append(artList, artMap)
}
}
if len(artList) > 0 {
msgInfo["articles"] = artList
} else {
err = errors.New("没有要发送得信息!不可发送信息")
return
}
} else {
err = errors.New("没有要发送得信息!不可发送信息")
return
}
msgMap = msgInfo
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 13:40:45
@ 功能: 图文消息mpnews
*/
func (s *SendMessage) MpnewsMethod() (msgMap map[string]interface{}, err error) {
msgInfo := publicmethod.MapOut[string]() //模版输出
if len(s.MpnewsMsg.Articles) > 0 {
var newList []interface{}
for _, v := range s.MpnewsMsg.Articles {
newCont, newIsTrue := v.Articles_list_mpn()
if newIsTrue {
newList = append(newList, newCont)
}
}
if len(newList) > 0 {
msgInfo["articles"] = newList
} else {
err = errors.New("没有要发送得信息!不可发送信息")
return
}
} else {
err = errors.New("没有要发送得信息!不可发送信息")
return
}
msgMap = msgInfo
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 13:40:45
@ 功能: markdown消息
*/
func (s *SendMessage) MarkdownMethod() (msgMap map[string]interface{}, err error) {
msgInfo := publicmethod.MapOut[string]() //模版输出
if s.MarkdownMsg.Content != "" {
msgInfo["content"] = s.MarkdownMsg.Content
} else {
err = errors.New("没有要发送的markdown消息内容!不可发送信息")
return
}
msgMap = msgInfo
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 13:40:45
@ 功能: 小程序通知消息
*/
func (s *SendMessage) MiniprogramNoticeMethod() (msgMap map[string]interface{}, err error) {
msgInfo := publicmethod.MapOut[string]() //模版输出
if s.MiniprogramMoticeMsg.Appid != "" && s.MiniprogramMoticeMsg.Title != "" {
msgInfo := publicmethod.MapOut[string]() //模版输出
msgInfo["appid"] = s.MiniprogramMoticeMsg.Appid
msgInfo["title"] = s.MiniprogramMoticeMsg.Title
msgInfo["emphasis_first_item"] = s.MiniprogramMoticeMsg.EmphasisFirstItem
if s.MiniprogramMoticeMsg.Page != "" {
msgInfo["page"] = s.MiniprogramMoticeMsg.Page
}
if s.MiniprogramMoticeMsg.Description != "" {
msgInfo["description"] = s.MiniprogramMoticeMsg.Description
}
if len(s.MiniprogramMoticeMsg.ContentItem) > 0 {
var cotList []interface{}
for _, v := range s.MiniprogramMoticeMsg.ContentItem {
cotInFo, cotIsTrue := v.Content_item()
if cotIsTrue {
cotList = append(cotList, cotInFo)
}
}
if len(cotList) > 0 {
msgInfo["content_item"] = cotList
}
}
} else {
err = errors.New("发送信息不全!不可发送信息")
return
}
msgMap = msgInfo
return
}

278
api/version1/workWechat/sendMsg.go

@ -0,0 +1,278 @@
package workWechat
import (
"appPlatform/overall"
"appPlatform/overall/publicmethod"
"encoding/json"
"errors"
"fmt"
"strconv"
"time"
"github.com/gin-gonic/gin"
)
/*
*
@ 作者: 秦东
@ 时间: 2024-12-09 16:37:10
@ 功能: 发送消息
@ 参数
#
@ 返回值
#
@ 方法原型
#
*/
func (a *ApiMethod) SendMsg(c *gin.Context) {
var requestData SendMessage
c.ShouldBindJSON(&requestData)
// var sendText SendMessage
// sendText.Touser = "KaiXinGuo"
// sendText.Msgtype = "template_card"
// sendText.Agentid = 1000108
// sendText.TemplateCard.TaskId = strconv.FormatInt(publicmethod.GetUUid(1), 10)
// sendText.TemplateCard.CardType = requestData.Name
// sendText.TemplateCard.TextTemplate.CardAction.Type = 1
// sendText.TemplateCard.TextTemplate.CardAction.Url = "https://www.baidu.com"
err := requestData.SendMsg("stzl", 1)
fmt.Printf("sendText: %v\n\n\n", err)
if err != nil {
publicmethod.Result(1, requestData, c, "消息发送失败!")
} else {
publicmethod.Result(0, err, c)
}
}
func (m *SendMapMsg) SendMsg(systemApp string, calss int) (err error) {
sendUrl, _, err := GetSendMsgTokenUrl(systemApp, 1)
if err != nil {
return
}
sendMsgData, _ := json.Marshal(m.Send)
callBackByte := publicmethod.CurlPostJosn(sendUrl, sendMsgData)
var callBackMap interface{}
err = json.Unmarshal(callBackByte, &callBackMap)
fmt.Printf("jsonCont==>%v\n\n\n\n", string(sendMsgData))
resendIsRun := false
if val, isOk := callBackMap.(map[string]interface{}); isOk {
if mapVal, isOk := val["errcode"]; isOk {
errcode, err := publicmethod.StringToInt64(mapVal)
if err != nil {
resendIsRun = true
} else {
// fmt.Printf("errcode==>%v\n\n\n\n", errcode)
if errcode == 0 {
resendIsRun = false
} else {
resendIsRun = true
}
}
} else {
resendIsRun = true
}
} else {
resendIsRun = true
}
if resendIsRun {
m.Number++
err = m.ResendSendMsg(systemApp, calss)
// fmt.Scanln()
// m.SendMsg(systemApp, calss)
return
}
// fmt.Printf("callBackMap==>%v\n\n-->%T\n\n", callBackMap, callBackMap)
// fmt.Printf("token==>%v\n\n\n\n", token)
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 09:56:18
@ 功能: 为得到正确信息是重复发送请求最多发送三次
*/
func (m *SendMapMsg) ResendSendMsg(systemApp string, calss int) (err error) {
fmt.Printf("执行第几次--->%v\n", m.Number)
if m.Number <= 3 {
go func() {
time.Sleep(time.Duration(5) * time.Second)
// fmt.Println("这条信息将在几秒后显示。")
err = m.SendMsg(systemApp, calss)
}()
} else {
fmt.Printf("超过最大补发次数!消息作废!--->%v\n", m.Number)
err = errors.New("超过最大补发次数!消息作废!")
}
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-10 16:28:43
@ 功能: 企业微信发送应用消息URL组装
@ 参数
#systemApp 系统
#class 类型 1发送2更新3撤回
@ 返回值
#sendUrl 发送应用消息URL
#token token
#err 系统信息
@ 方法原型
#
*/
func GetSendMsgTokenUrl(systemApp string, class int) (sendUrl string, token string, err error) {
//获取token
token, err = GainWechatToken(systemApp, "sendWorkWechat", 2)
if err != nil {
return
}
switch class {
case 2:
sendUrl = fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/message/update_template_card?access_token=%v", token)
case 3:
sendUrl = fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/message/recall?access_token=%v", token)
default:
sendUrl = fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%v", token)
}
return
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-11 10:19:18
@ 功能:
*/
func (s *SendMessage) MsgInit() {
if s.Msgtype == "" {
s.Msgtype = "template_card"
}
if s.Agentid == 0 || s.Agentid == 1 {
s.Agentid, _ = strconv.Atoi(overall.CONSTANT_CONFIG.ShuTongZhiLian.Agentid)
}
if s.DuplicateCheckInterval == 0 {
s.DuplicateCheckInterval = 1800
}
if s.TemplateCard.CardType == "" {
s.TemplateCard.CardType = "text_notice"
}
if s.TemplateCard.Source.IconUrl == "" {
s.TemplateCard.Source.IconUrl = "https://docu.hxgk.group/images/2022_01/3f7a1120a559e9bee3991b85eb34d103.png"
}
if s.TemplateCard.Source.Desc == "" {
s.TemplateCard.Source.Desc = "数通智联化工云平台"
} else {
s.TemplateCard.Source.Desc = fmt.Sprintf("数通智联化工云平台 - %v", s.TemplateCard.Source.Desc)
}
if s.TemplateCard.Source.DescColor == 0 {
s.TemplateCard.Source.DescColor = 1
}
}
/*
*
@ 作者: 秦东
@ 时间: 2024-12-10 13:55:14
@ 功能: 通用发送消息
@ 参数
#
@ 返回值
#
@ 方法原型
#
*/
func (s *SendMessage) SendMsg(systemApp string, class int) (err error) {
s.MsgInit()
topMapAry, err := s.MsgCommon.MsgCommon()
if err != nil {
return
}
msgCommonFooter := s.MsgCommonFooter.MsgCommonFooter(s.Msgtype)
var mapAry SendMapMsg
mapAry.Send = topMapAry
for i, v := range msgCommonFooter {
mapAry.Send[i] = v
}
switch s.Msgtype {
case "text":
mapAry.Send["text"], err = s.TextMethod()
if err != nil {
return
}
case "image":
mapAry.Send["image"], err = s.ImageMethod()
if err != nil {
return
}
case "voice":
mapAry.Send["voice"], err = s.VoiceMethod()
if err != nil {
return
}
case "video": //视频消息
mapAry.Send["video"], err = s.VideoMethod()
if err != nil {
return
}
case "file": //文件消息
mapAry.Send["file"], err = s.FileMethod()
if err != nil {
return
}
case "textcard": //文本卡片消息
mapAry.Send["textcard"], err = s.TextcardMethod()
if err != nil {
return
}
case "news": //图文消息
mapAry.Send["news"], err = s.NewsMethod()
if err != nil {
return
}
case "mpnews": //图文消息(mpnews)
mapAry.Send["mpnews"], err = s.MpnewsMethod()
if err != nil {
return
}
case "markdown": //markdown消息
mapAry.Send["markdown"], err = s.MarkdownMethod()
if err != nil {
return
}
case "miniprogram_notice": //小程序通知消息
mapAry.Send["content_item"], err = s.MiniprogramNoticeMethod()
if err != nil {
return
}
case "template_card":
mapAry.Send["template_card"], err = s.TemplateCardMethod()
if err != nil {
return
}
default:
err = errors.New("没有消息类型!不可发送信息")
return
}
// mapAry.Send["template_card"] = templateCard
return mapAry.SendMsg(systemApp, class)
}

421
api/version1/workWechat/workMsgType.go

@ -0,0 +1,421 @@
package workWechat
//公用头部
//touser&toparty&totag 这三个参数进行三选一。必须有一个存在!
type MsgCommon struct {
Touser string `json:"touser"` //成员ID列表(消息接收者,多个接收者用‘|’分隔,最多支持1000个)。特殊情况:指定为@all,则向关注该企业应用的全部成员发送
Toparty string `json:"toparty"` //部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为@all时忽略本参数
Totag string `json:"totag"` //标签ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为@all时忽略本参数
Msgtype string `json:"msgtype"` //消息类型,此时固定为:template_card
Agentid int `json:"agentid"` //企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值
}
//公用底部
//此部分参数为非必填参数
type MsgCommonFooter struct {
Safe int `json:"safe"` //表示是否开启id转译,0表示否,1表示是,默认0
EnableIdTrans int `json:"enable_id_trans"` //表示是否开启id转译,0表示否,1表示是,默认0
EnableDuplicateCheck int `json:"enable_duplicate_check"` //表示是否开启重复消息检查,0表示否,1表示是,默认0
DuplicateCheckInterval int `json:"duplicate_check_interval"` //表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时
}
/**
@ 作者: 秦东
@ 时间: 2024-12-09 15:23:36
@ 功能: 消息卡片相同的地方
*/
type TemplateCardCommon struct {
CardType string `json:"card_type"` //模板卡片类型,文本通知型卡片填写 "text_notice"
Source Source `json:"source"` //卡片来源样式信息,不需要来源样式可不填写
ActionMenu Action_menu `json:"action_menu"` //卡片右上角更多操作按钮
TaskId string `json:"task_id"` //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填
MainTitle Main_title `json:"main_title"` //一级标题
QuoteArea Quote_area `json:"quote_area"` //引用文献样式
HorizontalContentList []Horizontal_content_list `json:"horizontal_content_list"` //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6
JumpList []Jump_list `json:"jump_list"` //跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3
CardAction Card_action `json:"card_action"` //整体卡片的点击跳转事件,news_notice必填本字段
}
//卡片来源样式信息,不需要来源样式可不填写
type Source struct {
IconUrl string `json:"icon_url"` //来源图片的url,来源图片的尺寸建议为72*72
Desc string `json:"desc"` //来源图片的描述,建议不超过20个字,
DescColor int `json:"desc_color"` //来源文字的颜色,目前支持:0(默认) 灰色,1 黑色,2 红色,3 绿色
}
//操作列表,列表长度取值范围为 [1, 3]
type Action_list struct {
Text string `json:"text"` //操作的描述文案
Key string `json:"key"` //操作key值,用户点击后,会产生回调事件将本参数作为EventKey返回,回调事件会带上该key值,最长支持1024字节,不可重复
}
//卡片右上角更多操作按钮
type Action_menu struct {
Desc string `json:"desc"` //更多操作界面的描述
ActionList []Action_list `json:"action_list"` //操作列表,列表长度取值范围为 [1, 3]
}
//一级标题
type Main_title struct {
Title string `json:"title"` //一级标题,建议不超过36个字,文本通知型卡片本字段非必填,但不可本字段和sub_title_text都不填
Desc string `json:"desc"` //标题辅助信息,建议不超过44个字
}
//引用文献样式
type Quote_area struct {
Type int `json:"type"` //引用文献样式区域点击事件,0或不填代表没有点击事件,1 代表跳转url,2 代表跳转小程序
Url string `json:"url"` //点击跳转的url,quote_area.type是1时必填
Appid string `json:"appid"` //点击跳转的小程序的appid,必须是与当前应用关联的小程序,quote_area.type是2时必填
Pagepath string `json:"pagepath"` //点击跳转的小程序的pagepath,quote_area.type是2时选填
Title string `json:"title"` //引用文献样式的标题
Quote_text string `json:"quote_text"` //引用文献样式的引用文案
}
//关键数据样式
type Emphasis_content struct {
Title string `json:"title"` //关键数据样式的数据内容,建议不超过14个字
Desc string `json:"desc"` //关键数据样式的数据描述内容,建议不超过22个字
}
//二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6
type Horizontal_content_list 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个字,
Url string `json:"url"` //链接跳转的url,horizontal_content_list.type是1时必填
MediaId string `json:"media_id"` //附件的media_id,horizontal_content_list.type是2时必填
UserId string `json:"userid"` //成员详情的userid,horizontal_content_list.type是3时必填
}
//跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3
type Jump_list struct {
Type int `json:"type"` //跳转链接类型,0或不填代表不是链接,1 代表跳转url,2 代表跳转小程序
Title string `json:"title"` //跳转链接样式的文案内容,建议不超过18个字
Url string `json:"url"` //跳转链接的url,jump_list.type是1时必填
Appid string `json:"appid"` //跳转链接的小程序的appid,必须是与当前应用关联的小程序,jump_list.type是2时必填
Pagepath string `json:"pagepath"` //跳转链接的小程序的pagepath,jump_list.type是2时选填
}
//整体卡片的点击跳转事件,text_notice必填本字段
type Card_action struct {
Type int `json:"type"` //跳转事件类型,1 代表跳转url,2 代表打开小程序。text_notice卡片模版中该字段取值范围为[1,2]
Url string `json:"url"` //跳转事件的url,card_action.type是1时必填
Appid string `json:"appid"` //跳转事件的小程序的appid,必须是与当前应用关联的小程序,card_action.type是2时必填
Pagepath string `json:"pagepath"` //跳转事件的小程序的pagepath,card_action.type是2时选填
}
/**
@ 作者: 秦东
@ 时间: 2024-12-09 15:55:58
@ 功能: 发送文本通知型消息
*/
type SendTextMessage struct {
MsgCommon
TemplateCard TextTemplateCard `json:"template_card"` //消息类型
MsgCommonFooter
}
//文本发射体
type TextTemplateCard struct {
TemplateCardCommon
Emphasis_content
Sub_title_text string `json:"sub_title_text"`
}
/**
@ 作者: 秦东
@ 时间: 2024-12-09 16:08:53
@ 功能: 发送图片通知消息
*/
type SendPictureMessage struct {
MsgCommon
TemplateCard TextTemplateCard `json:"template_card"` //消息类型
MsgCommonFooter
}
//图片发射体
type PictureTemplateCard struct {
TemplateCardCommon
ImageTextArea Image_text_area `json:"image_text_area"` //左图右文样式,news_notice类型的卡片,card_image和image_text_area两者必填一个字段,不可都不填
CardImage Card_image `json:"card_image"` //图片样式,news_notice类型的卡片,card_image和image_text_area两者必填一个字段,不可都不填
VerticalContentList Vertical_content_list `json:"vertical_content_list"` //卡片二级垂直内容,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过4
Sub_title_text string `json:"sub_title_text"`
}
//卡片二级垂直内容,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过4
type Vertical_content_list struct {
Title string `json:"title"` //卡片二级标题,建议不超过38个字
Desc string `json:"desc"` //二级普通文本,建议不超过160个字
}
//图片样式,news_notice类型的卡片,card_image和image_text_area两者必填一个字段,不可都不填
type Card_image struct {
Url string `json:"url"` //图片的url
AspectRatio float32 `json:"aspect_ratio"` //图片的宽高比,宽高比要小于2.25,大于1.3,不填该参数默认1.3
}
//左图右文样式,news_notice类型的卡片,card_image和image_text_area两者必填一个字段,不可都不填
type Image_text_area 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
Appid string `json:"appid"` //点击跳转的小程序的appid,必须是与当前应用关联的小程序,image_text_area.type是2时必填
Pagepath string `json:"pagepath"` //点击跳转的小程序的pagepath,image_text_area.type是2时选填
}
//下拉式的选择器
type Button_selection struct {
QuestionKey string `json:"question_key"` //下拉式的选择器的key,用户提交选项后,会产生回调事件,回调事件会带上该key值表示该题,最长支持1024字节
Title string `json:"title"` //下拉式的选择器左边的标题
SelectedId string `json:"selected_id"` //默认选定的id,不填或错填默认第一个
OptionList []Option_list `json:"option_list"` //选项列表,下拉选项不超过 10 个,最少1个
}
//选项列表,下拉选项不超过 10 个,最少1个
type Option_list struct {
Id string `json:"id"` //下拉式的选择器选项的id,用户提交后,会产生回调事件,回调事件会带上该id值表示该选项,最长支持128字节,不可重复
Text string `json:"text"` //下拉式的选择器选项的文案,建议不超过16个字
}
//按钮列表,列表长度不超过6
type Button_list struct {
Type int `json:"type"` //按钮点击事件类型,0 或不填代表回调点击事件,1 代表跳转url
Text string `json:"text"` //按钮文案,建议不超过10个字
Style int `json:"style"` //按钮样式,目前可填1~4,不填或错填默认1
Key string `json:"key"` //按钮key值,用户点击后,会产生回调事件将本参数作为EventKey返回,回调事件会带上该key值,最长支持1024字节,不可重复,button_list.type是0时必填
Url string `json:"url"` //跳转事件的url,button_list.type是1时必填
}
//
type Checkbox struct {
Mode int `json:"mode"` //选择题模式,单选:0,多选:1,不填默认0
QuestionKey string `json:"question_key"` //选择题key值,用户提交选项后,会产生回调事件,回调事件会带上该key值表示该题,最长支持1024字节
OptionList []OptionList `json:"option_list"` //选项list,选项个数不超过 20 个,最少1个
}
//选项list,选项个数不超过 20 个,最少1个
type OptionList struct {
Id string `json:"id"` //选项id,用户提交选项后,会产生回调事件,回调事件会带上该id值表示该选项,最长支持128字节,不可重复
Text string `json:"text"` //选项文案描述,建议不超过17个字
IsChecked bool `json:"is_checked"` //该选项是否要默认选中
}
//提交按钮样式
type Submit_button struct {
Text string `json:"text"` //按钮文案,建议不超过10个字,不填默认为提交
Key string `json:"key"` //提交按钮的key,会产生回调事件将本参数作为EventKey返回,最长支持1024字节
}
//发送消息接口
type SendMsgInterface interface {
SendTextMessage | SendPictureMessage
}
//Map类型发送消息
type SendMapMsg struct {
Send map[string]interface{}
Number int
}
//文本消息
type Text_msg struct {
Content string `json:"content"` //消息内容,最长不超过2048个字节,超过将截断
}
//图片消息
type Image_msg struct {
MediaId string `json:"media_id"` //图片媒体文件id,可以调用上传临时素材接口获取
}
//视频消息
type Video_msg struct {
Image_msg //视频媒体文件id,可以调用上传临时素材接口获取
Title string `json:"title"` //视频消息的标题,不超过128个字节,超过会自动截断
Description string `json:"description"` //视频消息的描述,不超过512个字节,超过会自动截断
}
//音频消息
type Voice_msg struct {
Image_msg
}
//文件消息
type File_msg struct {
Image_msg //文件id,可以调用上传临时素材接口获取
}
//文本卡片消息
type Textcard_msg struct {
Title string `json:"title"` //标题,不超过128个字符,超过会自动截断(支持id转译)
Description string `json:"description"` //描述,不超过512个字符,超过会自动截断(支持id转译)
Url string `json:"url"` //点击后跳转的链接。最长2048字节,请确保包含了协议头(http/https)
Btntxt string `json:"btntxt"` //按钮文字。 默认为“详情”, 不超过4个文字,超过自动截断。
}
//图文消息
type News_msg struct {
Articles []ArticlesList `json:"articles"` //图文消息,一个图文消息支持1到8条图文
}
//图文消息,
type ArticlesList struct {
Title string `json:"title"` //标题,不超过128个字节,超过会自动截断(支持id转译)
Description string `json:"description"` //描述,不超过512个字节,超过会自动截断(支持id转译)
Url string `json:"url"` //点击后跳转的链接。 最长2048字节,请确保包含了协议头(http/https),小程序或者url必须填写一个
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字段
}
//图文消息(mpnews)
type Mpnews_msg struct {
Articles []ArticlesListMpn `json:"articles"` //图文消息,一个图文消息支持1到8条图文
}
type ArticlesListMpn struct {
Title string `json:"title"` //标题,不超过128个字节,超过会自动截断(支持id转译)
ThumbMediaId string `json:"thumb_media_id"` //图文消息缩略图的media_id, 可以通过素材管理接口获得。此处thumb_media_id即上传接口返回的media_id
Author string `json:"author"` //图文消息的作者,不超过64个字节
ContentSourceUrl string `json:"content_source_url"` //图文消息点击“阅读原文”之后的页面链接
Content string `json:"content"` //图文消息的内容,支持html标签,不超过666 K个字节(支持id转译)
Digest string `json:"digest"` //图文消息的描述,不超过512个字节,超过会自动截断(支持id转译)
}
//markdown消息
type Markdown_msg struct {
Content string `json:"content"` //markdown内容,最长不超过2048个字节,必须是utf8编码
}
//小程序通知消息
type Miniprogram_notice_msg struct {
Appid string `json:"appid"` //小程序appid,必须是与当前应用关联的小程序
Page string `json:"page"` //点击消息卡片后的小程序页面,最长1024个字节,仅限本小程序内的页面。该字段不填则消息点击后不跳转。
Title string `json:"title"` //消息标题,长度限制4-12个汉字(支持id转译)
Description string `json:"description"` //消息描述,长度限制4-12个汉字(支持id转译)
EmphasisFirstItem bool `json:"emphasis_first_item"` //是否放大第一个content_item
ContentItem []Content_item `json:"content_item"` //消息内容键值对,最多允许10个item
}
//消息内容键值对,最多允许10个item
type Content_item struct {
Key string `json:"key"` //长度10个汉字以内
Value string `json:"value"` //长度30个汉字以内(支持id转译)key和value两个字段同时为空时,该键值对将被忽略
}
/**
@ 作者: 秦东
@ 时间: 2024-12-10 13:05:27
@ 功能: 发送消息
*/
type SendMessage struct {
MsgCommon
TextMsg Text_msg `json:"text"` //文本消息
ImageMsg Image_msg `json:"image"` //图片消息
VoiceMsg Voice_msg `json:"voice"` //语音消息
VideoMsg Video_msg `json:"video"` //视频消息
FileMsg File_msg `json:"file"` //文件消息
Textcard Textcard_msg `json:"textcard"` //文本卡片消息
NewsMsg News_msg `json:"news"` //图文消息
MpnewsMsg Mpnews_msg `json:"mpnews"` //图文消息(mpnews)
MarkdownMsg Markdown_msg `json:"markdown"` //markdown消息
MiniprogramMoticeMsg Miniprogram_notice_msg `json:"miniprogram_notice"` //小程序通知消息
TemplateCard TemplateCard `json:"template_card"` //模版卡片消息类型
MsgCommonFooter
}
//发送消息发射体
type TemplateCard struct {
TemplateCommon
TextTemplate //专属文本消息
ImageTemplate //专属图文消息
ButtonTemplate //专属按钮消息
VoteTemplate //专属投票消息
MultipleTemplate //专属多选消息
}
/**
@ 作者: 秦东
@ 时间: 2024-12-09 15:23:36
@ 功能: 所有消息卡片相同的地方
*/
type TemplateCommon struct {
CardType string `json:"card_type"` //模板卡片类型,文本通知型卡片填写 "text_notice"
Source Source `json:"source"` //卡片来源样式信息,不需要来源样式可不填写
TaskId string `json:"task_id"` //任务id,同一个应用任务id不能重复,只能由数字、字母和“_-@”组成,最长128字节,填了action_menu字段的话本字段必填
MainTitle Main_title `json:"main_title"` //一级标题
}
/**
@ 作者: 秦东
@ 时间: 2024-12-10 13:48:50
@ 功能: 专属多选消息
*/
type MultipleTemplate struct {
SelectList []Button_selection `json:"select_list"` //下拉式的选择器列表,multiple_interaction类型的卡片该字段不可为空,一个消息最多支持 3 个选择器
}
/**
@ 作者: 秦东
@ 时间: 2024-12-10 13:38:16
@ 功能: 专属投票消息
*/
type VoteTemplate struct {
CheckBox Checkbox `json:"checkbox"` //选择题样式
SubmitButton Submit_button `json:"submit_button"` //提交按钮样式
}
/**
@ 作者: 秦东
@ 时间: 2024-12-10 13:21:42
@ 功能: 专属按钮消息
*/
type ButtonTemplate struct {
// ActionMenu Action_menu `json:"action_menu"` //卡片右上角更多操作按钮
// QuoteArea Quote_area `json:"quote_area"` //引用文献样式
// SubTitleText string `json:"sub_title_text"` //二级普通文本,建议不超过160个字,(支持id转译)
// HorizontalContentList []Horizontal_content_list `json:"horizontal_content_list"` //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6
// CardAction Card_action `json:"card_action"` //整体卡片的点击跳转事件,news_notice必填本字段
ButtonSelection Button_selection `json:"button_selection"` //下拉式的选择器
ButtonList []Button_list `json:"button_list"` //按钮列表,列表长度不超过6
}
/**
@ 作者: 秦东
@ 时间: 2024-12-10 13:13:24
@ 功能: 专属文本消息
*/
type TextTemplate struct {
ActionMenu Action_menu `json:"action_menu"` //卡片右上角更多操作按钮
QuoteArea Quote_area `json:"quote_area"` //引用文献样式
EmphasisContent Emphasis_content `json:"emphasis_content"` //关键数据样式
SubTitleText string `json:"sub_title_text"` //二级普通文本,建议不超过160个字,(支持id转译)
HorizontalContentList []Horizontal_content_list `json:"horizontal_content_list"` //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6
JumpList []Jump_list `json:"jump_list"` //跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3
CardAction Card_action `json:"card_action"` //整体卡片的点击跳转事件,news_notice必填本字段
}
/**
@ 作者: 秦东
@ 时间: 2024-12-10 13:18:26
@ 功能: 专属图文消息
*/
type ImageTemplate struct {
// ActionMenu Action_menu `json:"action_menu"` //卡片右上角更多操作按钮
// QuoteArea Quote_area `json:"quote_area"` //引用文献样式
ImageTextArea Image_text_area `json:"image_text_area"` //左图右文样式,news_notice类型的卡片,card_image和image_text_area两者必填一个字段,不可都不填
CardImage Card_image `json:"card_image"` //图片样式,news_notice类型的卡片,card_image和image_text_area两者必填一个字段,不可都不填
VerticalContentList []Vertical_content_list `json:"vertical_content_list"` //卡片二级垂直内容,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过4
// HorizontalContentList []Horizontal_content_list `json:"horizontal_content_list"` //二级标题+文本列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过6
// JumpList []Jump_list `json:"jump_list"` //跳转指引样式的列表,该字段可为空数组,但有数据的话需确认对应字段是否必填,列表长度不超过3
// CardAction Card_action `json:"card_action"` //整体卡片的点击跳转事件,news_notice必填本字段
}
//判断是否执行补发信息
type ResendInfo struct {
Number int
IsRun bool
}

2
apirouter/v1/customerformrouter/router.go

@ -98,5 +98,7 @@ func (a *ApiRouter) RouterGroupPc(router *gin.RouterGroup) {
appApiRouter.POST("getAppList", methodAppHand.GetAppList) //根据分组获取App列表
appApiRouter.POST("getGroupAndApp", methodAppHand.GetGroupAndApp) //获取分组及App
appApiRouter.POST("gainMenuGroupForm", methodAppHand.GainMenuGroupForm) //按菜单顶级分组和表单
}
}

20
apirouter/v1/taskrouter/workFlow.go

@ -0,0 +1,20 @@
package taskrouter
import (
"appPlatform/api/version1"
"github.com/gin-gonic/gin"
)
func (a *ApiRouter) RouterGroupFlow(router *gin.RouterGroup) {
apiRouter := router.Group("flow")
var workFlowRouter = version1.AppApiEntry.WorkFlowApi
{
apiRouter.GET("", workFlowRouter.Index) //入口
apiRouter.POST("", workFlowRouter.Index)
apiRouter.POST("startProcess", workFlowRouter.StartProcess) //启动流程
apiRouter.POST("runTaskFlow", workFlowRouter.RunTaskWorkFlow) //启动流程
}
}

1
apirouter/v1/workWechatRouter/router.go

@ -17,5 +17,6 @@ func (a *ApiRouter) RouterGroupPc(router *gin.RouterGroup) {
apiRouter.POST("lookOnePeopleArchives", methodBinding.LookOnePeopleArchives) //获取人员信息单页(手机)查看权限
apiRouter.GET("obtainAuthorization", methodBinding.ObtainAuthorization) //构造企业微信网页授权code
apiRouter.GET("wechatCallBack", methodBinding.WechatCallBack) //企业微信参数地址重定向回调
apiRouter.POST("sendMsg", methodBinding.SendMsg) //向企业微信发送消息
}
}

5
initialization/route/initRoute.go

@ -103,6 +103,11 @@ func InitialRouter() *gin.Engine {
//注册数学函数处理
mathsApiVerify := apirouter.RouterGroupEntry.MathsRouter
mathsApiVerify.RouterGroup(VerifyIdentity)
//工作流执行相关
workFlowRouterApi := apirouter.RouterGroupEntry.TaskRouter
{
workFlowRouterApi.RouterGroupFlow(VerifyIdentity)
}
}
//验证身份接口 无需鉴权Url(主要web端使用)
VerifyIdentityWeb := router.Group("")

1
models/customerForm/taskrecord.go

@ -29,6 +29,7 @@ type TaskRecord struct {
TableKey int64 `json:"tableKey" gorm:"column:tableKey;type:bigint(20) unsigned;default:0;not null;comment:归属自定义表"`
AppKey int64 `json:"appKey" gorm:"column:appKey;type:bigint(20) unsigned;default:0;not null;comment:归属App(0:非app表单)"`
RunFlowId int64 `json:"runFlowId" gorm:"column:runFlowId;type:bigint(20) unsigned;default:0;not null;comment:正在执行得流程"`
MsgId int64 `json:"msgId" gorm:"column:msgId;type:bigint(20) unsigned;default:0;not null;comment:发送消息得任务ID"`
}
func (TaskRecord *TaskRecord) TableName() string {

40
overall/publicmethod/technique.go

@ -2570,6 +2570,29 @@ func (g *GetOrgAllParent) GetOrgSun(superior int64) {
}
}
/*
*
@ 作者: 秦东
@ 时间: 2024-11-27 09:44:25
@ 功能: 获取自定义App子菜单
*/
func (g *GetOrgAllParent) GetAppMenuSun(appKey, superior int64) {
var id []int64
if superior == 0 {
return
}
err := overall.CONSTANT_DB_AppPlatform.Model(&modelAppPlatform.Appmenus{}).Select("`id`").Where("`state` = 1 AND `type` = 1 AND `isLock` = 2 AND `appkey` = ? AND `parent` = ?", appKey, superior).Find(&id).Error
if err != nil || len(id) < 1 {
return
}
for _, v := range id {
if !IsInTrue[int64](v, g.Id) {
g.Id = append(g.Id, v)
}
g.GetAppMenuSun(appKey, v)
}
}
/*
*
@ 作者: 秦东
@ -2905,3 +2928,20 @@ func TeamidNameInt(val string) int64 {
}
return 0
}
//取最大值
func GetMaxNum[T GenericityVariable](ary []T) T {
maxVal := ary[0]
if len(ary) == 0 {
return maxVal
}
for i := 1; i < len(ary); i++ {
if maxVal < ary[i] {
maxVal = ary[i]
}
}
return maxVal
}

Loading…
Cancel
Save