report.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. package home
  2. import (
  3. "context"
  4. contDao "dashoo.cn/micro/app/dao/contract"
  5. projDao "dashoo.cn/micro/app/dao/proj"
  6. "dashoo.cn/micro/app/model/home"
  7. "dashoo.cn/micro/app/model/plat"
  8. "dashoo.cn/micro/app/service"
  9. contractService "dashoo.cn/micro/app/service/contract"
  10. platService "dashoo.cn/micro/app/service/plat"
  11. projSrv "dashoo.cn/micro/app/service/proj"
  12. "dashoo.cn/opms_libary/micro_srv"
  13. "dashoo.cn/opms_libary/myerrors"
  14. "database/sql"
  15. "fmt"
  16. "github.com/gogf/gf/database/gdb"
  17. "github.com/gogf/gf/os/gtime"
  18. "github.com/gogf/gf/util/gconv"
  19. "math"
  20. "time"
  21. )
  22. // getPersonalContractReportData 获取个人数据
  23. // dataType:collection为回款;其他为合同
  24. func getPersonalContractReportData(ctx context.Context, dataType string, params *map[string]interface{}) (*home.ReportData, error) {
  25. var reportData home.ReportData
  26. targetMap := make(map[int]gdb.Record, 0)
  27. realMap := make(map[int][]*gdb.Record, 0)
  28. targetField := "sales_target"
  29. realField := "contract_amount"
  30. year := gtime.Now().Format("Y")
  31. if params != nil && (*params)["year"] != nil {
  32. year = gconv.String((*params)["year"])
  33. }
  34. // 统计字段
  35. if dataType == "COLLECTION" {
  36. targetField = "collection_target"
  37. realField = "collection_amount"
  38. }
  39. srv, err := contractService.NewCtrContractService(ctx)
  40. if err != nil {
  41. return nil, err
  42. }
  43. // 获取用户信息
  44. userInfo, err := micro_srv.GetUserInfo(ctx)
  45. if err != nil {
  46. return nil, fmt.Errorf("获取用户信息异常:%s", err.Error())
  47. }
  48. targets, err := srv.Dao.DB.Model("rpt_sales_target").Where("sale_user_id", userInfo.Id).Order("monthly ASC").FindAll()
  49. if err != nil && err != sql.ErrNoRows {
  50. return nil, err
  51. }
  52. for index, target := range targets {
  53. targetMap[target["monthly"].Int()] = targets[index]
  54. }
  55. // 统计12个月份的数据
  56. // 统计目标值
  57. for index := 1; index <= 12; index++ {
  58. reportData.XData = append(reportData.XData, fmt.Sprintf("%v月", index))
  59. if target, ok := targetMap[index]; ok {
  60. reportData.YDataTarget = append(reportData.YDataTarget, target[targetField].Float64())
  61. } else {
  62. reportData.YDataTarget = append(reportData.YDataTarget, 0)
  63. }
  64. }
  65. // 统计合同值
  66. contractModel := srv.Dao.DB.Model("ctr_contract").Where("ctr_contract.incharge_id", userInfo.Id)
  67. if dataType != "COLLECTION" {
  68. contracts, err := contractModel.Where("ctr_contract.contract_start_time LIKE ?", year+"-%").Order("ctr_contract.contract_start_time ASC").FindAll()
  69. if err != nil && err != sql.ErrNoRows {
  70. return nil, err
  71. }
  72. for index, contract := range contracts {
  73. realMap[contract["contract_start_time"].GTime().Month()] = append(realMap[contract["contract_start_time"].GTime().Month()], &contracts[index])
  74. }
  75. } else {
  76. // 回款数据统计
  77. collections, err := contractModel.InnerJoin("ctr_contract_collection", "ctr_contract.id=ctr_contract_collection.contract_id").Where("ctr_contract_collection.appro_status", "20").Where("ctr_contract_collection.collection_datetime LIKE ?", year+"-%").Order("ctr_contract_collection.collection_datetime ASC").Fields("ctr_contract_collection.*").FindAll()
  78. if err != nil && err != sql.ErrNoRows {
  79. return nil, err
  80. }
  81. for index, collection := range collections {
  82. realMap[collection["collection_datetime"].GTime().Month()] = append(realMap[collection["collection_datetime"].GTime().Month()], &collections[index])
  83. }
  84. }
  85. // 统计12个月份的数据
  86. // 统计实际值
  87. for index := 1; index <= 12; index++ {
  88. if realData, ok := realMap[index]; ok {
  89. realAmount := float64(0)
  90. for _, data := range realData {
  91. realAmount += (*data)[realField].Float64()
  92. }
  93. reportData.YDataReal = append(reportData.YDataReal, realAmount)
  94. } else {
  95. reportData.YDataReal = append(reportData.YDataReal, 0)
  96. }
  97. if reportData.YDataTarget[index-1] == 0 {
  98. reportData.PercentData = append(reportData.PercentData, 0)
  99. } else {
  100. reportData.PercentData = append(reportData.PercentData, reportData.YDataReal[index-1]*100/reportData.YDataTarget[index-1])
  101. }
  102. }
  103. return &reportData, nil
  104. }
  105. // getCompanyContractReportData 获取总部数据
  106. // dataType:collection为回款;其他为合同
  107. func getCompanyContractReportData(ctx context.Context, dataType string, params *map[string]interface{}) (*home.ReportData, error) {
  108. var reportData home.ReportData
  109. realMap := make(map[int]gdb.Record, 0)
  110. targetField := "sales_target"
  111. realField := "contract_amount"
  112. dateWhere1 := "" // 查询条件
  113. dateWhere2 := "" // 查询条件
  114. dateWhere3 := ""
  115. date := gtime.Now()
  116. if params != nil && (*params)["date"] != nil {
  117. date = gconv.GTime((*params)["date"])
  118. }
  119. dateWhere1 = fmt.Sprintf("ctr_contract.contract_start_time LIKE '%v'", date.Format("Y")+"-%")
  120. dateWhere2 = fmt.Sprintf("ctr_contract_collection.collection_datetime LIKE '%v'", date.Format("Y")+"-%")
  121. if params != nil && (*params)["searchType"] != nil {
  122. searchType := gconv.String((*params)["searchType"])
  123. if searchType == "month" {
  124. dateWhere1 = fmt.Sprintf("ctr_contract.contract_start_time LIKE '%v'", date.Format("Y-m")+"-%")
  125. dateWhere2 = fmt.Sprintf("ctr_contract_collection.collection_datetime LIKE '%v'", date.Format("Y-m")+"-%")
  126. dateWhere3 = fmt.Sprintf("monthly=%v", date.Month())
  127. } else if searchType == "quarter" {
  128. dateWhere1 = getQuarterWhere(date, "ctr_contract.contract_start_time")
  129. dateWhere2 = getQuarterWhere(date, "ctr_contract_collection.collection_datetime")
  130. dateWhere3 = getQuarterMonthWhere(date, "monthly")
  131. }
  132. }
  133. // 统计字段
  134. if dataType == "COLLECTION" {
  135. targetField = "collection_target"
  136. realField = "collection_amount"
  137. }
  138. srv, err := contractService.NewCtrContractService(ctx)
  139. if err != nil {
  140. return nil, err
  141. }
  142. targets, err := srv.Dao.DB.Model("rpt_sales_target").Where(dateWhere3).Order("sale_user_id ASC").Group("sale_user_id").Fields(fmt.Sprintf("sale_user_id, sale_user_name, SUM(%v) %v", targetField, targetField)).FindAll()
  143. if err != nil && err != sql.ErrNoRows {
  144. return nil, err
  145. }
  146. // 统计合同值
  147. contractModel := srv.Dao.DB.Model("ctr_contract").Group("ctr_contract.incharge_id").Order("ctr_contract.incharge_id ASC")
  148. if dataType != "COLLECTION" {
  149. contracts, err := contractModel.Where(dateWhere1).Fields("ctr_contract.incharge_id, ctr_contract.incharge_name, count(ctr_contract.contract_amount) contract_amount").FindAll()
  150. if err != nil && err != sql.ErrNoRows {
  151. return nil, err
  152. }
  153. for index, contract := range contracts {
  154. realMap[contract["incharge_id"].Int()] = contracts[index]
  155. }
  156. } else {
  157. // 回款数据统计
  158. collections, err := contractModel.InnerJoin("ctr_contract_collection", "ctr_contract.id=ctr_contract_collection.contract_id").Where("ctr_contract_collection.appro_status", "20").Where(dateWhere2).Fields("ctr_contract.incharge_id, ctr_contract.incharge_name, SUM(ctr_contract_collection.collection_amount) collection_amount").FindAll()
  159. if err != nil && err != sql.ErrNoRows {
  160. return nil, err
  161. }
  162. for index, collection := range collections {
  163. realMap[collection["incharge_id"].Int()] = collections[index]
  164. }
  165. }
  166. // 统计目标值和实际值
  167. for index, target := range targets {
  168. reportData.XData = append(reportData.XData, target["sale_user_name"].String())
  169. reportData.YDataTarget = append(reportData.YDataTarget, target[targetField].Float64())
  170. if realData, ok := realMap[target["sale_user_id"].Int()]; ok {
  171. reportData.YDataReal = append(reportData.YDataReal, realData[realField].Float64())
  172. } else {
  173. reportData.YDataReal = append(reportData.YDataReal, 0)
  174. }
  175. if reportData.YDataTarget[index] == 0 {
  176. reportData.PercentData = append(reportData.PercentData, 0)
  177. } else {
  178. reportData.PercentData = append(reportData.PercentData, reportData.YDataReal[index]*100/reportData.YDataTarget[index])
  179. }
  180. }
  181. return &reportData, nil
  182. }
  183. func getQuarterGoalReportData(ctx context.Context, dataType string, params *map[string]interface{}) (*home.ReportData, error) {
  184. if params == nil {
  185. return nil, fmt.Errorf("请输入年度")
  186. }
  187. p := *params
  188. year := gconv.Int(p["year"])
  189. quarter := gconv.Int(p["quarter"])
  190. if year == 0 {
  191. return nil, fmt.Errorf("请输入年度")
  192. }
  193. srv, err := contractService.NewCtrContractService(ctx)
  194. if err != nil {
  195. return nil, err
  196. }
  197. goal := map[string]float64{}
  198. goaldao := srv.GoalDao.Where("year = ?", year).Where("goal_type = ?", dataType)
  199. if quarter != 0 {
  200. goaldao = goaldao.Where("quarter = ?", quarter)
  201. } else {
  202. goaldao = goaldao.Where("quarter = 1 || quarter = 2 || quarter = 3 || quarter = 4")
  203. }
  204. goalent, err := goaldao.All()
  205. if err != nil {
  206. return nil, err
  207. }
  208. for _, ent := range goalent {
  209. goal[ent.ProductLine] += ent.Amount
  210. }
  211. got := map[string]float64{}
  212. ctrdao := srv.Dao.Where("year(created_time) = ?", year)
  213. if quarter != 0 {
  214. if quarter == 1 {
  215. ctrdao = ctrdao.Where("month(created_time) in (1,2,3)")
  216. }
  217. if quarter == 2 {
  218. ctrdao = ctrdao.Where("month(created_time) in (4,5,6)")
  219. }
  220. if quarter == 3 {
  221. ctrdao = ctrdao.Where("month(created_time) in (7,8,9)")
  222. }
  223. if quarter == 4 {
  224. ctrdao = ctrdao.Where("month(created_time) in (10,11,12)")
  225. }
  226. }
  227. ctrent, err := ctrdao.All()
  228. if err != nil {
  229. return nil, err
  230. }
  231. for _, ent := range ctrent {
  232. if dataType == "10" {
  233. got[ent.ProductLine] += ent.ContractAmount
  234. }
  235. if dataType == "20" {
  236. got[ent.ProductLine] += ent.CollectedAmount
  237. }
  238. }
  239. productLine, err := service.GetDictDataByType(ctx, "sys_product_line")
  240. if err != nil {
  241. return nil, err
  242. }
  243. productLineCode := []string{}
  244. productLineName := []string{}
  245. for k, v := range productLine {
  246. productLineCode = append(productLineCode, k)
  247. productLineName = append(productLineName, v)
  248. }
  249. var reportData home.ReportData
  250. for _, c := range productLineCode {
  251. reportData.XData = append(reportData.XData, productLine[c])
  252. reportData.YDataTarget = append(reportData.YDataTarget, goal[c])
  253. reportData.YDataReal = append(reportData.YDataReal, got[c]/10000)
  254. }
  255. return &reportData, nil
  256. }
  257. // 客户现场打卡频次
  258. func getClockfrequency(ctx context.Context, dataType string, params *map[string]interface{}) (*home.ReportData, error) {
  259. var reportData home.ReportData
  260. realMap := make(map[int]gdb.Record, 0)
  261. dateWhere1 := "" // 查询条件
  262. date := gtime.Now()
  263. nowTime := gtime.Datetime()
  264. if params != nil && (*params)["date"] != nil {
  265. date = gconv.GTime((*params)["date"])
  266. }
  267. if params != nil && (*params)["searchType"] != nil {
  268. searchType := gconv.String((*params)["searchType"])
  269. if searchType == "month" {
  270. dateWhere1 = fmt.Sprintf("plat_punch_records.punch_time LIKE '%v'", date.Format("Y-m")+"-%")
  271. } else if searchType == "week" {
  272. weekday := transferWeekday(date.Weekday())
  273. fmt.Println(weekday)
  274. beforeTime := gtime.NewFromStr(nowTime).AddDate(0, 0, -gconv.Int(weekday)).String()
  275. endTime := gtime.NewFromStr(nowTime).AddDate(0, 0, 7-gconv.Int(weekday)).String()
  276. dateWhere1 = fmt.Sprintf("plat_punch_records.punch_time between '%v' and '%v'", beforeTime, endTime)
  277. }
  278. }
  279. srv, err := platService.NewPunchRecordsService(ctx)
  280. if err != nil {
  281. return nil, err
  282. }
  283. platpunchrecords, err := srv.Dao.DB.Model("plat_punch_records").Where(dateWhere1).Fields("plat_punch_records.user_nick_name,Count(plat_punch_records.user_nick_name) as punch_sum").Group("plat_punch_records.user_nick_name").FindAll()
  284. if err != nil && err != sql.ErrNoRows {
  285. return nil, err
  286. }
  287. // 赋值实际值
  288. for index, target := range platpunchrecords {
  289. reportData.XData = append(reportData.XData, target["user_nick_name"].String())
  290. reportData.YDataTarget = append(reportData.YDataTarget, target["punch_sum"].Float64())
  291. if realData, ok := realMap[target["punch_sum"].Int()]; ok {
  292. reportData.YDataReal = append(reportData.YDataReal, realData["punch_sum"].Float64())
  293. } else {
  294. reportData.YDataReal = append(reportData.YDataReal, 0)
  295. }
  296. if reportData.YDataTarget[index] == 0 {
  297. reportData.PercentData = append(reportData.PercentData, 0)
  298. } else {
  299. reportData.PercentData = append(reportData.PercentData, reportData.YDataReal[index]*100/reportData.YDataTarget[index])
  300. }
  301. }
  302. return &reportData, nil
  303. }
  304. // 销售工程师跟进记录的打卡频次
  305. func getFollowUpRecord(ctx context.Context, dataType string, params *map[string]interface{}) ([]plat.Statistics, error) {
  306. now := time.Now()
  307. date := gconv.Int(gtime.Now().Month())
  308. if params != nil && (*params)["date"] != nil {
  309. date = gconv.Int((*params)["date"])
  310. }
  311. // 获取本月的第一天
  312. firstOfMonth := time.Date(now.Year(), time.Month(date), 1, 0, 0, 0, 0, now.Location())
  313. // 获取本月的最后一天
  314. lastOfMonth := firstOfMonth.AddDate(0, 1, -1)
  315. l, _ := time.LoadLocation("Asia/Shanghai")
  316. startTime, _ := time.ParseInLocation("2006-01-02", firstOfMonth.Format("2006-01-02"), l)
  317. endTime, _ := time.ParseInLocation("2006-01-02", lastOfMonth.Format("2006-01-02"), l)
  318. datas := GroupByWeekDate(startTime, endTime)
  319. var Follows []plat.Followlist
  320. srv, err := platService.NewFollowupService(ctx)
  321. if err != nil {
  322. return nil, err
  323. }
  324. var stats []plat.Statistics
  325. for _, d := range datas {
  326. err = srv.Dao.DB.Model("plat_followup").
  327. Where("follow_date>=? and follow_date<=?", d.StartTime.Format("2006-01-02"), d.EndTime.Format("2006-01-02")).Fields("count(follow_type)as num ,follow_type").
  328. Group("date_format(follow_date,'%v'),follow_type").Scan(&Follows)
  329. if err != nil && err != sql.ErrNoRows {
  330. return nil, err
  331. }
  332. if len(Follows) > 0 {
  333. var stat plat.Statistics
  334. for _, val := range Follows {
  335. if val.FollowType == "10" {
  336. stat.Phone = gconv.Int(val.Num)
  337. } else if val.FollowType == "20" {
  338. stat.Mail = gconv.Int(val.Num)
  339. } else if val.FollowType == "30" {
  340. stat.PayVisit = gconv.Int(val.Num)
  341. }
  342. }
  343. stat.Total = stat.Phone + stat.Mail + stat.PayVisit
  344. stat.Week = d.WeekTh + "周"
  345. stats = append(stats, stat)
  346. }
  347. }
  348. return stats, nil
  349. }
  350. func getQuarterWhere(date *gtime.Time, field string) string {
  351. if date.Month() >= 1 && date.Month() <= 3 {
  352. return fmt.Sprintf("%v >= '%v' AND %v < '%v'", field, date.Format("Y-")+"01-01 00:00:00", field, date.Format("Y-")+"04-01 00:00:00")
  353. } else if date.Month() >= 4 && date.Month() <= 6 {
  354. return fmt.Sprintf("%v >= '%v' AND %v < '%v'", field, date.Format("Y-")+"04-01 00:00:00", field, date.Format("Y-")+"07-01 00:00:00")
  355. } else if date.Month() >= 7 && date.Month() <= 9 {
  356. return fmt.Sprintf("%v >= '%v' AND %v < '%v'", field, date.Format("Y-")+"07-01 00:00:00", field, date.Format("Y-")+"10-01 00:00:00")
  357. } else if date.Month() >= 10 && date.Month() <= 12 {
  358. return fmt.Sprintf("%v >= '%v' AND %v <= '%v'", field, date.Format("Y-")+"10-01 00:00:00", field, date.Format("Y-")+"12-31 23:59:59")
  359. }
  360. return ""
  361. }
  362. func getQuarterMonthWhere(date *gtime.Time, field string) string {
  363. if date.Month() >= 1 && date.Month() <= 3 {
  364. return fmt.Sprintf("%v >= %v AND %v < %v", field, 1, field, 4)
  365. } else if date.Month() >= 4 && date.Month() <= 6 {
  366. return fmt.Sprintf("%v >= %v AND %v < %v", field, 4, field, 7)
  367. } else if date.Month() >= 7 && date.Month() <= 9 {
  368. return fmt.Sprintf("%v >= %v AND %v < %v", field, 7, field, 10)
  369. } else if date.Month() >= 10 && date.Month() <= 12 {
  370. return fmt.Sprintf("%v >= %v AND %v <= %v", field, 10, field, 12)
  371. }
  372. return ""
  373. }
  374. func transferWeekday(day time.Weekday) string {
  375. switch day {
  376. case time.Monday:
  377. return "1"
  378. case time.Tuesday:
  379. return "2"
  380. case time.Wednesday:
  381. return "3"
  382. case time.Thursday:
  383. return "4"
  384. case time.Friday:
  385. return "5"
  386. case time.Saturday:
  387. return "6"
  388. case time.Sunday:
  389. return "7"
  390. default:
  391. return ""
  392. }
  393. }
  394. // 判断时间是当年的第几周
  395. func WeekByDate(t time.Time) string {
  396. yearDay := t.YearDay()
  397. yearFirstDay := t.AddDate(0, 0, -yearDay+1)
  398. firstDayInWeek := int(yearFirstDay.Weekday())
  399. //今年第一周有几天
  400. firstWeekDays := 1
  401. if firstDayInWeek != 0 {
  402. firstWeekDays = 7 - firstDayInWeek + 1
  403. }
  404. var week int
  405. Weeks := WeekByDates(t)
  406. if yearDay <= firstWeekDays {
  407. week = 1
  408. } else {
  409. week = (yearDay-firstWeekDays)/7 + 2
  410. }
  411. return fmt.Sprintf("%d", week-gconv.Int(Weeks)+1)
  412. }
  413. func WeekByDates(now time.Time) int {
  414. l, _ := time.LoadLocation("Asia/Shanghai")
  415. // 获取本月的第一天
  416. firstOfMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
  417. endTime, _ := time.ParseInLocation("2006-01-02", firstOfMonth.Format("2006-01-02"), l)
  418. t := endTime
  419. yearDay := t.YearDay()
  420. yearFirstDay := t.AddDate(0, 0, -yearDay+1)
  421. firstDayInWeek := int(yearFirstDay.Weekday())
  422. //今年第一周有几天
  423. firstWeekDays := 1
  424. if firstDayInWeek != 0 {
  425. firstWeekDays = 7 - firstDayInWeek + 1
  426. }
  427. var week int
  428. if yearDay <= firstWeekDays {
  429. week = 1
  430. } else {
  431. week = (yearDay-firstWeekDays)/7 + 2
  432. }
  433. return week
  434. }
  435. // 将开始时间和结束时间分割为周为单位
  436. func GroupByWeekDate(startTime, endTime time.Time) []plat.WeekDate {
  437. weekDate := make([]plat.WeekDate, 0)
  438. diffDuration := endTime.Sub(startTime)
  439. days := int(math.Ceil(float64(diffDuration/(time.Hour*24)))) + 1
  440. currentWeekDate := plat.WeekDate{}
  441. currentWeekDate.WeekTh = WeekByDate(endTime)
  442. currentWeekDate.EndTime = endTime
  443. currentWeekDay := int(endTime.Weekday())
  444. if currentWeekDay == 0 {
  445. currentWeekDay = 7
  446. }
  447. currentWeekDate.StartTime = endTime.AddDate(0, 0, -currentWeekDay+1)
  448. nextWeekEndTime := currentWeekDate.StartTime
  449. weekDate = append(weekDate, currentWeekDate)
  450. for i := 0; i < (days-currentWeekDay)/7; i++ {
  451. weekData := plat.WeekDate{}
  452. weekData.EndTime = nextWeekEndTime
  453. weekData.StartTime = nextWeekEndTime.AddDate(0, 0, -7)
  454. weekData.WeekTh = WeekByDate(weekData.StartTime)
  455. nextWeekEndTime = weekData.StartTime
  456. weekDate = append(weekDate, weekData)
  457. }
  458. if lastDays := (days - currentWeekDay) % 7; lastDays > 0 {
  459. lastData := plat.WeekDate{}
  460. lastData.EndTime = nextWeekEndTime
  461. lastData.StartTime = nextWeekEndTime.AddDate(0, 0, -lastDays)
  462. lastData.WeekTh = WeekByDate(lastData.StartTime)
  463. weekDate = append(weekDate, lastData)
  464. }
  465. return weekDate
  466. }
  467. type BusCount struct {
  468. NboType string `json:"nboType"`
  469. ProductLine string `json:"productLine"`
  470. Count int `json:"count"`
  471. Remark string `json:"remark"`
  472. }
  473. // 报表数据 三大产品线,新增以及转化项目(C转B、B转A、A转签约、C转A、C转签约、B转签约、储备转A/B/C/签约)数量, 按周和月
  474. // params 10:周 20:月
  475. func (s *HomeService) getNewAndConvertBusiness(productLine []string, params *map[string]interface{}) (interface{}, error) {
  476. if params == nil {
  477. return nil, myerrors.TipsError("请求参数传递不正确")
  478. }
  479. searchType, ok := (*params)["searchType"]
  480. if !ok {
  481. return nil, myerrors.TipsError("请求查询类型参数传递错误")
  482. }
  483. currentTime := gtime.Now()
  484. weekStart, weekEnd := currentTime.StartOfWeek(), currentTime.EndOfWeek()
  485. monthStart, monthEnd := currentTime.StartOfMonth(), currentTime.EndOfMonth()
  486. businessDao := projDao.NewProjBusinessDao(s.Tenant)
  487. busDynamicsDao := projDao.NewProjBusinessDynamicsDao(s.Tenant)
  488. contractDao := contDao.NewCtrContractDao(s.Tenant)
  489. // 获取三大产品线新增项目
  490. getAddBusCount := func(searchType string) (addCount []BusCount, err error) {
  491. commonDb := businessDao.DataScope(s.Ctx, "sale_id").Group(businessDao.C.ProductLine).OrderAsc(businessDao.C.ProductLine).
  492. Fields("product_line, count(id) as count")
  493. if searchType == "week" {
  494. err = commonDb.WhereGTE(businessDao.C.FilingTime, weekStart).WhereLTE(businessDao.C.FilingTime, weekEnd).Scan(&addCount)
  495. }
  496. if searchType == "month" {
  497. err = commonDb.WhereGTE(businessDao.C.FilingTime, monthStart).WhereLTE(businessDao.C.FilingTime, monthEnd).Scan(&addCount)
  498. }
  499. return addCount, err
  500. }
  501. addCount, err := getAddBusCount(searchType.(string))
  502. if err != nil {
  503. return nil, err
  504. }
  505. // 获取三大产品线签约项目
  506. getSignBusCount := func(searchType string) (signCount []BusCount, err error) {
  507. commonDb := contractDao.As("contract").DataScope(s.Ctx, "incharge_id").LeftJoin(businessDao.Table, "bus", "bus.id=contract.nbo_id").
  508. Fields("bus.product_line, bus.nbo_type, count(contract.id) as count").
  509. Group("bus.product_line, bus.nbo_type").Order("bus.product_line ASC, bus.nbo_type ASC")
  510. if searchType == "week" {
  511. err = commonDb.WhereGTE("contract."+contractDao.C.CreatedTime, weekStart).WhereLTE("contract."+contractDao.C.CreatedTime, weekEnd).Scan(&signCount)
  512. }
  513. if searchType == "month" {
  514. err = commonDb.WhereGTE("contract."+contractDao.C.CreatedTime, monthStart).WhereLTE("contract."+contractDao.C.CreatedTime, monthEnd).Scan(&signCount)
  515. }
  516. return signCount, err
  517. }
  518. signCount, err := getSignBusCount(searchType.(string))
  519. if err != nil {
  520. return nil, err
  521. }
  522. // 获取三大产品线转化项目(C转B、B转A、A转签约、C转A、C转签约、B转签约、储备转A/B/C/签约)数量
  523. getConvertBusData := func(searchType string) (convertData []BusCount, err error) {
  524. commonDb := busDynamicsDao.As("dy").LeftJoin(businessDao.Table, "bus", "bus.id=dy.bus_id").DataScope(s.Ctx, "sale_id", "bus").
  525. Where("dy."+busDynamicsDao.C.OpnType, projSrv.OpnUpgradeApproval).WhereNot("dy."+busDynamicsDao.C.Remark, "").
  526. Fields("bus.product_line, dy.remark").OrderAsc("bus.product_line")
  527. if searchType == "week" {
  528. err = commonDb.WhereGTE("dy."+busDynamicsDao.C.CreatedTime, weekStart).WhereLTE("dy."+busDynamicsDao.C.CreatedTime, weekEnd).Scan(&convertData)
  529. }
  530. if searchType == "month" {
  531. err = commonDb.WhereGTE("dy."+busDynamicsDao.C.CreatedTime, monthStart).WhereLTE("dy."+busDynamicsDao.C.CreatedTime, monthEnd).Scan(&convertData)
  532. }
  533. return convertData, err
  534. }
  535. convertBusData, err := getConvertBusData(searchType.(string))
  536. if err != nil {
  537. return nil, err
  538. }
  539. // 处理数据
  540. result := make([][]int, len(productLine))
  541. for i, pl := range productLine {
  542. result[i] = make([]int, 8)
  543. for _, item := range addCount {
  544. if item.ProductLine == pl {
  545. result[i][0] = item.Count
  546. }
  547. }
  548. for _, item := range signCount {
  549. if item.ProductLine != pl {
  550. continue
  551. }
  552. switch item.NboType {
  553. case projSrv.StatusA:
  554. result[i][3] += item.Count
  555. case projSrv.StatusB:
  556. result[i][6] += item.Count
  557. case projSrv.StatusC:
  558. result[i][5] += item.Count
  559. case projSrv.StatusReserve:
  560. result[i][7] += item.Count
  561. }
  562. }
  563. for _, item := range convertBusData {
  564. if item.ProductLine != pl {
  565. continue
  566. }
  567. info := gconv.Map(item.Remark)
  568. if info["origNboType"] == projSrv.StatusC && info["nboType"] == projSrv.StatusB {
  569. result[i][1] += 1
  570. }
  571. if info["origNboType"] == projSrv.StatusB && info["nboType"] == projSrv.StatusA {
  572. result[i][2] += 1
  573. }
  574. if info["origNboType"] == projSrv.StatusC && info["nboType"] == projSrv.StatusA {
  575. result[i][4] += 1
  576. }
  577. if info["origNboType"] == projSrv.StatusReserve {
  578. result[i][7] += 1
  579. }
  580. }
  581. }
  582. return result, nil
  583. }
  584. // 报表数据 三大产品线,AB类项目出货金额
  585. func (s *HomeService) getShipmentAmount(productLine, nboType []string) (interface{}, error) {
  586. businessDao := projDao.NewProjBusinessDao(s.Tenant)
  587. data, err := businessDao.Fields("product_line, nbo_type, SUM(est_trans_price) as est_trans_price").
  588. WhereIn("product_line", productLine).WhereIn("nbo_type", nboType).
  589. Group("product_line, nbo_type").Order("product_line ASC, nbo_type ASC").DataScope(s.Ctx, "sale_id").All()
  590. if err != nil {
  591. return nil, err
  592. }
  593. result := make([][]float64, len(productLine))
  594. for i, pl := range productLine {
  595. result[i] = make([]float64, len(nboType))
  596. for j, t := range nboType {
  597. for _, item := range data {
  598. if item.ProductLine == pl && item.NboType == t {
  599. result[i][j] = item.EstTransPrice
  600. }
  601. }
  602. }
  603. }
  604. return arrayReversal(result), nil
  605. }
  606. // 报表数据 三大产品线,当月和累计的签约、回款额
  607. func (s *HomeService) getProductLineSignedAndBackAmount(productLine []string) (interface{}, error) {
  608. currentTime := gtime.Now()
  609. monthStart := currentTime.StartOfMonth()
  610. monthEnd := currentTime.EndOfMonth()
  611. contractDao := contDao.NewCtrContractDao(s.Tenant)
  612. commonDao := contractDao.DataScope(s.Ctx, "incharge_id").WhereIn(contractDao.C.ProductLine, productLine).
  613. Group(contractDao.C.ProductLine).OrderAsc(contractDao.C.ProductLine)
  614. //累计签约合同金额 contract_amount
  615. allContractAmount, err := commonDao.Fields("product_line, SUM(contract_amount) as contract_amount").All()
  616. if err != nil {
  617. return nil, err
  618. }
  619. //累计回款金额 collected_amount
  620. allCollectedAmount, err := commonDao.Fields("product_line, SUM(collected_amount) as collected_amount").All()
  621. if err != nil {
  622. return nil, err
  623. }
  624. //当月签约合同金额(维度:月)
  625. monthContractAmount, err := commonDao.WhereGTE(contractDao.C.ContractStartTime, monthStart).WhereLTE(contractDao.C.ContractStartTime, monthEnd).
  626. Fields("product_line, SUM(contract_amount) as contract_amount").All()
  627. if err != nil {
  628. return nil, err
  629. }
  630. //当月回款金额(维度:月)
  631. monthCollectedAmount, err := commonDao.WhereGTE(contractDao.C.ContractStartTime, monthStart).WhereLTE(contractDao.C.ContractStartTime, monthEnd).
  632. Fields("product_line, SUM(collected_amount) as collected_amount").All()
  633. if err != nil {
  634. return nil, err
  635. }
  636. result := make([][]float64, len(productLine))
  637. for i, pl := range productLine {
  638. result[i] = make([]float64, 4)
  639. for _, item := range monthContractAmount {
  640. if item.ProductLine == pl {
  641. result[i][0] = item.ContractAmount
  642. }
  643. }
  644. for _, item := range allContractAmount {
  645. if item.ProductLine == pl {
  646. result[i][1] = item.ContractAmount
  647. }
  648. }
  649. for _, item := range monthCollectedAmount {
  650. if item.ProductLine == pl {
  651. result[i][2] = item.CollectedAmount
  652. }
  653. }
  654. for _, item := range allCollectedAmount {
  655. if item.ProductLine == pl {
  656. result[i][3] = item.CollectedAmount
  657. }
  658. }
  659. }
  660. return arrayReversal(result), nil
  661. }
  662. // 二维数组反转
  663. func arrayReversal(result [][]float64) [][]float64 {
  664. if len(result) == 0 {
  665. return [][]float64{}
  666. }
  667. data := make([][]float64, len(result[0]))
  668. for k, v := range result {
  669. for m, n := range v {
  670. if k == 0 {
  671. data[m] = make([]float64, len(result))
  672. }
  673. data[m][k] = n
  674. }
  675. }
  676. return data
  677. }