plat_followup.go 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. package plat
  2. import (
  3. "context"
  4. distDao "dashoo.cn/micro/app/dao/base"
  5. "dashoo.cn/micro/app/dao/cust"
  6. projDao "dashoo.cn/micro/app/dao/proj"
  7. "dashoo.cn/opms_libary/myerrors"
  8. "database/sql"
  9. "github.com/gogf/gf/container/garray"
  10. "github.com/gogf/gf/frame/g"
  11. "github.com/gogf/gf/os/gtime"
  12. "github.com/gogf/gf/util/gconv"
  13. "strconv"
  14. "strings"
  15. "dashoo.cn/micro/app/dao/plat"
  16. model "dashoo.cn/micro/app/model/plat"
  17. "dashoo.cn/micro/app/service"
  18. )
  19. type followupService struct {
  20. *service.ContextService
  21. Dao *plat.PlatFollowupDao
  22. }
  23. func NewFollowupService(ctx context.Context) (svc *followupService, err error) {
  24. svc = new(followupService)
  25. if svc.ContextService, err = svc.Init(ctx); err != nil {
  26. return nil, err
  27. }
  28. svc.Dao = plat.NewPlatFollowupDao(svc.Tenant)
  29. return svc, nil
  30. }
  31. // 跟进记录信息列表
  32. func (s *followupService) GetList(req *model.SearchPlatFollowupReq) (total int, followupList []*model.PlatFollowup, err error) {
  33. followupModel := s.Dao.DataScope(s.Ctx)
  34. if req.CustId != "" {
  35. followupModel = followupModel.Where("cust_id", req.CustId)
  36. }
  37. if req.CustName != "" {
  38. followupModel = followupModel.WhereLike("cust_name", "%"+req.CustName+"%")
  39. }
  40. if req.TargetId != "" {
  41. followupModel = followupModel.Where("target_id", req.TargetId)
  42. }
  43. if req.TargetType != "" {
  44. followupModel = followupModel.Where("target_type", req.TargetType)
  45. }
  46. if req.TargetName != "" {
  47. followupModel = followupModel.WhereLike("target_name", "%"+req.TargetName+"%")
  48. }
  49. // 负责人查询
  50. if req.ManagerId != "" {
  51. followupModel = followupModel.Where("created_by", req.ManagerId)
  52. }
  53. if req.IsMyself == "1" {
  54. followupModel = followupModel.Where("created_by", s.GetCxtUserId())
  55. }
  56. total, err = followupModel.Count()
  57. if err != nil {
  58. g.Log().Error(err)
  59. err = myerrors.DbError("获取总行数失败。")
  60. return
  61. }
  62. err = followupModel.Page(req.GetPage()).Order("follow_date DESC").Scan(&followupList)
  63. return
  64. }
  65. // 添加信息
  66. func (s *followupService) Create(req *model.AddPlatFollowupReq) (err error) {
  67. platFollowup := new(model.PlatFollowup)
  68. var files []*model.PlatFollowupFile
  69. if err = gconv.Struct(req, platFollowup); err != nil {
  70. return
  71. }
  72. // 填充创建信息
  73. service.SetCreatedInfo(platFollowup, s.GetCxtUserId(), s.GetCxtUserName())
  74. // 填充更新信息
  75. //service.SetUpdatedInfo(platFollowup, s.GetCxtUserId(), s.GetCxtUserName())
  76. res, err := s.Dao.Insert(platFollowup)
  77. if err != nil {
  78. return
  79. }
  80. // 更新附件数据
  81. id, _ := res.LastInsertId()
  82. for _, file := range req.Files {
  83. var fileData model.PlatFollowupFile
  84. if err = gconv.Struct(file, &fileData); err != nil {
  85. return
  86. }
  87. fileData.FollowId = strconv.Itoa(int(id))
  88. // 填充创建信息
  89. service.SetCreatedInfo(&fileData, s.GetCxtUserId(), s.GetCxtUserName())
  90. // 填充更新信息
  91. //service.SetUpdatedInfo(fileData, s.GetCxtUserId(), s.GetCxtUserName())
  92. files = append(files, &fileData)
  93. }
  94. // 保存附件信息
  95. if len(files) > 0 {
  96. _, err = s.Dao.DB.Insert(plat.PlatFollowupFile.Table, files)
  97. if err != nil {
  98. return
  99. }
  100. }
  101. // 更新客户 最后跟进时间 字段
  102. toUpdate := map[string]interface{}{
  103. "follow_up_date": req.FollowDate,
  104. "follow_up_man": s.GetCxtUserName(),
  105. }
  106. _, err = s.Dao.DB.Update("cust_customer", toUpdate, "id = ?", req.CustId)
  107. if platFollowup.TargetType == "20" {
  108. // 更新客户 最后跟进时间 字段
  109. toUpdate := map[string]interface{}{
  110. projDao.ProjBusiness.C.FinalFollowTime: req.FollowDate,
  111. projDao.ProjBusiness.C.FinalFollowId: s.GetCxtUserId(),
  112. projDao.ProjBusiness.C.FinalFollowName: s.GetCxtUserName(),
  113. }
  114. _, err = s.Dao.DB.Update(projDao.ProjBusiness.Table, toUpdate, "id = ?", req.TargetId)
  115. }
  116. return
  117. }
  118. // 跟进记录信息列表:按照日期显示,并附带评论
  119. func (s *followupService) GetListByDay(req *model.SearchPlatFollowupReq) (total int, followupList []*model.FollowupInfoResp, err error) {
  120. filter := map[string]interface{}{}
  121. if req.TargetType == "20" && req.TargetId != "" {
  122. filter = map[string]interface{}{
  123. "target_id": req.TargetId,
  124. "orcols": "target_id",
  125. }
  126. } else if req.CustId != "" {
  127. filter = map[string]interface{}{
  128. "cust_id": req.CustId,
  129. "orcols": "cust_id",
  130. }
  131. } else if garray.NewStrArrayFrom(s.CxtUser.Roles, true).Contains("ProductLineManager") {
  132. var orCols []string
  133. filter = map[string]interface{}{}
  134. busIds, _ := projDao.NewProjBusinessDao(s.Tenant).DataScope(s.Ctx, "sale_id").Fields("id").Array()
  135. custIds, _ := cust.NewCustCustomerDao(s.Tenant).DataScope(s.Ctx, "sales_id").Where("is_public", "20").Fields("id").Array()
  136. distributorIds, _ := distDao.NewBaseDistributorDao(s.Tenant).Fields("id").Array()
  137. if len(busIds) > 0 {
  138. filter["target_type='20' AND target_id"] = busIds
  139. orCols = append(orCols, "target_type='20' AND target_id")
  140. }
  141. if len(custIds) > 0 {
  142. filter["target_type='10' AND target_id"] = custIds
  143. orCols = append(orCols, "target_type='10' AND target_id")
  144. }
  145. if len(distributorIds) > 0 {
  146. filter["target_type='50' AND target_id"] = distributorIds
  147. orCols = append(orCols, "target_type='50' AND target_id")
  148. }
  149. filter["orcols"] = orCols
  150. } else {
  151. if s.DataScope["userIds"] != "-1" {
  152. var orCols []string
  153. filter = map[string]interface{}{}
  154. custIds, _ := cust.NewCustCustomerDao(s.Tenant).DataScope(s.Ctx, "sales_id").Where("is_public", "20").Fields("id").Array()
  155. distributorModel := &distDao.NewBaseDistributorDao(s.Tenant).BaseDistributorDao
  156. if garray.NewStrArrayFrom(s.CxtUser.Roles, true).Contains("SalesEngineer") {
  157. distributorModel = distributorModel.DataScope(s.Ctx, "belong_sale_id")
  158. }
  159. distributorIds, _ := distributorModel.Fields("id").Array()
  160. if len(custIds) > 0 {
  161. filter["cust_id"] = custIds
  162. orCols = append(orCols, "cust_id")
  163. }
  164. if len(distributorIds) > 0 {
  165. filter["target_type='50' AND target_id"] = distributorIds
  166. orCols = append(orCols, "target_type='50' AND target_id")
  167. }
  168. filter["orcols"] = orCols
  169. }
  170. }
  171. followupModel := s.Dao.DataScope(s.Ctx, filter)
  172. // 用户仅有销售工程师角色展示自己的数据,其他人可以看到所有数据
  173. //if garray.NewStrArrayFrom(s.CxtUser.Roles, true).Contains("SalesEngineer") {
  174. // followupModel = followupModel.WhereIn("created_by", s.DataScope["userIds"])
  175. //}
  176. if req.CustId != "" {
  177. followupModel = followupModel.Where("cust_id", req.CustId)
  178. }
  179. if req.CustName != "" {
  180. followupModel = followupModel.WhereLike("cust_name", "%"+req.CustName+"%")
  181. }
  182. if req.TargetId != "" {
  183. followupModel = followupModel.Where("target_id", req.TargetId)
  184. }
  185. if req.TargetType != "" {
  186. followupModel = followupModel.Where("target_type", req.TargetType)
  187. }
  188. if req.TargetName != "" {
  189. followupModel = followupModel.WhereLike("target_name", "%"+req.TargetName+"%")
  190. }
  191. if req.CreatedName != "" {
  192. followupModel = followupModel.WhereLike("created_name", "%"+req.CreatedName+"%")
  193. }
  194. // 负责人查询
  195. if req.ManagerId != "" {
  196. followupModel = followupModel.Where("created_by", req.ManagerId)
  197. }
  198. if req.IsMyself == "1" {
  199. followupModel = followupModel.Where("created_by", s.GetCxtUserId())
  200. }
  201. // 日期条件
  202. if req.DaysBeforeToday > 0 { // 获取前N天的跟进记录
  203. now := gtime.Now()
  204. begin := now.AddDate(0, 0, -req.DaysBeforeToday).Format("Y-m-d 00:00:00")
  205. followupModel = followupModel.Where("follow_date>=?", begin)
  206. }
  207. // 获取日期区间范围内的记录
  208. if req.BeginTime != "" && req.EndTime != "" {
  209. begin := strings.Split(req.BeginTime, " ")[0] + " 00:00:00"
  210. end := strings.Split(req.EndTime, " ")[0] + " 23:59:59"
  211. followupModel = followupModel.Where("follow_date>=? AND follow_date<=?", begin, end)
  212. }
  213. if req.FollowType != "" {
  214. followupModel = followupModel.Where("follow_type", req.FollowType)
  215. }
  216. //跟进记录销售 添加销售人权限
  217. arr := garray.NewStrArrayFrom(s.CxtUser.Roles, true)
  218. if arr.Len() == 1 && arr.Contains("SalesEngineer") && req.Sell != "" {
  219. followupModel = followupModel.Where("created_by", s.CxtUser.Id)
  220. }
  221. //total, err = followupModel.Count()
  222. //if err != nil {
  223. // g.Log().Error(err)
  224. // err = gerror.New("获取总行数失败")
  225. // return
  226. //}
  227. // 查询原始记录
  228. var originalFollowupList []model.FollowupInfo
  229. err = followupModel.Order("follow_date DESC").Scan(&originalFollowupList)
  230. if err != nil && err != sql.ErrNoRows {
  231. return
  232. }
  233. // 查询一级评论
  234. var comments []model.PlatFollowupComment
  235. err = s.Dao.InnerJoin(plat.PlatFollowupComment.Table, "plat_followup.id=plat_followup_comment.follow_id").Where("plat_followup_comment.pid=0 OR plat_followup_comment.pid IS NULL").Fields("plat_followup_comment.*").Structs(&comments)
  236. if err != nil && err != sql.ErrNoRows {
  237. return
  238. }
  239. // 构造数据
  240. var days []string
  241. followupMap := make(map[string][]*model.FollowupInfo, 0)
  242. commentMap := make(map[int][]*model.PlatFollowupComment, 0)
  243. // 评论数据map
  244. for index, comment := range comments {
  245. if _, ok := commentMap[comment.FollowId]; !ok {
  246. commentMap[comment.FollowId] = make([]*model.PlatFollowupComment, 0)
  247. }
  248. commentMap[comment.FollowId] = append(commentMap[comment.FollowId], &comments[index])
  249. }
  250. // 跟进记录map
  251. for index, followup := range originalFollowupList {
  252. if _, ok := followupMap[followup.FollowDate.Format("Y-m-d")]; !ok {
  253. days = append(days, followup.FollowDate.Format("Y-m-d"))
  254. followupMap[followup.FollowDate.Format("Y-m-d")] = make([]*model.FollowupInfo, 0)
  255. }
  256. if followup.Comments == nil {
  257. originalFollowupList[index].Comments = make([]*model.PlatFollowupComment, 0)
  258. }
  259. // 为跟进记录填充评论数据
  260. if _, ok := commentMap[followup.Id]; ok {
  261. originalFollowupList[index].Comments = append(originalFollowupList[index].Comments, commentMap[followup.Id]...)
  262. }
  263. originalFollowupList[index].CommentNumber = len(originalFollowupList[index].Comments)
  264. followupMap[followup.FollowDate.Format("Y-m-d")] = append(followupMap[followup.FollowDate.Format("Y-m-d")], &originalFollowupList[index])
  265. }
  266. for _, day := range days {
  267. var followup model.FollowupInfoResp
  268. followup.FollowDay = day
  269. followup.FollowupList = followupMap[day]
  270. followupList = append(followupList, &followup)
  271. }
  272. return
  273. }