apply_record.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  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. sourceStr := ""
  392. if v.ApplyRecordId > 0 {
  393. if v.SourceAgent == 3 {
  394. sourceStr = "弘则研究"
  395. } else if v.SourceAgent == 1 {
  396. switch v.Source {
  397. case 1:
  398. sourceStr = "我的(小程序)"
  399. case 2:
  400. sourceStr = "活动(小程序)"
  401. case 3:
  402. sourceStr = "图库(小程序)"
  403. case 4:
  404. sourceStr = "研报(小程序)"
  405. case 5:
  406. sourceStr = "问答社区(小程序)"
  407. default:
  408. if v.FromPage != "" {
  409. sourceStr = v.FromPage + "(小程序)"
  410. } else {
  411. sourceStr = "研报(小程序)"
  412. }
  413. }
  414. } else if v.SourceAgent == 2 || v.SourceAgent == 4 {
  415. switch v.Source {
  416. case 1:
  417. sourceStr = "我的(PC端)"
  418. case 2:
  419. sourceStr = "活动(PC端)"
  420. case 3:
  421. sourceStr = "图库(PC端)"
  422. case 4:
  423. sourceStr = "研报(PC端)"
  424. case 5:
  425. sourceStr = "问答社区(PC端)"
  426. default:
  427. if v.FromPage != "" {
  428. sourceStr = v.FromPage + "(PC端)"
  429. } else {
  430. sourceStr = "研报(PC端)"
  431. }
  432. }
  433. }
  434. } else if v.RegisterSource != 0 {
  435. switch v.RegisterSource {
  436. case 1:
  437. sourceStr = "弘则研究"
  438. case 2:
  439. sourceStr = "研报(PC端)"
  440. case 5:
  441. sourceStr = "活动(小程序)"
  442. case 6:
  443. sourceStr = "研报(小程序)"
  444. default:
  445. sourceStr = ""
  446. }
  447. }
  448. list[k].SourceStr = sourceStr
  449. // 统计申请数
  450. if applyTotal, ok := userApplyTotalMap[v.UserId]; ok {
  451. list[k].ApplyTotal = applyTotal
  452. }
  453. //统计阅读数
  454. if num, ok := mobileTotalMap[v.Mobile]; ok {
  455. list[k].ViewTotal += num
  456. }
  457. if num, ok := emailTotalMap[v.Email]; ok {
  458. list[k].ViewTotal += num
  459. }
  460. //最新阅读时间
  461. if t, ok := lastTimeMobileMap[v.Mobile]; ok {
  462. if list[k].LastViewTime.Before(t) {
  463. list[k].LastViewTime = t
  464. }
  465. }
  466. if t, ok := lastTimeEmailMap[v.Email]; ok {
  467. if list[k].LastViewTime.Before(t) {
  468. list[k].LastViewTime = t
  469. }
  470. }
  471. list[k].LastViewTimeStr = list[k].LastViewTime.Format(utils.FormatDateTime)
  472. if list[k].LastViewTimeStr == "0001-01-01 00:00:00" {
  473. list[k].LastViewTimeStr = ""
  474. }
  475. list[k].LastTimeStr = list[k].LastTime.Format(utils.FormatDateTime)
  476. if v.Status == "权益用户" {
  477. list[k].Status = "潜在用户"
  478. }
  479. //查询是否展示潜在用户删除按钮权限
  480. if v.CompanyId == 1 && list[k].Status == "潜在用户" {
  481. list[k].DelBtn = true
  482. }
  483. }
  484. page := paging.GetPaging(currentIndex, pageSize, total)
  485. resp := ybResp.ApplyRecordListV2Resp{
  486. List: list,
  487. Paging: page,
  488. }
  489. br.Ret = 200
  490. br.Success = true
  491. br.Msg = "获取成功"
  492. br.Data = resp
  493. }
  494. // ApplyExport
  495. // @Title 导出用户申请列表
  496. // @Description 导出用户申请列表
  497. // @Param KeyWord query string false "搜索关键字 string"
  498. // @Param State query string false "用户状态 string 潜在用户/权益用户/冻结/流失"
  499. // @Success Ret=200 导出成功
  500. // @router /apply_record/listV2/export [get]
  501. func (this *ApplyRecordController) ApplyExport() {
  502. br := new(models.BaseResponse).Init()
  503. defer func() {
  504. this.Data["json"] = br
  505. this.ServeJSON()
  506. }()
  507. reqKeyword := this.GetString("KeyWord")
  508. reqState := this.GetString("States")
  509. markGroup := this.GetString("MarkGroup")
  510. sysUser := this.SysUser
  511. if sysUser == nil {
  512. br.Msg = "请登录"
  513. br.ErrMsg = "请登录,SysUser Is Empty"
  514. br.Ret = 408
  515. return
  516. }
  517. //管理员才让导出数据
  518. if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_ADMIN && sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_FICC_ADMIN {
  519. br.Msg = "没有权限"
  520. br.ErrMsg = "没有权限"
  521. return
  522. }
  523. var condition string
  524. var pars []interface{}
  525. if reqState != "" {
  526. statusSlice := strings.Split(reqState, ",")
  527. conditionSub := ""
  528. if len(statusSlice) == 0 {
  529. br.Msg = "入参:状态格式出错"
  530. return
  531. }
  532. for _, v := range statusSlice {
  533. if v == "潜在用户" {
  534. conditionSub += ` or y.status = "潜在用户" or y.status is null or y.status = "权益用户"`
  535. } else {
  536. conditionSub += ` or y.status = "` + v + `"`
  537. }
  538. }
  539. conditionSubByte := []byte(conditionSub)
  540. conditionSub = string(conditionSubByte[4:])
  541. condition += ` AND (` + conditionSub + `)`
  542. }
  543. if reqKeyword != "" {
  544. reqKeyword = "%" + reqKeyword + "%"
  545. 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 ?))"
  546. pars = append(pars, reqKeyword, reqKeyword, reqKeyword, reqKeyword, reqKeyword)
  547. }
  548. reqApplyStatus := this.GetString("ApplyStatus")
  549. if reqApplyStatus != "" {
  550. if reqApplyStatus == "已申请" {
  551. condition += " AND y.apply_record_id > 0"
  552. } else if reqApplyStatus == "未申请" {
  553. condition += " AND y.apply_record_id is null"
  554. }
  555. }
  556. if markGroup != "" {
  557. condition += `AND (y.mark_group = `+"'"+markGroup+"'"+ ` OR a.mark_group = `+"'"+markGroup+"')"
  558. }
  559. startTime := "2022-01-01"
  560. list, err := yb.GetApplyRecordListV2Export(condition, pars, startTime)
  561. if err != nil {
  562. br.Msg = "获取失败"
  563. br.ErrMsg = "获取失败,Err:" + err.Error()
  564. return
  565. }
  566. mobilesSlice := make([]string, 0)
  567. emailsSlice := make([]string, 0)
  568. userIdsStr := ""
  569. for _, v := range list {
  570. userIdsStr += "," + strconv.Itoa(v.UserId)
  571. if v.Mobile != "" {
  572. mobilesSlice = append(mobilesSlice, v.Mobile)
  573. } else if v.Email != "" {
  574. emailsSlice = append(emailsSlice, v.Email)
  575. }
  576. }
  577. userIdsStr = strings.Trim(userIdsStr, ",")
  578. //统计申请数
  579. userApplyTotalMap := make(map[int]int)
  580. if userIdsStr != "" {
  581. userApplyTotal, err := yb.GetTotalByUserIds(userIdsStr)
  582. if err != nil {
  583. br.Msg = "获取申请数失败!"
  584. br.ErrMsg = "获取申请数失败,Err:" + err.Error()
  585. return
  586. }
  587. for _, v := range userApplyTotal {
  588. userApplyTotalMap[v.UserId] = v.Total
  589. }
  590. }
  591. w := sync.WaitGroup{}
  592. mobileTotalMap := make(map[string]int)
  593. lastTimeMobileMap := make(map[string]time.Time)
  594. w.Add(1)
  595. //统计阅读数
  596. go func() {
  597. defer w.Done()
  598. mobileTotalMap, lastTimeMobileMap = ybService.GetUserViewTotalByMobiles(mobilesSlice)
  599. }()
  600. emailTotalMap := make(map[string]int)
  601. lastTimeEmailMap := make(map[string]time.Time)
  602. w.Add(1)
  603. go func() {
  604. defer w.Done()
  605. emailTotalMap, lastTimeEmailMap = ybService.GetUserViewTotalByEmails(emailsSlice)
  606. }()
  607. w.Wait()
  608. for k, v := range list {
  609. sourceStr := ""
  610. if v.ApplyRecordId > 0 {
  611. if v.SourceAgent == 3 {
  612. sourceStr = "弘则研究"
  613. } else if v.SourceAgent == 1 {
  614. switch v.Source {
  615. case 1:
  616. sourceStr = "我的(小程序)"
  617. case 2:
  618. sourceStr = "活动(小程序)"
  619. case 3:
  620. sourceStr = "图库(小程序)"
  621. case 4:
  622. sourceStr = "研报(小程序)"
  623. case 5:
  624. sourceStr = "问答社区(小程序)"
  625. default:
  626. if v.FromPage != "" {
  627. sourceStr = v.FromPage + "(小程序)"
  628. } else {
  629. sourceStr = "研报(小程序)"
  630. }
  631. }
  632. } else if v.SourceAgent == 2 {
  633. switch v.Source {
  634. case 1:
  635. sourceStr = "我的(PC端)"
  636. case 2:
  637. sourceStr = "活动(PC端)"
  638. case 3:
  639. sourceStr = "图库(PC端)"
  640. case 4:
  641. sourceStr = "研报(PC端)"
  642. case 5:
  643. sourceStr = "问答社区(PC端)"
  644. default:
  645. if v.FromPage != "" {
  646. sourceStr = v.FromPage + "(PC端)"
  647. } else {
  648. sourceStr = "研报(PC端)"
  649. }
  650. }
  651. }
  652. } else if v.RegisterSource != 0 {
  653. switch v.RegisterSource {
  654. case 1:
  655. sourceStr = "弘则研究"
  656. case 2:
  657. sourceStr = "研报(PC端)"
  658. case 5:
  659. sourceStr = "活动(小程序)"
  660. case 6:
  661. sourceStr = "研报(小程序)"
  662. default:
  663. sourceStr = ""
  664. }
  665. }
  666. list[k].SourceStr = sourceStr
  667. // 统计申请数
  668. if applyTotal, ok := userApplyTotalMap[v.UserId]; ok {
  669. list[k].ApplyTotal = applyTotal
  670. }
  671. //统计阅读数
  672. if num, ok := mobileTotalMap[v.Mobile]; ok {
  673. list[k].ViewTotal += num
  674. }
  675. if num, ok := emailTotalMap[v.Email]; ok {
  676. list[k].ViewTotal += num
  677. }
  678. //最新阅读时间
  679. if t, ok := lastTimeMobileMap[v.Mobile]; ok {
  680. if list[k].LastViewTime.Before(t) {
  681. list[k].LastViewTime = t
  682. }
  683. }
  684. if t, ok := lastTimeEmailMap[v.Email]; ok {
  685. if list[k].LastViewTime.Before(t) {
  686. list[k].LastViewTime = t
  687. }
  688. }
  689. list[k].LastViewTimeStr = list[k].LastViewTime.Format(utils.FormatDateTime)
  690. if list[k].LastViewTimeStr == "0001-01-01 00:00:00" {
  691. list[k].LastViewTimeStr = ""
  692. }
  693. list[k].LastTimeStr = list[k].LastTime.Format(utils.FormatDateTime)
  694. if v.Status == "权益用户" {
  695. list[k].Status = "潜在用户"
  696. }
  697. }
  698. dir, err := os.Executable()
  699. exPath := filepath.Dir(dir)
  700. downLoadnFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
  701. xlsxFile := xlsx.NewFile()
  702. if err != nil {
  703. br.Msg = "生成文件失败"
  704. br.ErrMsg = "生成文件失败"
  705. return
  706. }
  707. style := xlsx.NewStyle()
  708. alignment := xlsx.Alignment{
  709. Horizontal: "center",
  710. Vertical: "center",
  711. WrapText: true,
  712. }
  713. style.Alignment = alignment
  714. style.ApplyAlignment = true
  715. sheel, err := xlsxFile.AddSheet("客户数据")
  716. if err != nil {
  717. br.Msg = "新增Sheet失败"
  718. br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
  719. return
  720. }
  721. titleRow := sheel.AddRow()
  722. titleRow.AddCell().SetValue("姓名")
  723. titleRow.AddCell().SetValue("手机号")
  724. titleRow.AddCell().SetValue("邮箱")
  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. for _, v := range list {
  735. dataRow := sheel.AddRow()
  736. dataRow.SetHeight(20)
  737. dataRow.AddCell().SetString(v.RealName)
  738. dataRow.AddCell().SetString(v.Mobile)
  739. dataRow.AddCell().SetString(v.Email)
  740. dataRow.AddCell().SetString(v.LastTimeStr)
  741. dataRow.AddCell().SetString(strconv.Itoa(v.ApplyTotal))
  742. dataRow.AddCell().SetString(v.LastViewTimeStr)
  743. dataRow.AddCell().SetString(strconv.Itoa(v.ViewTotal))
  744. dataRow.AddCell().SetString(v.CompanyName)
  745. dataRow.AddCell().SetString(v.OriginSellerName)
  746. dataRow.AddCell().SetString(v.SourceStr)
  747. dataRow.AddCell().SetString(v.ApplyStatus)
  748. dataRow.AddCell().SetString(v.Status)
  749. }
  750. err = xlsxFile.Save(downLoadnFilePath)
  751. if err != nil {
  752. br.Msg = "保存文件失败"
  753. br.ErrMsg = "保存文件失败"
  754. return
  755. }
  756. randStr := time.Now().Format(utils.FormatDateTimeUnSpace)
  757. downloadFileName := "用户申请列表_" + randStr + ".xlsx"
  758. this.Ctx.Output.Download(downLoadnFilePath, downloadFileName)
  759. defer func() {
  760. _ = os.Remove(downLoadnFilePath)
  761. }()
  762. br.Ret = 200
  763. br.Success = true
  764. br.Msg = "导出成功"
  765. }
  766. // DelPotentialUser
  767. // @Title 删除潜在用户账号和申请记录
  768. // @Description 删除潜在用户账号和申请记录
  769. // @Param request body company.DeleteUserReq true "type json string"
  770. // @Success 200 {object} 删除成功
  771. // @router /potential/user/del [post]
  772. func (this *ApplyRecordController) DelPotentialUser() {
  773. br := new(models.BaseResponse).Init()
  774. defer func() {
  775. this.Data["json"] = br
  776. this.ServeJSON()
  777. }()
  778. sysUser := this.SysUser
  779. if sysUser == nil {
  780. br.Msg = "请登录"
  781. br.ErrMsg = "请登录,SysUser Is Empty"
  782. br.Ret = 408
  783. return
  784. }
  785. var req company.DeleteUserReq
  786. err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
  787. if err != nil {
  788. br.Msg = "参数解析异常!"
  789. br.ErrMsg = "参数解析失败,Err:" + err.Error()
  790. return
  791. }
  792. if req.UserId <= 0 {
  793. br.Msg = "请输入正确的用户ID"
  794. return
  795. }
  796. //获取联系人详情
  797. userInfo, err := models.GetWxUserByUserId(req.UserId)
  798. if err != nil {
  799. br.Msg = "获取联系人异常!"
  800. br.ErrMsg = "获取联系人异常,Err:" + err.Error()
  801. return
  802. }
  803. if userInfo.CompanyId != 1 {
  804. br.Msg = "该联系人已绑定客户,不允许删除!"
  805. return
  806. }
  807. //操作权限校验, 超管和ficc管理员有删除权限
  808. if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_FICC_ADMIN && sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_ADMIN {
  809. br.Msg = "没有操作权限"
  810. return
  811. }
  812. //如果不是超管权限,那么删除的时候,需要获取下联系人归属销售信息
  813. //产品权限
  814. productId := services.GetProductId(sysUser.RoleTypeCode)
  815. //联系人与销售的关系
  816. userSellerRelationList, err := models.GetUserSellerRelationList(int(userInfo.UserId))
  817. if err != nil {
  818. br.Msg = "获取联系人关系失败"
  819. br.ErrMsg = "获取联系人关系失败,Err:" + err.Error()
  820. return
  821. }
  822. userSellerRelationInfo, _ := json.Marshal(userSellerRelationList)
  823. //删除所有的标识,并真正删除数据
  824. _ = models.DeleteUserSellerRelationByUserId(req.UserId)
  825. //真正删除用户
  826. err = services.DeleteWxUser(req.UserId)
  827. if err != nil {
  828. br.Msg = "删除失败!"
  829. br.ErrMsg = "删除失败,Err:" + err.Error()
  830. return
  831. }
  832. if len(userSellerRelationList) > 0 && productId != 0 {
  833. content := fmt.Sprint("联系人:", userInfo.RealName, "被删除")
  834. if userSellerRelationList[0].CompanyId != 1 {
  835. companyInfo, tErr := company.GetCompanyById(userSellerRelationList[0].CompanyId)
  836. if tErr != nil {
  837. if tErr.Error() != utils.ErrNoRow() {
  838. br.Msg = "获取客户信息失败"
  839. br.ErrMsg = "获取客户信息失败,Err:" + tErr.Error()
  840. return
  841. }
  842. } else {
  843. content = fmt.Sprint(companyInfo.CompanyName, ":", content)
  844. for _, userRelation := range userSellerRelationList {
  845. if userRelation.ProductId != productId {
  846. go services.AddCompanyMessage(sysUser.AdminId, userRelation.SellerId, userRelation.CompanyId, 0, 1, companyInfo.CompanyName, content, content)
  847. }
  848. }
  849. }
  850. }
  851. }
  852. //联系人信息
  853. originalUserInfo, _ := json.Marshal(userInfo)
  854. go services.AddWxUserOpLog(company.WxUserOpLog{
  855. LogType: "delete",
  856. UserId: int(userInfo.UserId),
  857. CompanyId: userInfo.CompanyId,
  858. Mobile: userInfo.Mobile,
  859. Email: userInfo.Email,
  860. OriginalUserInfo: string(originalUserInfo),
  861. UserInfo: "",
  862. OriginalUserSellerInfo: string(userSellerRelationInfo),
  863. UserSellerInfo: "",
  864. OpUserId: sysUser.AdminId,
  865. OpUserName: sysUser.RealName,
  866. CreateTime: time.Now(),
  867. })
  868. // 若该联系人为弘则研究公司下的,则同步禁用手机号关联的系统管理员
  869. if userInfo.CompanyId == 16 {
  870. go services.ForbiddenSysUserByMobile(userInfo.Mobile)
  871. }
  872. // 删除用户的申请记录
  873. go ybService.DeleteApplyUser(userInfo.UserId)
  874. br.Ret = 200
  875. br.Success = true
  876. br.Msg = "删除成功"
  877. br.IsAddLog = true
  878. return
  879. }
  880. // MarkGroup
  881. // @Title 标记分组
  882. // @Description 标记分组
  883. // @Param request body request.ApplyMarkReq true "type json string"
  884. // @Success 200 {object} 标记处理成功
  885. // @router /apply_record/mark_group [post]
  886. func (this *ApplyRecordController) MarkGroup() {
  887. br := new(models.BaseResponse).Init()
  888. defer func() {
  889. this.Data["json"] = br
  890. this.ServeJSON()
  891. }()
  892. sysUser := this.SysUser
  893. if sysUser == nil {
  894. br.Msg = "请登录"
  895. br.ErrMsg = "请登录,SysUser is Empty"
  896. br.Ret = 408
  897. return
  898. }
  899. var req request.ApplyMarkGroupReq
  900. err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
  901. if err != nil {
  902. br.Msg = "参数解析异常"
  903. br.ErrMsg = "参数解析失败,Err:" + err.Error()
  904. return
  905. }
  906. if req.GroupName == "" || req.UserId == 0 {
  907. br.Msg = "申请记录ID或者分组名异常"
  908. br.ErrMsg = "申请记录ID或者分组名异常"
  909. return
  910. }
  911. // 标记处理
  912. err = ybService.MarkGroupApplyRecord(req.ApplyRecordId, this.SysUser.AdminId, req.UserId, req.GroupName)
  913. if err != nil {
  914. br.Msg = "标记处理失败! "
  915. br.ErrMsg = "标记处理失败,Err:" + err.Error()
  916. return
  917. }
  918. br.Ret = 200
  919. br.Success = true
  920. br.Msg = "标记处理成功"
  921. }