package yb import ( "encoding/json" "fmt" "github.com/rdlucklib/rdluck_tools/paging" "hongze/hz_crm_api/controllers" "hongze/hz_crm_api/models" ybModels "hongze/hz_crm_api/models/yb" "hongze/hz_crm_api/models/yb/request" "hongze/hz_crm_api/services" "hongze/hz_crm_api/services/yb" "hongze/hz_crm_api/utils" "sort" "strings" "time" ) // RoadVideoController 研报视频社区 type RoadVideoController struct { controllers.BaseAuthController } // List // @Title 视频列表 // @Description 视频列表 // @Param Keywords query string false "关键词" // @Param SortParam query string false "排序字段参数,用来排序的字段, 枚举值:'ClickNum':点击量" // @Param SortType query string true "如何排序,是正序还是倒序,枚举值:`asc 正序`,`desc 倒叙`" // @Success 200 {object} response.CommunityQuestionListResp // @router /road/video/list [get] func (r *RoadVideoController) List() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { r.Data["json"] = br r.ServeJSON() }() sysUser := r.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } condition := "" pars := make([]interface{}, 0) keywords := r.GetString("Keywords", "") if keywords != "" { keywords = "%" + keywords + "%" condition += ` AND v.title LIKE ? ` pars = append(pars, keywords) } var startSize int pageSize, _ := r.GetInt("PageSize") currentIndex, _ := r.GetInt("CurrentIndex") if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } startSize = paging.StartIndex(currentIndex, pageSize) // 排序相关 sortParam := r.GetString("SortParam") sortType := r.GetString("SortType") orderStr := "" if sortType != "" && strings.ToLower(sortType) != "desc" && strings.ToLower(sortType) != "asc" { br.Msg = "请输入正确的排序类型" return } if sortParam == "ClickNum" { orderStr = " ORDER BY l.click_num" if sortType != "" { orderStr += " " + sortType } else { orderStr += " DESC" } orderStr += ", v.modify_time DESC" } total, resp, err, errMsg := yb.GetRoadVideoList(condition, pars, orderStr, startSize, pageSize) if err != nil { br.Msg = errMsg br.ErrMsg = err.Error() return } page := paging.GetPaging(currentIndex, pageSize, total) resp.Paging = page br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // Save // @Title 保存视频 // @Description 保存视频 // @Param request body request.RoadVideoSaveReq true "type json string" // @Success 200 string "操作成功" // @router /road/video/save [post] func (r *RoadVideoController) Save() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { r.Data["json"] = br r.ServeJSON() }() sysUser := r.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req request.RoadVideoSaveReq if err := json.Unmarshal(r.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.Title == "" { br.Msg = "请输入标题" return } if req.ChartPermissionIds == "" { br.Msg = "请选择品种" return } if req.CoverImgUrl == "" { br.Msg = "请上传封面图" return } if req.VideoUrl == "" { br.Msg = "请上传视频" return } data, errMsg, err := yb.SaveRoadVideo(sysUser, req.VideoId, req.ReportId, req.ChartPermissionIds, req.Title, req.CoverImgUrl, req.VideoUrl, req.VideoSeconds) if err != nil { br.Msg = errMsg br.ErrMsg = "Yb-SaveVideo ErrMsg:" + err.Error() return } br.Ret = 200 br.Success = true br.Msg = "操作成功" br.Data = data } // Delete // @Title 删除视频 // @Description 删除视频 // @Param request body request.RoadVideoOptionReq true "type json string" // @Success 200 string "操作成功" // @router /road/video/delete [post] func (r *RoadVideoController) Delete() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { r.Data["json"] = br r.ServeJSON() }() sysUser := r.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req request.RoadVideoOptionReq if err := json.Unmarshal(r.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.VideoId <= 0 { br.Msg = "参数有误" return } errMsg, err := yb.SoftDeleteRoadVideo(req.VideoId) if err != nil { br.Msg = errMsg br.ErrMsg = "Yb-DeleteVideo ErrMsg:" + err.Error() return } br.Ret = 200 br.Success = true br.Msg = "操作成功" } // Publish // @Title 发布/取消视频 // @Description 发布/取消视频 // @Param request body request.RoadVideoPublishReq true "type json string" // @Success 200 string "操作成功" // @router /road/video/publish [post] func (r *RoadVideoController) Publish() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { r.Data["json"] = br r.ServeJSON() }() sysUser := r.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req request.RoadVideoPublishReq if err := json.Unmarshal(r.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.VideoId <= 0 { br.Msg = "参数有误" return } errMsg, err := yb.PublishRoadVideo(req.VideoId, req.PublishState) if err != nil { br.Msg = errMsg br.ErrMsg = "Yb-PublishVideo ErrMsg:" + err.Error() return } br.Ret = 200 br.Success = true br.Msg = "操作成功" } // SendThs // @Title 推送客群消息 // @Description 推送客群消息 // @Param request body request.RoadVideoOptionReq true "type json string" // @Success 200 string "操作成功" // @router /road/video/send_ths [post] func (r *RoadVideoController) SendThs() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { r.Data["json"] = br r.ServeJSON() }() sysUser := r.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req request.RoadVideoOptionReq if err := json.Unmarshal(r.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.VideoId <= 0 { br.Msg = "参数有误" return } errMsg, err := yb.SendRoadVideoThsMsg(req.VideoId) if err != nil { br.Msg = errMsg br.ErrMsg = "Yb-SendVideoThsMsg ErrMsg:" + err.Error() return } br.Ret = 200 br.Success = true br.Msg = "操作成功" } // VideoPlayLogList // @Title 获取视频点击量列表 // @Description 获取视频点击量列表 // @Param VideoId query int false "视频ID" // @Param SortType query int false "播放时长排序:默认倒序; 1-倒序(多一个数方便前端回显); 2-正序" // @Success 200 {object} response.QuestionClickLogListResp // @router /road/video/click/logs [get] func (r *RoadVideoController) VideoPlayLogList() { br := new(models.BaseResponse).Init() defer func() { r.Data["json"] = br r.ServeJSON() }() sysUser := r.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } videoId, _ := r.GetInt("VideoId") if videoId <= 0 { br.Msg = "请输入正确的视频ID" return } // 播放时长排序:1-DESC; 2-ASC; sortType, _ := r.GetInt("SortType") var startSize int pageSize, _ := r.GetInt("PageSize") currentIndex, _ := r.GetInt("CurrentIndex") if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } startSize = paging.StartIndex(currentIndex, pageSize) total, resp, err := yb.GetVideoPlayLogList(videoId, 2, startSize, pageSize, sortType) if err != nil { br.Msg = "获取点击量详情列表失败" br.ErrMsg = "VideoPlayLogList ErrMsg:" + err.Error() return } page := paging.GetPaging(currentIndex, pageSize, int(total)) resp.Paging = page br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // SendTemplateMsg // @Title 推送模板消息 // @Description 推送模板消息 // @Param request body request.RoadVideoOptionReq true "type json string" // @Success 200 string "操作成功" // @router /road/video/send_template_msg [post] func (r *RoadVideoController) SendTemplateMsg() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { r.Data["json"] = br r.ServeJSON() }() sysUser := r.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req request.RoadVideoOptionReq if err := json.Unmarshal(r.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.VideoId <= 0 { br.Msg = "参数有误" return } errMsg, err := yb.SendRoadVideoTemplateMsg(req.VideoId) if err != nil { br.Msg = errMsg br.ErrMsg = "Yb-SendRoadVideoTemplateMsg ErrMsg:" + err.Error() return } br.Ret = 200 br.Success = true br.Msg = "操作成功" } // GetPermission // @Title 查询品种权限 // @Description 查询品种权限 // @Param request body request.RoadVideoOptionReq true "type json string" // @Success 200 string "操作成功" // @router /road/permission [get] func (r *RoadVideoController) GetPermission() { br := new(models.BaseResponse).Init() defer func() { r.Data["json"] = br r.ServeJSON() }() sysUser := r.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } ret, err := yb.GetFiccPermission() if err != nil { br.Msg = "查询权限出错" br.ErrMsg = "Yb-SendVideoThsMsg ErrMsg:" + err.Error() return } br.Ret = 200 br.Success = true br.Msg = "操作成功" br.Data = ret } // TwoWeekClassifyList // @Title 路演视频-关联报告类型列表 // @Description 路演视频-关联报告类型列表 // @Success 200 {object} models.SimpleClassifyList // @router /road/video/two_week_classify_list [get] func (r *RoadVideoController) TwoWeekClassifyList() { br := new(models.BaseResponse).Init() defer func() { r.Data["json"] = br r.ServeJSON() }() sysUser := r.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } // 2023-04-19 取classify表relate_video=1的二级分类, 但是需要分层级, 所以对应的一级分类也要组合起来 list, e := models.GetAllClassify() if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取路演视频可选报告分类失败, Err: " + e.Error() return } resp := make([]*models.SimpleClassifyList, 0) parentMap := make(map[int]*models.SimpleClassifyList) classifyMap := make(map[int]*models.Classify) for _, c := range list { classifyMap[c.Id] = c if c.ParentId > 0 && c.RelateVideo == 1 { if parentMap[c.ParentId] == nil { parentMap[c.ParentId] = new(models.SimpleClassifyList) } } } for k, v := range parentMap { p := classifyMap[k] if p == nil { continue } v.Id = p.Id v.ClassifyName = p.ClassifyName v.Sort = p.Sort v.Child = make([]*models.SimpleClassifyList, 0) for _, c := range list { if c.ParentId == v.Id && c.RelateVideo == 1 { v.Child = append(v.Child, &models.SimpleClassifyList{ Id: c.Id, ClassifyName: c.ClassifyName, ParentId: c.ParentId, Sort: c.Sort, }) } } sort.Slice(v.Child, func(i, j int) bool { return v.Child[j].Sort > v.Child[i].Sort }) resp = append(resp, v) } sort.Slice(resp, func(i, j int) bool { return resp[j].Sort > resp[i].Sort }) br.Ret = 200 br.Success = true br.Msg = "操作成功" br.Data = resp } // SimpleReportList // @Title 路演视频选择报告-列表 // @Description 路演视频选择报告-列表 // @Param ClassifyIdSecond query int false "二级分类ID" // @Param Keyword query string false "关键词-报告标题" // @Success 200 string "获取成功" // @router /road/video/simple_report_list [get] func (r *RoadVideoController) SimpleReportList() { br := new(models.BaseResponse).Init() defer func() { r.Data["json"] = br r.ServeJSON() }() sysUser := r.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } cond := ` AND state = 2` pars := make([]interface{}, 0) classifyIdSecond, _ := r.GetInt("ClassifyIdSecond", 0) if classifyIdSecond <= 0 { // 2023-03-03 直接取classify表relate_video=1的二级分类下的报告 classifyCond := ` AND parent_id > 0 AND relate_video = 1` classifyPars := make([]interface{}, 0) classifyList, e := models.GetClassifyByCondition(classifyCond, "", classifyPars) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取路演视频可选报告分类失败, Err: " + e.Error() return } classifyIds := make([]int, 0) for _, c := range classifyList { classifyIds = append(classifyIds, c.Id) } if len(classifyIds) > 0 { cond += ` AND classify_id_second IN ( ` + utils.GetOrmInReplace(len(classifyIds)) + ` ) ` pars = append(pars, classifyIds) } else { cond += ` AND 1 = 2` } } if classifyIdSecond > 0 { cond += ` AND classify_id_second = ? ` pars = append(pars, classifyIdSecond) } keyword := r.GetString("Keyword", "") if keyword != "" { kw := fmt.Sprint("%", keyword, "%") cond += ` AND title LIKE ?` pars = append(pars, kw) } fieldArr := []string{"id", "classify_id_second", "title", "publish_time"} orderRule := ` ORDER BY publish_time DESC, id DESC` reports, e := models.GetReportByCondition(cond, pars, fieldArr, orderRule, true, 0, 5) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取双周报列表失败, Err: " + e.Error() return } // 查询报告权限 classifyPermissions := make(map[int][]int, 0) { classifyIds := make([]int, 0) for _, v := range reports { if utils.InArrayByInt(classifyIds, v.ClassifyIdSecond) { continue } classifyIds = append(classifyIds, v.ClassifyIdSecond) } if len(classifyIds) > 0 { cnd := fmt.Sprintf(` AND id IN (%s)`, utils.GetOrmInReplace(len(classifyIds))) ps := make([]interface{}, 0) ps = append(ps, classifyIds) classifies, e := models.GetClassifyByCondition(cnd, "", ps) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取报告分类失败, Err: " + e.Error() return } classifyNames := make([]string, 0) classifyNameId := make(map[string]int, 0) for _, v := range classifies { classifyNameId[v.ClassifyName] = v.Id classifyNames = append(classifyNames, v.ClassifyName) } if len(classifyNames) > 0 { classifyNamePermissions, e := models.GetPermissionsByClassifyNames(classifyNames) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取分类权限失败, Err: " + e.Error() return } namePermissions := make(map[string][]int, 0) for _, v := range classifyNamePermissions { if namePermissions[v.KeyWord] == nil { namePermissions[v.KeyWord] = make([]int, 0) } namePermissions[v.KeyWord] = append(namePermissions[v.KeyWord], v.ChartPermissionId) } for k, v := range classifyNameId { classifyPermissions[v] = namePermissions[k] } } } } type SimpleReportListResp struct { ReportId int Title string PublishTime string BindVideo int BindVideoTitle string PermissionIds []int } respList := make([]*SimpleReportListResp, 0) if len(reports) > 0 { reportIds := make([]int, 0) for i := range reports { reportIds = append(reportIds, reports[i].Id) } // 是否绑定 videos, e := ybModels.GetRoadVideoListByReportIds(reportIds) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取路演视频列表失败, Err: " + e.Error() return } bindMap := make(map[int]int) bindTitleMap := make(map[int]string) for i := range videos { bindMap[videos[i].ReportId] = videos[i].RoadVideoId bindTitleMap[videos[i].ReportId] = videos[i].Title } for i := range reports { respList = append(respList, &SimpleReportListResp{ ReportId: reports[i].Id, Title: reports[i].Title, PublishTime: reports[i].PublishTime.Format(utils.FormatDateTime), BindVideo: bindMap[reports[i].Id], BindVideoTitle: bindTitleMap[reports[i].Id], PermissionIds: classifyPermissions[reports[i].ClassifyIdSecond], }) } } br.Ret = 200 br.Success = true br.Msg = "操作成功" br.Data = respList } // SendMsg // @Title 推送消息(模板/客群) // @Description 推送消息(模板/客群) // @Param request body request.RoadVideoOptionReq true "type json string" // @Success 200 string "操作成功" // @router /road/video/send_msg [post] func (r *RoadVideoController) SendMsg() { br := new(models.BaseResponse).Init() br.IsSendEmail = false defer func() { r.Data["json"] = br r.ServeJSON() }() sysUser := r.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req request.RoadVideoOptionReq if err := json.Unmarshal(r.Ctx.Input.RequestBody, &req); err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.VideoId <= 0 { br.Msg = "参数有误" return } // 加锁,避免重复点击造成的多次推送 { redisKey := fmt.Sprint("road_video:send:msg:", req.VideoId) ok := utils.Rc.SetNX(redisKey, 1, time.Second*300) if !ok { br.Msg = "消息已推送, 请勿重复推送" return } defer func() { _ = utils.Rc.Delete(redisKey) }() } item, e := ybModels.GetRoadVideoById(req.VideoId) if e != nil { br.Msg = "视频不存在或已被删除" br.ErrMsg = "获取路演视频失败, Err: " + e.Error() return } if item.PublishState != 1 { br.Msg = "视频未发布, 不可推送" return } if item.SendThsState == 1 && item.SendTemplateState == 1 { br.Msg = "请勿重复推送" return } nowTime := time.Now().Local() updateCols := make([]string, 0) // 可能存在历史数据两个只推了一个所以此处加个判断 // 模板消息 if item.SendTemplateState == 0 { updateCols = append(updateCols, "SendTemplateState", "SendTemplateTime") item.SendTemplateState = 1 item.SendTemplateTime = nowTime go func() { _ = services.SendYbRoadVideoWxMsg(item.RoadVideoId, item.Title, item.PublishTime.Format(utils.FormatDateTime), item.ChartPermissionIds) }() } // 客群消息 if item.SendThsState == 0 { updateCols = append(updateCols, "SendThsState", "SendThsTime") item.SendThsState = 1 item.SendThsTime = nowTime //go func() { // _ = services.SendYbRoadVideoThs(item.RoadVideoId, item.Title, item.ChartPermissionIds) //}() } // 更新状态 if e := item.Update(updateCols); e != nil { br.Msg = "推送失败" br.ErrMsg = "更新路演视频信息失败, Err: " + e.Error() return } br.Ret = 200 br.Success = true br.Msg = "操作成功" }