wxwork.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. package util
  2. import (
  3. "crypto/sha1"
  4. "fmt"
  5. "html/template"
  6. "io/ioutil"
  7. "log"
  8. "net/url"
  9. "strconv"
  10. "time"
  11. "github.com/fastwego/offiaccount"
  12. template1 "github.com/fastwego/offiaccount/apis/message/template"
  13. "github.com/fastwego/offiaccount/apis/oauth"
  14. user1 "github.com/fastwego/offiaccount/apis/user"
  15. "github.com/fastwego/offiaccount/type/type_message"
  16. "github.com/fastwego/offiaccount/util"
  17. "github.com/fastwego/wxwork/corporation"
  18. "github.com/fastwego/wxwork/corporation/apis/external_contact/customer"
  19. message1 "github.com/fastwego/wxwork/corporation/apis/message"
  20. "github.com/gin-gonic/gin"
  21. // "github.com/robfig/cron"
  22. "github.com/robfig/cron/v3"
  23. "kpt.xdmy/apiserver/routers/restful"
  24. "kpt.xdmy/pkg/logging"
  25. "kpt.xdmy/pkg/setting"
  26. )
  27. //企业微信
  28. var OffiAccount *offiaccount.OffiAccount
  29. var Corp *corporation.Corporation
  30. var App *corporation.App
  31. var MsgChan chan []map[string]string
  32. type UserMsg struct {
  33. Touser string `json:"touser"`
  34. Msgtype string `json:"msgtype"`
  35. Agentid string `json:"agentid"`
  36. Text interface{} `json:"text"`
  37. }
  38. func CronWXwork() {
  39. defer func() { // 必须要先声明defer
  40. if err := recover(); err != nil {
  41. fmt.Printf("CronTest pnic err%+v \n", err)
  42. logging.Error("panic recover err ", err)
  43. }
  44. }()
  45. initWXwork()
  46. go SendRun()
  47. log.Println("Starting CronWXwork...")
  48. c := cron.New()
  49. _, err := c.AddFunc("00 00 06 * * *", Getuseinfor) //* * * * *, 从分钟开始
  50. if err != nil {
  51. println("cron4 err", err.Error())
  52. }
  53. _, err = c.AddFunc("30 * * * * *", GetMsg) //* * * * *, 从分钟开始
  54. _, err = c.AddFunc("00 00 07 * * *", GetPartsInfo) //* * * * *, 每天七点
  55. if err != nil {
  56. println("cron5 err", err.Error())
  57. }
  58. c.Start()
  59. }
  60. func Ceshi() {
  61. fmt.Println("sasdsdadasa")
  62. }
  63. func GetPartsInfo() {
  64. tx, err1 := restful.Dbs.Beginx()
  65. defer func() {
  66. switch {
  67. case err1 != nil:
  68. println("tx.Begin 事务启动失败__error:", err1.Error())
  69. if tx != nil {
  70. tx.Rollback()
  71. }
  72. default:
  73. if tx != nil {
  74. err1 = tx.Commit()
  75. }
  76. }
  77. }()
  78. query, err := restful.MapStrListTx(tx, "select count(*) success,(select count(*) from parts ps "+
  79. " where ps.chargeDate >= DATE_SUB(now(),INTERVAL 1 DAY) and ps.issync=0 ) woring "+
  80. " from parts where parts.chargeDate >= DATE_SUB(now(),INTERVAL 1 DAY) and parts.issync=1 ")
  81. query1, err := restful.MapStrListTx(tx, " select empid from user where id in(select user_id from user_role "+
  82. "where role_id in (select id from role where easInformationReception = 1))")
  83. if err != nil {
  84. logging.Error("获取备件同步成功与否__error:", err.Error())
  85. } else {
  86. if len(query1) > 0 && len(query) > 0 {
  87. for i := 0; i < len(query1); i++ {
  88. success := query[0]["success"]
  89. personId := query1[i]["empid"]
  90. woring := query[0]["woring"]
  91. _, err = tx.Exec("INSERT INTO wxworkmsg(date,userid,msg,formcode,type,note) VALUES(?,?,?,?,?,?)",
  92. time.Now().Format("2006-01-02"), personId, "【eas】同步成功"+success+"条"+"同步失败"+woring+"条",
  93. "eas", 0, nil)
  94. if err != nil {
  95. }
  96. }
  97. }
  98. if err != nil {
  99. logging.Error("插入eas同步信息到微信信息表__error:", err.Error())
  100. }
  101. }
  102. }
  103. func Getuseinfor1() {
  104. logging.Error("PostDataByNames========= ")
  105. }
  106. func Getuseinfor() {
  107. defer func() { // 必须要先声明defer
  108. if err := recover(); err != nil {
  109. logging.Error("Getuseinfor pnic err", err) // 这里的err其实就是panic传入的内容,55
  110. }
  111. }()
  112. value := make(url.Values, 1)
  113. value.Add("department_id", "1")
  114. value.Add("fetch_child", "1")
  115. msgmap := make(map[string]interface{})
  116. resp, err := customer.List(App, value)
  117. if err != nil {
  118. println("contact.UserList err", err.Error())
  119. }
  120. err = json.Unmarshal(resp, &msgmap)
  121. if err != nil {
  122. println("json.Unmarshal err", err.Error())
  123. }
  124. tx, err1 := restful.Dbs.Beginx()
  125. defer func() {
  126. switch {
  127. case err1 != nil:
  128. logging.Error("tx.Begin 事务启动失败__error:", err.Error())
  129. if tx != nil {
  130. tx.Rollback()
  131. }
  132. default:
  133. if tx != nil {
  134. err = tx.Commit()
  135. }
  136. }
  137. }()
  138. if _, ok := msgmap["userlist"]; ok {
  139. for _, value := range msgmap["userlist"].([]interface{}) {
  140. userid := value.(map[string]interface{})["userid"]
  141. name := value.(map[string]interface{})["name"]
  142. var department interface{}
  143. if len(value.(map[string]interface{})["department"].([]interface{})) > 0 {
  144. department = value.(map[string]interface{})["department"].([]interface{})[0]
  145. }
  146. var empcode interface{}
  147. if len(value.(map[string]interface{})["extattr"].(map[string]interface{})["attrs"].([]interface{})) == 1 {
  148. empcode = value.(map[string]interface{})["extattr"].(map[string]interface{})["attrs"].([]interface{})[0].(map[string]interface{})["value"]
  149. } else if len(value.(map[string]interface{})["extattr"].(map[string]interface{})["attrs"].([]interface{})) > 1 {
  150. for _, va := range value.(map[string]interface{})["extattr"].(map[string]interface{})["attrs"].([]interface{}) {
  151. if va.(map[string]interface{})["name"] == "工号" {
  152. empcode = va.(map[string]interface{})["value"]
  153. break
  154. }
  155. }
  156. }
  157. //jvalue,_ :=json.Marshal(value)
  158. _, err = tx.Exec("insert into wxworkuser(userid,name,department,empcode)values(?,?,?,?)ON DUPLICATE KEY UPDATE empcode =?,department=?", userid, name, department, empcode, empcode, department)
  159. //_,err =tx.Exec("insert into wxworkuser(userid,name,department,empcode,json)values(?,?,?,?,?)ON DUPLICATE KEY UPDATE empcode =?",userid,name,department,empcode,string(jvalue),empcode)
  160. if err != nil {
  161. logging.Error("insert into wxworkuser err ", err.Error())
  162. }
  163. }
  164. }
  165. logging.Info("update wxworkuser success ")
  166. }
  167. func SendRun() {
  168. defer func() {
  169. if err := recover(); err != nil {
  170. logging.Error("GetMsg pnic err", err)
  171. }
  172. }()
  173. for {
  174. msgs := <-MsgChan
  175. println(len(msgs))
  176. for _, value := range msgs {
  177. content := make(map[string]interface{})
  178. content["content"] = value["msg"]
  179. msg := UserMsg{
  180. Touser: value["userid"],
  181. Agentid: setting.ServerSetting.WXworkAgentid,
  182. Text: content,
  183. Msgtype: "text",
  184. }
  185. msgbyte, err := json.Marshal(msg)
  186. if err != nil {
  187. logging.Error("json.Marshal err ", err.Error())
  188. }
  189. _, err = message1.Send(App, msgbyte)
  190. if err != nil {
  191. logging.Error("message1.Send err ", err.Error())
  192. fmt.Println("message1.Send err", err.Error())
  193. } else {
  194. }
  195. }
  196. }
  197. }
  198. func GetMsgv1() {
  199. go GetMsgv2()
  200. }
  201. func GetMsgv2() {
  202. defer func() { // 必须要先声明defer
  203. if err := recover(); err != nil {
  204. logging.Error("GetMsg pnic err", err) // 这里的err其实就是panic传入的内容,55
  205. }
  206. }()
  207. time.Sleep(time.Second)
  208. a := 0
  209. b := 1 / a
  210. println(b)
  211. }
  212. func GetMsg() {
  213. defer func() { // 必须要先声明defer
  214. if err := recover(); err != nil {
  215. logging.Error("GetMsg pnic err", err) // 这里的err其实就是panic传入的内容,55
  216. }
  217. }()
  218. tx, err1 := restful.Dbs.Beginx()
  219. defer func() {
  220. switch {
  221. case err1 != nil:
  222. println("tx.Begin 事务启动失败__error:", err1.Error())
  223. if tx != nil {
  224. tx.Rollback()
  225. }
  226. default:
  227. if tx != nil {
  228. err1 = tx.Commit()
  229. }
  230. }
  231. }()
  232. sqls, err := restful.MapStrListTx(tx, "select sqlstr from apisql where sqlname in ('getWXworkMsg','updateWXworkMsg') order by sqlname")
  233. if err != nil {
  234. logging.Error("select from sqls err ", err.Error())
  235. }
  236. if len(sqls) < 2 {
  237. return
  238. }
  239. sqlmsg := sqls[0]["sqlstr"]
  240. sqlupdate := sqls[1]["sqlstr"]
  241. var query []map[string]string
  242. if len(sqls) > 0 {
  243. query, err = restful.MapStrListTx(tx, sqlmsg)
  244. if err != nil {
  245. logging.Error("select from wxworkmsg err ", err.Error(), len(query))
  246. } else {
  247. _, err = tx.Exec(sqlupdate)
  248. if err != nil {
  249. logging.Error("update wxworkmsg err ", err.Error(), len(query))
  250. }
  251. }
  252. }
  253. if len(query) > 0 {
  254. go func() {
  255. msgs := query
  256. MsgChan <- msgs
  257. }()
  258. }
  259. }
  260. func SendMsgtest() {
  261. message1.Send(App, []byte(`{
  262. "touser": "18322596935",
  263. "toparty": "PartyID1|PartyID2",
  264. "totag": "TagID1 | TagID2",
  265. "msgtype": "text",
  266. "agentid": 1000022,
  267. "text": {
  268. "content": "你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看<a href=\"http://work.weixin.qq.com\">邮件中心视频实况</a>,聪明避开排队。"
  269. },
  270. "safe": 0,
  271. "enable_id_trans": 0,
  272. "enable_duplicate_check": 0
  273. }`))
  274. }
  275. func initOffiAccount() {
  276. // 加载配置文件
  277. // 创建公众号实例
  278. OffiAccount = offiaccount.New(offiaccount.Config{
  279. // wxe1cc563ba393dd1a
  280. Appid: "wxe1cc563ba393dd1a",
  281. Secret: "25e56243da9581eab6f4d67a12ef4658",
  282. Token: "123",
  283. // 6yYJ4sS5y1hJgvIXEqavV2rmCutyXkywndxUQFgX54f
  284. EncodingAESKey: "6yYJ4sS5y1hJgvIXEqavV2rmCutyXkywndxUQFgX54f",
  285. })
  286. //payload := []byte(`
  287. //{
  288. // "button":[
  289. // {
  290. // "name":"菜单",
  291. // "sub_button":[
  292. // {
  293. // "type":"view",
  294. // "name":"搜索",
  295. // "url":"http://www.baidu.com/"
  296. // }]
  297. // }]
  298. //}`)
  299. //resp, err := menu.Create(OffiAccount, payload)
  300. //fmt.Println(resp, err)
  301. //guide.SetGuideConfig(OffiAccount,[]byte("欢迎关注"))
  302. }
  303. func initWXwork() {
  304. // 加载配置文件
  305. // 创建企业微信实例
  306. Corp = corporation.New(corporation.Config{Corpid: setting.ServerSetting.WXworkCorpid})
  307. App = Corp.NewApp(corporation.AppConfig{
  308. AgentId: setting.ServerSetting.WXworkAgentid,
  309. Secret: setting.ServerSetting.WXworkSecret,
  310. Token: "",
  311. EncodingAESKey: "",
  312. })
  313. MsgChan = make(chan []map[string]string, 100)
  314. }
  315. func InitRouter() *gin.Engine {
  316. r := gin.New()
  317. // ginpprof.Wrap(r)
  318. r.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
  319. // 你的自定义格式
  320. return fmt.Sprintf(" %+v \n",
  321. param.Keys,
  322. )
  323. }))
  324. r.Use(gin.Logger()) // 日志
  325. //r.Use(Cors()) // 跨域请求rolemenus
  326. r.Use(gin.Recovery())
  327. r.GET("/", func(c *gin.Context) {
  328. //OffiAccount.Server.EchoStr(c.Writer, c.Request)
  329. config, err := jsapiConfig(c)
  330. if err != nil {
  331. fmt.Println("==========1", err)
  332. return
  333. }
  334. t1, err := template.ParseFiles("index.html")
  335. if err != nil {
  336. fmt.Println("==========2", err)
  337. return
  338. }
  339. println("===========", t1.Name())
  340. t1.Execute(c.Writer, config)
  341. })
  342. r.POST("/", HandleMessage)
  343. return r
  344. }
  345. func jsapiConfig(c *gin.Context) (config template.JS, err error) {
  346. // 优先从环缓存获取
  347. jsapi_ticket, err := OffiAccount.AccessToken.Cache.Fetch("jsapi_ticket:" + OffiAccount.Config.Appid)
  348. if len(jsapi_ticket) == 0 {
  349. var ttl int64
  350. jsapi_ticket, ttl, err = oauth.GetJSApiTicket(OffiAccount)
  351. if err != nil {
  352. return
  353. }
  354. err = OffiAccount.AccessToken.Cache.Save("jsapi_ticket:"+OffiAccount.Config.Appid, jsapi_ticket, time.Duration(ttl)*time.Second)
  355. if err != nil {
  356. return
  357. }
  358. }
  359. nonceStr := util.GetRandString(6)
  360. timestamp := strconv.FormatInt(time.Now().Unix(), 10)
  361. pageUrl := "http://" + c.Request.Host + c.Request.RequestURI
  362. plain := "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + pageUrl
  363. signature := fmt.Sprintf("%x", sha1.Sum([]byte(plain)))
  364. fmt.Println(plain, signature)
  365. configMap := map[string]string{
  366. "url": pageUrl,
  367. "nonceStr": nonceStr,
  368. "appid": OffiAccount.Config.Appid,
  369. "timestamp": timestamp,
  370. "signature": signature,
  371. }
  372. marshal, err := json.Marshal(configMap)
  373. if err != nil {
  374. return
  375. }
  376. return template.JS(marshal), nil
  377. }
  378. func HandleMessage(c *gin.Context) {
  379. // 区分不同账号
  380. //account := path.Base(c.Request.URL.Path)
  381. // 调用相应公众号服务
  382. body, _ := ioutil.ReadAll(c.Request.Body)
  383. log.Println(string(body))
  384. message, err := OffiAccount.Server.ParseXML(body)
  385. if err != nil {
  386. log.Println(err)
  387. }
  388. var output interface{}
  389. switch message.(type) {
  390. case type_message.MessageText: // 文本 消息
  391. msg := message.(type_message.MessageText)
  392. // 回复文本消息
  393. output = type_message.ReplyMessageText{
  394. ReplyMessage: type_message.ReplyMessage{
  395. ToUserName: type_message.CDATA(msg.FromUserName),
  396. FromUserName: type_message.CDATA(msg.ToUserName),
  397. CreateTime: strconv.FormatInt(time.Now().Unix(), 10),
  398. MsgType: type_message.ReplyMsgTypeText,
  399. },
  400. Content: type_message.CDATA(msg.Content),
  401. }
  402. resp, err := template1.Send(OffiAccount, []byte(`
  403. {
  404. "touser":"`+msg.FromUserName+`",
  405. "template_id":"BtkN1rWKOJtKP0C64lGxIrPzLRFsYFas-4gupX2-pFo",
  406. "data":{
  407. "first": {
  408. "value":"恭喜你购买成功!",
  409. "color":"#173177"
  410. },
  411. "keyword1":{
  412. "value":"巧克力",
  413. "color":"#173177"
  414. },
  415. "keyword2": {
  416. "value":"39.8元",
  417. "color":"#173177"
  418. },
  419. "keyword3": {
  420. "value":"2014年9月22日",
  421. "color":"#173177"
  422. },
  423. "remark":{
  424. "value":"欢迎再次购买!",
  425. "color":"#173177"
  426. }
  427. }
  428. }`))
  429. println("msg", resp, err, msg.FromUserName)
  430. }
  431. res, _ := user1.Get(OffiAccount, nil)
  432. println("res======", string(res))
  433. OffiAccount.Server.Response(c.Writer, c.Request, output)
  434. }