package home import ( "context" "encoding/json" "fmt" "strings" "time" baseDao "dashoo.cn/micro/app/dao/base" contDao "dashoo.cn/micro/app/dao/contract" custDao "dashoo.cn/micro/app/dao/cust" 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" server "dashoo.cn/micro/app/service/plat" projSrv "dashoo.cn/micro/app/service/proj" "github.com/gogf/gf/frame/g" "github.com/gogf/gf/os/gtime" "github.com/gogf/gf/util/gconv" ) type HomeService struct { *service.ContextService } func NewHomeService(ctx context.Context) (svc *HomeService, err error) { svc = new(HomeService) if svc.ContextService, err = svc.Init(ctx); err != nil { return nil, err } return svc, nil } func (s *HomeService) SetUpHomeReportConfig(param *home.SetUpHomeConfig) (err error) { svc, err := server.NewUserConfigService(s.Ctx) config, _ := svc.QueryByUserIdAndModelCode(s.GetCxtUserId(), param.ModuleCode) by, _ := json.Marshal(param) if config != nil { config.ConfigInfo = gconv.String(by) err = svc.Edit(config) } else { config := new(plat.PlatUserConfig) config.UserId = s.GetCxtUserId() config.ModuleCode = param.ModuleCode config.ConfigInfo = gconv.String(by) _, err = svc.Create(config) } return } func (s *HomeService) QueryHomeReportConfig(moduleCode string) (config *plat.PlatUserConfig, err error) { svc, err := server.NewUserConfigService(s.Ctx) config, err = svc.QueryByUserIdAndModelCode(s.GetCxtUserId(), moduleCode) return } func (s *HomeService) QueryHomeNumReportData(param *home.SearchNumReportData) (resp *home.NumReportResponses, err error) { resp = new(home.NumReportResponses) numConfig := make([]*home.NumReportResponse, 0) tempMap := map[int64]byte{} for _, v := range param.ReportId { l := len(tempMap) tempMap[v] = 0 if len(tempMap) == l { continue } numReport := new(home.NumReportResponse) numReport.Id = v value, _ := s.getReportData(v, nil) numReport.Data = value numConfig = append(numConfig, numReport) } resp.NumReportResponse = numConfig return } func (s *HomeService) QueryHomeDataReportData(param *home.SearchDataReportData) (resp *home.DataReportResponse, err error) { resp = new(home.DataReportResponse) resp.Id = param.ReportId value, err := s.getReportData(param.ReportId, ¶m.Params) if err != nil { return nil, err } resp.Data = value return } // 10000-20000之间:个人看板数据 TODO 疑似与 sys_report 表对应? // 20000-30000之间:报表数据 TODO 疑似与 sys_report 表对应? func (s *HomeService) getReportData(id int64, params *map[string]interface{}) (interface{}, error) { switch id { case 10000, 10001, 10002, 10003, 10004, 10005, 10006, 10007, 10008, 10009, 10010, 10011, 10012, 10013, 10014, 10015, 10016, 10017, 10018, 10019, 10020, 10021: // 获取数值指标统计数据 return s.getNumStatisticsData(id, params) case 20000: // 报表数据 个人销售金额 return getPersonalContractReportData(s.ContextService.Ctx, "CONTRACT", params) case 20001: // 报表数据 个人销售回款 return getPersonalContractReportData(s.ContextService.Ctx, "COLLECTION", params) case 20002: // 报表数据 总部销售金额 return getCompanyContractReportData(s.ContextService.Ctx, "CONTRACT", params) case 20003: // 报表数据 总部销售回款 return getCompanyContractReportData(s.ContextService.Ctx, "COLLECTION", params) case 20006: // 报表数据 季度销售指标 return getQuarterGoalReportData(s.ContextService.Ctx, "10", params) case 20007: // 报表数据 季度回款指标 return getQuarterGoalReportData(s.ContextService.Ctx, "20", params) case 20008: //报表数据 现场打卡频次 return getClockfrequency(s.ContextService.Ctx, "20", params) case 20009: //表格数据 跟进记录频次 return getFollowUpRecord(s.ContextService.Ctx, "20", params) case 20010: // 报表数据 三大产品线,新增以及转化项目(C转B、B转A、A转签约、C转A、C转签约、B转签约、储备转A/B/C/签约)数量, 按周和月 return s.getNewAndConvertBusiness([]string{"10", "20", "30"}, params) case 20011: // 报表数据 三大产品线,AB类项目出货金额 return s.getShipmentAmount([]string{"10", "20", "30"}, []string{projSrv.StatusA, projSrv.StatusB}) case 20012: // 报表数据 三大产品线,当月和累计的签约、回款额 return s.getProductLineSignedAndBackAmount([]string{"10", "20", "30"}) default: return nil, nil } } // 获取数值指标统计数据 func (s *HomeService) getNumStatisticsData(id int64, params *map[string]interface{}) (string, error) { customerDao := custDao.NewCustCustomerDao(s.Tenant) businessDao := projDao.NewProjBusinessDao(s.Tenant) busDynamicsDao := projDao.NewProjBusinessDynamicsDao(s.Tenant) contractDao := contDao.NewCtrContractDao(s.Tenant) contractCollDao := contDao.NewCtrContractCollectionDao(s.Tenant) distDao := baseDao.NewBaseDistributorDao(s.Tenant) taskDao := platDao.NewPlatTaskDao(s.Tenant) bidDao := custDao.NewCustCustomerBidRecordDao(s.Tenant) currentTime := gtime.Now() monthStart := currentTime.StartOfMonth() monthEnd := currentTime.EndOfMonth() yearStart := currentTime.StartOfYear() yearEnd := currentTime.EndOfYear() switch id { case 10001: //当前客户数量(维度:总数) count, err := customerDao.DataScope(s.Ctx, "sales_id").CountColumn("id") return gconv.String(count), err case 10002: //当前项目数量(维度:总数) count, err := businessDao.DataScope(s.Ctx, "sale_id").CountColumn("id") return gconv.String(count), err case 10003: //当前合同数量(维度:总数) count, err := contractDao.DataScope(s.Ctx, "incharge_id").CountColumn("id") return gconv.String(count), err case 10004: //当月新增客户数量(维度:月) count, err := customerDao.DataScope(s.Ctx, "sales_id").WhereGTE(customerDao.C.CreatedTime, monthStart).WhereLTE(customerDao.C.CreatedTime, monthEnd).CountColumn("id") return gconv.String(count), err case 10005: //当月新增项目数量(维度:月) count, err := businessDao.DataScope(s.Ctx, "sale_id").WhereGTE(businessDao.C.FilingTime, monthStart).WhereLTE(businessDao.C.FilingTime, monthEnd).CountColumn("id") return gconv.String(count), err case 10006: //当月新增合同数量(维度:月) count, err := contractDao.DataScope(s.Ctx, "incharge_id").WhereGTE(contractDao.C.ContractSignTime, monthStart).WhereLTE(contractDao.C.ContractSignTime, monthEnd).CountColumn("id") return gconv.String(count), err case 10007: //当月签约合同金额(维度:月) count, err := contractDao.DataScope(s.Ctx, "incharge_id").WhereGTE(contractDao.C.ContractSignTime, monthStart).WhereLTE(contractDao.C.ContractSignTime, monthEnd). Sum(contractDao.C.ContractAmount) return gconv.String(count), err case 10008: //当月回款金额(维度:月) count, err := contractCollDao.Where("appro_status = 20").Where("collection_datetime >= ?", monthStart).Where("collection_datetime <= ?", monthEnd).Sum("collection_amount") return gconv.String(count), err case 10009: //当年的签约金额(维度:年) count, err := contractDao.DataScope(s.Ctx, "incharge_id").WhereGTE(contractDao.C.ContractSignTime, yearStart).WhereLTE(contractDao.C.ContractSignTime, yearEnd). Sum(contractDao.C.ContractAmount) return gconv.String(count), err case 10010: //当年的回款金额(维度:年) //count, err := contractDao.DataScope(s.Ctx, "incharge_id").WhereGTE(contractDao.C.ContractStartTime, yearStart).WhereLTE(contractDao.C.ContractStartTime, yearEnd). // Sum(contractDao.C.CollectedAmount) // 修改为报表统计相同的逻辑 count, err := contractDao.As("a").DataScope(s.Ctx, "incharge_id").InnerJoin("ctr_contract_collection b", "a.id=b.contract_id").Where("b.collection_datetime>=? AND b.collection_datetime<=?", yearStart, yearEnd). Sum("b.collection_amount") return gconv.String(count), err case 10011: //我发起的督办 count, err := taskDao.Where(taskDao.C.CreatedBy, s.GetCxtUserId()).CountColumn("id") return gconv.String(count), err case 10012: //我处理的督办 count, err := taskDao.As("task").InnerJoin("plat_task_handle", "handle", "handle.task_id=task.id"). Where(fmt.Sprintf("handle.task_status='20' AND handle.handle_user_id=%v", s.GetCxtUserId())).Distinct().CountColumn("task.id") return gconv.String(count), err case 10013: //当月项目转化数量(升级) count, err := busDynamicsDao.As("dynamics").LeftJoin(businessDao.Table, "bus", "bus.id=dynamics.bus_id"). WhereGTE("dynamics."+busDynamicsDao.C.CreatedTime, monthStart).WhereLTE("dynamics."+busDynamicsDao.C.CreatedTime, monthEnd). Where(busDynamicsDao.C.OpnType, projSrv.OpnUpgradeApproval). Fields(busDynamicsDao.C.BusId).DataScope(s.Ctx, "sale_id", "bus").Distinct().Count() return gconv.String(count), err case 10014: //签约未回款总金额,数据=全部历史合同中未回款金额,过程中有实际回款时数据实时扣减 count, err := contractDao.DataScope(s.Ctx, "incharge_id").Sum(contractDao.C.ContractAmount + " - " + contractDao.C.CollectedAmount) return gconv.String(count), err case 10015: //当年未开票金额,数据=2023年未开票金额 count, err := contractDao.DataScope(s.Ctx, "incharge_id"). Where("year(contract_sign_time) = ?", time.Now().Year()). Sum(contractDao.C.ContractAmount + " - " + contractDao.C.InvoiceAmount) return gconv.String(count), err case 10016: //当年签约未回款金额,数据=2023年合同中未回款金额,过程中有实际回款时数据 count, err := contractDao.DataScope(s.Ctx, "incharge_id"). Where("year(contract_sign_time) = ?", time.Now().Year()). Sum(contractDao.C.ContractAmount + " - " + contractDao.C.CollectedAmount) return gconv.String(count), err case 10017: //当月新增经销商数量:统计自然月当月新创建的经销商数量。 count, err := distDao.Where("dist_type = '10'").Where("created_time >= ?", monthStart).Where("created_time <= ?", monthEnd).Count() return gconv.String(count), err case 10018: //进行中的督办:统计正在进行的督办数量。 count, err := taskDao.Where("task_status = '20'").Count() return gconv.String(count), err case 10019: //当月新增招标信息 // 数据权限 // 系统管理员、总经理、销售总监、销售助理看全部的 where := "" if service.StringsContains(s.CxtUser.Roles, "GeneralManager") || service.StringsContains(s.CxtUser.Roles, "SalesDirector") || service.StringsContains(s.CxtUser.Roles, "SaleAssociate") || service.StringsContains(s.CxtUser.Roles, "SysAdmin") { } else { // 默认按照产品线 productCode, err := service.ColumnString(bidDao.DB.Model("base_product_auth").Wheref("user_id = ?", s.CxtUser.Id), "product_code") if err != nil { return "", err } g.Log().Infof("CustCustomerBidRecordService List product_code %v", productCode) if len(productCode) > 0 { where = fmt.Sprintf("product_line in (%v)", strings.Join(productCode, ",")) } else { where = "1=0" } } count, err := bidDao.Where(fmt.Sprintf("created_time LIKE '%v%%'", currentTime.Format("Y-m"))).Where(where).Count() return gconv.String(count), err case 10020: //项目来源为招标信息转化 count, err := businessDao.Where("bid_id<>0").Count() return gconv.String(count), err case 10021: //当年的已开票金额(维度:年) count, err := contractDao.DataScope(s.Ctx, "incharge_id").WhereGTE(contractDao.C.ContractStartTime, yearStart).WhereLTE(contractDao.C.ContractStartTime, yearEnd). Sum(contractDao.C.InvoiceAmount) return gconv.String(count), err } return "", nil } // QueryWechatHomeNumReportData 获取微信首页个人看板数据 func (s *HomeService) QueryWechatHomeNumReportData(req *home.SearchWechatNumReportDataReq) (resp *home.SearchWechatNumReportDataRes, err error) { customerDao := custDao.NewCustCustomerDao(s.Tenant).DataScope(s.Ctx, "sales_id") businessDao := projDao.NewProjBusinessDao(s.Tenant).DataScope(s.Ctx, "sales_id") taskHandleDao := platDao.NewPlatTaskHandleDao(s.Tenant).M currentTime := gtime.Now() monthStart := currentTime.StartOfMonth() monthEnd := currentTime.EndOfMonth() weekStart := currentTime.StartOfWeek() weekEnd := currentTime.EndOfWeek() if req.ViewInterval == "week" { customerDao = customerDao.WhereGTE("created_time", weekStart).WhereLTE("created_time", weekEnd) businessDao = businessDao.WhereGTE("filing_time", weekStart).WhereLTE("filing_time", weekEnd) taskHandleDao = taskHandleDao.WhereGTE("created_time", weekStart).WhereLTE("created_time", weekEnd) } if req.ViewInterval == "month" { customerDao = customerDao.WhereGTE("created_time", monthStart).WhereLTE("created_time", monthEnd) businessDao = businessDao.WhereGTE("filing_time", monthStart).WhereLTE("filing_time", monthEnd) taskHandleDao = taskHandleDao.WhereGTE("created_time", monthStart).WhereLTE("created_time", monthEnd) } taskHandleDao = taskHandleDao.Where(platDao.PlatTaskHandle.C.TaskStatus, "10"). Where(fmt.Sprintf("main_user_id=%v OR FIND_IN_SET(%v, owner_user_id)", s.GetCxtUserId(), s.GetCxtUserId())) // 新增客户数量 newCustomerCount, err := customerDao.CountColumn("id") if err != nil { g.Log().Error(err) } // 新增项目数量 newBusinessCount, err := businessDao.CountColumn("id") if err != nil { g.Log().Error(err) } // 未处理督办事项 newTaskCount, err := taskHandleDao.CountColumn("task_id") if err != nil { g.Log().Error(err) } resp = new(home.SearchWechatNumReportDataRes) resp.NewCustomer = newCustomerCount resp.NewBusiness = newBusinessCount resp.NewTask = newTaskCount return resp, nil }