community_question.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. package yb
  2. import (
  3. "errors"
  4. "fmt"
  5. ybResponse "hongze/hongze_mobile_admin/models/response/yb"
  6. "hongze/hongze_mobile_admin/models/tables/admin"
  7. "hongze/hongze_mobile_admin/models/tables/company"
  8. "hongze/hongze_mobile_admin/models/tables/company_approval_message"
  9. "hongze/hongze_mobile_admin/models/tables/sys_role"
  10. "hongze/hongze_mobile_admin/models/tables/sys_role_admin"
  11. "hongze/hongze_mobile_admin/models/tables/variety_classify"
  12. "hongze/hongze_mobile_admin/models/tables/variety_tag"
  13. "hongze/hongze_mobile_admin/models/tables/wx_user"
  14. "hongze/hongze_mobile_admin/models/tables/yb_community_question"
  15. "hongze/hongze_mobile_admin/services"
  16. "hongze/hongze_mobile_admin/services/alarm_msg"
  17. "hongze/hongze_mobile_admin/utils"
  18. "strconv"
  19. "strings"
  20. "time"
  21. )
  22. // GetQuestionList 问题列表
  23. func GetQuestionList(condition string, pars []interface{}, startSize, pageSize int) (total int, resp *ybResponse.CommunityQuestionListResp, err error) {
  24. resp = new(ybResponse.CommunityQuestionListResp)
  25. total, list, e := yb_community_question.GetCommunityQuestionList(condition, pars, startSize, pageSize)
  26. if e != nil {
  27. err = errors.New("获取问题列表失败 Err:" + e.Error())
  28. return
  29. }
  30. if len(list) == 0 {
  31. return
  32. }
  33. // 判断是否存在已禁用的回复人, 需要重新分配回复人
  34. adminIdArr := make([]string, 0)
  35. questionLen := len(list)
  36. for i := 0; i < questionLen; i++ {
  37. if list[i].ReplierAdminId > 0 {
  38. adminIdArr = append(adminIdArr, strconv.Itoa(list[i].ReplierAdminId))
  39. }
  40. }
  41. //管理员信息
  42. adminEnableMap := make(map[int]int, 0)
  43. if len(adminIdArr) > 0 {
  44. adminIds := strings.Join(adminIdArr, ",")
  45. adminList, tmpErr := admin.GetAdminListByIds(adminIds)
  46. if tmpErr != nil {
  47. err = tmpErr
  48. return
  49. }
  50. adminLen := len(adminList)
  51. if adminLen > 0 {
  52. for i := 0; i < adminLen; i++ {
  53. adminEnableMap[adminList[i].AdminId] = adminList[i].Enabled
  54. }
  55. }
  56. }
  57. respList := make([]*ybResponse.CommunityQuestionItem, 0)
  58. for _, v := range list {
  59. // 根据回复人被禁用/待回答/已推送消息判断是否需要重新分配
  60. needReset := false
  61. adminEnable := 1
  62. if v.ReplierAdminId > 0 {
  63. adminEnable = adminEnableMap[v.ReplierAdminId]
  64. }
  65. if adminEnable == 0 && v.ReplyStatus == 2 && v.MsgSendStatus >= 1 {
  66. needReset = true
  67. }
  68. item := &ybResponse.CommunityQuestionItem{
  69. CommunityQuestionId: v.CommunityQuestionId,
  70. UserId: v.UserId,
  71. Mobile: v.Mobile,
  72. RealName: v.RealName,
  73. QuestionContent: v.QuestionContent,
  74. ReplierUserId: v.ReplierUserId,
  75. ReplierAdminId: v.ReplierAdminId,
  76. ReplierRealName: v.ReplierRealName,
  77. ReplierAvatar: v.ReplierAvatar,
  78. ResearchGroupFirstId: v.ResearchGroupFirstId,
  79. ResearchGroupSecondId: v.ResearchGroupSecondId,
  80. ResearchGroupFirstName: v.ResearchGroupFirstName,
  81. ResearchGroupSecondName: v.ResearchGroupSecondName,
  82. ReplyStatus: v.ReplyStatus,
  83. MsgSendStatus: v.MsgSendStatus,
  84. NeedRedistribute: needReset,
  85. CreateTime: v.CreateTime.Format(utils.FormatDateTime),
  86. ReplyTime: v.ReplyTime.Format(utils.FormatDateTime),
  87. ClickNum: v.ClickNum,
  88. StopReason: v.StopReason,
  89. }
  90. respList = append(respList, item)
  91. }
  92. // 数量统计
  93. //countList, e := yb_community_question.GetCommunityQuestionCount()
  94. //if e != nil {
  95. // err = errors.New("获取问题数量统计失败 Err:" + e.Error())
  96. // return
  97. //}
  98. //respCount := new(ybResponse.CommunityQuestionCount)
  99. //for _, v := range countList {
  100. // if v.ReplyStatus == 1 {
  101. // respCount.Free = v.Total
  102. // continue
  103. // }
  104. // if v.ReplyStatus == 2 {
  105. // respCount.Wait = v.Total
  106. // continue
  107. // }
  108. // if v.ReplyStatus == 3 {
  109. // respCount.Replied = v.Total
  110. // continue
  111. // }
  112. //}
  113. //respCount.Total = respCount.Free + respCount.Wait + respCount.Replied
  114. resp.List = respList
  115. //resp.Count = respCount
  116. return
  117. }
  118. // GetQuestionCompanyUser 获取提问者详情
  119. func GetQuestionCompanyUser(questionId int) (ret *ybResponse.QuestionCompanyUser, err error) {
  120. questionInfo, e := yb_community_question.GetQuestionById(questionId)
  121. if e != nil {
  122. err = errors.New("提问信息有误 Err:" + e.Error())
  123. return
  124. }
  125. companyUserList, err := company.GetFiccCompanyUserByUserIds(strconv.Itoa(questionInfo.UserId))
  126. if err != nil {
  127. err = errors.New("获取客户信息失败 Err:" + err.Error())
  128. return
  129. }
  130. if len(companyUserList) > 0 {
  131. item := companyUserList[0]
  132. ret = &ybResponse.QuestionCompanyUser{
  133. UserId: int(item.UserId),
  134. CompanyStatus: item.Status,
  135. CompanyName: item.CompanyName,
  136. RealName: item.RealName,
  137. CompanyId: item.CompanyId,
  138. QuestionContent: questionInfo.QuestionContent,
  139. CommunityQuestionId: questionInfo.CommunityQuestionId,
  140. }
  141. } else {
  142. err = errors.New("用户不存在")
  143. return
  144. }
  145. return
  146. }
  147. // DistributeQuestion 分配回复人
  148. func DistributeQuestion(questionId, adminId, researchGroupFirstId, researchGroupSecondId, distributeId int) (errMsg string, err error) {
  149. errMsg = "操作成功"
  150. // 校验提问信息
  151. item, e := yb_community_question.GetQuestionById(questionId)
  152. if e != nil {
  153. errMsg = "分配失败, 提问信息有误"
  154. err = errors.New("提问信息有误 Err:" + e.Error())
  155. return
  156. }
  157. contentRune := []rune(item.QuestionContent)
  158. if len(contentRune) > 28 {
  159. errMsg = "问题字数不可超过28个字符"
  160. err = errors.New("问题字数不可超过28个字符")
  161. return
  162. }
  163. if item.ReplyStatus == 3 {
  164. errMsg = "分配失败, 回复状态有误"
  165. err = errors.New(fmt.Sprintf("分配失败, 回复状态有误, ReplyStatus:%d", item.ReplyStatus))
  166. return
  167. }
  168. // 获取研究员信息
  169. adminInfo, e := admin.GetAdminById(adminId)
  170. if e != nil {
  171. errMsg = "分配失败, 研究员信息有误"
  172. err = errors.New("研究员信息有误 Err:" + e.Error())
  173. return
  174. }
  175. if adminInfo.Mobile == "" {
  176. errMsg = "分配失败, 研究员手机号有误"
  177. err = errors.New("研究员手机号为空")
  178. return
  179. }
  180. // 获取研究员关联的联系人信息
  181. companyId := 16
  182. userInfo, e := wx_user.GetWxUserByCompanyIdAndMobile(companyId, adminInfo.Mobile)
  183. if e != nil {
  184. if e.Error() == utils.ErrNoRow() {
  185. errMsg = "分配失败, 未找到研究员手机号对应的联系人信息"
  186. err = errors.New("未获取到相关联系人信息")
  187. return
  188. }
  189. errMsg = "分配失败"
  190. err = errors.New("获取手机号所属联系人失败, Err:" + e.Error())
  191. return
  192. }
  193. // 回复人openid, 此处可能会出现取不到openid的情况, 可直接忽略掉
  194. replierUserId := int(userInfo.UserId)
  195. replierOpenid := ""
  196. // 分组、品种权限信息
  197. //firstGroup, e := admin.GetResearchGroupById(researchGroupFirstId)
  198. firstGroup, e := variety_classify.GetVarietyClassifyById(researchGroupFirstId)
  199. if e != nil {
  200. errMsg = "分配失败, 一级分组信息有误"
  201. err = errors.New("获取一级分组信息失败, Err:" + e.Error())
  202. return
  203. }
  204. //secondGroup, e := admin.GetResearchGroupById(researchGroupSecondId)
  205. secondGroup, e := variety_tag.GetVarietyTagById(researchGroupSecondId)
  206. if e != nil {
  207. errMsg = "分配失败, 二级分组信息有误"
  208. err = errors.New("获取二级分组信息失败, Err:" + e.Error())
  209. return
  210. }
  211. // 0627-不绑定品种权限了
  212. //permissionInfo, e := models.GetChartPermissionById(secondGroup.ChartPermissionId)
  213. //if e != nil {
  214. // errMsg = "分配失败, 品种权限信息有误"
  215. // err = errors.New("获取品种权限信息失败, Err:" + e.Error())
  216. // return
  217. //}
  218. // 更新提问信息
  219. updateCols := make([]string, 0)
  220. updateCols = append(updateCols, "ReplierUserId", "ReplierOpenid", "ReplierAdminId", "ReplierRealName", "ReplierAvatar", "ResearchGroupFirstId",
  221. "ResearchGroupSecondId", "ResearchGroupFirstName", "ResearchGroupSecondName", "DistributeAdminId", "DistributeTime", "VarietyTagId",
  222. "VarietyTagName", "ReplyStatus", "ReplierIsRead", "MsgSendStatus", "ModifyTime")
  223. item.ReplierUserId = replierUserId
  224. item.ReplierOpenid = replierOpenid
  225. item.ReplierAdminId = adminId
  226. item.ReplierRealName = adminInfo.RealName
  227. item.ReplierAvatar = adminInfo.AdminAvatar
  228. item.ResearchGroupFirstId = researchGroupFirstId
  229. item.ResearchGroupSecondId = researchGroupSecondId
  230. item.ResearchGroupFirstName = firstGroup.ClassifyName
  231. item.ResearchGroupSecondName = secondGroup.TagName
  232. item.DistributeAdminId = distributeId
  233. item.DistributeTime = time.Now().Local()
  234. item.VarietyTagId = secondGroup.VarietyTagId
  235. item.VarietyTagName = secondGroup.TagName
  236. item.ReplyStatus = 2
  237. item.ReplierIsRead = 0
  238. item.MsgSendStatus = 0
  239. item.ModifyTime = time.Now().Local()
  240. if e := item.Update(updateCols); e != nil {
  241. errMsg = "分配失败,更新提问信息失败"
  242. err = errors.New("更新提问信息失败, Err:" + e.Error())
  243. }
  244. return
  245. }
  246. // SoftDeleteQuestion 删除问题
  247. func SoftDeleteQuestion(questionId int) (err error) {
  248. if _, e := yb_community_question.GetQuestionById(questionId); e != nil {
  249. err = errors.New("提问信息有误 Err:" + e.Error())
  250. return
  251. }
  252. if e := yb_community_question.DeleteQuestion(questionId); e != nil {
  253. err = errors.New("删除提问失败 Err:" + e.Error())
  254. }
  255. // 删除问答后的逻辑处理
  256. go afterDeleteQuestion(questionId)
  257. return
  258. }
  259. // SendMsgToReplier 推送消息给回复人
  260. func SendMsgToReplier(questionId int) (errMsg string, err error) {
  261. defer func() {
  262. if err != nil {
  263. go alarm_msg.SendAlarmMsg(fmt.Sprintf("问答分配给研究员后,推送消息失败,问答id:%d;errMsg:%s;ERR:%s", questionId, errMsg, err.Error()), 3)
  264. }
  265. }()
  266. errMsg = "推送成功"
  267. item, e := yb_community_question.GetQuestionById(questionId)
  268. if e != nil {
  269. errMsg = "问答信息有误"
  270. err = errors.New("提问信息有误, Err:" + e.Error())
  271. return
  272. }
  273. if item.MsgSendStatus >= 1 {
  274. return
  275. }
  276. if item.ReplierUserId == 0 {
  277. errMsg = "请先分配回复人"
  278. err = errors.New("未分配回复人, 不可推送")
  279. return
  280. }
  281. // 回复人openid为空时查询当前是否已有openid
  282. updateCols := make([]string, 0)
  283. // 找到研究员的手机号,并查到管理员绑定的账号,找到对应的openid
  284. adminInfo, e := admin.GetAdminById(item.ReplierAdminId)
  285. if e != nil {
  286. errMsg = "发送失败, 研究员账号查询失败"
  287. err = errors.New("发送失败, 研究员账号查询失败, Err:" + e.Error())
  288. return
  289. }
  290. if adminInfo.OpenId == "" {
  291. errMsg = "该研究员未关注公众号,无法发送消息通知"
  292. err = errors.New("回复人openid为空, 不可推送")
  293. return
  294. }
  295. if e := services.SendYbQuestionDistributeWxMsg(item.CommunityQuestionId, item.ReplierUserId, adminInfo.OpenId, item.QuestionContent); e != nil {
  296. err = errors.New("推送模板消息失败, Err:" + e.Error())
  297. return
  298. }
  299. // 更新问答信息
  300. updateCols = append(updateCols, "ModifyTime", "MsgSendStatus")
  301. item.ModifyTime = time.Now().Local()
  302. item.MsgSendStatus = 1
  303. if e := item.Update(updateCols); e != nil {
  304. err = errors.New("更新问答信息失败, Err:" + e.Error())
  305. }
  306. return
  307. }
  308. // EditQuestion 编辑问题
  309. func EditQuestion(questionId int, content string) (errMsg string, err error) {
  310. item, e := yb_community_question.GetQuestionById(questionId)
  311. if e != nil {
  312. errMsg = "提问信息有误"
  313. err = errors.New("提问信息有误 Err:" + e.Error())
  314. return
  315. }
  316. if item.MsgSendStatus >= 1 {
  317. errMsg = "问题状态有误,不可编辑"
  318. err = errors.New(fmt.Sprintf("问题状态不可编辑, MsgSendStatus:%d", item.MsgSendStatus))
  319. return
  320. }
  321. updateCols := make([]string, 0)
  322. updateCols = append(updateCols, "QuestionContent", "ModifyTime")
  323. item.QuestionContent = content
  324. item.ModifyTime = time.Now().Local()
  325. if e := item.Update(updateCols); e != nil {
  326. errMsg = "更新提问信息失败"
  327. err = errors.New("更新提问信息失败, Err:" + e.Error())
  328. }
  329. return
  330. }
  331. // CheckCommunityQuestionPermission 查询当前操作用户是否运营管理员权限
  332. func CheckCommunityQuestionPermission(adminId int) (errMsg string, err error) {
  333. roleInfo, e := sys_role.GetSysRoleByRoleTypeCode("yb_question_admin")
  334. if e != nil {
  335. errMsg = "角色信息有误"
  336. if e.Error() == utils.ErrNoRow() {
  337. err = errors.New("角色不存在, Err: " + e.Error())
  338. return
  339. }
  340. err = errors.New("角色信息有误, Err: " + e.Error())
  341. return
  342. }
  343. _, e = sys_role_admin.GetRoleIdsByAdminIdRoleId(adminId, roleInfo.RoleId)
  344. if e != nil {
  345. errMsg = "无权操作"
  346. err = errors.New("无权操作, Err: " + e.Error())
  347. return
  348. }
  349. return
  350. }
  351. // afterDeleteQuestion 删除问答后的逻辑处理
  352. func afterDeleteQuestion(questionId int) {
  353. var err error
  354. defer func() {
  355. if err != nil {
  356. go alarm_msg.SendAlarmMsg("问答信息删除后,标记站内消息失败"+time.Now().Format(utils.FormatDateTime)+";Err:"+err.Error(), 3)
  357. }
  358. }()
  359. err = company_approval_message.CancelCompanyApprovalMessage(questionId, services.CompanyApprovalMessageSourceTypeByQuestion)
  360. return
  361. }