apply_record.go 27 KB

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