day_new.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. package services
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "github.com/silenceper/wechat/v2/work/msgaudit"
  7. "hongze/hongze_open_api/models/tables/day_new"
  8. "hongze/hongze_open_api/models/tables/yb"
  9. "hongze/hongze_open_api/services/alarm_msg"
  10. "hongze/hongze_open_api/services/wework"
  11. "hongze/hongze_open_api/utils"
  12. "strconv"
  13. "strings"
  14. "time"
  15. )
  16. func DayNewWeworkMsgRefresh() (err error) {
  17. defer func() {
  18. if err != nil {
  19. go alarm_msg.SendAlarmMsg("企业微信 会议存档消息刷新失败, Err:"+err.Error(), 1)
  20. }
  21. }()
  22. list := make([]msgaudit.TextMessage, 0)
  23. //获取最新的拉取日志,得到seq和limit的值
  24. lastReq, e := day_new.GetLasReqLog()
  25. if e != nil && e.Error() != utils.ErrNoRow() {
  26. err = errors.New(fmt.Sprintf("获取最新请求日志失败 err: %v", e))
  27. return
  28. }
  29. now := time.Now()
  30. seq := uint64(0)
  31. limit := uint64(100)
  32. timeout := 5
  33. seqRes := uint64(0)
  34. if e == nil {
  35. seq = lastReq.Seq
  36. limit = uint64(lastReq.Limit)
  37. }
  38. msgAuditClient := wework.NewWeWorkMsgAuditClient()
  39. list, seqRes, err = msgAuditClient.GetMsgAuditContent(seq, limit, timeout)
  40. if err != nil {
  41. err = errors.New(fmt.Sprintf("查询会话存档信息失败 err: %v", err))
  42. return
  43. }
  44. if len(list) == 0 { //本次无消息更新
  45. return
  46. }
  47. //查询5天内的消息,用来判断消息是否已存在
  48. before5Time := time.Now().Add(-120*time.Hour).Unix() * 1000
  49. cond := " and msg_time > ?"
  50. var pars []interface{}
  51. pars = append(pars, before5Time)
  52. existList, err := day_new.GetWeworkMsgByCondition(cond, pars)
  53. if err != nil {
  54. return
  55. }
  56. existMsgMap := make(map[string]struct{}, 0)
  57. for _, v := range existList {
  58. existMsgMap[v.MsgId] = struct{}{}
  59. }
  60. //如果成功获取到值,则新增一条新的请求日志,是否需要加入事务,防止请求成功后,数据没有正常插入引起
  61. userMap := make(map[string]struct{}, 0) //企业内用户
  62. extendUserMap := make(map[string]struct{}, 0) //企业外联系人
  63. insertList := make([]*day_new.WeworkMsg, 0)
  64. //配置只查询特定群消息
  65. var limitRoomId string
  66. chatConfig, tErr := yb.GetConfigByCode("wework_chat_room_id")
  67. if tErr == nil {
  68. if chatConfig.ConfigValue != "" {
  69. limitRoomId = chatConfig.ConfigValue
  70. }
  71. }
  72. for _, v := range list {
  73. if _, ok := existMsgMap[v.MsgID]; ok {
  74. continue
  75. }
  76. if limitRoomId != "" {
  77. if v.RoomID != limitRoomId {
  78. continue
  79. }
  80. }
  81. toList, _ := json.Marshal(v.ToList)
  82. v.ToList = append(v.ToList, v.From) //把发言者的userid也加入到用户map里
  83. for _, u := range v.ToList {
  84. if len(u) > 10 && strings.HasPrefix(u, "wm") {
  85. if _, ok := extendUserMap[u]; !ok {
  86. extendUserMap[u] = struct{}{}
  87. }
  88. }else{
  89. if _, ok := userMap[u]; !ok {
  90. userMap[u] = struct{}{}
  91. }
  92. }
  93. }
  94. tmp := &day_new.WeworkMsg{
  95. MsgId: v.MsgID,
  96. Action: v.Action,
  97. From: v.From,
  98. ToList: string(toList),
  99. RoomId: v.RoomID,
  100. MsgTime: v.MsgTime,
  101. MsgType: v.MsgType,
  102. Content: v.Text.Content,
  103. ContentEn: "",
  104. ReportId: 0,
  105. CreateTime: now,
  106. IsAdd: 0,
  107. IsDelete: 0,
  108. ModifyTime: now,
  109. }
  110. insertList = append(insertList, tmp)
  111. }
  112. if len(insertList) > 0 {
  113. //批量插入数据库
  114. err = day_new.AddWeworkMsgMulti(insertList)
  115. if err != nil {
  116. err = errors.New(fmt.Sprintf("批量新增消息失败 err: %v", err))
  117. return
  118. }
  119. }
  120. reqLog := &day_new.WeworkMsgLog{
  121. Seq: seqRes,
  122. Limit: int(limit),
  123. Total: len(list),
  124. ReqResult: int8(1),
  125. CreateTime: now,
  126. ModifyTime: now,
  127. }
  128. err = day_new.AddMsgReqLog(reqLog)
  129. if err != nil {
  130. err = errors.New(fmt.Sprintf("新增请求日志失败 err: %v", err))
  131. return
  132. }
  133. //批量插入用户信息
  134. //查询已有的用户信息,判断是否需要新增
  135. allUsers, err := day_new.GetAllWeworkUser()
  136. if err != nil {
  137. err = errors.New(fmt.Sprintf("查询所有企业微信用户失败 err: %v", err))
  138. return
  139. }
  140. insertUserList := make([]*day_new.WeworkUser, 0)
  141. userExistMap := make(map[string]struct{}, 0) //企业内用户
  142. extendUseExistrMap := make(map[string]struct{}, 0) //企业外联系人
  143. for _, v := range allUsers {
  144. if v.WwExtendUserId != "" {
  145. extendUseExistrMap[v.WwExtendUserId] = struct{}{}
  146. }
  147. if v.WwUserId != "" {
  148. userExistMap[v.WwUserId] = struct{}{}
  149. }
  150. }
  151. for k := range extendUserMap {
  152. if _, ok := extendUseExistrMap[k]; !ok {
  153. tmp := &day_new.WeworkUser{
  154. WwUserId: "",
  155. WwExtendUserId: k,
  156. WwNickName: "",
  157. WwDeptId: 0,
  158. CreateTime: now,
  159. ModifyTime: now,
  160. }
  161. insertUserList = append(insertUserList, tmp)
  162. }
  163. }
  164. for k := range userMap {
  165. if _, ok := userExistMap[k]; !ok {
  166. tmp := &day_new.WeworkUser{
  167. WwUserId: k,
  168. WwExtendUserId: "",
  169. WwNickName: "",
  170. WwDeptId: 0,
  171. CreateTime: now,
  172. ModifyTime: now,
  173. }
  174. insertUserList = append(insertUserList, tmp)
  175. }
  176. }
  177. if len(insertUserList) > 0 {
  178. err = day_new.AddWeworkUserMulti(insertUserList)
  179. if err != nil {
  180. err = errors.New(fmt.Sprintf("新增企业微信用户失败 err: %v", err))
  181. return
  182. }
  183. }
  184. //批量翻译
  185. go DayNewTranslateContent()
  186. //go GetWeWorkUsersNickName()
  187. return
  188. }
  189. func GetWeWorkUsersNickName() (err error) {
  190. defer func() {
  191. if err != nil {
  192. go alarm_msg.SendAlarmMsg("企业微信 查询用户昵称失败, Err:"+err.Error(), 1)
  193. }
  194. }()
  195. //查询没有昵称的用户库,循环调用查询昵称接口
  196. users, err := day_new.GetEmptyNickNameWeworkUser()
  197. if err != nil {
  198. return
  199. }
  200. if len(users) == 0{
  201. return
  202. }
  203. multi := ""
  204. needChangeIds := ""
  205. client := wework.NewWeWorkUserNameClient()
  206. ExtendClient := wework.NewWeWorkExternalContactClient()
  207. //设置批量更新
  208. for _, v := range users {
  209. if v.WwUserId != "" {
  210. ret, e := client.GetUser(v.WwUserId)
  211. if e != nil {
  212. err = e
  213. return
  214. }
  215. if ret.Name != "" {
  216. needChangeIds += strconv.Itoa(int(v.Id)) + ","
  217. multi += ` WHEN `+strconv.Itoa(int(v.Id))+` THEN "`+ ret.Name +`"`
  218. }
  219. }else if v.WwExtendUserId != "" {
  220. // todo 获取外部联系人姓名
  221. ret1, e := ExtendClient.GetExternalContact(v.WwExtendUserId)
  222. if e != nil {
  223. //err = e
  224. utils.ApiLog.Println("查询外部联系人失败:"+e.Error())
  225. continue
  226. }
  227. if ret1.ExternalContact.Name != "" {
  228. needChangeIds += strconv.Itoa(int(v.Id)) + ","
  229. multi += ` WHEN `+strconv.Itoa(int(v.Id))+` THEN "`+ ret1.ExternalContact.Name +`"`
  230. }
  231. }
  232. }
  233. if needChangeIds != "" {
  234. needChangeIds = strings.Trim(needChangeIds, ",")
  235. err = day_new.MultiUpdateWeworkUserName(multi, needChangeIds)
  236. if err != nil {
  237. err = errors.New(fmt.Sprintf("更新企业微信成员姓名失败 err: %v", err))
  238. return
  239. }
  240. }
  241. return
  242. }
  243. func DayNewTranslateContent() (err error) {
  244. defer func() {
  245. if err != nil {
  246. utils.ApiLog.Println("企业微信 中翻英操作失败, Err:"+err.Error())
  247. go alarm_msg.SendAlarmMsg("企业微信 中翻英操作失败, Err:"+err.Error(), 1)
  248. }
  249. }()
  250. //查询待翻译的内容列表
  251. condition := ` and (content_en = "" or content_en is null) and is_delete = 0`
  252. var pars []interface{}
  253. list, err := day_new.GetWeworkMsgByConditionLimit(condition, pars, 2000) //默认最多查询2000条
  254. if err != nil {
  255. err = errors.New(fmt.Sprintf("查询未翻译的聊天记录失败 err: %v", err))
  256. return
  257. }
  258. multi := ""
  259. needChangeIds := ""
  260. count := 0
  261. contentMap := make(map[string]string, 0)
  262. contentEnMap := make(map[string]string)
  263. var ups []interface{}
  264. for _, v := range list {
  265. //如果单条翻译的字符数超过1000,则直接翻译,否则批量翻译
  266. //if len(v.Content) > 1000 {
  267. en, e := AliTranslate(v.Content)
  268. if e != nil {
  269. err = e
  270. return
  271. }
  272. needChangeIds += strconv.Itoa(int(v.Id)) + ","
  273. multi += ` WHEN `+strconv.Itoa(int(v.Id))+` THEN ?`
  274. ups = append(ups, en)
  275. /*}else{
  276. if count >= 50 { //待翻译的条数不能超过50; 单条翻译字符数不能超过1000字符
  277. contentEnMap, err = batchTranslateHandler(contentMap)
  278. if err != nil {
  279. return
  280. }
  281. // 拼接更新sql
  282. for rk, rv := range contentEnMap {
  283. needChangeIds += rk + ","
  284. multi += ` WHEN `+rk+` THEN ?`
  285. ups = append(ups, rv)
  286. }
  287. contentMap = make(map[string]string, 0)
  288. count = 0
  289. }
  290. contentMap[strconv.Itoa(int(v.Id))] = dealPunctuationToEn(strings.Trim(v.Content, " "))+`{end}`
  291. count += 1
  292. }*/
  293. }
  294. //剩余不满50条的content
  295. if count > 0 {
  296. contentEnMap, err = batchTranslateHandler(contentMap)
  297. if err != nil {
  298. return
  299. }
  300. // 拼接更新sql
  301. for rk, rv := range contentEnMap {
  302. needChangeIds += rk + ","
  303. multi += ` WHEN `+rk+` THEN ?`
  304. ups = append(ups, rv)
  305. }
  306. }
  307. if needChangeIds != "" {
  308. needChangeIds = strings.Trim(needChangeIds, ",")
  309. err = day_new.MultiUpdateContentEn(multi, needChangeIds, ups)
  310. if err != nil {
  311. err = errors.New(fmt.Sprintf("更新翻译后的内容失败 err: %v", err))
  312. return
  313. }
  314. }
  315. return
  316. }
  317. func batchTranslateHandler(contentMap map[string]string) (contentEnMap map[string]string, err error) {
  318. bytes, err := json.Marshal(contentMap)
  319. if err != nil {
  320. err = errors.New("未翻译的内容json.Marshal失败"+err.Error())
  321. return
  322. }
  323. content := string(bytes)
  324. en, err := AliTranslate(content)
  325. if err != nil {
  326. return
  327. }
  328. //json转为map数据结构
  329. err = json.Unmarshal([]byte(en), &contentEnMap)
  330. if err != nil {
  331. err = errors.New("翻译后的内容json.Unmarshal失败"+err.Error())
  332. return
  333. }
  334. for k, v := range contentEnMap {
  335. v = strings.ReplaceAll(v,`{end}`, "")
  336. contentEnMap[k] = strings.ReplaceAll(v,`{quot}`, `"`)
  337. }
  338. return
  339. }
  340. var punctuationMap = map[rune]rune{
  341. 8216: 34, // '
  342. 8217: 34, // '
  343. 8220: 34, // " //把“符号转换成
  344. 8221: 34, // " //把”符号转换成
  345. 12298: 34, // " //把《 符号转换成
  346. 12299: 34, // " //把 》符号转换成
  347. 12304: 91, // [ //把【 符号转换成
  348. 12305: 93, // ] //把 】符号转换成
  349. 12302: 91, // [ //把『符号转换成
  350. 12303: 93, // ] //把 』符号转换成
  351. }
  352. func dealPunctuationToEn(text string) string {
  353. text = strings.Map(func(r rune) rune {
  354. if v, ok := punctuationMap[r]; ok {
  355. return v
  356. }
  357. return r
  358. }, text)
  359. text = strings.ReplaceAll(text,`"`,`{quot}`)
  360. return text
  361. }