apply_record.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981
  1. package yb
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/rdlucklib/rdluck_tools/paging"
  6. "github.com/tealeg/xlsx"
  7. "hongze/hz_crm_api/controllers"
  8. "hongze/hz_crm_api/models"
  9. "hongze/hz_crm_api/models/company"
  10. "hongze/hz_crm_api/models/system"
  11. "hongze/hz_crm_api/models/yb"
  12. "hongze/hz_crm_api/models/yb/request"
  13. ybResp "hongze/hz_crm_api/models/yb/response"
  14. "hongze/hz_crm_api/services"
  15. ybService "hongze/hz_crm_api/services/yb"
  16. "hongze/hz_crm_api/utils"
  17. "os"
  18. "path/filepath"
  19. "strconv"
  20. "strings"
  21. "sync"
  22. "time"
  23. )
  24. type ApplyRecordController struct {
  25. controllers.BaseAuthController
  26. }
  27. // List
  28. // @Title 获取申请列表
  29. // @Description 获取申请列表
  30. // @Param Keyword query string false "搜索关键字 string"
  31. // @Param State query string false "用户状态 string 潜在用户/权益用户/冻结/流失"
  32. // @Success 200 {object} []yb.ApplyRecordListResp
  33. // @router /apply_record/list [get]
  34. func (this *ApplyRecordController) List() {
  35. br := new(models.BaseResponse).Init()
  36. defer func() {
  37. this.Data["json"] = br
  38. this.ServeJSON()
  39. }()
  40. sysUser := this.SysUser
  41. if sysUser == nil {
  42. br.Msg = "请登录"
  43. br.ErrMsg = "请登录,SysUser is Empty"
  44. br.Ret = 408
  45. return
  46. }
  47. pageSize, _ := this.GetInt("PageSize")
  48. currentIndex, _ := this.GetInt("CurrentIndex")
  49. var startSize int
  50. if pageSize <= 0 {
  51. pageSize = utils.PageSize20
  52. }
  53. if currentIndex <= 0 {
  54. currentIndex = 1
  55. }
  56. startSize = paging.StartIndex(currentIndex, pageSize)
  57. condition := ""
  58. pars := make([]interface{}, 0)
  59. // 数据权限
  60. condition, pars = getDataAuthWhere(condition, pars, this.SysUser)
  61. reqState := this.GetString("State", "")
  62. if reqState != "" {
  63. condition += " AND a.status = ?"
  64. pars = append(pars, reqState)
  65. }
  66. reqKeyword := this.GetString("Keyword")
  67. if reqKeyword != "" {
  68. reqKeyword = "%" + reqKeyword + "%"
  69. condition += " AND (a.real_name LIKE ? OR a.mobile LIKE ? OR a.email LIKE ?)"
  70. pars = append(pars, reqKeyword, reqKeyword, reqKeyword)
  71. }
  72. // 获取列表
  73. total, list, err := yb.GetApplyRecordList(condition, pars, startSize, pageSize)
  74. if err != nil {
  75. br.Msg = "获取申请列表失败!"
  76. br.ErrMsg = "获取申请列表失败,Err:" + err.Error()
  77. return
  78. }
  79. page := paging.GetPaging(currentIndex, pageSize, total)
  80. resp := ybResp.ApplyRecordListResp{
  81. List: list,
  82. Paging: page,
  83. }
  84. br.Ret = 200
  85. br.Success = true
  86. br.Msg = "获取成功"
  87. br.Data = resp
  88. }
  89. // getDataAuth 过滤数据权限
  90. func getDataAuthWhere(condition string, pars []interface{}, sysUser *system.Admin) (newCondition string, newPars []interface{}) {
  91. roleCode := sysUser.RoleTypeCode
  92. // 超管账户不做限制
  93. if roleCode == utils.ROLE_TYPE_CODE_ADMIN {
  94. return
  95. }
  96. // 是否为FICC角色
  97. allowRole := []string{
  98. utils.ROLE_TYPE_CODE_FICC_ADMIN, utils.ROLE_TYPE_CODE_FICC_SELLER, utils.ROLE_TYPE_CODE_FICC_GROUP,
  99. utils.ROLE_TYPE_CODE_FICC_DEPARTMENT, utils.ROLE_TYPE_CODE_FICC_RESEARCHR, utils.ROLE_TYPE_CODE_RESEARCHR,
  100. }
  101. isAllow := false
  102. for _, role := range allowRole {
  103. if roleCode == role {
  104. isAllow = true
  105. }
  106. }
  107. if isAllow {
  108. // 销售ID为当前用户且客户状态为冻结
  109. condition += " AND b.seller_id = ?"
  110. pars = append(pars, sysUser.AdminId)
  111. condition += " AND b.status = ?"
  112. pars = append(pars, "冻结")
  113. } else {
  114. condition += " AND 1=2"
  115. }
  116. newCondition = condition
  117. newPars = pars
  118. return
  119. }
  120. func getDataAuthWhereV2(condition string, pars []interface{}, sysUser *system.Admin) (newCondition string, newPars []interface{}, err error) {
  121. roleCode := sysUser.RoleTypeCode
  122. // 超管账户不做限制
  123. if roleCode == utils.ROLE_TYPE_CODE_ADMIN || roleCode == utils.ROLE_TYPE_CODE_FICC_ADMIN {
  124. return
  125. }
  126. // 是否为FICC角色
  127. allowRole := []string{
  128. utils.ROLE_TYPE_CODE_FICC_ADMIN, utils.ROLE_TYPE_CODE_FICC_SELLER, utils.ROLE_TYPE_CODE_FICC_GROUP, utils.ROLE_TYPE_CODE_FICC_TEAM,
  129. utils.ROLE_TYPE_CODE_FICC_DEPARTMENT, utils.ROLE_TYPE_CODE_FICC_RESEARCHR, utils.ROLE_TYPE_CODE_RESEARCHR,
  130. }
  131. isAllow := false
  132. for _, role := range allowRole {
  133. if roleCode == role {
  134. isAllow = true
  135. }
  136. }
  137. if isAllow {
  138. // 超管和ficc 管理员,才允许看潜在用户和流失用户,
  139. condition += ` and y.status != "潜在用户" and y.status is not null and y.status != "权益用户" and y.status != "流失"`
  140. // 如果是ficc销售主管,查询对应的小组
  141. if roleCode == utils.ROLE_TYPE_CODE_FICC_GROUP && sysUser.GroupId > 0 {
  142. subAdmins, tErr := system.GetSysUserByParentIdGroupId(sysUser.GroupId)
  143. if tErr != nil && tErr.Error() != utils.ErrNoRow() {
  144. err = tErr
  145. return
  146. }
  147. var sellerIdsStr string
  148. for _, v := range subAdmins {
  149. // 只能看比主管权限低的角色
  150. if v.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_SELLER || v.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_TEAM || v.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_RESEARCHR || v.RoleTypeCode == utils.ROLE_TYPE_CODE_RESEARCHR {
  151. sellerIdsStr += strconv.Itoa(v.AdminId) + ","
  152. }
  153. }
  154. if sellerIdsStr != "" {
  155. sellerIdsStr += strconv.Itoa(sysUser.AdminId)
  156. // 销售ID为当前用户且客户状态为冻结
  157. condition += " AND bp.seller_id in (" + sellerIdsStr + ")"
  158. } else {
  159. condition += " AND bp.seller_id = ?"
  160. pars = append(pars, sysUser.AdminId)
  161. }
  162. } else if roleCode == utils.ROLE_TYPE_CODE_FICC_TEAM && sysUser.GroupId > 0 { // 如果是ficc 销售组长
  163. subAdmins, tErr := system.GetAdminByGroupId(sysUser.GroupId)
  164. if tErr != nil && tErr.Error() != utils.ErrNoRow() {
  165. err = tErr
  166. return
  167. }
  168. var sellerIdsStr string
  169. for _, v := range subAdmins {
  170. // 只能看比主管权限低的角色
  171. if v.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_SELLER || v.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_RESEARCHR || v.RoleTypeCode == utils.ROLE_TYPE_CODE_RESEARCHR {
  172. sellerIdsStr += strconv.Itoa(v.AdminId) + ","
  173. }
  174. }
  175. if sellerIdsStr != "" {
  176. sellerIdsStr += strconv.Itoa(sysUser.AdminId)
  177. // 销售ID为当前用户且客户状态为冻结
  178. condition += " AND bp.seller_id in (" + sellerIdsStr + ")"
  179. } else {
  180. condition += " AND bp.seller_id = ?"
  181. pars = append(pars, sysUser.AdminId)
  182. }
  183. } else { // 如果是ficc 销售
  184. condition += " AND bp.seller_id = ?"
  185. pars = append(pars, sysUser.AdminId)
  186. }
  187. } else {
  188. condition += " AND 1=2"
  189. }
  190. newCondition = condition
  191. newPars = pars
  192. return
  193. }
  194. // MarkHandle
  195. // @Title 处理申请记录
  196. // @Description 处理申请记录
  197. // @Param request body request.ApplyMarkReq true "type json string"
  198. // @Success 200 {object} 标记处理成功
  199. // @router /apply_record/mark_handle [post]
  200. func (this *ApplyRecordController) MarkHandle() {
  201. br := new(models.BaseResponse).Init()
  202. defer func() {
  203. this.Data["json"] = br
  204. this.ServeJSON()
  205. }()
  206. sysUser := this.SysUser
  207. if sysUser == nil {
  208. br.Msg = "请登录"
  209. br.ErrMsg = "请登录,SysUser is Empty"
  210. br.Ret = 408
  211. return
  212. }
  213. var req request.ApplyMarkReq
  214. err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
  215. if err != nil {
  216. br.Msg = "参数解析异常"
  217. br.ErrMsg = "参数解析失败,Err:" + err.Error()
  218. return
  219. }
  220. if req.ApplyRecordId <= 0 && req.UserId <= 0 {
  221. br.Msg = "申请记录ID或者用户ID异常"
  222. br.ErrMsg = "申请记录ID或者用户ID异常"
  223. return
  224. }
  225. // 标记处理
  226. err = ybService.MarkApplyRecord(req.ApplyRecordId, this.SysUser.AdminId, req.UserId)
  227. if err != nil {
  228. br.Msg = "标记处理失败! "
  229. br.ErrMsg = "标记处理失败,Err:" + err.Error()
  230. return
  231. }
  232. br.Ret = 200
  233. br.Success = true
  234. br.Msg = "标记处理成功"
  235. }
  236. // ListV2
  237. // @Title 获取用户申请列表
  238. // @Description 获取用户申请列表
  239. // @Param KeyWord query string false "搜索关键字 string"
  240. // @Param States query string false "用户状态 string 潜在用户/权益用户/冻结/流失"
  241. // @Success 200 {object} []yb.ApplyRecordListRespV2
  242. // @router /apply_record/listV2 [get]
  243. func (this *ApplyRecordController) UserApplyList() {
  244. br := new(models.BaseResponse).Init()
  245. defer func() {
  246. this.Data["json"] = br
  247. this.ServeJSON()
  248. }()
  249. sysUser := this.SysUser
  250. if sysUser == nil {
  251. br.Msg = "请登录"
  252. br.ErrMsg = "请登录,SysUser is Empty"
  253. br.Ret = 408
  254. return
  255. }
  256. pageSize, _ := this.GetInt("PageSize")
  257. currentIndex, _ := this.GetInt("CurrentIndex")
  258. markGroup := this.GetString("MarkGroup")
  259. startDate := this.GetString("StartDate")
  260. endDate := this.GetString("EndDate")
  261. var startSize int
  262. if pageSize <= 0 {
  263. pageSize = utils.PageSize20
  264. }
  265. if currentIndex <= 0 {
  266. currentIndex = 1
  267. }
  268. startSize = paging.StartIndex(currentIndex, pageSize)
  269. condition := ""
  270. pars := make([]interface{}, 0)
  271. // 数据权限
  272. condition, pars, err := getDataAuthWhereV2(condition, pars, this.SysUser)
  273. if err != nil {
  274. br.Msg = "权限查询出错"
  275. br.ErrMsg = "权限查询出错:" + err.Error()
  276. return
  277. }
  278. reqState := this.GetString("States", "")
  279. if reqState != "" {
  280. statusSlice := strings.Split(reqState, ",")
  281. conditionSub := ""
  282. if len(statusSlice) == 0 {
  283. br.Msg = "入参:状态格式出错"
  284. return
  285. }
  286. for _, v := range statusSlice {
  287. if v == "潜在用户" {
  288. conditionSub += ` or y.status = "潜在用户" or y.status is null or y.status = "权益用户"`
  289. } else {
  290. conditionSub += ` or y.status = "` + v + `"`
  291. }
  292. }
  293. conditionSubByte := []byte(conditionSub)
  294. conditionSub = string(conditionSubByte[4:])
  295. condition += ` AND (` + conditionSub + `)`
  296. }
  297. reqKeyword := this.GetString("KeyWord")
  298. if reqKeyword != "" {
  299. reqKeyword = "%" + reqKeyword + "%"
  300. condition += " AND (a.real_name LIKE ? OR a.mobile LIKE ? OR a.email LIKE ? OR (a.company_id > 1 AND b.company_name LIKE ?) OR (a.company_id = 1 AND a.note LIKE ?))"
  301. pars = append(pars, reqKeyword, reqKeyword, reqKeyword, reqKeyword, reqKeyword)
  302. }
  303. if markGroup != "" {
  304. condition += `AND (y.mark_group = `+"'"+markGroup+"'"+ ` OR a.mark_group = `+"'"+markGroup+"')"
  305. }
  306. if startDate != "" {
  307. startDate += " 00:00:00"
  308. condition += ` AND IF(y.apply_record_id > 0,y.create_time, a.created_time) >= '` + startDate + `' `
  309. }
  310. if endDate != "" {
  311. endDate += " 23:59:59"
  312. condition += ` AND IF(y.apply_record_id > 0,y.create_time, a.created_time) <= '` + endDate + `' `
  313. }
  314. reqApplyStatus := this.GetString("ApplyStatus")
  315. if reqApplyStatus != "" {
  316. if reqApplyStatus == "已申请" {
  317. condition += " AND y.apply_record_id > 0"
  318. } else if reqApplyStatus == "未申请" {
  319. condition += " AND ISNULL(y.apply_record_id) = 1"
  320. }
  321. }
  322. // 获取列表
  323. w := sync.WaitGroup{}
  324. var list []*yb.ApplyListV2
  325. var total int
  326. startTime := "2022-01-01"
  327. w.Add(1)
  328. go func() {
  329. defer w.Done()
  330. list, err = yb.GetApplyRecordListV2(condition, pars, startTime, startSize, pageSize)
  331. }()
  332. if err != nil {
  333. br.Msg = "获取申请列表失败!"
  334. br.ErrMsg = "获取申请列表失败,Err:" + err.Error()
  335. return
  336. }
  337. w.Add(1)
  338. go func() {
  339. defer w.Done()
  340. total, err = yb.GetApplyRecordTotal(condition, pars, startTime)
  341. }()
  342. w.Wait()
  343. if err != nil {
  344. br.Msg = "获取申请列表总数失败!"
  345. br.ErrMsg = "获取申请列表总数失败,Err:" + err.Error()
  346. return
  347. }
  348. mobilesSlice := make([]string, 0)
  349. emailsSlice := make([]string, 0)
  350. userIdsStr := ""
  351. for _, v := range list {
  352. userIdsStr += "," + strconv.Itoa(v.UserId)
  353. if v.Mobile != "" {
  354. mobilesSlice = append(mobilesSlice, v.Mobile)
  355. } else if v.Email != "" {
  356. emailsSlice = append(emailsSlice, v.Email)
  357. }
  358. }
  359. //统计申请数
  360. userApplyTotalMap := make(map[int]int)
  361. if userIdsStr != "" {
  362. userIdsStr = strings.Trim(userIdsStr, ",")
  363. userApplyTotal, tErr := yb.GetTotalByUserIds(userIdsStr)
  364. if tErr != nil {
  365. br.Msg = "获取申请数失败!"
  366. br.ErrMsg = "获取申请数失败,Err:" + tErr.Error()
  367. return
  368. }
  369. for _, v := range userApplyTotal {
  370. userApplyTotalMap[v.UserId] = v.Total
  371. }
  372. }
  373. w2 := sync.WaitGroup{}
  374. mobileTotalMap := make(map[string]int)
  375. lastTimeMobileMap := make(map[string]time.Time)
  376. w2.Add(1)
  377. //统计阅读数
  378. go func() {
  379. defer w2.Done()
  380. mobileTotalMap, lastTimeMobileMap = ybService.GetUserViewTotalByMobiles(mobilesSlice)
  381. }()
  382. emailTotalMap := make(map[string]int)
  383. lastTimeEmailMap := make(map[string]time.Time)
  384. w2.Add(1)
  385. go func() {
  386. defer w2.Done()
  387. emailTotalMap, lastTimeEmailMap = ybService.GetUserViewTotalByEmails(emailsSlice)
  388. }()
  389. w2.Wait()
  390. for k, v := range list {
  391. if v.OpStatus == 1 && v.MarkGroup == "" {
  392. list[k].OpStatus = 0
  393. }
  394. sourceStr := ""
  395. if v.ApplyRecordId > 0 {
  396. if v.SourceAgent == 3 {
  397. sourceStr = "弘则研究"
  398. } else if v.SourceAgent == 1 {
  399. switch v.Source {
  400. case 1:
  401. sourceStr = "我的(小程序)"
  402. case 2:
  403. sourceStr = "活动(小程序)"
  404. case 3:
  405. sourceStr = "图库(小程序)"
  406. case 4:
  407. sourceStr = "研报(小程序)"
  408. case 5:
  409. sourceStr = "问答社区(小程序)"
  410. default:
  411. if v.FromPage != "" {
  412. sourceStr = v.FromPage + "(小程序)"
  413. } else {
  414. sourceStr = "研报(小程序)"
  415. }
  416. }
  417. } else if v.SourceAgent == 2 || v.SourceAgent == 4 {
  418. switch v.Source {
  419. case 1:
  420. sourceStr = "我的(PC端)"
  421. case 2:
  422. sourceStr = "活动(PC端)"
  423. case 3:
  424. sourceStr = "图库(PC端)"
  425. case 4:
  426. sourceStr = "研报(PC端)"
  427. case 5:
  428. sourceStr = "问答社区(PC端)"
  429. default:
  430. if v.FromPage != "" {
  431. sourceStr = v.FromPage + "(PC端)"
  432. } else {
  433. sourceStr = "研报(PC端)"
  434. }
  435. }
  436. }
  437. } else if v.RegisterSource != 0 {
  438. switch v.RegisterSource {
  439. case 1:
  440. sourceStr = "弘则研究"
  441. case 2:
  442. sourceStr = "研报(PC端)"
  443. case 5:
  444. sourceStr = "活动(小程序)"
  445. case 6:
  446. sourceStr = "研报(小程序)"
  447. default:
  448. sourceStr = ""
  449. }
  450. }
  451. list[k].SourceStr = sourceStr
  452. // 统计申请数
  453. if applyTotal, ok := userApplyTotalMap[v.UserId]; ok {
  454. list[k].ApplyTotal = applyTotal
  455. }
  456. //统计阅读数
  457. if num, ok := mobileTotalMap[v.Mobile]; ok {
  458. list[k].ViewTotal += num
  459. }
  460. if num, ok := emailTotalMap[v.Email]; ok {
  461. list[k].ViewTotal += num
  462. }
  463. //最新阅读时间
  464. if t, ok := lastTimeMobileMap[v.Mobile]; ok {
  465. if list[k].LastViewTime.Before(t) {
  466. list[k].LastViewTime = t
  467. }
  468. }
  469. if t, ok := lastTimeEmailMap[v.Email]; ok {
  470. if list[k].LastViewTime.Before(t) {
  471. list[k].LastViewTime = t
  472. }
  473. }
  474. list[k].LastViewTimeStr = list[k].LastViewTime.Format(utils.FormatDateTime)
  475. if list[k].LastViewTimeStr == "0001-01-01 00:00:00" {
  476. list[k].LastViewTimeStr = ""
  477. }
  478. list[k].LastTimeStr = list[k].LastTime.Format(utils.FormatDateTime)
  479. if v.Status == "权益用户" {
  480. list[k].Status = "潜在用户"
  481. }
  482. //查询是否展示潜在用户删除按钮权限
  483. if v.CompanyId == 1 && list[k].Status == "潜在用户" {
  484. list[k].DelBtn = true
  485. }
  486. }
  487. page := paging.GetPaging(currentIndex, pageSize, total)
  488. resp := ybResp.ApplyRecordListV2Resp{
  489. List: list,
  490. Paging: page,
  491. }
  492. br.Ret = 200
  493. br.Success = true
  494. br.Msg = "获取成功"
  495. br.Data = resp
  496. }
  497. // ApplyExport
  498. // @Title 导出用户申请列表
  499. // @Description 导出用户申请列表
  500. // @Param KeyWord query string false "搜索关键字 string"
  501. // @Param State query string false "用户状态 string 潜在用户/权益用户/冻结/流失"
  502. // @Success Ret=200 导出成功
  503. // @router /apply_record/listV2/export [get]
  504. func (this *ApplyRecordController) ApplyExport() {
  505. br := new(models.BaseResponse).Init()
  506. defer func() {
  507. this.Data["json"] = br
  508. this.ServeJSON()
  509. }()
  510. reqKeyword := this.GetString("KeyWord")
  511. reqState := this.GetString("States")
  512. markGroup := this.GetString("MarkGroup")
  513. sysUser := this.SysUser
  514. if sysUser == nil {
  515. br.Msg = "请登录"
  516. br.ErrMsg = "请登录,SysUser Is Empty"
  517. br.Ret = 408
  518. return
  519. }
  520. //管理员才让导出数据
  521. if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_ADMIN && sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_FICC_ADMIN {
  522. br.Msg = "没有权限"
  523. br.ErrMsg = "没有权限"
  524. return
  525. }
  526. var condition string
  527. var pars []interface{}
  528. if reqState != "" {
  529. statusSlice := strings.Split(reqState, ",")
  530. conditionSub := ""
  531. if len(statusSlice) == 0 {
  532. br.Msg = "入参:状态格式出错"
  533. return
  534. }
  535. for _, v := range statusSlice {
  536. if v == "潜在用户" {
  537. conditionSub += ` or y.status = "潜在用户" or y.status is null or y.status = "权益用户"`
  538. } else {
  539. conditionSub += ` or y.status = "` + v + `"`
  540. }
  541. }
  542. conditionSubByte := []byte(conditionSub)
  543. conditionSub = string(conditionSubByte[4:])
  544. condition += ` AND (` + conditionSub + `)`
  545. }
  546. if reqKeyword != "" {
  547. reqKeyword = "%" + reqKeyword + "%"
  548. condition += " AND (a.real_name LIKE ? OR a.mobile LIKE ? OR a.email LIKE ? OR (a.company_id > 1 AND b.company_name LIKE ?) OR (a.company_id = 1 AND a.note LIKE ?))"
  549. pars = append(pars, reqKeyword, reqKeyword, reqKeyword, reqKeyword, reqKeyword)
  550. }
  551. reqApplyStatus := this.GetString("ApplyStatus")
  552. if reqApplyStatus != "" {
  553. if reqApplyStatus == "已申请" {
  554. condition += " AND y.apply_record_id > 0"
  555. } else if reqApplyStatus == "未申请" {
  556. condition += " AND y.apply_record_id is null"
  557. }
  558. }
  559. if markGroup != "" {
  560. condition += `AND (y.mark_group = `+"'"+markGroup+"'"+ ` OR a.mark_group = `+"'"+markGroup+"')"
  561. }
  562. startTime := "2022-01-01"
  563. list, err := yb.GetApplyRecordListV2Export(condition, pars, startTime)
  564. if err != nil {
  565. br.Msg = "获取失败"
  566. br.ErrMsg = "获取失败,Err:" + err.Error()
  567. return
  568. }
  569. mobilesSlice := make([]string, 0)
  570. emailsSlice := make([]string, 0)
  571. userIdsStr := ""
  572. for _, v := range list {
  573. userIdsStr += "," + strconv.Itoa(v.UserId)
  574. if v.Mobile != "" {
  575. mobilesSlice = append(mobilesSlice, v.Mobile)
  576. } else if v.Email != "" {
  577. emailsSlice = append(emailsSlice, v.Email)
  578. }
  579. }
  580. userIdsStr = strings.Trim(userIdsStr, ",")
  581. //统计申请数
  582. userApplyTotalMap := make(map[int]int)
  583. if userIdsStr != "" {
  584. userApplyTotal, err := yb.GetTotalByUserIds(userIdsStr)
  585. if err != nil {
  586. br.Msg = "获取申请数失败!"
  587. br.ErrMsg = "获取申请数失败,Err:" + err.Error()
  588. return
  589. }
  590. for _, v := range userApplyTotal {
  591. userApplyTotalMap[v.UserId] = v.Total
  592. }
  593. }
  594. w := sync.WaitGroup{}
  595. mobileTotalMap := make(map[string]int)
  596. lastTimeMobileMap := make(map[string]time.Time)
  597. w.Add(1)
  598. //统计阅读数
  599. go func() {
  600. defer w.Done()
  601. mobileTotalMap, lastTimeMobileMap = ybService.GetUserViewTotalByMobiles(mobilesSlice)
  602. }()
  603. emailTotalMap := make(map[string]int)
  604. lastTimeEmailMap := make(map[string]time.Time)
  605. w.Add(1)
  606. go func() {
  607. defer w.Done()
  608. emailTotalMap, lastTimeEmailMap = ybService.GetUserViewTotalByEmails(emailsSlice)
  609. }()
  610. w.Wait()
  611. for k, v := range list {
  612. sourceStr := ""
  613. if v.ApplyRecordId > 0 {
  614. if v.SourceAgent == 3 {
  615. sourceStr = "弘则研究"
  616. } else if v.SourceAgent == 1 {
  617. switch v.Source {
  618. case 1:
  619. sourceStr = "我的(小程序)"
  620. case 2:
  621. sourceStr = "活动(小程序)"
  622. case 3:
  623. sourceStr = "图库(小程序)"
  624. case 4:
  625. sourceStr = "研报(小程序)"
  626. case 5:
  627. sourceStr = "问答社区(小程序)"
  628. default:
  629. if v.FromPage != "" {
  630. sourceStr = v.FromPage + "(小程序)"
  631. } else {
  632. sourceStr = "研报(小程序)"
  633. }
  634. }
  635. } else if v.SourceAgent == 2 {
  636. switch v.Source {
  637. case 1:
  638. sourceStr = "我的(PC端)"
  639. case 2:
  640. sourceStr = "活动(PC端)"
  641. case 3:
  642. sourceStr = "图库(PC端)"
  643. case 4:
  644. sourceStr = "研报(PC端)"
  645. case 5:
  646. sourceStr = "问答社区(PC端)"
  647. default:
  648. if v.FromPage != "" {
  649. sourceStr = v.FromPage + "(PC端)"
  650. } else {
  651. sourceStr = "研报(PC端)"
  652. }
  653. }
  654. }
  655. } else if v.RegisterSource != 0 {
  656. switch v.RegisterSource {
  657. case 1:
  658. sourceStr = "弘则研究"
  659. case 2:
  660. sourceStr = "研报(PC端)"
  661. case 5:
  662. sourceStr = "活动(小程序)"
  663. case 6:
  664. sourceStr = "研报(小程序)"
  665. default:
  666. sourceStr = ""
  667. }
  668. }
  669. list[k].SourceStr = sourceStr
  670. // 统计申请数
  671. if applyTotal, ok := userApplyTotalMap[v.UserId]; ok {
  672. list[k].ApplyTotal = applyTotal
  673. }
  674. //统计阅读数
  675. if num, ok := mobileTotalMap[v.Mobile]; ok {
  676. list[k].ViewTotal += num
  677. }
  678. if num, ok := emailTotalMap[v.Email]; ok {
  679. list[k].ViewTotal += num
  680. }
  681. //最新阅读时间
  682. if t, ok := lastTimeMobileMap[v.Mobile]; ok {
  683. if list[k].LastViewTime.Before(t) {
  684. list[k].LastViewTime = t
  685. }
  686. }
  687. if t, ok := lastTimeEmailMap[v.Email]; ok {
  688. if list[k].LastViewTime.Before(t) {
  689. list[k].LastViewTime = t
  690. }
  691. }
  692. list[k].LastViewTimeStr = list[k].LastViewTime.Format(utils.FormatDateTime)
  693. if list[k].LastViewTimeStr == "0001-01-01 00:00:00" {
  694. list[k].LastViewTimeStr = ""
  695. }
  696. list[k].LastTimeStr = list[k].LastTime.Format(utils.FormatDateTime)
  697. if v.Status == "权益用户" {
  698. list[k].Status = "潜在用户"
  699. }
  700. }
  701. dir, err := os.Executable()
  702. exPath := filepath.Dir(dir)
  703. downLoadnFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
  704. xlsxFile := xlsx.NewFile()
  705. if err != nil {
  706. br.Msg = "生成文件失败"
  707. br.ErrMsg = "生成文件失败"
  708. return
  709. }
  710. style := xlsx.NewStyle()
  711. alignment := xlsx.Alignment{
  712. Horizontal: "center",
  713. Vertical: "center",
  714. WrapText: true,
  715. }
  716. style.Alignment = alignment
  717. style.ApplyAlignment = true
  718. sheel, err := xlsxFile.AddSheet("客户数据")
  719. if err != nil {
  720. br.Msg = "新增Sheet失败"
  721. br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
  722. return
  723. }
  724. titleRow := sheel.AddRow()
  725. titleRow.AddCell().SetValue("姓名")
  726. titleRow.AddCell().SetValue("手机号")
  727. titleRow.AddCell().SetValue("邮箱")
  728. titleRow.AddCell().SetValue("最新提交时间")
  729. titleRow.AddCell().SetValue("累计提交次数")
  730. titleRow.AddCell().SetValue("最近一次阅读时间")
  731. titleRow.AddCell().SetValue("累计阅读次数")
  732. titleRow.AddCell().SetValue("公司")
  733. titleRow.AddCell().SetValue("原销售")
  734. titleRow.AddCell().SetValue("来源")
  735. titleRow.AddCell().SetValue("申请类型")
  736. titleRow.AddCell().SetValue("用户状态")
  737. for _, v := range list {
  738. dataRow := sheel.AddRow()
  739. dataRow.SetHeight(20)
  740. dataRow.AddCell().SetString(v.RealName)
  741. dataRow.AddCell().SetString(v.Mobile)
  742. dataRow.AddCell().SetString(v.Email)
  743. dataRow.AddCell().SetString(v.LastTimeStr)
  744. dataRow.AddCell().SetString(strconv.Itoa(v.ApplyTotal))
  745. dataRow.AddCell().SetString(v.LastViewTimeStr)
  746. dataRow.AddCell().SetString(strconv.Itoa(v.ViewTotal))
  747. dataRow.AddCell().SetString(v.CompanyName)
  748. dataRow.AddCell().SetString(v.OriginSellerName)
  749. dataRow.AddCell().SetString(v.SourceStr)
  750. dataRow.AddCell().SetString(v.ApplyStatus)
  751. dataRow.AddCell().SetString(v.Status)
  752. }
  753. err = xlsxFile.Save(downLoadnFilePath)
  754. if err != nil {
  755. br.Msg = "保存文件失败"
  756. br.ErrMsg = "保存文件失败"
  757. return
  758. }
  759. randStr := time.Now().Format(utils.FormatDateTimeUnSpace)
  760. downloadFileName := "用户申请列表_" + randStr + ".xlsx"
  761. this.Ctx.Output.Download(downLoadnFilePath, downloadFileName)
  762. defer func() {
  763. _ = os.Remove(downLoadnFilePath)
  764. }()
  765. br.Ret = 200
  766. br.Success = true
  767. br.Msg = "导出成功"
  768. }
  769. // DelPotentialUser
  770. // @Title 删除潜在用户账号和申请记录
  771. // @Description 删除潜在用户账号和申请记录
  772. // @Param request body company.DeleteUserReq true "type json string"
  773. // @Success 200 {object} 删除成功
  774. // @router /potential/user/del [post]
  775. func (this *ApplyRecordController) DelPotentialUser() {
  776. br := new(models.BaseResponse).Init()
  777. defer func() {
  778. this.Data["json"] = br
  779. this.ServeJSON()
  780. }()
  781. sysUser := this.SysUser
  782. if sysUser == nil {
  783. br.Msg = "请登录"
  784. br.ErrMsg = "请登录,SysUser Is Empty"
  785. br.Ret = 408
  786. return
  787. }
  788. var req company.DeleteUserReq
  789. err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
  790. if err != nil {
  791. br.Msg = "参数解析异常!"
  792. br.ErrMsg = "参数解析失败,Err:" + err.Error()
  793. return
  794. }
  795. if req.UserId <= 0 {
  796. br.Msg = "请输入正确的用户ID"
  797. return
  798. }
  799. //获取联系人详情
  800. userInfo, err := models.GetWxUserByUserId(req.UserId)
  801. if err != nil {
  802. br.Msg = "获取联系人异常!"
  803. br.ErrMsg = "获取联系人异常,Err:" + err.Error()
  804. return
  805. }
  806. if userInfo.CompanyId != 1 {
  807. br.Msg = "该联系人已绑定客户,不允许删除!"
  808. return
  809. }
  810. //操作权限校验, 超管和ficc管理员有删除权限
  811. if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_FICC_ADMIN && sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_ADMIN {
  812. br.Msg = "没有操作权限"
  813. return
  814. }
  815. //如果不是超管权限,那么删除的时候,需要获取下联系人归属销售信息
  816. //产品权限
  817. productId := services.GetProductId(sysUser.RoleTypeCode)
  818. //联系人与销售的关系
  819. userSellerRelationList, err := models.GetUserSellerRelationList(int(userInfo.UserId))
  820. if err != nil {
  821. br.Msg = "获取联系人关系失败"
  822. br.ErrMsg = "获取联系人关系失败,Err:" + err.Error()
  823. return
  824. }
  825. userSellerRelationInfo, _ := json.Marshal(userSellerRelationList)
  826. //删除所有的标识,并真正删除数据
  827. _ = models.DeleteUserSellerRelationByUserId(req.UserId)
  828. //真正删除用户
  829. err = services.DeleteWxUser(req.UserId)
  830. if err != nil {
  831. br.Msg = "删除失败!"
  832. br.ErrMsg = "删除失败,Err:" + err.Error()
  833. return
  834. }
  835. if len(userSellerRelationList) > 0 && productId != 0 {
  836. content := fmt.Sprint("联系人:", userInfo.RealName, "被删除")
  837. if userSellerRelationList[0].CompanyId != 1 {
  838. companyInfo, tErr := company.GetCompanyById(userSellerRelationList[0].CompanyId)
  839. if tErr != nil {
  840. if tErr.Error() != utils.ErrNoRow() {
  841. br.Msg = "获取客户信息失败"
  842. br.ErrMsg = "获取客户信息失败,Err:" + tErr.Error()
  843. return
  844. }
  845. } else {
  846. content = fmt.Sprint(companyInfo.CompanyName, ":", content)
  847. for _, userRelation := range userSellerRelationList {
  848. if userRelation.ProductId != productId {
  849. go services.AddCompanyMessage(sysUser.AdminId, userRelation.SellerId, userRelation.CompanyId, 0, 1, companyInfo.CompanyName, content, content)
  850. }
  851. }
  852. }
  853. }
  854. }
  855. //联系人信息
  856. originalUserInfo, _ := json.Marshal(userInfo)
  857. go services.AddWxUserOpLog(company.WxUserOpLog{
  858. LogType: "delete",
  859. UserId: int(userInfo.UserId),
  860. CompanyId: userInfo.CompanyId,
  861. Mobile: userInfo.Mobile,
  862. Email: userInfo.Email,
  863. OriginalUserInfo: string(originalUserInfo),
  864. UserInfo: "",
  865. OriginalUserSellerInfo: string(userSellerRelationInfo),
  866. UserSellerInfo: "",
  867. OpUserId: sysUser.AdminId,
  868. OpUserName: sysUser.RealName,
  869. CreateTime: time.Now(),
  870. })
  871. // 若该联系人为弘则研究公司下的,则同步禁用手机号关联的系统管理员
  872. if userInfo.CompanyId == 16 {
  873. go services.ForbiddenSysUserByMobile(userInfo.Mobile)
  874. }
  875. // 删除用户的申请记录
  876. go ybService.DeleteApplyUser(userInfo.UserId)
  877. br.Ret = 200
  878. br.Success = true
  879. br.Msg = "删除成功"
  880. br.IsAddLog = true
  881. return
  882. }
  883. // MarkGroup
  884. // @Title 标记分组
  885. // @Description 标记分组
  886. // @Param request body request.ApplyMarkReq true "type json string"
  887. // @Success 200 {object} 标记处理成功
  888. // @router /apply_record/mark_group [post]
  889. func (this *ApplyRecordController) MarkGroup() {
  890. br := new(models.BaseResponse).Init()
  891. defer func() {
  892. this.Data["json"] = br
  893. this.ServeJSON()
  894. }()
  895. sysUser := this.SysUser
  896. if sysUser == nil {
  897. br.Msg = "请登录"
  898. br.ErrMsg = "请登录,SysUser is Empty"
  899. br.Ret = 408
  900. return
  901. }
  902. var req request.ApplyMarkGroupReq
  903. err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
  904. if err != nil {
  905. br.Msg = "参数解析异常"
  906. br.ErrMsg = "参数解析失败,Err:" + err.Error()
  907. return
  908. }
  909. if req.GroupName == "" || req.UserId == 0 {
  910. br.Msg = "申请记录ID或者分组名异常"
  911. br.ErrMsg = "申请记录ID或者分组名异常"
  912. return
  913. }
  914. // 标记处理
  915. err = ybService.MarkGroupApplyRecord(req.ApplyRecordId, this.SysUser.AdminId, req.UserId, req.GroupName)
  916. if err != nil {
  917. br.Msg = "标记处理失败! "
  918. br.ErrMsg = "标记处理失败,Err:" + err.Error()
  919. return
  920. }
  921. br.Ret = 200
  922. br.Success = true
  923. br.Msg = "标记处理成功"
  924. }