123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- package merchant
- import (
- "errors"
- stringUtils "eta/eta_mini_ht_api/common/utils/string"
- "eta/eta_mini_ht_api/models"
- "fmt"
- "sort"
- "strings"
- "sync/atomic"
- "time"
- )
- type SaleStatus string
- type MerchantProductType string
- const (
- detailColumns = "id,source_id,title,cover_src,cover_url,description,price,type,is_permanent,valid_days,sale_status,created_time,updated_time,deleted"
- detailColumnsWithRisk = "merchant_products.id,source_id,title,cover_src,cover_url,description,price,type,is_permanent,valid_days,sale_status,created_time,updated_time,deleted,permissions.risk_level as risk_level"
- sourceIdColumn = "id,source_id"
- )
- const (
- OnSale SaleStatus = "on_sale" //上架
- OffSale SaleStatus = "off_sale" //下架
- Package MerchantProductType = "package"
- Report MerchantProductType = "report"
- Video MerchantProductType = "video"
- Audio MerchantProductType = "audio"
- )
- // MerchantProduct 商户产品信息结构体
- type MerchantProduct struct {
- Id int `gorm:"column:id;primary_key;autoIncrement;comment:主键"`
- SourceId int `gorm:"column:source_id;type:int(11);comment:单品或者套餐对应的主键"`
- Title string `gorm:"column:title;type:varchar(255);comment:标题"`
- CoverSrc int `gorm:"column:cover_src;type:int(11);comment:封面图片资源库id"`
- CoverUrl string `gorm:"column:cover_url;type:varchar(255);comment:封面图片url"`
- Description string `gorm:"column:description;type:varchar(255);comment:描述"`
- Price string `gorm:"column:price;type:decimal(10,2);comment:价格"`
- RiskLevel string `gorm:"column:risk_level;type:varchar(100);comment:风险等级"`
- Type MerchantProductType `gorm:"column:type;type:enum('report','video','audio','package');not null;comment:类型"`
- IsPermanent bool `gorm:"column:is_permanent;type:int(1);not null;default:0;comment:是否永久"`
- ValidDays int `gorm:"column:valid_days;type:int(11);comment:有效期天数"`
- SaleStatus SaleStatus `gorm:"column:sale_status;type:enum('on_sale','off_sale');not null;default:'on_sale';comment:上架/下架状态"`
- Deleted int `gorm:"column:deleted;type:tinyint(1);not null;default:0;comment:是否删除"`
- CreatedTime time.Time `gorm:"column:created_time;type:datetime;comment:创建时间"`
- UpdatedTime time.Time `gorm:"column:updated_time;type:datetime;comment:更新时间;default:CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP"`
- }
- // TableName 指定表名
- func (MerchantProduct) TableName() string {
- return "merchant_products"
- }
- func GetMerchantProductById(id int) (product MerchantProduct, err error) {
- db := models.Main()
- err = db.Select(detailColumns).Where("id = ? ", id).First(&product).Error
- return
- }
- func GetMerchantProductBySourceId(sourceId int, productType ...MerchantProductType) (product MerchantProduct, err error) {
- db := models.Main()
- if len(productType) > 0 {
- if len(productType) == 1 {
- if productType[0] == Package {
- err = db.Select(detailColumnsWithRisk).Joins("left join permissions on permissions.permission_id=source_id").Where("source_id =? and type = ? and deleted =?", sourceId, productType[0], 0).First(&product).Error
- } else {
- err = db.Select(detailColumns).Where("source_id =? and type = ? and deleted =?", sourceId, productType[0], 0).First(&product).Error
- }
- } else {
- err = db.Select(detailColumns).Where("source_id =? and type in (?) and deleted =?", sourceId, productType, 0).First(&product).Error
- }
- } else {
- err = db.Select(detailColumns).Where("source_id =? and deleted =?", sourceId, 0).First(&product).Error
- }
- return
- }
- func GetProductListBySourceIds(ids []int, detail bool, productType ...MerchantProductType) (productList []MerchantProduct, err error) {
- db := models.Main()
- var columns string
- if productType == nil {
- err = errors.New("productType参数不能为空")
- return
- }
- if detail {
- columns = detailColumns
- } else {
- columns = sourceIdColumn
- }
- if len(productType) > 0 {
- if len(productType) == 1 {
- if productType[0] == Package {
- err = db.Select(detailColumnsWithRisk).Joins("left join permissions on permissions.permission_id=source_id").Where("source_id in ? and type = ? and deleted =? order by created_time desc", ids, productType[0], false).Find(&productList).Error
- } else {
- err = db.Select(columns).Where("source_id in ? and type = ? and deleted =? order by created_time desc", ids, productType[0], false).Find(&productList).Error
- }
- } else {
- err = db.Select(columns).Where("source_id in ? and type in (?) and deleted =? by created_time desc", ids, productType, false).Find(&productList).Error
- }
- } else {
- err = db.Select(columns).Where("source_id in ? and deleted =? by created_time desc", ids, productType, false).Find(&productList).Error
- }
- return
- }
- func GetTotalPageCountByProductType(productType MerchantProductType) (total int64, latestId int64) {
- db := models.Main()
- _ = db.Model(&MerchantProduct{}).Select("count(*)").Where("type=? and deleted =?", productType, false).Scan(&total).Error
- _ = db.Model(&MerchantProduct{}).Select("max(id)").Where("type=? and deleted =?", productType, false).Scan(&latestId).Error
- return
- }
- func GetProductPageByProductType(productIds []int, id int64, offset int, limit int) (list []MerchantProduct, err error) {
- db := models.Main()
- err = db.Select(detailColumns).Where("id <= ? and deleted =? and id in ? order by created_time desc limit ?,? ", id, false, productIds, offset, limit).Find(&list).Error
- return
- }
- func GetProductListByProductType(productType MerchantProductType, detail bool) (list []MerchantProduct, err error) {
- db := models.Main()
- var columns string
- if detail {
- columns = detailColumns
- } else {
- columns = sourceIdColumn
- }
- if productType == "" {
- err = errors.New("productType参数不能为空")
- return
- }
- err = db.Select(columns).Where(" type = ? and deleted =? order by created_time desc", productType, false).Find(&list).Error
- return
- }
- type MerchantProductIdMap struct {
- Type string
- SourceId string
- }
- func GetProductByProductType() (productIds map[string]string, err error) {
- db := models.Main()
- var productIdMap []MerchantProductIdMap
- sql := `SELECT type,GROUP_CONCAT(source_id ORDER BY source_id SEPARATOR ',') as source_id FROM merchant_products GROUP BY type`
- err = db.Raw(sql).Find(&productIdMap).Error
- productIds = make(map[string]string, len(productIdMap))
- for _, v := range productIdMap {
- productIds[v.Type] = v.SourceId
- }
- return
- }
- func generateSignalPdSql(idMap map[string][]int) (condition string) {
- for k, v := range idMap {
- if condition == "" {
- condition = "(" + fmt.Sprintf("(type ='%s' and source_id in (%s))", k, strings.Join(stringUtils.IntToStringSlice(v), ","))
- } else {
- condition = condition + fmt.Sprintf(" or (type ='%s' and source_id in (%s))", k, strings.Join(stringUtils.IntToStringSlice(v), ","))
- }
- }
- condition = condition + ")"
- if len(idMap) == 1 {
- condition = condition[1 : len(condition)-1]
- }
- return
- }
- func LatestId() (latestId int64) {
- db := models.Main()
- _ = db.Model(&MerchantProduct{}).Select("max(id)").Where("deleted=?", false).Scan(&latestId).Error
- return
- }
- type ProductDTO struct {
- SourceId int
- SourceType string
- Score float64
- }
- func ProductListBySort(list []ProductDTO, id int64, offset int, size int) (productList []MerchantProduct, err error) {
- var productMap = make(map[string][]int, len(list))
- sort.Slice(list, func(i, j int) bool {
- return list[i].Score > list[j].Score
- })
- var idSort []int
- for _, v := range list {
- idSort = append(idSort, v.SourceId)
- }
- for _, v := range list {
- ids := productMap[v.SourceType]
- ids = append(ids, v.SourceId)
- productMap[v.SourceType] = ids
- }
- sql := generateSignalPdSql(productMap)
- db := models.Main()
- query := fmt.Sprintf("id <= ? and deleted =? and %s order by Field(id,?) desc limit ?,?", sql)
- err = db.Select(detailColumns).Where(query, id, false, strings.Join(stringUtils.IntToStringSlice(idSort), ","), offset, size).Find(&productList).Error
- return
- }
- type packageStruct struct {
- SourceId int
- Weight int32
- }
- func PackageListBySort(weightMap map[int]*atomic.Int32, id int64, offset int, size int) (productList []MerchantProduct, err error) {
- var packageList []packageStruct
- for k, v := range weightMap {
- packageList = append(packageList, packageStruct{
- SourceId: k,
- Weight: v.Load(),
- })
- }
- sort.Slice(packageList, func(i, j int) bool {
- return packageList[i].Weight > packageList[j].Weight
- })
- var idSort []int
- for _, v := range packageList {
- idSort = append(idSort, v.SourceId)
- }
- db := models.Main()
- err = db.Select(detailColumns).Where("id <= ? and type =? and deleted =? and source_id in ? order by Field(id,?) desc limit ?,? ", id, Package, false, idSort, strings.Join(stringUtils.IntToStringSlice(idSort), ","), offset, size).Find(&productList).Error
- return
- }
- func GetOffSaleProducts(query []MerchantProductType) (list []MerchantProduct, err error) {
- db := models.Main()
- err = db.Select(detailColumns).Where(" deleted =? and type in ? and sale_status = ? ", false, query, OffSale).Find(&list).Error
- return
- }
- func GetReportOnSalePackageIds(ids []int) (sourceIds []int, err error) {
- sql := `
- SELECT
- r.id
- FROM
- reports r
- LEFT JOIN permission_classify_mapping pcm ON r.classify_id = pcm.classify_id
- LEFT JOIN merchant_products mp ON mp.source_id = pcm.permission_id
- AND mp.type = 'package'
- AND mp.sale_status = 'on_sale'
- AND mp.deleted = 0
- WHERE
- mp.id IS NOT NULL and r.id in ?
- UNION ALL
- SELECT
- r.id
- FROM
- reports r
- LEFT JOIN permissions p ON r.plate_name = p.NAME
- LEFT JOIN merchant_products mp ON mp.source_id = p.permission_id
- AND mp.type = 'package'
- AND mp.sale_status = 'on_sale'
- AND mp.deleted = 0
- WHERE
- mp.id IS NOT NULL and r.id in ?`
- db := models.Main()
- err = db.Raw(sql, ids, ids).Scan(&sourceIds).Error
- return
- }
- func GetMediaOnSalePackageIds(ids []int) (sourceIds []int, err error) {
- sql := ` SELECT
- distinct mpm.media_id
- FROM
- media_permission_mappings mpm
- LEFT JOIN merchant_products mp ON mp.source_id = mpm.permission_id
- AND mp.type = 'package'
- AND mp.sale_status = 'on_sale'
- and mp.deleted=0
- WHERE
- mpm.deleted=0 and mp.id is not null and mpm.media_id in ?`
- db := models.Main()
- err = db.Raw(sql, ids).Scan(&sourceIds).Error
- return
- }
- func GetOnSaleReportIds(ids []int) (sourceIds []int, err error) {
- sql := `SELECT
- r.id
- FROM
- reports r
- LEFT JOIN merchant_products mp ON mp.source_id = r.id
- AND mp.type = 'report'
- AND mp.sale_status = 'on_sale'
- AND mp.deleted = 0
- WHERE
- mp.id IS NOT NULL and r.id in ?`
- db := models.Main()
- err = db.Raw(sql, ids).Scan(&sourceIds).Error
- return
- }
- func GetOnSaleMediaIds(ids []int, productType MerchantProductType) (sourceIds []int, err error) {
- sql := `SELECT
- distinct mpm.media_id
- FROM
- media_permission_mappings mpm
- LEFT JOIN merchant_products mp ON mp.source_id = mpm.media_id
- AND mp.type = ?
- AND mp.sale_status = 'on_sale'
- AND mp.deleted = 0
- WHERE
- mpm.deleted=0 and mp.id is not null and mpm.media_id in ?`
- db := models.Main()
- err = db.Raw(sql, productType, ids).Scan(&sourceIds).Error
- return
- }
|