wxwork.go 15 KB

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