package yb import ( "errors" "fmt" "hongze/hz_crm_api/models" "hongze/hz_crm_api/models/company" "hongze/hz_crm_api/models/yb" "hongze/hz_crm_api/models/yb/request" "hongze/hz_crm_api/models/yb/response" "hongze/hz_crm_api/services" "hongze/hz_crm_api/utils" "strconv" "strings" "time" ) // GetPriceDrivenDetail 获取价格驱动详情 func GetPriceDrivenDetail(varietyTagId int) (detail *response.PriceDrivenDetail, errMsg string, err error) { detail = new(response.PriceDrivenDetail) if varietyTagId <= 0 { return } item, e := yb.GetPriceDrivenByVarietyTagId(varietyTagId) if e != nil && e.Error() != utils.ErrNoRow() { errMsg = "获取价格驱动失败" err = errors.New("获取价格驱动详情失败, Err:" + e.Error()) return } if item != nil { // 查询草稿 draft, e := yb.GetPriceDrivenSaveLogByPriceDrivenId(item.PriceDrivenId) if e != nil && e.Error() != utils.ErrNoRow() { errMsg = "获取价格驱动草稿失败" err = errors.New("获取价格驱动草稿失败, Err:" + e.Error()) return } if draft != nil && draft.CreateTime.After(item.ModifyTime) { item.MainVariable = draft.MainVariable item.CoreDrivenType = draft.CoreDrivenType item.CoreDrivenContent = draft.CoreDrivenContent item.CoreContent = draft.CoreContent item.LastUpdateAdminId = draft.AdminId item.LastUpdateAdminName = draft.AdminName } detail = formatPriceDrivenItemToDetail(item) } return } // UpdatePriceDriven 更新价格驱动 func UpdatePriceDriven(req request.UpdatePriceDrivenReq) (detail *response.PriceDrivenDetail, errMsg string, err error) { detail = new(response.PriceDrivenDetail) if req.VarietyTagId <= 0 { errMsg = "标签有误" err = errors.New("UpdatePriceDriven 标签有误") return } // 非自动保存校验品种是否开启 priceTag, e := yb.GetPriceDrivenTagByTagId(req.VarietyTagId) if e != nil { errMsg = "获取价格驱动标签信息失败" err = errors.New("UpdatePriceDriven 获取价格驱动标签信息失败, Err:" + e.Error()) return } if req.AutoSave == 0 { if priceTag.State != 1 { errMsg = "请开启品种后重试" err = errors.New("UpdatePriceDriven 品种未开启") return } } // 最近的一条数据 item, e := yb.GetPriceDrivenByVarietyTagId(req.VarietyTagId) if e != nil && e.Error() != utils.ErrNoRow() { errMsg = "获取价格驱动失败" err = errors.New("UpdatePriceDriven 获取价格驱动详情失败, Err:" + e.Error()) return } nowTime := time.Now().Local() // 最新的一条数据为今日的则更新 if item != nil { todayStart := time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 0, 0, 0, 0, time.Local) todayEnd := time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 23, 59, 59, 0, time.Local) if item.CreateTime.After(todayStart) && item.CreateTime.Before(todayEnd) { item.MainVariable = req.MainVariable item.CoreDrivenType = req.CoreDrivenType item.CoreDrivenContent = req.CoreDrivenContent item.CoreContent = req.CoreContent item.LastUpdateAdminId = req.LastUpdateAdminId item.LastUpdateAdminName = req.LastUpdateAdminName if req.AutoSave == 0 { // 发布更新 updateCols := make([]string, 0) updateCols = append(updateCols, "MainVariable", "CoreDrivenType", "CoreDrivenContent", "CoreContent", "LastUpdateAdminId", "LastUpdateAdminName", "ModifyTime", "PublishState") item.ModifyTime = nowTime item.PublishState = 1 if e := item.Update(updateCols); e != nil { errMsg = "更新价格驱动失败" err = errors.New("UpdatePriceDriven 更新价格驱动失败, Err:" + e.Error()) return } } else { // 存草稿 go func() { if e = savePriceDrivenDraft(item.PriceDrivenId, req.VarietyTagId, req.CoreDrivenType, req.LastUpdateAdminId, req.MainVariable, req.CoreDrivenContent, req.CoreContent, req.LastUpdateAdminName); e != nil { utils.FileLog.Info("%s", "记录价格驱动草稿失败, Err: "+e.Error()) } }() } detail = formatPriceDrivenItemToDetail(item) return } } // 否则新增, 不记录草稿 publishState := 0 if req.AutoSave == 0 { publishState = 1 } newPriceDriven := &yb.PriceDriven{ VarietyTagId: req.VarietyTagId, VarietyTagName: priceTag.VarietyTagName, MainVariable: req.MainVariable, CoreDrivenType: req.CoreDrivenType, CoreDrivenContent: req.CoreDrivenContent, CoreContent: req.CoreContent, LastUpdateAdminId: req.LastUpdateAdminId, LastUpdateAdminName: req.LastUpdateAdminName, PublishState: publishState, CreateTime: nowTime, ModifyTime: nowTime, } if e := newPriceDriven.Add(); e != nil { errMsg = "新增价格驱动失败" err = errors.New("UpdatePriceDriven 新增价格驱动失败, Err:" + e.Error()) } detail = formatPriceDrivenItemToDetail(newPriceDriven) return } // savePriceDrivenDraft 保存草稿 func savePriceDrivenDraft(priceDrivenId, varietyTagId, coreDrivenType, adminId int, mainVariable, coreDrivenContent, coreContent, adminName string) (err error) { draft := &yb.PriceDrivenSaveLog{ PriceDrivenId: priceDrivenId, VarietyTagId: varietyTagId, MainVariable: mainVariable, CoreDrivenType: coreDrivenType, CoreDrivenContent: coreDrivenContent, CoreContent: coreContent, AdminId: adminId, AdminName: adminName, CreateTime: time.Now().Local(), } if e := draft.Add(); e != nil { err = errors.New("savePriceDrivenDraft 新增价格驱动草稿失败, Err:" + e.Error()) } return } // formatPriceDrivenItemToDetail 格式化详情 func formatPriceDrivenItemToDetail(item *yb.PriceDriven) (detail *response.PriceDrivenDetail) { if item == nil { return } detail = &response.PriceDrivenDetail{ PriceDrivenId: item.PriceDrivenId, VarietyTagId: item.VarietyTagId, VarietyTagName: item.VarietyTagName, MainVariable: item.MainVariable, CoreDrivenType: item.CoreDrivenType, CoreDrivenContent: item.CoreDrivenContent, CoreContent: item.CoreContent, LastUpdateAdminId: item.LastUpdateAdminId, LastUpdateAdminName: item.LastUpdateAdminName, SendThsMsgTime: item.SendThsMsgTime.Format(utils.FormatDateTime), SendTemplateMsgTime: item.SendTemplateMsgTime.Format(utils.FormatDateTime), ThsMsgState: item.ThsMsgState, TemplateMsgState: item.TemplateMsgState, PublishState: item.PublishState, CreateTime: item.CreateTime.Format(utils.FormatDateTime), ModifyTime: item.ModifyTime.Format(utils.FormatDateTime), } return } // GetPriceDrivenPermissionTree 获取价格驱动品种列表 func GetPriceDrivenPermissionTree() (list []*response.ChartPermissionTree, err error) { firstList, e := models.GetYbChartPermissionFirst() if e != nil { return } list = make([]*response.ChartPermissionTree, 0) if len(firstList) > 0 { productId := 1 for _, v := range firstList { classify := new(response.ChartPermissionTree) classify.ClassifyName = v.YbIndexName children, e := models.GetPermissionByProductIdAndClassifyName(productId, v.ClassifyName) if e != nil { return } items := make([]*response.PermissionItem, 0) for _, iv := range children { items = append(items, &response.PermissionItem{ PermissionId: iv.ChartPermissionId, PermissionName: iv.PermissionName, PriceDrivenState: iv.PriceDrivenState, }) } classify.Items = items list = append(list, classify) } } return } // SwitchPriceDrivenPermissionState 切换价格驱动分类状态 func SwitchPriceDrivenPermissionState(varietyTagId int, priceDrivenState int) (errMsg string, err error) { priceTag, e := yb.GetPriceDrivenTagByTagId(varietyTagId) if e != nil { errMsg = "获取价格驱动标签信息失败" err = errors.New("UpdatePriceDriven 获取价格驱动标签信息失败, Err:" + e.Error()) return } if priceTag.State == priceDrivenState { return } updateCols := make([]string, 0) updateCols = append(updateCols, "State") priceTag.State = priceDrivenState if e := priceTag.Update(updateCols); e != nil { err = errors.New("SwitchPriceDrivenPermissionState 更新价格驱动分类状态失败, Err:" + e.Error()) } return } // SendPriceDrivenTemplateMsg 推送价格驱动模板消息 func SendPriceDrivenTemplateMsg(priceDrivenId int) (errMsg string, err error) { item, e := yb.GetPriceDrivenById(priceDrivenId) if e != nil { errMsg = "获取价格驱动失败" err = errors.New("SendPriceDrivenTemplateMsg 获取价格驱动详情失败, Err:" + e.Error()) return } if item.CoreContent == "" { errMsg = "核心内容不能为空" err = errors.New("SendPriceDrivenTemplateMsg 核心内容不能为空") return } if item.TemplateMsgState == 1 { errMsg = "未更新品种或今日推送次数已达上限" err = errors.New("SendPriceDrivenTemplateMsg 今日推送次数已达上限") return } // 推送消息 go func() { _ = services.SendYbPriceDrivenWxMsg(item.VarietyTagId, item.CoreDrivenContent, time.Now().Format(utils.FormatDateTime)) }() // 更新推送信息 updateCols := make([]string, 0) updateCols = append(updateCols, "SendTemplateMsgTime", "TemplateMsgState") item.SendTemplateMsgTime = time.Now().Local() item.TemplateMsgState = 1 if e := item.Update(updateCols); e != nil { errMsg = "更新模板消息信息失败" err = errors.New("SendPriceDrivenTemplateMsg 更新模板消息信息失败, Err:" + e.Error()) } return } // SendPriceDrivenThsMsg 推送价格驱动同花顺客群消息 func SendPriceDrivenThsMsg(priceDrivenId int) (errMsg string, err error) { item, e := yb.GetPriceDrivenById(priceDrivenId) if e != nil { errMsg = "获取价格驱动失败" err = errors.New("SendPriceDrivenThsMsg 获取价格驱动详情失败, Err:" + e.Error()) return } if item.CoreContent == "" { errMsg = "核心内容不能为空" err = errors.New("SendPriceDrivenThsMsg 核心内容不能为空") return } if item.ThsMsgState == 1 { errMsg = "未更新品种或今日推送次数已达上限" err = errors.New("SendPriceDrivenThsMsg 今日推送次数已达上限") return } // 推送客群消息 //go func() { // _ = services.SendYbPriceDrivenToThs(priceDrivenId, item.VarietyTagId) //}() // 更新推送信息 updateCols := make([]string, 0) updateCols = append(updateCols, "SendThsMsgTime", "ThsMsgState") item.SendThsMsgTime = time.Now().Local() item.ThsMsgState = 1 if e := item.Update(updateCols); e != nil { errMsg = "更新客群消息信息失败" err = errors.New("SendPriceDrivenThsMsg 更新客群消息信息失败, Err:" + e.Error()) } return } // GetPriceDrivenClickCensusList 获取价格驱动统计列表 func GetPriceDrivenClickCensusList(startSize, pageSize, sortField, sortRule int) (total int, list []*response.PriceDrivenClickCensusItem, err error) { list = make([]*response.PriceDrivenClickCensusItem, 0) // 获取每个品种的最新的价格驱动信息 priceDrivenList, e := yb.GetRecentPriceDrivenList() if e != nil { err = errors.New("获取最新的价格驱动信息失败, Err: " + e.Error()) return } priceDrivenMap := make(map[int]*yb.PriceDriven, 0) for _, p := range priceDrivenList { priceDrivenMap[p.VarietyTagId] = p } total = len(priceDrivenList) // 获取标签累计点击量 priceDrivenIds := "" totalClickList, e := yb.GetPriceDrivenClick(priceDrivenIds) if e != nil { err = errors.New("获取价格驱动标签累计点击量失败, Err: " + e.Error()) return } totalClickMap := make(map[int]int) recentClickTimeMap := make(map[int]string) for _, t := range totalClickList { totalClickMap[t.VarietyTagId] = t.CountNum recentClickTimeMap[t.VarietyTagId] = t.RecentClickTime } // 获取标签最近点击量 priceDrivenIdArr := make([]string, 0) priceDrivenLen := len(priceDrivenList) for i := 0; i < priceDrivenLen; i++ { priceDrivenIdArr = append(priceDrivenIdArr, strconv.Itoa(priceDrivenList[i].PriceDrivenId)) } priceDrivenIds = strings.Join(priceDrivenIdArr, ",") recentClickList, e := yb.GetPriceDrivenClick(priceDrivenIds) if e != nil { err = errors.New("获取价格驱动标签最近点击量失败, Err: " + e.Error()) return } recentClickMap := make(map[int]int) for _, r := range recentClickList { recentClickMap[r.VarietyTagId] = r.CountNum } // 根据排序规则确定分页列表 pageList := make([]*yb.PriceDrivenVarietyTagClick, 0) if sortField == 0 { // 默认排序-价格驱动更新时间降序 pageList, e = yb.GetDefaultPriceDrivenPageClick(startSize, pageSize, priceDrivenIds) if e != nil { err = errors.New("获取价格驱动统计默认分页列表失败, Err: " + e.Error()) return } } else { // sortField排序字段:1-按照累计点击量排序 2-按照最近点击量排序 groupRule := "pd.price_driven_id" joinRule := "pd.variety_tag_id = vl.variety_tag_id" if sortField == 2 { joinRule = "pd.price_driven_id = vl.price_driven_id" groupRule = "pd.variety_tag_id " } // sortRule排序规则:1-升序 2-降序 orderRule := "count_num DESC" if sortRule == 1 { orderRule = "count_num ASC" } pageList, e = yb.GetPriceDrivenPageClick(startSize, pageSize, priceDrivenIds, joinRule, groupRule, orderRule) if e != nil { err = errors.New("获取价格驱动统计分页列表失败, Err: " + e.Error()) return } } // 获取标签列表 tagList, e := models.GetVarietyTagList() if e != nil { err = errors.New("获取标签列表失败, Err: " + e.Error()) return } tagMap := make(map[int]*models.VarietyTag, 0) for _, t := range tagList { tagMap[t.VarietyTagId] = t } // 遍历组合信息 for _, v := range pageList { fmt.Println(v.VarietyTagId) item := new(response.PriceDrivenClickCensusItem) pd := priceDrivenMap[v.VarietyTagId] if pd == nil { continue } tag := tagMap[v.VarietyTagId] if tag != nil { item.ClassifyId = tag.VarietyClassifyId item.ClassifyName = tag.VarietyClassifyName } item.PriceDrivenId = pd.PriceDrivenId item.VarietyTagId = pd.VarietyTagId item.VarietyTagName = pd.VarietyTagName item.MainVariable = pd.MainVariable item.CoreDrivenType = pd.CoreDrivenType item.CoreDrivenContent = pd.CoreDrivenContent item.LastModifyTime = pd.ModifyTime.Format(utils.FormatDateTime) item.TotalClickNum = totalClickMap[v.VarietyTagId] item.RecentClickNum = recentClickMap[v.VarietyTagId] item.RecentClickTime = recentClickTimeMap[v.VarietyTagId] list = append(list, item) } return } // GetPriceDrivenClickCensusList 获取价格驱动统计详情 func GetPriceDrivenClickCensusDetail(startSize, pageSize, varietyTagId, priceDrivenId int) (total, pageTotal int, list []*response.PriceDrivenClickCensusDetailItem, err error) { list = make([]*response.PriceDrivenClickCensusDetailItem, 0) total, detailList, e := yb.GetPriceDrivenPageClickDetail(startSize, pageSize, varietyTagId, priceDrivenId) if e != nil { err = errors.New("获取价格驱动统计详情列表失败, Err: " + e.Error()) return } // 查询用户相关的客户信息 detailLen := len(detailList) userIdArr := make([]string, 0) for i := 0; i < detailLen; i++ { userIdArr = append(userIdArr, strconv.Itoa(detailList[i].UserId)) } userIds := strings.Join(userIdArr, ",") userCompanyMap := make(map[int]*company.CompanyUser) if userIds != "" { companyUserList, e := company.GetFiccCompanyUserByUserIds(userIds) if e != nil { err = errors.New("获取客户信息失败 Err:" + e.Error()) return } for _, v := range companyUserList { userCompanyMap[int(v.UserId)] = v } } for _, v := range detailList { pageTotal += v.CountNum item := new(response.PriceDrivenClickCensusDetailItem) if u, ok := userCompanyMap[v.UserId]; ok { item.RealName = u.RealName item.CompanyName = u.CompanyName item.CompanyStatus = u.Status } item.CountNum = v.CountNum item.SourceAgent = v.NewSourceAgent item.RecentClickTime = v.RecentClickTime list = append(list, item) } return }