package media import ( "errors" logger "eta/eta_mini_ht_api/common/component/log" "eta/eta_mini_ht_api/common/exception" "eta/eta_mini_ht_api/common/utils/page" stringUtils "eta/eta_mini_ht_api/common/utils/string" configService "eta/eta_mini_ht_api/domian/config" permissionService "eta/eta_mini_ht_api/domian/config" mediaService "eta/eta_mini_ht_api/domian/media" productService "eta/eta_mini_ht_api/domian/merchant" userService "eta/eta_mini_ht_api/domian/user" mediaDao "eta/eta_mini_ht_api/models/media" productDao "eta/eta_mini_ht_api/models/merchant" "eta/eta_mini_ht_api/service/config" "eta/eta_mini_ht_api/service/report" "eta/eta_mini_ht_api/service/user" "fmt" "gorm.io/gorm" "strconv" "strings" "sync" ) const ( RiskLevelUnMatch = "unMatch" RiskLevelUnTest = "unTest" RiskLevelExpired = "expired" RiskLevelMatch = "match" defaultProductPrice = "0" ) type RecordCount struct { UserId int Mobile string MediaId int TraceId string MediaType string IpAddress string Location string Referer string Additional string } func convertToMediaCountDTO(record RecordCount) (dto userService.RecordCountDTO) { return userService.RecordCountDTO{ UserId: record.UserId, TraceId: record.TraceId, Mobile: record.Mobile, SourceId: record.MediaId, } } func CountMedia(count RecordCount) (traceId string, err error) { meida, err := mediaService.GetMediaById(count.MediaType, count.MediaId) if err != nil { err = exception.New(exception.MediaFoundFailed) return } dto := convertToMediaCountDTO(count) return userService.CountMedia(dto, meida.MediaType) } func RangeSearchByAnalyst(mediaType string, analystId int, userId int) (total int64, latestId int64, ids []int, mappingRiskLevel string) { var err error //登录了需要校验风险等级,如果风险等级没做或者过期直接返回空,做了就筛选风险等级 userProfile, userErr := user.GetUserProfile(userId) if userErr != nil { if errors.Is(userErr, gorm.ErrRecordNotFound) { err = exception.New(exception.TemplateUserNotFound) } else { err = exception.New(exception.TemplateUserFoundFailed) } logger.Error("分页查询报告列表失败:%v", err) return } //获取产品风险等级 if userProfile.RiskLevel == user.RiskUnTest { logger.Error("客户未做风险等级测评,mobile:%v", userProfile.Mobile) return } if userProfile.RiskLevelStatus == user.RiskExpired { logger.Error("客户风险等级已过期,mobile:%v", userProfile.Mobile) return } mapping, mappingErr := permissionService.GetRiskMappingByCustomerRiskLevel(userProfile.RiskLevel) if mappingErr != nil { logger.Error("查询产品风险等级映射失败:%v", mappingErr) return } mappingRiskLevel = mapping.ProductRiskLevel var permissionList []permissionService.PermissionDTO //获取所有设置风险等级的品种 permissionList, err = permissionService.GetPermissionListWithRisk() permissionList = filterPermissionsByRisk(permissionList, mapping.ProductRiskLevel) if len(permissionList) == 0 { return } var filterPermissionIds []int for _, permission := range permissionList { filterPermissionIds = append(filterPermissionIds, permission.PermissionId) } return mediaService.GetAnalystMediaPermissionMappingByPermissionIds(mediaType, filterPermissionIds, analystId, mappingRiskLevel) } func getCount(mediaType string, permissionIds []int, isLogin bool, userId int) (total int64, latestId int64, orgIds []int, mappingPdRisk string) { filterPermissionIds, riskLevel, err := report.CheckUserRisk(permissionIds, isLogin, userId) if err != nil { logger.Error("校验用户风险等级失败:%v", err) return } return mediaService.GetMediaPermissionMappingByPermissionIds(mediaType, filterPermissionIds, riskLevel) } func RangeSearch(mediaType string, isLogin bool, userId int) (total int64, latestId int64, ids []int, mappingPdRisk string) { return getCount(mediaType, nil, isLogin, userId) } func GetTotalPageCountByPermissionIds(mediaType string, permissionIds []int, isLogin bool, userId int) (total int64, latestId int64, ids []int, mappingPdRisk string) { if mediaType == "" { return } return getCount(mediaType, permissionIds, isLogin, userId) } func filterPermissionsByRisk(permissionList []permissionService.PermissionDTO, riskLevel string) (resultList []permissionService.PermissionDTO) { riskLevelNum, err := config.ParseRiskLevel(riskLevel) if err != nil { logger.Error("风险等级解析失败:%v", err) return } for _, permission := range permissionList { pRiskNum, riskErr := config.ParseRiskLevel(permission.RiskLevel) if riskErr != nil { logger.Error("解析品种风险等级失败 permission:%d,risk:%v", permission.PermissionId, permission.RiskLevel) continue } if pRiskNum <= riskLevelNum { resultList = append(resultList, permission) } } return } func SearchMaxMediaId(mediaType string, key string) (total int64, latestId int64) { return mediaService.SearchMaxMediaId(mediaType, key) } func GetMediaById(mediaType string, mediaId int, isLogin bool, userId int) (media mediaService.MediaDTO, err error) { media, err = mediaService.GetMediaById(mediaType, mediaId) if err != nil { logger.Error("获取媒体失败:%v", err) err = exception.New(exception.MediaFoundFailed) return } var status string status, media.RiskLevel, err = matchRiskLevel(userId, media) if err != nil { logger.Error("匹配风险等级失败:%v", err) err = exception.New(exception.ReportRiskLevelUnSet) return } idStr := strings.Split(media.PermissionIDs, ",") var ids []int ids, err = stringUtils.StringToIntSlice(idStr) if err != nil { logger.Error("品种名称列表转换失败:%v", err) return } media.PermissionNames = GetMediaPermissionNames(ids) if isLogin { media.Login = true if status != RiskLevelMatch { media.Src = "" } media.RiskLevelStatus = status } else { logger.Info("当前用户未登录,展示部分详情") media.Src = "" media.RiskLevelStatus = RiskLevelUnMatch media.Login = false } return } func matchRiskLevel(userId int, media mediaService.MediaDTO) (riskLevelMatch string, productRiskLevel string, err error) { userProfile, userErr := user.GetUserProfile(userId) if userErr != nil { if errors.Is(userErr, gorm.ErrRecordNotFound) { logger.Error("用户信息不存在,mobile:%d", userProfile.Mobile) err = exception.New(exception.TemplateUserNotFound) return } else { logger.Error("获取用户信息失败:%v", userErr) err = exception.New(exception.TemplateUserFoundFailed) return } } //比较风险等级 if userProfile.RiskLevelStatus == user.RiskUnTest { logger.Info("客户风险等级未测试,mobile:%v", userProfile.Mobile) riskLevelMatch = RiskLevelUnTest return } if userProfile.RiskLevelStatus == user.RiskExpired { logger.Info("客户风险等级已过期,mobile:%v", userProfile.Mobile) riskLevelMatch = RiskLevelExpired return } level, err := permissionService.GetRiskMappingByCustomerRiskLevel(userProfile.RiskLevel) if err != nil { logger.Error("获取媒体风险等级设置失败:%v", err) return } var permissionIds []int permissionStrList := strings.Split(media.PermissionIDs, ",") permissionIds, err = stringUtils.StringToIntSlice(permissionStrList) if err != nil { logger.Error("解析媒体品种ID列表失败:%v", err) } permissionDTOs, err := permissionService.GetPermissionListByIds(permissionIds) if err != nil { logger.Error("获取品种风险等级失败:%v", err) return } //能够查看最高等级 matchNum, err := config.ParseRiskLevel(level.ProductRiskLevel) if err != nil { logger.Error("解析风险等级失败:%v", err) return } if len(permissionDTOs) == 0 { logger.Error("当前报告对应品种未设置风险等级") err = exception.New(exception.ReportRiskLevelUnSet) return } //能够查看需要的最小等级 num := config.GetHighestRiskLevel(permissionDTOs) productRiskLevel = fmt.Sprintf("R%d", num) if num > matchNum { riskLevelMatch = RiskLevelUnMatch return } else { riskLevelMatch = RiskLevelMatch return } } func getLowestRiskLevel(permissions []permissionService.PermissionDTO) (riskLevelNum int) { for _, permission := range permissions { pRiskNum, err := config.ParseRiskLevel(permission.RiskLevel) if err != nil { logger.Error("解析风险等级失败:%v", err) continue } if riskLevelNum == 0 { riskLevelNum = pRiskNum } else { if riskLevelNum > pRiskNum { riskLevelNum = pRiskNum } } } return } func GetMediaPageByAnalystId(mediaType string, pageInfo page.PageInfo, analystId int, mediaIds []int, userId int, mappingRiskLevel string) (list []mediaService.MediaDTO, err error) { list, err = mediaService.GetMediaPageByAnalystId(mediaType, pageInfo, analystId, mediaIds) if err != nil { err = exception.New(exception.GetAnalystMediaListFailed) return } if len(list) == 0 { logger.Info("研究员媒体列表为空") return } //并发获取媒体的标签 var wg sync.WaitGroup wg.Add(len(list)) for i := 0; i < len(list); i++ { //go func(media *mediaService.MediaDTO) { // defer wg.Done() // idStr := strings.Split(media.PermissionIDs, ",") // var ids []int // ids, err = stringUtils.StringToIntSlice(idStr) // if err != nil { // logger.Error("品种名称列表转换失败:%v", err) // } // media.PermissionNames = getMediaPermissionNames(ids) go func(media *mediaService.MediaDTO) { defer wg.Done() idStr := strings.Split(media.PermissionIDs, ",") var ids []int ids, err = stringUtils.StringToIntSlice(idStr) if err != nil { logger.Error("获取品种列表失败:%v", err) } media.PermissionNames = GetMediaPermissionNames(ids) permissions, permissionErr := getMediaSecondPermissions(ids) if permissionErr != nil { logger.Error("获取媒体品种信息失败:%v,无法设置媒体风险等级", err) } riskNum := config.GetHighestRiskLevel(permissions) media.RiskLevel = strings.Join([]string{"R", strconv.Itoa(riskNum)}, "") media.Login = true var productType productDao.MerchantProductType switch media.MediaType { case string(mediaDao.Audio): productType = productDao.Audio case string(mediaDao.Video): productType = productDao.Video default: logger.Error("未知媒体类型:%s", media.MediaType) productType = "" } product, pdErr := productService.GetProductBySourceId(media.MediaId, productType) if pdErr != nil { if errors.Is(pdErr, gorm.ErrRecordNotFound) { media.Price = defaultProductPrice media.IsFree = true media.IsSubscribe = false } else { media.Price = defaultProductPrice media.IsFree = false media.IsSubscribe = false } } else { media.Price = product.Price.String() media.IsFree = false } subscribe, subscribeErr := userService.GetUserSubscribe(product.Id, userId) if subscribeErr != nil { media.IsSubscribe = false } else { media.IsSubscribe = subscribe.Status == productDao.SubscribeValid } media.RiskLevelStatus = RiskLevelMatch pdRiskNum, parseErr := config.ParseRiskLevel(product.RiskLevel) if parseErr != nil { media.RiskLevelStatus = RiskLevelUnMatch return } rpRiskNum, parseErr := config.ParseRiskLevel(media.RiskLevel) if parseErr != nil { media.RiskLevelStatus = RiskLevelUnMatch return } mappingRiskNum, parseErr := config.ParseRiskLevel(mappingRiskLevel) if parseErr != nil { media.RiskLevelStatus = RiskLevelUnMatch return } if rpRiskNum <= pdRiskNum { media.RiskLevel = product.RiskLevel if mappingRiskNum < pdRiskNum { media.RiskLevelStatus = RiskLevelUnMatch } } else { if mappingRiskNum < rpRiskNum { media.RiskLevelStatus = RiskLevelUnMatch } } }(&list[i]) } wg.Wait() if err != nil { err = exception.New(exception.GetAnalystMediaListFailed) } return } func getMediaSecondPermissions(ids []int) (permissionDTOs []configService.PermissionDTO, err error) { return mediaService.GetSecondPermissionsByIds(ids) } func GetMediaPageByIds(mediaType string, pageInfo page.PageInfo, mediaIds []int, isLogin bool, userId int, mappingRiskLevel string) (list []mediaService.MediaDTO, err error) { list, err = mediaService.GetMediaPageByIds(mediaType, pageInfo, mediaIds) if err != nil { err = exception.New(exception.GetMediaListFailed) return } //并发获取媒体的标签 var wg sync.WaitGroup wg.Add(len(list)) for i := 0; i < len(list); i++ { go func(media *mediaService.MediaDTO) { defer wg.Done() idStr := strings.Split(media.PermissionIDs, ",") var ids []int ids, err = stringUtils.StringToIntSlice(idStr) if err != nil { logger.Error("品种名称列表转换失败:%v", err) } media.PermissionNames = GetMediaPermissionNames(ids) permissions, permissionErr := getMediaSecondPermissions(ids) if permissionErr != nil { logger.Error("获取媒体品种信息失败:%v,无法设置媒体风险等级", err) } riskNum := config.GetHighestRiskLevel(permissions) media.RiskLevel = strings.Join([]string{"R", strconv.Itoa(riskNum)}, "") if !isLogin { media.Src = "" } media.Login = isLogin var productType productDao.MerchantProductType switch media.MediaType { case string(mediaDao.Audio): productType = productDao.Audio case string(mediaDao.Video): productType = productDao.Video default: logger.Error("未知媒体类型:%s", media.MediaType) productType = "" } product, pdErr := productService.GetProductBySourceId(media.MediaId, productType) isFree := true if pdErr != nil { if errors.Is(pdErr, gorm.ErrRecordNotFound) { media.Price = defaultProductPrice media.IsFree = true media.IsSubscribe = false } else { media.Price = defaultProductPrice media.IsFree = false media.IsSubscribe = false } } else { media.Price = product.Price.String() media.IsFree = false isFree = false } if isLogin { subscribe, subscribeErr := userService.GetUserSubscribe(product.Id, userId) if subscribeErr != nil { media.IsSubscribe = false } else { media.IsSubscribe = subscribe.Status == productDao.SubscribeValid } } media.RiskLevelStatus = RiskLevelMatch mappingRiskNum, parseErr := config.ParseRiskLevel(mappingRiskLevel) if parseErr != nil { media.RiskLevelStatus = RiskLevelUnMatch return } var rpRiskNum int rpRiskNum, parseErr = config.ParseRiskLevel(media.RiskLevel) if parseErr != nil { media.RiskLevelStatus = RiskLevelUnMatch return } if !isFree { var pdRiskNum int pdRiskNum, parseErr = config.ParseRiskLevel(product.RiskLevel) if parseErr != nil { media.RiskLevelStatus = RiskLevelUnMatch return } if rpRiskNum <= pdRiskNum { media.RiskLevel = product.RiskLevel if mappingRiskNum < pdRiskNum { media.RiskLevelStatus = RiskLevelUnMatch } } else { if mappingRiskNum < rpRiskNum { media.RiskLevelStatus = RiskLevelUnMatch } } } else { if mappingRiskNum < rpRiskNum { media.RiskLevelStatus = RiskLevelUnMatch } } }(&list[i]) } wg.Wait() if err != nil { err = exception.New(exception.QueryReportPageFailed) } return } func GetMediaPermissionNames(id []int) (labels []string) { permissions, err := mediaService.GetPermissionsByIds(id) if err != nil { logger.Error("查询品种名称列表失败:%v", err) labels = []string{} return } for _, permission := range permissions { labels = append(labels, permission.PermissionName) } return } // stringToIntSlice 将一个包含数字字符串的切片转换为整数切片 func SearchMediaList(mediaType string, key string, mediaIds []int, pageInfo page.PageInfo, isLogin bool, userId int, mappingRiskLevel string) (medias []mediaService.MediaDTO, err error) { offset := page.StartIndex(pageInfo.Current, pageInfo.PageSize) medias, err = mediaService.SearchMediaList(mediaType, key, mediaIds, offset, pageInfo.PageSize, pageInfo.LatestId) var wg sync.WaitGroup wg.Add(len(medias)) for i := 0; i < len(medias); i++ { go func(media *mediaService.MediaDTO) { defer wg.Done() idStr := strings.Split(media.PermissionIDs, ",") var ids []int ids, err = stringUtils.StringToIntSlice(idStr) if err != nil { logger.Error("获取品种列表失败:%v", err) } media.PermissionNames = GetMediaPermissionNames(ids) permissions, permissionErr := getMediaSecondPermissions(ids) if permissionErr != nil { logger.Error("获取媒体品种信息失败:%v,无法设置媒体风险等级", err) } riskNum := config.GetHighestRiskLevel(permissions) media.RiskLevel = strings.Join([]string{"R", strconv.Itoa(riskNum)}, "") if !isLogin { media.Src = "" } media.Login = isLogin var productType productDao.MerchantProductType switch media.MediaType { case string(mediaDao.Audio): productType = productDao.Audio case string(mediaDao.Video): productType = productDao.Video default: logger.Error("未知媒体类型:%s", media.MediaType) productType = "" } product, pdErr := productService.GetProductBySourceId(media.MediaId, productType) if pdErr != nil { if errors.Is(pdErr, gorm.ErrRecordNotFound) { media.Price = defaultProductPrice media.IsFree = true media.IsSubscribe = false } else { media.Price = defaultProductPrice media.IsFree = false media.IsSubscribe = false } } else { media.Price = product.Price.String() media.IsFree = false } if isLogin { subscribe, subscribeErr := userService.GetUserSubscribe(product.Id, userId) if subscribeErr != nil { media.IsSubscribe = false } else { media.IsSubscribe = subscribe.Status == productDao.SubscribeValid } } media.RiskLevelStatus = RiskLevelMatch pdRiskNum, parseErr := config.ParseRiskLevel(product.RiskLevel) if parseErr != nil { media.RiskLevelStatus = RiskLevelUnMatch return } rpRiskNum, parseErr := config.ParseRiskLevel(media.RiskLevel) if parseErr != nil { media.RiskLevelStatus = RiskLevelUnMatch return } mappingRiskNum, parseErr := config.ParseRiskLevel(mappingRiskLevel) if parseErr != nil { media.RiskLevelStatus = RiskLevelUnMatch return } if rpRiskNum <= pdRiskNum { media.RiskLevel = product.RiskLevel if mappingRiskNum < pdRiskNum { media.RiskLevelStatus = RiskLevelUnMatch } } else { if mappingRiskNum < rpRiskNum { media.RiskLevelStatus = RiskLevelUnMatch } } }(&medias[i]) } wg.Wait() if err != nil { err = exception.New(exception.SearchReportPageFailed) } return }