price_driven.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. package yb
  2. import (
  3. "errors"
  4. "fmt"
  5. "hongze/hz_crm_api/models"
  6. "hongze/hz_crm_api/models/company"
  7. "hongze/hz_crm_api/models/yb"
  8. "hongze/hz_crm_api/models/yb/request"
  9. "hongze/hz_crm_api/models/yb/response"
  10. "hongze/hz_crm_api/services"
  11. "hongze/hz_crm_api/utils"
  12. "strconv"
  13. "strings"
  14. "time"
  15. )
  16. // GetPriceDrivenDetail 获取价格驱动详情
  17. func GetPriceDrivenDetail(varietyTagId int) (detail *response.PriceDrivenDetail, errMsg string, err error) {
  18. detail = new(response.PriceDrivenDetail)
  19. if varietyTagId <= 0 {
  20. return
  21. }
  22. item, e := yb.GetPriceDrivenByVarietyTagId(varietyTagId)
  23. if e != nil && e.Error() != utils.ErrNoRow() {
  24. errMsg = "获取价格驱动失败"
  25. err = errors.New("获取价格驱动详情失败, Err:" + e.Error())
  26. return
  27. }
  28. if item != nil {
  29. // 查询草稿
  30. draft, e := yb.GetPriceDrivenSaveLogByPriceDrivenId(item.PriceDrivenId)
  31. if e != nil && e.Error() != utils.ErrNoRow() {
  32. errMsg = "获取价格驱动草稿失败"
  33. err = errors.New("获取价格驱动草稿失败, Err:" + e.Error())
  34. return
  35. }
  36. if draft != nil && draft.CreateTime.After(item.ModifyTime) {
  37. item.MainVariable = draft.MainVariable
  38. item.CoreDrivenType = draft.CoreDrivenType
  39. item.CoreDrivenContent = draft.CoreDrivenContent
  40. item.CoreContent = draft.CoreContent
  41. item.LastUpdateAdminId = draft.AdminId
  42. item.LastUpdateAdminName = draft.AdminName
  43. }
  44. detail = formatPriceDrivenItemToDetail(item)
  45. }
  46. return
  47. }
  48. // UpdatePriceDriven 更新价格驱动
  49. func UpdatePriceDriven(req request.UpdatePriceDrivenReq) (detail *response.PriceDrivenDetail, errMsg string, err error) {
  50. detail = new(response.PriceDrivenDetail)
  51. if req.VarietyTagId <= 0 {
  52. errMsg = "标签有误"
  53. err = errors.New("UpdatePriceDriven 标签有误")
  54. return
  55. }
  56. // 非自动保存校验品种是否开启
  57. priceTag, e := yb.GetPriceDrivenTagByTagId(req.VarietyTagId)
  58. if e != nil {
  59. errMsg = "获取价格驱动标签信息失败"
  60. err = errors.New("UpdatePriceDriven 获取价格驱动标签信息失败, Err:" + e.Error())
  61. return
  62. }
  63. if req.AutoSave == 0 {
  64. if priceTag.State != 1 {
  65. errMsg = "请开启品种后重试"
  66. err = errors.New("UpdatePriceDriven 品种未开启")
  67. return
  68. }
  69. }
  70. // 最近的一条数据
  71. item, e := yb.GetPriceDrivenByVarietyTagId(req.VarietyTagId)
  72. if e != nil && e.Error() != utils.ErrNoRow() {
  73. errMsg = "获取价格驱动失败"
  74. err = errors.New("UpdatePriceDriven 获取价格驱动详情失败, Err:" + e.Error())
  75. return
  76. }
  77. nowTime := time.Now().Local()
  78. // 最新的一条数据为今日的则更新
  79. if item != nil {
  80. todayStart := time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 0, 0, 0, 0, time.Local)
  81. todayEnd := time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 23, 59, 59, 0, time.Local)
  82. if item.CreateTime.After(todayStart) && item.CreateTime.Before(todayEnd) {
  83. item.MainVariable = req.MainVariable
  84. item.CoreDrivenType = req.CoreDrivenType
  85. item.CoreDrivenContent = req.CoreDrivenContent
  86. item.CoreContent = req.CoreContent
  87. item.LastUpdateAdminId = req.LastUpdateAdminId
  88. item.LastUpdateAdminName = req.LastUpdateAdminName
  89. if req.AutoSave == 0 {
  90. // 发布更新
  91. updateCols := make([]string, 0)
  92. updateCols = append(updateCols, "MainVariable", "CoreDrivenType", "CoreDrivenContent", "CoreContent",
  93. "LastUpdateAdminId", "LastUpdateAdminName", "ModifyTime", "PublishState")
  94. item.ModifyTime = nowTime
  95. item.PublishState = 1
  96. if e := item.Update(updateCols); e != nil {
  97. errMsg = "更新价格驱动失败"
  98. err = errors.New("UpdatePriceDriven 更新价格驱动失败, Err:" + e.Error())
  99. return
  100. }
  101. } else {
  102. // 存草稿
  103. go func() {
  104. if e = savePriceDrivenDraft(item.PriceDrivenId, req.VarietyTagId, req.CoreDrivenType, req.LastUpdateAdminId, req.MainVariable, req.CoreDrivenContent, req.CoreContent, req.LastUpdateAdminName); e != nil {
  105. utils.FileLog.Info("%s", "记录价格驱动草稿失败, Err: "+e.Error())
  106. }
  107. }()
  108. }
  109. detail = formatPriceDrivenItemToDetail(item)
  110. return
  111. }
  112. }
  113. // 否则新增, 不记录草稿
  114. publishState := 0
  115. if req.AutoSave == 0 {
  116. publishState = 1
  117. }
  118. newPriceDriven := &yb.PriceDriven{
  119. VarietyTagId: req.VarietyTagId,
  120. VarietyTagName: priceTag.VarietyTagName,
  121. MainVariable: req.MainVariable,
  122. CoreDrivenType: req.CoreDrivenType,
  123. CoreDrivenContent: req.CoreDrivenContent,
  124. CoreContent: req.CoreContent,
  125. LastUpdateAdminId: req.LastUpdateAdminId,
  126. LastUpdateAdminName: req.LastUpdateAdminName,
  127. PublishState: publishState,
  128. CreateTime: nowTime,
  129. ModifyTime: nowTime,
  130. }
  131. if e := newPriceDriven.Add(); e != nil {
  132. errMsg = "新增价格驱动失败"
  133. err = errors.New("UpdatePriceDriven 新增价格驱动失败, Err:" + e.Error())
  134. }
  135. detail = formatPriceDrivenItemToDetail(newPriceDriven)
  136. return
  137. }
  138. // savePriceDrivenDraft 保存草稿
  139. func savePriceDrivenDraft(priceDrivenId, varietyTagId, coreDrivenType, adminId int, mainVariable, coreDrivenContent, coreContent, adminName string) (err error) {
  140. draft := &yb.PriceDrivenSaveLog{
  141. PriceDrivenId: priceDrivenId,
  142. VarietyTagId: varietyTagId,
  143. MainVariable: mainVariable,
  144. CoreDrivenType: coreDrivenType,
  145. CoreDrivenContent: coreDrivenContent,
  146. CoreContent: coreContent,
  147. AdminId: adminId,
  148. AdminName: adminName,
  149. CreateTime: time.Now().Local(),
  150. }
  151. if e := draft.Add(); e != nil {
  152. err = errors.New("savePriceDrivenDraft 新增价格驱动草稿失败, Err:" + e.Error())
  153. }
  154. return
  155. }
  156. // formatPriceDrivenItemToDetail 格式化详情
  157. func formatPriceDrivenItemToDetail(item *yb.PriceDriven) (detail *response.PriceDrivenDetail) {
  158. if item == nil {
  159. return
  160. }
  161. detail = &response.PriceDrivenDetail{
  162. PriceDrivenId: item.PriceDrivenId,
  163. VarietyTagId: item.VarietyTagId,
  164. VarietyTagName: item.VarietyTagName,
  165. MainVariable: item.MainVariable,
  166. CoreDrivenType: item.CoreDrivenType,
  167. CoreDrivenContent: item.CoreDrivenContent,
  168. CoreContent: item.CoreContent,
  169. LastUpdateAdminId: item.LastUpdateAdminId,
  170. LastUpdateAdminName: item.LastUpdateAdminName,
  171. SendThsMsgTime: item.SendThsMsgTime.Format(utils.FormatDateTime),
  172. SendTemplateMsgTime: item.SendTemplateMsgTime.Format(utils.FormatDateTime),
  173. ThsMsgState: item.ThsMsgState,
  174. TemplateMsgState: item.TemplateMsgState,
  175. PublishState: item.PublishState,
  176. CreateTime: item.CreateTime.Format(utils.FormatDateTime),
  177. ModifyTime: item.ModifyTime.Format(utils.FormatDateTime),
  178. }
  179. return
  180. }
  181. // GetPriceDrivenPermissionTree 获取价格驱动品种列表
  182. func GetPriceDrivenPermissionTree() (list []*response.ChartPermissionTree, err error) {
  183. firstList, e := models.GetYbChartPermissionFirst()
  184. if e != nil {
  185. return
  186. }
  187. list = make([]*response.ChartPermissionTree, 0)
  188. if len(firstList) > 0 {
  189. productId := 1
  190. for _, v := range firstList {
  191. classify := new(response.ChartPermissionTree)
  192. classify.ClassifyName = v.YbIndexName
  193. children, e := models.GetPermissionByProductIdAndClassifyName(productId, v.ClassifyName)
  194. if e != nil {
  195. return
  196. }
  197. items := make([]*response.PermissionItem, 0)
  198. for _, iv := range children {
  199. items = append(items, &response.PermissionItem{
  200. PermissionId: iv.ChartPermissionId,
  201. PermissionName: iv.PermissionName,
  202. PriceDrivenState: iv.PriceDrivenState,
  203. })
  204. }
  205. classify.Items = items
  206. list = append(list, classify)
  207. }
  208. }
  209. return
  210. }
  211. // SwitchPriceDrivenPermissionState 切换价格驱动分类状态
  212. func SwitchPriceDrivenPermissionState(varietyTagId int, priceDrivenState int) (errMsg string, err error) {
  213. priceTag, e := yb.GetPriceDrivenTagByTagId(varietyTagId)
  214. if e != nil {
  215. errMsg = "获取价格驱动标签信息失败"
  216. err = errors.New("UpdatePriceDriven 获取价格驱动标签信息失败, Err:" + e.Error())
  217. return
  218. }
  219. if priceTag.State == priceDrivenState {
  220. return
  221. }
  222. updateCols := make([]string, 0)
  223. updateCols = append(updateCols, "State")
  224. priceTag.State = priceDrivenState
  225. if e := priceTag.Update(updateCols); e != nil {
  226. err = errors.New("SwitchPriceDrivenPermissionState 更新价格驱动分类状态失败, Err:" + e.Error())
  227. }
  228. return
  229. }
  230. // SendPriceDrivenTemplateMsg 推送价格驱动模板消息
  231. func SendPriceDrivenTemplateMsg(priceDrivenId int) (errMsg string, err error) {
  232. item, e := yb.GetPriceDrivenById(priceDrivenId)
  233. if e != nil {
  234. errMsg = "获取价格驱动失败"
  235. err = errors.New("SendPriceDrivenTemplateMsg 获取价格驱动详情失败, Err:" + e.Error())
  236. return
  237. }
  238. if item.CoreContent == "" {
  239. errMsg = "核心内容不能为空"
  240. err = errors.New("SendPriceDrivenTemplateMsg 核心内容不能为空")
  241. return
  242. }
  243. if item.TemplateMsgState == 1 {
  244. errMsg = "未更新品种或今日推送次数已达上限"
  245. err = errors.New("SendPriceDrivenTemplateMsg 今日推送次数已达上限")
  246. return
  247. }
  248. // 推送消息
  249. go func() {
  250. _ = services.SendYbPriceDrivenWxMsg(item.VarietyTagId, item.CoreDrivenContent, time.Now().Format(utils.FormatDateTime))
  251. }()
  252. // 更新推送信息
  253. updateCols := make([]string, 0)
  254. updateCols = append(updateCols, "SendTemplateMsgTime", "TemplateMsgState")
  255. item.SendTemplateMsgTime = time.Now().Local()
  256. item.TemplateMsgState = 1
  257. if e := item.Update(updateCols); e != nil {
  258. errMsg = "更新模板消息信息失败"
  259. err = errors.New("SendPriceDrivenTemplateMsg 更新模板消息信息失败, Err:" + e.Error())
  260. }
  261. return
  262. }
  263. // SendPriceDrivenThsMsg 推送价格驱动同花顺客群消息
  264. func SendPriceDrivenThsMsg(priceDrivenId int) (errMsg string, err error) {
  265. item, e := yb.GetPriceDrivenById(priceDrivenId)
  266. if e != nil {
  267. errMsg = "获取价格驱动失败"
  268. err = errors.New("SendPriceDrivenThsMsg 获取价格驱动详情失败, Err:" + e.Error())
  269. return
  270. }
  271. if item.CoreContent == "" {
  272. errMsg = "核心内容不能为空"
  273. err = errors.New("SendPriceDrivenThsMsg 核心内容不能为空")
  274. return
  275. }
  276. if item.ThsMsgState == 1 {
  277. errMsg = "未更新品种或今日推送次数已达上限"
  278. err = errors.New("SendPriceDrivenThsMsg 今日推送次数已达上限")
  279. return
  280. }
  281. // 推送客群消息
  282. //go func() {
  283. // _ = services.SendYbPriceDrivenToThs(priceDrivenId, item.VarietyTagId)
  284. //}()
  285. // 更新推送信息
  286. updateCols := make([]string, 0)
  287. updateCols = append(updateCols, "SendThsMsgTime", "ThsMsgState")
  288. item.SendThsMsgTime = time.Now().Local()
  289. item.ThsMsgState = 1
  290. if e := item.Update(updateCols); e != nil {
  291. errMsg = "更新客群消息信息失败"
  292. err = errors.New("SendPriceDrivenThsMsg 更新客群消息信息失败, Err:" + e.Error())
  293. }
  294. return
  295. }
  296. // GetPriceDrivenClickCensusList 获取价格驱动统计列表
  297. func GetPriceDrivenClickCensusList(startSize, pageSize, sortField, sortRule int) (total int, list []*response.PriceDrivenClickCensusItem, err error) {
  298. list = make([]*response.PriceDrivenClickCensusItem, 0)
  299. // 获取每个品种的最新的价格驱动信息
  300. priceDrivenList, e := yb.GetRecentPriceDrivenList()
  301. if e != nil {
  302. err = errors.New("获取最新的价格驱动信息失败, Err: " + e.Error())
  303. return
  304. }
  305. priceDrivenMap := make(map[int]*yb.PriceDriven, 0)
  306. for _, p := range priceDrivenList {
  307. priceDrivenMap[p.VarietyTagId] = p
  308. }
  309. total = len(priceDrivenList)
  310. // 获取标签累计点击量
  311. priceDrivenIds := ""
  312. totalClickList, e := yb.GetPriceDrivenClick(priceDrivenIds)
  313. if e != nil {
  314. err = errors.New("获取价格驱动标签累计点击量失败, Err: " + e.Error())
  315. return
  316. }
  317. totalClickMap := make(map[int]int)
  318. recentClickTimeMap := make(map[int]string)
  319. for _, t := range totalClickList {
  320. totalClickMap[t.VarietyTagId] = t.CountNum
  321. recentClickTimeMap[t.VarietyTagId] = t.RecentClickTime
  322. }
  323. // 获取标签最近点击量
  324. priceDrivenIdArr := make([]string, 0)
  325. priceDrivenLen := len(priceDrivenList)
  326. for i := 0; i < priceDrivenLen; i++ {
  327. priceDrivenIdArr = append(priceDrivenIdArr, strconv.Itoa(priceDrivenList[i].PriceDrivenId))
  328. }
  329. priceDrivenIds = strings.Join(priceDrivenIdArr, ",")
  330. recentClickList, e := yb.GetPriceDrivenClick(priceDrivenIds)
  331. if e != nil {
  332. err = errors.New("获取价格驱动标签最近点击量失败, Err: " + e.Error())
  333. return
  334. }
  335. recentClickMap := make(map[int]int)
  336. for _, r := range recentClickList {
  337. recentClickMap[r.VarietyTagId] = r.CountNum
  338. }
  339. // 根据排序规则确定分页列表
  340. pageList := make([]*yb.PriceDrivenVarietyTagClick, 0)
  341. if sortField == 0 {
  342. // 默认排序-价格驱动更新时间降序
  343. pageList, e = yb.GetDefaultPriceDrivenPageClick(startSize, pageSize, priceDrivenIds)
  344. if e != nil {
  345. err = errors.New("获取价格驱动统计默认分页列表失败, Err: " + e.Error())
  346. return
  347. }
  348. } else {
  349. // sortField排序字段:1-按照累计点击量排序 2-按照最近点击量排序
  350. groupRule := "pd.price_driven_id"
  351. joinRule := "pd.variety_tag_id = vl.variety_tag_id"
  352. if sortField == 2 {
  353. joinRule = "pd.price_driven_id = vl.price_driven_id"
  354. groupRule = "pd.variety_tag_id "
  355. }
  356. // sortRule排序规则:1-升序 2-降序
  357. orderRule := "count_num DESC"
  358. if sortRule == 1 {
  359. orderRule = "count_num ASC"
  360. }
  361. pageList, e = yb.GetPriceDrivenPageClick(startSize, pageSize, priceDrivenIds, joinRule, groupRule, orderRule)
  362. if e != nil {
  363. err = errors.New("获取价格驱动统计分页列表失败, Err: " + e.Error())
  364. return
  365. }
  366. }
  367. // 获取标签列表
  368. tagList, e := models.GetVarietyTagList()
  369. if e != nil {
  370. err = errors.New("获取标签列表失败, Err: " + e.Error())
  371. return
  372. }
  373. tagMap := make(map[int]*models.VarietyTag, 0)
  374. for _, t := range tagList {
  375. tagMap[t.VarietyTagId] = t
  376. }
  377. // 遍历组合信息
  378. for _, v := range pageList {
  379. fmt.Println(v.VarietyTagId)
  380. item := new(response.PriceDrivenClickCensusItem)
  381. pd := priceDrivenMap[v.VarietyTagId]
  382. if pd == nil {
  383. continue
  384. }
  385. tag := tagMap[v.VarietyTagId]
  386. if tag != nil {
  387. item.ClassifyId = tag.VarietyClassifyId
  388. item.ClassifyName = tag.VarietyClassifyName
  389. }
  390. item.PriceDrivenId = pd.PriceDrivenId
  391. item.VarietyTagId = pd.VarietyTagId
  392. item.VarietyTagName = pd.VarietyTagName
  393. item.MainVariable = pd.MainVariable
  394. item.CoreDrivenType = pd.CoreDrivenType
  395. item.CoreDrivenContent = pd.CoreDrivenContent
  396. item.LastModifyTime = pd.ModifyTime.Format(utils.FormatDateTime)
  397. item.TotalClickNum = totalClickMap[v.VarietyTagId]
  398. item.RecentClickNum = recentClickMap[v.VarietyTagId]
  399. item.RecentClickTime = recentClickTimeMap[v.VarietyTagId]
  400. list = append(list, item)
  401. }
  402. return
  403. }
  404. // GetPriceDrivenClickCensusList 获取价格驱动统计详情
  405. func GetPriceDrivenClickCensusDetail(startSize, pageSize, varietyTagId, priceDrivenId int) (total, pageTotal int, list []*response.PriceDrivenClickCensusDetailItem, err error) {
  406. list = make([]*response.PriceDrivenClickCensusDetailItem, 0)
  407. total, detailList, e := yb.GetPriceDrivenPageClickDetail(startSize, pageSize, varietyTagId, priceDrivenId)
  408. if e != nil {
  409. err = errors.New("获取价格驱动统计详情列表失败, Err: " + e.Error())
  410. return
  411. }
  412. // 查询用户相关的客户信息
  413. detailLen := len(detailList)
  414. userIdArr := make([]string, 0)
  415. for i := 0; i < detailLen; i++ {
  416. userIdArr = append(userIdArr, strconv.Itoa(detailList[i].UserId))
  417. }
  418. userIds := strings.Join(userIdArr, ",")
  419. userCompanyMap := make(map[int]*company.CompanyUser)
  420. if userIds != "" {
  421. companyUserList, e := company.GetFiccCompanyUserByUserIds(userIds)
  422. if e != nil {
  423. err = errors.New("获取客户信息失败 Err:" + e.Error())
  424. return
  425. }
  426. for _, v := range companyUserList {
  427. userCompanyMap[int(v.UserId)] = v
  428. }
  429. }
  430. for _, v := range detailList {
  431. pageTotal += v.CountNum
  432. item := new(response.PriceDrivenClickCensusDetailItem)
  433. if u, ok := userCompanyMap[v.UserId]; ok {
  434. item.RealName = u.RealName
  435. item.CompanyName = u.CompanyName
  436. item.CompanyStatus = u.Status
  437. }
  438. item.CountNum = v.CountNum
  439. item.SourceAgent = v.NewSourceAgent
  440. item.RecentClickTime = v.RecentClickTime
  441. list = append(list, item)
  442. }
  443. return
  444. }