diff --git a/api/personalityTest/entry.go b/api/personalityTest/entry.go
index 892dcec..4d8aae2 100644
--- a/api/personalityTest/entry.go
+++ b/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 {
diff --git a/api/personalityTest/rongXin/controller.go b/api/personalityTest/rongXinPage/controller.go
similarity index 99%
rename from api/personalityTest/rongXin/controller.go
rename to api/personalityTest/rongXinPage/controller.go
index 0889ce8..6e93c35 100644
--- a/api/personalityTest/rongXin/controller.go
+++ b/api/personalityTest/rongXinPage/controller.go
@@ -1,4 +1,4 @@
-package rongxin
+package rongXinPage
import (
"appPlatform/models/modelshr"
diff --git a/api/personalityTest/rongXin/downLoad.go b/api/personalityTest/rongXinPage/downLoad.go
similarity index 89%
rename from api/personalityTest/rongXin/downLoad.go
rename to api/personalityTest/rongXinPage/downLoad.go
index 2f8ae93..e6184c6 100644
--- a/api/personalityTest/rongXin/downLoad.go
+++ b/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))
diff --git a/api/personalityTest/rongXinPage/testCaput.go b/api/personalityTest/rongXinPage/testCaput.go
new file mode 100644
index 0000000..547ef07
--- /dev/null
+++ b/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
+}
diff --git a/api/personalityTest/rongXin/type.go b/api/personalityTest/rongXinPage/type.go
similarity index 91%
rename from api/personalityTest/rongXin/type.go
rename to api/personalityTest/rongXinPage/type.go
index a814c04..1ea6029 100644
--- a/api/personalityTest/rongXin/type.go
+++ b/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"` //选项
+}
diff --git a/api/shiyan/maptostruct/shiyan.go b/api/shiyan/maptostruct/shiyan.go
index 88b49f6..9e3a873 100644
--- a/api/shiyan/maptostruct/shiyan.go
+++ b/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)
}
/*
diff --git a/api/version1/customerApp/runAppControll.go b/api/version1/customerApp/runAppControll.go
index 1c7fa8e..f8838e8 100644
--- a/api/version1/customerApp/runAppControll.go
+++ b/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)
+}
diff --git a/api/version1/customerApp/type.go b/api/version1/customerApp/type.go
index 04cd66e..603682e 100644
--- a/api/version1/customerApp/type.go
+++ b/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"`
+}
diff --git a/api/version1/customerform/formTable.go b/api/version1/customerform/formTable.go
index bc6a639..aed1b60 100644
--- a/api/version1/customerform/formTable.go
+++ b/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)
}
}
diff --git a/api/version1/customerform/formTableView.go b/api/version1/customerform/formTableView.go
index 36b1b3e..bbf8cd0 100644
--- a/api/version1/customerform/formTableView.go
+++ b/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
diff --git a/api/version1/customerform/type.go b/api/version1/customerform/type.go
index 8089207..7489c25 100644
--- a/api/version1/customerform/type.go
+++ b/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字段
diff --git a/api/version1/entry.go b/api/version1/entry.go
index af6597d..32a2e7c 100644
--- a/api/version1/entry.go
+++ b/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)
diff --git a/api/version1/publicapi/api.go b/api/version1/publicapi/api.go
index 3cd3714..4e325c1 100644
--- a/api/version1/publicapi/api.go
+++ b/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
}
diff --git a/api/version1/taskplatform/taskmanagement/flowType.go b/api/version1/taskplatform/taskmanagement/flowType.go
index 376ace4..06bef7e 100644
--- a/api/version1/taskplatform/taskmanagement/flowType.go
+++ b/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
diff --git a/api/version1/taskplatform/taskmanagement/runTaskFlow.go b/api/version1/taskplatform/taskmanagement/runTaskFlow.go
index 8cfe56f..96175cc 100644
--- a/api/version1/taskplatform/taskmanagement/runTaskFlow.go
+++ b/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:
}
diff --git a/api/version1/taskplatform/taskmanagement/runWorkFlow.go b/api/version1/taskplatform/taskmanagement/runWorkFlow.go
index db93cca..973abdc 100644
--- a/api/version1/taskplatform/taskmanagement/runWorkFlow.go
+++ b/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 {
diff --git a/api/version1/taskplatform/taskmanagement/sendWechatMsg.go b/api/version1/taskplatform/taskmanagement/sendWechatMsg.go
new file mode 100644
index 0000000..8a740fd
--- /dev/null
+++ b/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("
%v
%v
%v
驳回原因:%v
", 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
+}
diff --git a/api/version1/workFlow/common.go b/api/version1/workFlow/common.go
new file mode 100644
index 0000000..2248765
--- /dev/null
+++ b/api/version1/workFlow/common.go
@@ -0,0 +1,1061 @@
+package workflow
+
+import (
+ "appPlatform/api/version1/customerform"
+ "appPlatform/api/version1/taskplatform/taskmanagement"
+ "appPlatform/api/version1/workWechat"
+ "appPlatform/models/modelAppPlatform"
+ "appPlatform/models/modelshr"
+ "appPlatform/overall"
+ "appPlatform/overall/publicmethod"
+ "encoding/json"
+ "fmt"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+// 入口函数
+func (a *ApiMethod) Index(c *gin.Context) {
+ outputCont := publicmethod.MapOut[string]()
+ outputCont["index"] = "工作流入口"
+ publicmethod.Result(0, outputCont, c)
+}
+
+/*
+*
+@ 作者: 秦东
+@ 时间: 2024-12-12 16:46:21
+@ 功能: 执行工作流
+@ 参数
+
+ #userKey //当前执行人
+ #AgreeToRefuse //同意或者驳回
+ #runCont //执行意见
+
+@ 返回值
+
+ #
+
+@ 方法原型
+
+ #
+*/
+func (r *RunWorkFlow) GainRunNodeNew(userKey string, runSetup, AgreeToRefuse int, runCont string) (currentStep, nextStep int) {
+
+ if len(r.FlowList) > 0 {
+ userkInt, _ := strconv.ParseInt(userKey, 10, 64) //将字符型转换成64位整型
+ for i := 0; i < r.TotalSteps; i++ { //循环比对获取出当前执行节点
+ if r.FlowList[i].Step == runSetup { //获取当前执行节点内容
+ fmt.Printf("执行工作流当前节点-1-r.FlowList[i].Step:%v\n---1--》r.Step:%v\n", r.FlowList[i].Step, runSetup)
+ r.FlowList[i].Status = AgreeToRefuse //节点状态
+ currentStep, nextStep = r.TallyPaceStepes(userKey, runSetup, r.FlowList[i])
+ fmt.Printf("执行工作流当前节点-2-currentStep:%v\n--2---》nextStep:%v\n", currentStep, nextStep)
+ //获取参与人几当前节点操作记录
+ operatorAry, nodeUser := CopeParticipantEnforcerLog(userKey, r.RunUid, AgreeToRefuse, r.FlowList[i].Operator, runCont)
+ r.FlowList[i].Operator = operatorAry //节点操作记录
+ r.Participant = append(r.Participant, nodeUser...) //参与人
+ // panic("中断一下")
+ switch r.FlowList[i].Types { //0:发起节点;1:审批节点;2:抄送;3:执行节点
+ case 0:
+
+ taskmanagement.FlowRunLog(r.Uuid, userkInt, AgreeToRefuse, r.FlowList[i].NodeKey, runCont, "")
+
+ //判断下一个节点是否满足自动审批条件
+ if r.ToNextNodeRunOrClose(userKey, nextStep) {
+ // r.Step = r.NextStep
+ fmt.Printf("执行下一节点--r.Step:%v\n----->r.NextStep:%v\n", r.Step, nextStep)
+ currentStep, nextStep = r.GainRunNodeNew(userKey, nextStep, AgreeToRefuse, "自动审批")
+ } else {
+ //判断是否向下一个节点的人发送信息
+ r.SendWecharMsgTopct(userKey, nextStep)
+ }
+ r.Step = currentStep
+ r.NextStep = nextStep
+ return
+ case 1, 3:
+
+ taskmanagement.FlowRunLog(r.Uuid, userkInt, AgreeToRefuse, r.FlowList[i].NodeKey, runCont, "")
+ fmt.Printf("执行下一节点-34324234-currentStep:%v\n----->nextStep:%v\n", currentStep, nextStep)
+ //判断下一个节点是否满足自动审批条件
+ if r.ToNextNodeRunOrClose(userKey, nextStep) {
+ // r.Step = r.NextStep
+ fmt.Printf("执行下一节点-34324234-r.Step:%v\n----->r.NextStep:%v\n", r.Step, r.NextStep)
+ currentStep, nextStep = r.GainRunNodeNew(userKey, nextStep, AgreeToRefuse, "自动审批")
+ } else {
+ //判断是否向下一个节点的人发送信息
+ r.SendWecharMsgTopct(userKey, nextStep)
+ }
+ r.Step = currentStep
+ r.NextStep = nextStep
+ return
+ case 2:
+ r.SendWecharMsgTopct("", r.NextStep)
+ if r.NextStep > 0 {
+ currentStep, nextStep = r.GainRunNodeNew(userKey, nextStep, AgreeToRefuse, "自动审批")
+ }
+ r.Step = currentStep
+ r.NextStep = nextStep
+ return
+ default:
+ }
+ }
+ }
+ }
+ return
+}
+
+/*
+*
+@ 作者: 秦东
+@ 时间: 2024-12-14 13:37:04
+@ 功能: 获取下一节点审批人
+@ 参数
+
+ #
+
+@ 返回值
+
+ #userKeyAry 节点审批人
+
+@ 方法原型
+
+ #
+*/
+func (r *RunWorkFlow) NextNodePeople() (userKeyAry []string) {
+ if r.NextStep > 0 {
+ for _, v := range r.FlowList {
+ if r.NextStep == v.Step {
+ for _, ov := range v.Operator {
+ if ov.Id != "" {
+ userKeyAry = append(userKeyAry, ov.Id)
+ }
+ }
+ }
+ }
+ }
+ return
+}
+
+/*
+*
+@ 作者: 秦东
+@ 时间: 2024-12-13 13:38:52
+@ 功能: 向下一个节点人员发送消息
+@ 参数
+
+ #
+
+@ 返回值
+
+ #
+
+@ 方法原型
+
+ #
+*/
+func (r *RunWorkFlow) SendWecharMsgTopct(userKey string, nextStep int) {
+ fmt.Printf("发射消息---->userKey: %v\n nextStep: %v\n", userKey, nextStep)
+ 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 {
+ if len(ov.LogList) > 0 {
+ 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)
+ }
+ }
+ }
+ }
+ } else {
+ if ov.Wechat != "" {
+ sendUserAry = append(sendUserAry, ov.Wechat)
+ }
+ }
+
+ }
+ }
+
+ }
+ }
+ fmt.Printf("发射消息--2-->sendUserAry: %v\n nextStep: %v\n", sendUserAry, nextStep)
+ 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-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
+}
+
+/*
+*
+@ 作者: 秦东
+@ 时间: 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
+}
+
+/*
+*
+@ 作者: 秦东
+@ 时间: 2024-12-17 08:42:53
+@ 功能: 判断是否执行下一步(副本)
+@ 参数
+
+ #runSetup 当前要执行的步骤
+ #nodeInfo 当前节点状态
+
+@ 返回值
+
+ #currentStep 计算后的当前节点
+ #nextStep 计算后的下一个节点
+
+@ 方法原型
+
+ #
+*/
+func (r *RunWorkFlow) TallyPaceStepes(userKey string, runSetup int, nodeInfo RunFlow) (currentStep, nextStep int) {
+ runIdStr := strconv.FormatInt(r.RunUid, 10)
+ nodeInfoJson, _ := json.Marshal(nodeInfo)
+ fmt.Printf("计步器runIdStr:%v---1-----runSetup:%v--------nodeInfo.Types:%v----------->nodeInfoJson:%v\n", runIdStr, runSetup, nodeInfo.Types, string(nodeInfoJson))
+ if nodeInfo.Types == 2 {
+ currentStep = runSetup
+ nextStep = runSetup + 1
+ return
+ } else {
+
+ optUserCount := len(nodeInfo.Operator) //此节点有几个人审批
+ jiBuQi := 0
+ for _, v := range nodeInfo.Operator {
+ for _, l := range v.LogList {
+ if l.UID == runIdStr {
+ jiBuQi++
+ }
+ }
+ // if v.Id == userKey {
+ // jiBuQi++
+ // }
+ }
+ fmt.Printf("计步器 optUserCount:%v---2-----runSetup:%v-----jiBuQi:%v\n", optUserCount, runSetup, jiBuQi)
+ if jiBuQi > 0 { //存在有人审批的情况
+ if jiBuQi >= optUserCount { //当前节点所有人已经审批则进入下一个节点
+ currentStep = runSetup
+ if currentStep >= r.TotalSteps {
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ nextStep = currentStep + 1
+ if nextStep >= r.TotalSteps {
+ nextStep = r.TotalSteps
+ }
+ }
+ } else { //有未参与审批的人员,根据节点属性进行判断
+ fmt.Printf("计步器 nodeInfo.ExamineMode :%v---3-----runSetup:%v-----r.TotalSteps:%v\n", nodeInfo.ExamineMode, runSetup, r.TotalSteps)
+ switch nodeInfo.ExamineMode { //多人审批时采用的审批方式。0:无操作 1依次审批 2会签 3:或签
+ case 1, 2:
+ if runSetup >= r.TotalSteps { //当前步数大于等于总步数时
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ currentStep = runSetup - 1
+ if currentStep <= 0 {
+ currentStep = 1
+ }
+ if currentStep >= r.TotalSteps {
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ nextStep = currentStep + 1
+ if nextStep >= r.TotalSteps {
+ nextStep = r.TotalSteps
+ }
+ }
+ }
+ case 3:
+ if runSetup >= r.TotalSteps { //当前步数大于等于总步数时
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ currentStep = runSetup
+ if currentStep >= r.TotalSteps {
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ nextStep = currentStep + 1
+ if nextStep >= r.TotalSteps {
+ nextStep = r.TotalSteps
+ }
+ }
+ }
+ default:
+ }
+ }
+
+ } else { //此节点没有人审批
+ fmt.Printf("计步器 r.TotalSteps:%v---4-----runSetup:%v-----jiBuQi:%v\n", r.TotalSteps, runSetup, jiBuQi)
+ if optUserCount > 1 {
+ currentStep = runSetup - 1
+ if currentStep >= r.TotalSteps {
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ nextStep = currentStep + 1
+ if nextStep >= r.TotalSteps {
+ nextStep = r.TotalSteps
+ }
+ }
+ } else {
+ currentStep = runSetup
+ if currentStep >= r.TotalSteps {
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ nextStep = currentStep + 1
+ if nextStep >= r.TotalSteps {
+ nextStep = r.TotalSteps
+ }
+ }
+ }
+
+ }
+ }
+ return
+}
+
+/*
+*
+@ 作者: 秦东
+@ 时间: 2024-12-13 10:27:15
+@ 功能: 判断是否执行下一步
+#nodeInfo 当前执行节点内容
+*/
+func (r *RunWorkFlow) TallyPaceStep(runSetup int, nodeInfo RunFlow) (currentStep, nextStep int) {
+ nodeInfoJson, _ := json.Marshal(nodeInfo)
+ fmt.Printf("判断是否执行下一步runSetup:%v=============>r.TotalSteps:%v=============>nodeInfo.ExamineMode:%v=============>%v\n", runSetup, r.TotalSteps, nodeInfo.ExamineMode, string(nodeInfoJson))
+ switch nodeInfo.ExamineMode { //多人审批时采用的审批方式。0:无操作 1依次审批 2会签 3:或签
+ case 1, 2:
+ runIdStr := strconv.FormatInt(r.RunUid, 10)
+ optUserCount := len(nodeInfo.Operator)
+ jiBuQi := 0
+ for _, v := range nodeInfo.Operator {
+ for _, l := range v.LogList {
+ if l.UID == runIdStr {
+ jiBuQi++
+ }
+ }
+ }
+ fmt.Printf("计步器runIdStr:%v---1-----currentStep:%v--------optUserCount:%v----------->jiBuQi:%v\n", runIdStr, currentStep, optUserCount, jiBuQi)
+ if jiBuQi >= optUserCount { //会签人员全部签署
+ if runSetup >= r.TotalSteps { //当前步数大于等于总步数时
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ currentStep = runSetup
+ if currentStep >= r.TotalSteps {
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ nextStep = currentStep + 1
+ if nextStep >= r.TotalSteps {
+ nextStep = r.TotalSteps
+ }
+ }
+ }
+ } else { //会签中有人未签署
+ if runSetup >= r.TotalSteps { //当前步数大于等于总步数时
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ currentStep = runSetup
+ if currentStep >= r.TotalSteps {
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ nextStep = currentStep + 1
+ if nextStep >= r.TotalSteps {
+ nextStep = r.TotalSteps
+ }
+ }
+ }
+ }
+ case 3:
+
+ runIdStr := strconv.FormatInt(r.RunUid, 10)
+ jiBuQi := 0
+ for _, v := range nodeInfo.Operator {
+ for _, l := range v.LogList {
+ if l.UID == runIdStr {
+ jiBuQi++
+ }
+ }
+ }
+
+ fmt.Printf("计步器runIdStr:%v----2----currentStep:%v--------runSetup:%v----------->jiBuQi:%v\n", runIdStr, currentStep, runSetup, jiBuQi)
+
+ if jiBuQi > 0 { //或签中已有一人签署
+ if runSetup >= r.TotalSteps { //当前步数大于等于总步数时
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ currentStep = runSetup
+ if currentStep >= r.TotalSteps {
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ nextStep = currentStep + 1
+ if nextStep >= r.TotalSteps {
+ nextStep = r.TotalSteps
+ }
+ }
+ }
+ } else { //没有任何人签署
+ if runSetup >= r.TotalSteps { //当前步数大于等于总步数时
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ currentStep = runSetup
+ if currentStep >= r.TotalSteps {
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ nextStep = currentStep + 1
+ if nextStep >= r.TotalSteps {
+ nextStep = r.TotalSteps
+ }
+ }
+ }
+ }
+ default:
+
+ if runSetup >= r.TotalSteps { //当前步数大于等于总步数时
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ currentStep = runSetup
+ if currentStep >= r.TotalSteps {
+ currentStep = r.TotalSteps
+ nextStep = 0
+ } else {
+ nextStep = currentStep + 1
+ if nextStep >= r.TotalSteps {
+ nextStep = r.TotalSteps
+ }
+ }
+ }
+ fmt.Printf("计步器r.TotalSteps:%v----3----currentStep:%v--------runSetup:%v----------->jiBuQi:%v\n", r.TotalSteps, currentStep, runSetup, currentStep)
+ }
+ return
+}
+
+/*
+*
+@ 作者: 秦东
+@ 时间: 2024-12-13 08:20:36
+@ 功能: 处理执行节点参与人和执行人操作记录
+@ 参数
+
+ #userKey 操作人
+ #runUid 执行Uid
+ #AgreeToRefuse 同意或者驳回
+ #operator 当前节点操作人
+ #suggest 审批意见
+
+@ 返回值
+
+ #OperatorAry 节点操作记录
+ #nodeUser 节点参与人
+
+@ 方法原型
+
+ #
+*/
+func CopeParticipantEnforcerLog(userKey string, runUid int64, AgreeToRefuse int, operator []OperatorList, suggest string) (OperatorAry []OperatorList, nodeUser []string) {
+ var logInfo LogList
+ logInfo.State = AgreeToRefuse //状态 1、未操作;2、通过;3、驳回
+ logInfo.TimeVal = publicmethod.UnixTimeToDay(time.Now().Unix(), 1) //操作时间
+ logInfo.UID = strconv.FormatInt(runUid, 10)
+ logInfo.Cause = suggest
+ isNewAdd := true //判断当前执行人是否再执行列表中
+ for _, v := range operator {
+ nodeUser = append(nodeUser, v.Id)
+ if v.Id == userKey {
+ v.LogList = append(v.LogList, logInfo)
+ isNewAdd = false
+ }
+ OperatorAry = append(OperatorAry, v)
+ }
+ if isNewAdd { //如果此人没有在此节点中,则增加此人
+ var myInfo modelshr.ManCont
+ myInfo.GetCont(map[string]interface{}{"`key`": userKey})
+ userKey := strconv.FormatInt(myInfo.Key, 10)
+ nodeUser = append(nodeUser, userKey)
+ nodeMan := TransformPublicUs(myInfo)
+ nodeMan.LogList = append(nodeMan.LogList, logInfo)
+ OperatorAry = append(OperatorAry, nodeMan)
+ }
+ return
+}
+
+/*
+*
+@ 作者: 秦东
+@ 时间: 2023-11-15 11:37:00
+@ 功能: 装通用执行人数据
+@ 参数
+
+ #v 人员信息
+
+@ 返回值
+
+ #userCont 统一操作人信息
+
+@ 方法原型
+
+ #
+*/
+func TransformPublicUs(v modelshr.ManCont) (userCont OperatorList) {
+ userCont.Id = strconv.FormatInt(v.Key, 10)
+ userCont.Types = 1 //1:人员;2:角色;3:行政组织
+ userCont.Name = v.Name //操作人姓名
+ userCont.Number = v.Number //操作人工号
+ userCont.Icon = v.Icon //操作人头像
+ userCont.IconBase64 = v.IconPhpto //操作人头像
+ userCont.Wechat = v.Wechat //微信Openid、
+ userCont.Tel = v.Mobilephone
+ if v.WorkWechat != "" {
+ userCont.Wechat = v.WorkWechat //微信Openid
+ }
+ if v.Company != 0 {
+ var orgGroupCont modelshr.AdministrativeOrganization
+ orgGroupCont.GetCont(map[string]interface{}{"`id`": v.Company}, "`name`")
+ userCont.CompanyName = orgGroupCont.Name //公司名称
+ }
+ _, companyId, _, _, _ := publicmethod.GetOrgStructurees(v.AdminOrg)
+ userCont.DepartmentId = companyId //分厂Id
+ if companyId != 0 {
+ var orgCont modelshr.AdministrativeOrganization
+ orgCont.GetCont(map[string]interface{}{"`id`": companyId}, "`name`")
+ userCont.DepartmentName = orgCont.Name //分厂名称
+ }
+ //获取岗位
+ if v.Position != 0 {
+ var postCont modelshr.Position
+ postCont.GetCont(map[string]interface{}{"`id`": v.Position}, "`name`")
+ userCont.PostId = v.Position //职务Id
+ userCont.PostName = postCont.Name //职务名称
+ }
+ if v.TeamId != 0 {
+ var teamCont modelshr.TeamGroup
+ teamCont.GetCont(map[string]interface{}{"`id`": v.TeamId}, "`name`")
+ userCont.Tema = v.TeamId //班组Id
+ userCont.TemaName = teamCont.Name //班组名称
+ }
+ return
+}
+
+/*
+*
+@ 作者: 秦东
+@ 时间: 2024-12-17 11:04:48
+@ 功能: 执行工作流节点处理
+@ 参数
+
+ #userKey 当前处理人
+ #AgreeToRefuse 1:同意,2:驳回
+ #Suggest 审批意见
+
+@ 返回值
+
+ #
+
+@ 方法原型
+
+ #
+*/
+func (r *RunWorkFlow) RunNodeHandle(userKey int64, AgreeToRefuse int, Suggest string) {
+ fmt.Printf("执行工作流节点处理------------->userKey=======>%v, AgreeToRefuse=======>%v, Suggest=======>%v, r.Step=======>%v\n", userKey, AgreeToRefuse, Suggest, r.Step)
+ //判断流程是否存在
+ if len(r.FlowList) < 1 {
+ return
+ }
+ userKeyStr := strconv.FormatInt(userKey, 10) //当前操作人识别符转字符类型
+ for i, v := range r.FlowList { //遍历流程步骤判断当前执行的哪一步
+ if v.Step == r.Step { //获取当前节点数据
+ switch v.Types { //0:发起节点;1:审批节点;2:抄送;3:执行节点
+ case 1, 3:
+ //判断操作人是有操作权限或是否已经操作过
+ r.IsRun, r.Msg = JudgeOperUser(userKey, r.RunUid, v.Operator) //判断操作人是有操作权限或是否已经操作过
+ if r.IsRun {
+ return
+ } else {
+ fmt.Printf("执行工作流节点处理-------1------>userKey=======>%v\n AgreeToRefuse=======>%v\n Suggest=======>%v\n\n", userKey, AgreeToRefuse, Suggest)
+ if AgreeToRefuse != 1 { //驳回操作
+ v.Status = 3 //驳回
+ operatorAry, nodeUser := CopeParticipantEnforcerLog(userKeyStr, r.RunUid, 3, v.Operator, Suggest)
+ r.FlowList[i].Operator = operatorAry
+ r.Participant = append(r.Participant, nodeUser...)
+ r.Step, r.NextStep, _ = r.CallBackToNode(v.GoBackNode)
+ fmt.Printf("执行工作流节点处理--------2----->userKey=======>%v\n AgreeToRefuse=======>%v\n Suggest=======>%v\n operatorAry=======>%v\n nodeUser=======>%v\n GoBackNode=======>%v\n r=======>%v\n\n", userKey, AgreeToRefuse, Suggest, operatorAry, nodeUser, v.GoBackNode, r)
+ r.SendWecharMsgTextCard(r.Step, "驳回", Suggest)
+ } else { //同意操作
+ v.Status = 2 //同意
+ operatorAry, nodeUser := CopeParticipantEnforcerLog(userKeyStr, r.RunUid, 2, v.Operator, Suggest)
+ r.FlowList[i].Operator = operatorAry
+ r.Participant = append(r.Participant, nodeUser...)
+ currentStep, nextStep := r.TallyPaceStepes(userKeyStr, r.Step, r.FlowList[i]) //获取执行步伐
+ fmt.Printf("执行工作流节点处理-------3------>userKey=======>%v\n AgreeToRefuse=======>%v\n Suggest=======>%v\n currentStep=======>%v\n nextStep=======>%v\n\n", userKey, AgreeToRefuse, Suggest, currentStep, nextStep)
+ if nextStep > 0 {
+ if r.ToNextNodeRunOrClose(userKeyStr, nextStep) {
+ r.Step = nextStep
+ // r.NextStep = nextStep
+ r.RunNodeHandle(userKey, AgreeToRefuse, Suggest)
+ } else {
+ userKeyStr := strconv.FormatInt(userKey, 10)
+ //判断是否向下一个节点的人发送信息
+ r.SendWecharMsgTopct(userKeyStr, nextStep)
+ }
+ }
+ r.Step = currentStep
+ r.NextStep = nextStep
+ taskmanagement.FlowRunLog(r.Uuid, userKey, AgreeToRefuse, v.NodeKey, Suggest, "")
+ }
+ }
+ return
+ case 2: //抄送
+ var sendUserAry []string
+ for _, ov := range v.Operator {
+ if !publicmethod.IsInTrue[string](ov.Id, r.MakeCopy) {
+ r.MakeCopy = append(r.MakeCopy, ov.Id)
+ }
+ if ov.Wechat != "" {
+ if !publicmethod.IsInTrue[string](ov.Wechat, sendUserAry) {
+ sendUserAry = append(sendUserAry, ov.Wechat)
+ }
+ }
+ userkIntId, _ := strconv.ParseInt(ov.Id, 10, 64)
+ title := fmt.Sprintf("向%v发送抄送数据", ov.Name)
+ taskmanagement.FlowRunLog(r.Uuid, userkIntId, AgreeToRefuse, v.NodeKey, title, "")
+ }
+ r.SendWecharMsgTopct(userKeyStr, r.Step)
+ currentStep, nextStep := r.TallyPaceStepes(userKeyStr, r.Step, r.FlowList[i])
+ if nextStep > 0 {
+ if r.ToNextNodeRunOrClose(userKeyStr, nextStep) {
+ r.Step = currentStep
+ r.NextStep = nextStep
+ r.RunNodeHandle(userKey, AgreeToRefuse, Suggest)
+ }
+ }
+ r.Step = currentStep
+ r.NextStep = nextStep
+ return
+ default:
+ v.Status = 2 //同意
+ operatorAry, nodeUser := CopeParticipantEnforcerLog(userKeyStr, r.RunUid, 2, v.Operator, "发起流程")
+ r.FlowList[i].Operator = operatorAry
+ r.Participant = append(r.Participant, nodeUser...)
+ currentStep, nextStep := r.TallyPaceStepes(userKeyStr, r.Step, r.FlowList[i]) //获取执行步伐
+ fmt.Printf("执行工作流节点处理-------4------>userKey=======>%v\n AgreeToRefuse=======>%v\n Suggest=======>%v\n currentStep=======>%v\n nextStep=======>%v\n\n", userKey, AgreeToRefuse, Suggest, currentStep, nextStep)
+ if nextStep > 0 {
+ if r.ToNextNodeRunOrClose(userKeyStr, nextStep) {
+ r.Step = currentStep
+ r.NextStep = nextStep
+ r.RunNodeHandle(userKey, AgreeToRefuse, "发起流程")
+ } else {
+ userKeyStr := strconv.FormatInt(userKey, 10)
+ //判断是否向下一个节点的人发送信息
+ r.SendWecharMsgTopct(userKeyStr, nextStep)
+ }
+ }
+ r.Step = currentStep
+ r.NextStep = nextStep
+ taskmanagement.FlowRunLog(r.Uuid, userKey, AgreeToRefuse, v.NodeKey, "发起流程", "")
+ }
+ }
+ }
+}
+
+/*
+*
+@ 作者: 秦东
+@ 时间: 2024-12-19 08:34:32
+@ 功能: 驳回到指定节点
+@ 参数
+
+ #nodeKey 返回的节点
+
+@ 返回值
+
+ #
+
+@ 方法原型
+
+ #
+*/
+func (r *RunWorkFlow) CallBackToNode(nodeKey string) (creeStep, nextStep int, isNew bool) {
+ if nodeKey == "beginnode" {
+ creeStep = 1
+ if len(r.FlowList) >= 2 {
+ nextStep = 2
+ isNew = false
+ } else {
+ nextStep = 0
+ isNew = true
+ }
+ r.Step = creeStep
+ r.NextStep = nextStep
+ } else {
+ creeStep = 1
+ nextStep = 0
+ for _, v := range r.FlowList {
+ if nodeKey == v.NodeKey {
+ creeStep = v.Step
+ nextStep := v.Step + 1
+ if nextStep <= len(r.FlowList) {
+ isNew = false
+ } else {
+ nextStep = 0
+ isNew = true
+ }
+ }
+ }
+ r.Step = creeStep
+ r.NextStep = nextStep
+ }
+ return
+}
+
+/*
+*
+@ 作者: 秦东
+@ 时间: 2024-12-17 11:45:12
+@ 功能: 判断操作人是否已经操作过或具备当前操作权限,并写入操作记录
+@ 参数
+
+ #userKey 当前操作人
+ #runId 执行码
+ #ExamineMode 多人审批时采用的审批方式。0:无操作 1依次审批 2会签 3:非会签
+ #Operator 操作人
+
+@ 返回值
+
+ #状态
+ #说明
+
+@ 方法原型
+
+ #
+*/
+func JudgeOperUser(userKey, runId int64, Operator []OperatorList) (bool, string) {
+ if len(Operator) < 1 {
+ return true, "您不是此节点操作人!请不要提交!"
+ }
+ jsonval, _ := json.Marshal(Operator)
+ fmt.Printf("判断操作人是否已经操作过userKey:%v\n\n\n\n runId:%v\n\n\n\njsonval:%v\n\n\n\n", userKey, runId, string(jsonval))
+ caoZuoQuanXian := true
+ for _, v := range Operator {
+ if v.Id == strconv.FormatInt(userKey, 10) {
+ caoZuoQuanXian = false
+ if len(v.LogList) > 0 {
+ for _, m := range v.LogList {
+ if m.UID == strconv.FormatInt(runId, 10) {
+ return true, "您已经操作过此节点!请不要重复提交!"
+ }
+ }
+ }
+ }
+ }
+ if caoZuoQuanXian {
+ return true, "您不是此节点操作人!请不要提交!"
+ }
+ return false, ""
+}
+
+/*
+*
+@ 作者: 秦东
+@ 时间: 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("%v
%v
%v
驳回原因:%v
", 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)
+ }
+}
diff --git a/api/version1/workFlow/flow.go b/api/version1/workFlow/flow.go
new file mode 100644
index 0000000..95de223
--- /dev/null
+++ b/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
+}
diff --git a/api/version1/workFlow/flowNode.go b/api/version1/workFlow/flowNode.go
new file mode 100644
index 0000000..e8d4cb1
--- /dev/null
+++ b/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"` //附件类型
+}
diff --git a/api/version1/workFlow/flowType.go b/api/version1/workFlow/flowType.go
new file mode 100644
index 0000000..481796b
--- /dev/null
+++ b/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"` //执行流程
+}
diff --git a/api/version1/workFlow/type.go b/api/version1/workFlow/type.go
new file mode 100644
index 0000000..7351b27
--- /dev/null
+++ b/api/version1/workFlow/type.go
@@ -0,0 +1,8 @@
+package workflow
+
+import "sync"
+
+// 协程设置
+var syncSeting = sync.WaitGroup{}
+
+type ApiMethod struct{}
diff --git a/api/version1/workWechat/msgMap.go b/api/version1/workWechat/msgMap.go
new file mode 100644
index 0000000..0f06d3c
--- /dev/null
+++ b/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
+}
diff --git a/api/version1/workWechat/msgMethod.go b/api/version1/workWechat/msgMethod.go
new file mode 100644
index 0000000..bddf785
--- /dev/null
+++ b/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
+}
diff --git a/api/version1/workWechat/sendMsg.go b/api/version1/workWechat/sendMsg.go
new file mode 100644
index 0000000..427267e
--- /dev/null
+++ b/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)
+}
diff --git a/api/version1/workWechat/workMsgType.go b/api/version1/workWechat/workMsgType.go
new file mode 100644
index 0000000..75e3ed3
--- /dev/null
+++ b/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
+}
diff --git a/apirouter/v1/customerformrouter/router.go b/apirouter/v1/customerformrouter/router.go
index 70cf0cb..876c506 100644
--- a/apirouter/v1/customerformrouter/router.go
+++ b/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) //按菜单顶级分组和表单
}
}
diff --git a/apirouter/v1/taskrouter/workFlow.go b/apirouter/v1/taskrouter/workFlow.go
new file mode 100644
index 0000000..93f4623
--- /dev/null
+++ b/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) //启动流程
+ }
+}
diff --git a/apirouter/v1/workWechatRouter/router.go b/apirouter/v1/workWechatRouter/router.go
index 756b159..8494c4c 100644
--- a/apirouter/v1/workWechatRouter/router.go
+++ b/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) //向企业微信发送消息
}
}
diff --git a/initialization/route/initRoute.go b/initialization/route/initRoute.go
index b505835..a84e9c7 100644
--- a/initialization/route/initRoute.go
+++ b/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("")
diff --git a/models/customerForm/taskrecord.go b/models/customerForm/taskrecord.go
index ec45374..b7d30f5 100644
--- a/models/customerForm/taskrecord.go
+++ b/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 {
diff --git a/overall/publicmethod/technique.go b/overall/publicmethod/technique.go
index 237f394..67e3260 100644
--- a/overall/publicmethod/technique.go
+++ b/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
+}