package home import ( "context" "database/sql" "fmt" "math" "time" contDao "dashoo.cn/micro/app/dao/contract" platDao "dashoo.cn/micro/app/dao/plat" projDao "dashoo.cn/micro/app/dao/proj" "dashoo.cn/micro/app/model/home" "dashoo.cn/micro/app/model/plat" "dashoo.cn/micro/app/service" contractService "dashoo.cn/micro/app/service/contract" platService "dashoo.cn/micro/app/service/plat" projSrv "dashoo.cn/micro/app/service/proj" "dashoo.cn/opms_libary/micro_srv" "dashoo.cn/opms_libary/myerrors" "github.com/gogf/gf/database/gdb" "github.com/gogf/gf/frame/g" "github.com/gogf/gf/os/gtime" "github.com/gogf/gf/util/gconv" ) // getPersonalContractReportData 获取个人数据 // dataType:collection为回款;其他为合同 func getPersonalContractReportData(ctx context.Context, dataType string, params *map[string]interface{}) (*home.ReportData, error) { var reportData home.ReportData targetMap := make(map[int]gdb.Record, 0) realMap := make(map[int][]*gdb.Record, 0) targetField := "sales_target" realField := "contract_amount" year := gtime.Now().Format("Y") if params != nil && (*params)["year"] != nil { year = gconv.String((*params)["year"]) } // 统计字段 if dataType == "COLLECTION" { targetField = "collection_target" realField = "collection_amount" } srv, err := contractService.NewCtrContractService(ctx) if err != nil { return nil, err } // 获取用户信息 userInfo, err := micro_srv.GetUserInfo(ctx) if err != nil { return nil, fmt.Errorf("获取用户信息异常:%s", err.Error()) } targets, err := srv.Dao.DB.Model("rpt_sales_target").Where("sale_user_id", userInfo.Id).Order("monthly ASC").FindAll() if err != nil && err != sql.ErrNoRows { return nil, err } for index, target := range targets { targetMap[target["monthly"].Int()] = targets[index] } // 统计12个月份的数据 // 统计目标值 for index := 1; index <= 12; index++ { reportData.XData = append(reportData.XData, fmt.Sprintf("%v月", index)) if target, ok := targetMap[index]; ok { reportData.YDataTarget = append(reportData.YDataTarget, target[targetField].Float64()) } else { reportData.YDataTarget = append(reportData.YDataTarget, 0) } } // 统计合同值 contractModel := srv.Dao.DB.Model("ctr_contract").Where("ctr_contract.incharge_id", userInfo.Id) if dataType != "COLLECTION" { contracts, err := contractModel.Where("ctr_contract.contract_start_time LIKE ?", year+"-%").Order("ctr_contract.contract_start_time ASC").FindAll() if err != nil && err != sql.ErrNoRows { return nil, err } for index, contract := range contracts { realMap[contract["contract_start_time"].GTime().Month()] = append(realMap[contract["contract_start_time"].GTime().Month()], &contracts[index]) } } else { // 回款数据统计 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() if err != nil && err != sql.ErrNoRows { return nil, err } for index, collection := range collections { realMap[collection["collection_datetime"].GTime().Month()] = append(realMap[collection["collection_datetime"].GTime().Month()], &collections[index]) } } // 统计12个月份的数据 // 统计实际值 for index := 1; index <= 12; index++ { if realData, ok := realMap[index]; ok { realAmount := float64(0) for _, data := range realData { realAmount += (*data)[realField].Float64() } reportData.YDataReal = append(reportData.YDataReal, realAmount) } else { reportData.YDataReal = append(reportData.YDataReal, 0) } if reportData.YDataTarget[index-1] == 0 { reportData.PercentData = append(reportData.PercentData, 0) } else { reportData.PercentData = append(reportData.PercentData, reportData.YDataReal[index-1]*100/reportData.YDataTarget[index-1]) } } return &reportData, nil } // getCompanyContractReportData 获取总部数据 // dataType:collection为回款;其他为合同 func getCompanyContractReportData(ctx context.Context, dataType string, params *map[string]interface{}) (*home.ReportData, error) { var reportData home.ReportData realMap := make(map[int]gdb.Record, 0) targetField := "sales_target" realField := "contract_amount" dateWhere1 := "" // 查询条件 dateWhere2 := "" // 查询条件 dateWhere3 := "" date := gtime.Now() if params != nil && (*params)["date"] != nil { date = gconv.GTime((*params)["date"]) } dateWhere1 = fmt.Sprintf("ctr_contract.contract_start_time LIKE '%v'", date.Format("Y")+"-%") dateWhere2 = fmt.Sprintf("ctr_contract_collection.collection_datetime LIKE '%v'", date.Format("Y")+"-%") if params != nil && (*params)["searchType"] != nil { searchType := gconv.String((*params)["searchType"]) if searchType == "month" { dateWhere1 = fmt.Sprintf("ctr_contract.contract_start_time LIKE '%v'", date.Format("Y-m")+"-%") dateWhere2 = fmt.Sprintf("ctr_contract_collection.collection_datetime LIKE '%v'", date.Format("Y-m")+"-%") dateWhere3 = fmt.Sprintf("monthly=%v AND created_time LIKE '%v%%'", date.Month(), date.Format("Y")) } else if searchType == "quarter" { dateWhere1 = getQuarterWhere(date, "ctr_contract.contract_start_time") dateWhere2 = getQuarterWhere(date, "ctr_contract_collection.collection_datetime") dateWhere3 = getQuarterMonthWhere(date, "monthly") + fmt.Sprintf(" AND created_time LIKE '%v%%'", date.Format("Y")) } } // 统计字段 if dataType == "COLLECTION" { targetField = "collection_target" realField = "collection_amount" } srv, err := contractService.NewCtrContractService(ctx) if err != nil { return nil, err } 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() if err != nil && err != sql.ErrNoRows { return nil, err } // 统计合同值 contractModel := srv.Dao.DB.Model("ctr_contract").Group("ctr_contract.incharge_id").Order("ctr_contract.incharge_id ASC") if dataType != "COLLECTION" { contracts, err := contractModel.Where(dateWhere1).Fields("ctr_contract.incharge_id, ctr_contract.incharge_name, count(ctr_contract.contract_amount) contract_amount").FindAll() if err != nil && err != sql.ErrNoRows { return nil, err } for index, contract := range contracts { realMap[contract["incharge_id"].Int()] = contracts[index] } } else { // 回款数据统计 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() if err != nil && err != sql.ErrNoRows { return nil, err } for index, collection := range collections { realMap[collection["incharge_id"].Int()] = collections[index] } } // 过滤掉已删除的销售 normalUserMap := make(map[int]bool) normalUsers, err := srv.Dao.DB.Model("sys_user").Where("status='10'").FindAll() if err != nil && err != sql.ErrNoRows { return nil, err } for _, user := range normalUsers { normalUserMap[user["id"].Int()] = true } // 统计目标值和实际值 var index int for _, target := range targets { // 过滤掉已删除的销售 if !normalUserMap[target["sale_user_id"].Int()] { continue } reportData.XData = append(reportData.XData, target["sale_user_name"].String()) reportData.YDataTarget = append(reportData.YDataTarget, target[targetField].Float64()) if realData, ok := realMap[target["sale_user_id"].Int()]; ok { reportData.YDataReal = append(reportData.YDataReal, realData[realField].Float64()) } else { reportData.YDataReal = append(reportData.YDataReal, 0) } if reportData.YDataTarget[index] == 0 { reportData.PercentData = append(reportData.PercentData, 0) } else { reportData.PercentData = append(reportData.PercentData, reportData.YDataReal[index]*100/reportData.YDataTarget[index]) } index++ } return &reportData, nil } func getQuarterGoalReportData(ctx context.Context, dataType string, params *map[string]interface{}) (*home.ReportData, error) { if params == nil { return nil, fmt.Errorf("请输入年度") } p := *params year := gconv.Int(p["year"]) quarter := gconv.Int(p["quarter"]) if year == 0 { return nil, fmt.Errorf("请输入年度") } srv, err := contractService.NewCtrContractService(ctx) if err != nil { return nil, err } goal := map[string]float64{} goaldao := srv.GoalDao.Where("year = ?", year).Where("goal_type = ?", dataType) if quarter != 0 { goaldao = goaldao.Where("quarter = ?", quarter) } else { goaldao = goaldao.Where("quarter = 1 || quarter = 2 || quarter = 3 || quarter = 4") } goalent, err := goaldao.All() if err != nil { return nil, err } for _, ent := range goalent { goal[ent.ProductLine] += ent.Amount } got := map[string]float64{} ctrdao := srv.Dao.As("a").InnerJoin("sys_user b", "a.incharge_id=b.id").Where("b.status='10'").Where("year(a.created_time) = ?", year) if quarter != 0 { if quarter == 1 { ctrdao = ctrdao.Where("month(a.created_time) in (1,2,3)") } if quarter == 2 { ctrdao = ctrdao.Where("month(a.created_time) in (4,5,6)") } if quarter == 3 { ctrdao = ctrdao.Where("month(a.created_time) in (7,8,9)") } if quarter == 4 { ctrdao = ctrdao.Where("month(a.created_time) in (10,11,12)") } } ctrent, err := ctrdao.All() if err != nil { return nil, err } for _, ent := range ctrent { if dataType == "10" { got[ent.ProductLine] += ent.ContractAmount } if dataType == "20" { got[ent.ProductLine] += ent.CollectedAmount } } productLine, err := service.GetDictDataByType(ctx, "sys_product_line") if err != nil { return nil, err } productLineCode := []string{} productLineName := []string{} for k, v := range productLine { productLineCode = append(productLineCode, k) productLineName = append(productLineName, v) } var reportData home.ReportData for _, c := range productLineCode { reportData.XData = append(reportData.XData, productLine[c]) reportData.YDataTarget = append(reportData.YDataTarget, goal[c]) reportData.YDataReal = append(reportData.YDataReal, got[c]/10000) } return &reportData, nil } // 客户现场打卡频次 func getClockfrequency(ctx context.Context, dataType string, params *map[string]interface{}) (*home.ReportData, error) { var reportData home.ReportData realMap := make(map[int]gdb.Record, 0) dateWhere1 := "" // 查询条件 date := gtime.Now() nowTime := gtime.Datetime() if params != nil && (*params)["date"] != nil { date = gconv.GTime((*params)["date"]) } if params != nil && (*params)["searchType"] != nil { searchType := gconv.String((*params)["searchType"]) if searchType == "month" { dateWhere1 = fmt.Sprintf("plat_punch_records.punch_time LIKE '%v'", date.Format("Y-m")+"-%") } else if searchType == "week" { weekday := transferWeekday(date.Weekday()) fmt.Println(weekday) beforeTime := gtime.NewFromStr(nowTime).AddDate(0, 0, -gconv.Int(weekday)).String() endTime := gtime.NewFromStr(nowTime).AddDate(0, 0, 7-gconv.Int(weekday)).String() dateWhere1 = fmt.Sprintf("plat_punch_records.punch_time between '%v' and '%v'", beforeTime, endTime) } } srv, err := platService.NewPunchRecordsService(ctx) if err != nil { return nil, err } 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() if err != nil && err != sql.ErrNoRows { return nil, err } // 过滤掉已删除的销售 normalUserMap := make(map[int]bool) normalUsers, err := srv.Dao.DB.Model("sys_user").Where("status='10'").FindAll() if err != nil && err != sql.ErrNoRows { return nil, err } for _, user := range normalUsers { normalUserMap[user["id"].Int()] = true } // 赋值实际值 var index int for _, target := range platpunchrecords { // 过滤掉已删除的销售 if !normalUserMap[target["user_id"].Int()] { continue } reportData.XData = append(reportData.XData, target["user_nick_name"].String()) reportData.YDataTarget = append(reportData.YDataTarget, target["punch_sum"].Float64()) if realData, ok := realMap[target["punch_sum"].Int()]; ok { reportData.YDataReal = append(reportData.YDataReal, realData["punch_sum"].Float64()) } else { reportData.YDataReal = append(reportData.YDataReal, 0) } if reportData.YDataTarget[index] == 0 { reportData.PercentData = append(reportData.PercentData, 0) } else { reportData.PercentData = append(reportData.PercentData, reportData.YDataReal[index]*100/reportData.YDataTarget[index]) } index++ } return &reportData, nil } // 销售工程师跟进记录的打卡频次 func getFollowUpRecord(ctx context.Context, dataType string, params *map[string]interface{}) ([]plat.Statistics, error) { now := time.Now() date := gconv.Int(gtime.Now().Month()) if params != nil && (*params)["date"] != nil { date = gconv.Int((*params)["date"]) } // 获取本月的第一天 firstOfMonth := time.Date(now.Year(), time.Month(date), 1, 0, 0, 0, 0, now.Location()) // 获取本月的最后一天 lastOfMonth := firstOfMonth.AddDate(0, 1, -1) l, _ := time.LoadLocation("Asia/Shanghai") startTime, _ := time.ParseInLocation("2006-01-02", firstOfMonth.Format("2006-01-02"), l) endTime, _ := time.ParseInLocation("2006-01-02", lastOfMonth.Format("2006-01-02"), l) datas := GroupByWeekDate(startTime, endTime) var Follows []plat.Followlist srv, err := platService.NewFollowupService(ctx) if err != nil { return nil, err } var stats []plat.Statistics for _, d := range datas { err = srv.Dao.DB.Model("plat_followup"). 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"). Group("date_format(follow_date,'%v'),follow_type").Scan(&Follows) if err != nil && err != sql.ErrNoRows { return nil, err } if len(Follows) > 0 { var stat plat.Statistics for _, val := range Follows { if val.FollowType == "10" { stat.Phone = gconv.Int(val.Num) } else if val.FollowType == "20" { stat.Mail = gconv.Int(val.Num) } else if val.FollowType == "30" { stat.PayVisit = gconv.Int(val.Num) } } stat.Total = stat.Phone + stat.Mail + stat.PayVisit stat.Week = d.WeekTh + "周" stats = append(stats, stat) } } return stats, nil } func getQuarterWhere(date *gtime.Time, field string) string { if date.Month() >= 1 && date.Month() <= 3 { 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") } else if date.Month() >= 4 && date.Month() <= 6 { 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") } else if date.Month() >= 7 && date.Month() <= 9 { 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") } else if date.Month() >= 10 && date.Month() <= 12 { 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") } return "" } func getQuarterMonthWhere(date *gtime.Time, field string) string { if date.Month() >= 1 && date.Month() <= 3 { return fmt.Sprintf("%v >= %v AND %v < %v", field, 1, field, 4) } else if date.Month() >= 4 && date.Month() <= 6 { return fmt.Sprintf("%v >= %v AND %v < %v", field, 4, field, 7) } else if date.Month() >= 7 && date.Month() <= 9 { return fmt.Sprintf("%v >= %v AND %v < %v", field, 7, field, 10) } else if date.Month() >= 10 && date.Month() <= 12 { return fmt.Sprintf("%v >= %v AND %v <= %v", field, 10, field, 12) } return "" } func transferWeekday(day time.Weekday) string { switch day { case time.Monday: return "1" case time.Tuesday: return "2" case time.Wednesday: return "3" case time.Thursday: return "4" case time.Friday: return "5" case time.Saturday: return "6" case time.Sunday: return "7" default: return "" } } // 判断时间是当年的第几周 func WeekByDate(t time.Time) string { yearDay := t.YearDay() yearFirstDay := t.AddDate(0, 0, -yearDay+1) firstDayInWeek := int(yearFirstDay.Weekday()) //今年第一周有几天 firstWeekDays := 1 if firstDayInWeek != 0 { firstWeekDays = 7 - firstDayInWeek + 1 } var week int Weeks := WeekByDates(t) if yearDay <= firstWeekDays { week = 1 } else { week = (yearDay-firstWeekDays)/7 + 2 } return fmt.Sprintf("%d", week-gconv.Int(Weeks)+1) } func WeekByDates(now time.Time) int { l, _ := time.LoadLocation("Asia/Shanghai") // 获取本月的第一天 firstOfMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location()) endTime, _ := time.ParseInLocation("2006-01-02", firstOfMonth.Format("2006-01-02"), l) t := endTime yearDay := t.YearDay() yearFirstDay := t.AddDate(0, 0, -yearDay+1) firstDayInWeek := int(yearFirstDay.Weekday()) //今年第一周有几天 firstWeekDays := 1 if firstDayInWeek != 0 { firstWeekDays = 7 - firstDayInWeek + 1 } var week int if yearDay <= firstWeekDays { week = 1 } else { week = (yearDay-firstWeekDays)/7 + 2 } return week } // 将开始时间和结束时间分割为周为单位 func GroupByWeekDate(startTime, endTime time.Time) []plat.WeekDate { weekDate := make([]plat.WeekDate, 0) diffDuration := endTime.Sub(startTime) days := int(math.Ceil(float64(diffDuration/(time.Hour*24)))) + 1 currentWeekDate := plat.WeekDate{} currentWeekDate.WeekTh = WeekByDate(endTime) currentWeekDate.EndTime = endTime currentWeekDay := int(endTime.Weekday()) if currentWeekDay == 0 { currentWeekDay = 7 } currentWeekDate.StartTime = endTime.AddDate(0, 0, -currentWeekDay+1) nextWeekEndTime := currentWeekDate.StartTime weekDate = append(weekDate, currentWeekDate) for i := 0; i < (days-currentWeekDay)/7; i++ { weekData := plat.WeekDate{} weekData.EndTime = nextWeekEndTime weekData.StartTime = nextWeekEndTime.AddDate(0, 0, -7) weekData.WeekTh = WeekByDate(weekData.StartTime) nextWeekEndTime = weekData.StartTime weekDate = append(weekDate, weekData) } if lastDays := (days - currentWeekDay) % 7; lastDays > 0 { lastData := plat.WeekDate{} lastData.EndTime = nextWeekEndTime lastData.StartTime = nextWeekEndTime.AddDate(0, 0, -lastDays) lastData.WeekTh = WeekByDate(lastData.StartTime) weekDate = append(weekDate, lastData) } return weekDate } type BusCount struct { NboType string `json:"nboType"` ProductLine string `json:"productLine"` Count int `json:"count"` Remark string `json:"remark"` } // 报表数据 三大产品线,新增以及转化项目(C转B、B转A、A转签约、C转A、C转签约、B转签约、储备转A/B/C/签约)数量, 按周和月 // params 10:周 20:月 func (s *HomeService) getNewAndConvertBusiness(productLine []string, params *map[string]interface{}) (interface{}, error) { if params == nil { return nil, myerrors.TipsError("请求参数传递不正确") } searchType, ok := (*params)["searchType"] if !ok { return nil, myerrors.TipsError("请求查询类型参数传递错误") } currentTime := gtime.Now() weekStart, weekEnd := currentTime.StartOfWeek(), currentTime.EndOfWeek() // monthStart, monthEnd := currentTime.StartOfMonth(), currentTime.EndOfMonth() monthStr, ok := (*params)["month"] if !ok { return nil, myerrors.TipsError("请求查询类型参数传递错误") } m := gconv.Int(monthStr) now := time.Now() firstOfMonth := time.Date(now.Year(), time.Month(m), 1, 0, 0, 0, 0, now.Location()) // 获取本月的第一天 lastOfMonth := firstOfMonth.AddDate(0, 1, -1) // 获取本月的最后一天 l, _ := time.LoadLocation("Asia/Shanghai") startTime, _ := time.ParseInLocation("2006-01-02", firstOfMonth.Format("2006-01-02"), l) endTime, _ := time.ParseInLocation("2006-01-02", lastOfMonth.Format("2006-01-02"), l) businessDao := projDao.NewProjBusinessDao(s.Tenant) busDynamicsDao := projDao.NewProjBusinessDynamicsDao(s.Tenant) contractDao := contDao.NewCtrContractDao(s.Tenant) // 获取三大产品线新增项目 getAddBusCount := func(searchType string) (addCount []BusCount, err error) { commonDb := businessDao.DataScope(s.Ctx, "sale_id").Group(businessDao.C.ProductLine).OrderAsc(businessDao.C.ProductLine). Fields("product_line, count(id) as count") if searchType == "week" { err = commonDb.WhereGTE(businessDao.C.FilingTime, weekStart).WhereLTE(businessDao.C.FilingTime, weekEnd).Scan(&addCount) } if searchType == "month" { err = commonDb.WhereGTE(businessDao.C.FilingTime, startTime).WhereLTE(businessDao.C.FilingTime, endTime).Scan(&addCount) } return addCount, err } addCount, err := getAddBusCount(searchType.(string)) if err != nil { return nil, err } // 获取三大产品线签约项目 getSignBusCount := func(searchType string) (signCount []BusCount, err error) { commonDb := contractDao.As("contract").DataScope(s.Ctx, "incharge_id").LeftJoin(businessDao.Table, "bus", "bus.id=contract.nbo_id"). Fields("bus.product_line, bus.nbo_type, count(contract.id) as count"). Group("bus.product_line, bus.nbo_type").Order("bus.product_line ASC, bus.nbo_type ASC") if searchType == "week" { err = commonDb.WhereGTE("contract."+contractDao.C.CreatedTime, weekStart).WhereLTE("contract."+contractDao.C.CreatedTime, weekEnd).Scan(&signCount) } if searchType == "month" { err = commonDb.WhereGTE("contract."+contractDao.C.CreatedTime, startTime).WhereLTE("contract."+contractDao.C.CreatedTime, endTime).Scan(&signCount) } return signCount, err } signCount, err := getSignBusCount(searchType.(string)) if err != nil { return nil, err } // 获取三大产品线转化项目(C转B、B转A、A转签约、C转A、C转签约、B转签约、储备转A/B/C/签约)数量 getConvertBusData := func(searchType string) (convertData []BusCount, err error) { commonDb := busDynamicsDao.As("dy").LeftJoin(businessDao.Table, "bus", "bus.id=dy.bus_id").DataScope(s.Ctx, "sale_id", "bus"). Where("dy."+busDynamicsDao.C.OpnType, projSrv.OpnUpgradeApproval).WhereNot("dy."+busDynamicsDao.C.Remark, ""). Fields("bus.product_line, dy.remark").OrderAsc("bus.product_line") if searchType == "week" { err = commonDb.WhereGTE("dy."+busDynamicsDao.C.CreatedTime, weekStart).WhereLTE("dy."+busDynamicsDao.C.CreatedTime, weekEnd).Scan(&convertData) } if searchType == "month" { err = commonDb.WhereGTE("dy."+busDynamicsDao.C.CreatedTime, startTime).WhereLTE("dy."+busDynamicsDao.C.CreatedTime, endTime).Scan(&convertData) } return convertData, err } convertBusData, err := getConvertBusData(searchType.(string)) if err != nil { return nil, err } // 处理数据 result := make([][]int, len(productLine)) for i, pl := range productLine { result[i] = make([]int, 8) for _, item := range addCount { if item.ProductLine == pl { result[i][0] = item.Count } } for _, item := range signCount { if item.ProductLine != pl { continue } switch item.NboType { case projSrv.StatusA: result[i][3] += item.Count case projSrv.StatusB: result[i][6] += item.Count case projSrv.StatusC: result[i][5] += item.Count case projSrv.StatusReserve: result[i][7] += item.Count } } for _, item := range convertBusData { if item.ProductLine != pl { continue } info := gconv.Map(item.Remark) if info["origNboType"] == projSrv.StatusC && info["nboType"] == projSrv.StatusB { result[i][1] += 1 } if info["origNboType"] == projSrv.StatusB && info["nboType"] == projSrv.StatusA { result[i][2] += 1 } if info["origNboType"] == projSrv.StatusC && info["nboType"] == projSrv.StatusA { result[i][4] += 1 } if info["origNboType"] == projSrv.StatusReserve { result[i][7] += 1 } } } return result, nil } // 报表数据 三大产品线,AB类项目出货金额 func (s *HomeService) getShipmentAmount(productLine, nboType []string) (interface{}, error) { businessDao := projDao.NewProjBusinessDao(s.Tenant) data, err := businessDao.As("a").InnerJoin("sys_user b", "a.sale_id=b.id").Fields("a.product_line, a.nbo_type, SUM(a.est_trans_price) as est_trans_price").Where("b.status='10'"). WhereIn("a.product_line", productLine).WhereIn("a.nbo_type", nboType). Group("a.product_line, a.nbo_type").Order("a.product_line ASC, a.nbo_type ASC").DataScope(s.Ctx, "a.sale_id").All() if err != nil { return nil, err } result := make([][]float64, len(productLine)) for i, pl := range productLine { result[i] = make([]float64, len(nboType)) for j, t := range nboType { for _, item := range data { if item.ProductLine == pl && item.NboType == t { result[i][j] = item.EstTransPrice } } } } return arrayReversal(result), nil } // 报表数据 三大产品线,当月和累计的签约、回款额 func (s *HomeService) getProductLineSignedAndBackAmount(productLine []string) (interface{}, error) { currentTime := gtime.Now() monthStart := currentTime.StartOfMonth() monthEnd := currentTime.EndOfMonth() contractDao := contDao.NewCtrContractDao(s.Tenant) commonDao := contractDao.As("a").InnerJoin("sys_user b", "a.incharge_id=b.id").DataScope(s.Ctx, "incharge_id").WhereIn(contractDao.C.ProductLine, productLine).Where("b.status='10'"). Group(contractDao.C.ProductLine).OrderAsc(contractDao.C.ProductLine) //累计签约合同金额 contract_amount allContractAmount, err := commonDao.Fields("a.product_line, SUM(a.contract_amount) as contract_amount").All() if err != nil { return nil, err } //累计回款金额 collected_amount allCollectedAmount, err := commonDao.Fields("a.product_line, SUM(a.collected_amount) as collected_amount").All() if err != nil { return nil, err } //当月签约合同金额(维度:月) monthContractAmount, err := commonDao.WhereGTE(contractDao.C.ContractStartTime, monthStart).WhereLTE(contractDao.C.ContractStartTime, monthEnd). Fields("a.product_line, SUM(a.contract_amount) as contract_amount").All() if err != nil { return nil, err } //当月回款金额(维度:月) monthCollectedAmount, err := commonDao.WhereGTE(contractDao.C.ContractStartTime, monthStart).WhereLTE(contractDao.C.ContractStartTime, monthEnd). Fields("a.product_line, SUM(a.collected_amount) as collected_amount").All() if err != nil { return nil, err } result := make([][]float64, len(productLine)) for i, pl := range productLine { result[i] = make([]float64, 4) for _, item := range monthContractAmount { if item.ProductLine == pl { result[i][0] = item.ContractAmount } } for _, item := range allContractAmount { if item.ProductLine == pl { result[i][1] = item.ContractAmount } } for _, item := range monthCollectedAmount { if item.ProductLine == pl { result[i][2] = item.CollectedAmount } } for _, item := range allCollectedAmount { if item.ProductLine == pl { result[i][3] = item.CollectedAmount } } } return arrayReversal(result), nil } // 二维数组反转 func arrayReversal(result [][]float64) [][]float64 { if len(result) == 0 { return [][]float64{} } data := make([][]float64, len(result[0])) for k, v := range result { for m, n := range v { if k == 0 { data[m] = make([]float64, len(result)) } data[m][k] = n } } return data } type FollowUpCount struct { CreatedBy int `json:"createdBy"` CreatedName string `json:"createdName"` FollowType string `json:"followType"` Count int `json:"count"` } // QuerySalesEngineerFollowUpNum 查询销售工程师跟进记录频次 func (s *HomeService) QuerySalesEngineerFollowUpNum(day *gtime.Time) (interface{}, error) { weekData := GetMonthWeekDay(day) followUpDao := platDao.NewPlatFollowupDao(s.Tenant) followUpMonthData := make([][]FollowUpCount, 0) for _, item := range weekData { data := make([]FollowUpCount, 0) err := followUpDao.Fields("created_by, created_name, follow_type, COUNT(id) as count"). WhereGTE(followUpDao.C.FollowDate, item[0]).WhereLTE(followUpDao.C.FollowDate, item[1]). Group("created_by, follow_type").Order("created_by ASC, follow_type ASC").Scan(&data) if err != nil { return nil, err } followUpMonthData = append(followUpMonthData, data) } // 409022238 userList, err := service.GetUsersByRoleCode(s.Ctx, []string{"SalesEngineer"}, 100) if err != nil { return nil, err } followMethod, err := service.GetDictDataTreeByType(s.Ctx, "plat_follow_method") if err != nil { return nil, err } header, data := make([]g.Map, 0), make([]g.Map, 0) header = append(header, g.Map{"prop": "userName", "label": "销售工程师"}) header = append(header, g.Map{"prop": "followType", "label": "跟进方式"}) for k, _ := range weekData { header = append(header, g.Map{"prop": fmt.Sprintf("W%d", k+1), "label": fmt.Sprintf("第%d周", k+1)}) } header = append(header, g.Map{"prop": "monthTotal", "label": "月度合计"}) for userName, id := range userList { for _, key := range followMethod.Keys() { data = append(data, followUpReportDataConvert(g.Map{ "userName": userName, "userId": id, "followTypeKey": key, "followType": followMethod.Get(key), }, followUpMonthData)) } } return g.Map{"header": header, "data": data}, nil } type PunchRecordsCount struct { UserId int `json:"userId"` UserNickName string `json:"userNickName"` PunchType string `json:"punchType"` Count int `json:"count"` } // QueryPunchRecordsNum 打卡记录数据统计 func (s *HomeService) QueryPunchRecordsNum(day *gtime.Time) (interface{}, error) { weekData := GetMonthWeekDay(day) punchRecordsDao := platDao.NewPlatPunchRecordsDao(s.Tenant) punchRecordsMonthData := make([][]PunchRecordsCount, 0) for _, item := range weekData { data := make([]PunchRecordsCount, 0) err := punchRecordsDao.Fields("user_id, user_nick_name, punch_type, COUNT(id) as count"). WhereGTE(punchRecordsDao.C.PunchTime, item[0]).WhereLTE(punchRecordsDao.C.PunchTime, item[1]). Group("user_id, punch_type").Order("user_id ASC, punch_type ASC").Scan(&data) if err != nil { return nil, err } punchRecordsMonthData = append(punchRecordsMonthData, data) } // 409022238 userList, err := service.GetUsersByRoleCode(s.Ctx, []string{"SalesEngineer"}, 100) if err != nil { return nil, err } // 打卡类型(10居家20客户30经销商40代理商) var punchTypes = []string{"10", "20", "30", "40"} var punchTypeNames = []string{"居家", "客户", "经销商", "代理商"} header, data := make([]g.Map, 0), make([]g.Map, 0) header = append(header, g.Map{"prop": "userName", "label": "销售工程师"}) header = append(header, g.Map{"prop": "punchType", "label": "打卡方式"}) for k, _ := range weekData { header = append(header, g.Map{"prop": fmt.Sprintf("W%d", k+1), "label": fmt.Sprintf("第%d周", k+1)}) } header = append(header, g.Map{"prop": "monthTotal", "label": "月度合计"}) // 打卡类型(10居家20客户30经销商40代理商) for userName, id := range userList { for index, key := range punchTypes { data = append(data, punchRecordsDataConvert(g.Map{ "userName": userName, "userId": id, "punchTypeKey": key, "punchType": punchTypeNames[index], }, punchRecordsMonthData)) } } return g.Map{"header": header, "data": data}, nil } func followUpReportDataConvert(data g.Map, followUpMonthData [][]FollowUpCount) g.Map { var total int for k, items := range followUpMonthData { data[fmt.Sprintf("W%d", k+1)] = 0 for _, item := range items { if item.CreatedBy == data["userId"] && item.FollowType == data["followTypeKey"] { data[fmt.Sprintf("W%d", k+1)] = item.Count total += item.Count break } } } data["monthTotal"] = total return data } func punchRecordsDataConvert(data g.Map, punchRecordsCMonthData [][]PunchRecordsCount) g.Map { var total int for k, items := range punchRecordsCMonthData { data[fmt.Sprintf("W%d", k+1)] = 0 for _, item := range items { if item.UserId == data["userId"] && item.PunchType == data["punchTypeKey"] { data[fmt.Sprintf("W%d", k+1)] = item.Count total += item.Count break } } } data["monthTotal"] = total return data } // GetMonthWeekDay 获取月份下的每周日期 func GetMonthWeekDay(day *gtime.Time) [][]*gtime.Time { fmt.Println(day) result := make([][]*gtime.Time, 0) monthStart, monthEnd := day.StartOfMonth(), day.EndOfMonth() startWeekS, startWeekE := monthStart.StartOfWeek(), monthStart.EndOfWeek() endWeekS, endWeekE := monthEnd.StartOfWeek(), monthEnd.EndOfWeek() // 计算开始 if startWeekS.Before(monthStart) || startWeekS.Equal(monthStart) { result = append(result, []*gtime.Time{monthStart, startWeekE}) } // 计算整周 sub := int(endWeekS.Sub(startWeekE).Hours() / 24 / 7) forDay := startWeekE.AddDate(0, 0, 1) for i := 1; i <= sub; i++ { result = append(result, []*gtime.Time{forDay.StartOfDay(), forDay.EndOfWeek()}) forDay = forDay.AddDate(0, 0, 7) } // 计算结束 if endWeekE.After(monthEnd) || endWeekE.Equal(monthEnd) { result = append(result, []*gtime.Time{endWeekS, monthEnd}) } return result }