You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

351 lines
8.6 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package article
import (
"cls/internal/domain/article"
"cls/internal/domain/free_trial"
"cls/internal/domain/purchase"
domainUser "cls/internal/domain/user"
"cls/pkg/logger"
"cls/pkg/util/page"
"errors"
"strings"
"time"
"xorm.io/builder"
)
type ArticleService struct {
repo article.ArticleRepository
userRepo domainUser.UserRepository
purchaseRepo purchase.Repository
FreeRepo free_trial.FreeTrialRepository
resp *ArticleResp
log logger.Logger
}
func NewArticleService(repo article.ArticleRepository,
userRepo domainUser.UserRepository,
purchaseRepo purchase.Repository,
FreeRepo free_trial.FreeTrialRepository,
resp *ArticleResp,
log logger.New) *ArticleService {
return &ArticleService{repo,
userRepo,
purchaseRepo,
FreeRepo,
resp,
log("cls:service:article")}
}
var class_type = map[int64]string{
20014: "狙击龙虎榜",
20015: "盘中宝",
20021: "风口研报",
20022: "公告全知道",
20023: "研选",
20025: "财联社早知道",
20026: "电报解读",
20087: "金牌纪要库",
}
var class_type_reverse = map[string]int64{
"狙击龙虎榜": 20014,
"盘中宝": 20015,
"风口研报": 20021,
"公告全知道": 20022,
"研选": 20023,
"财联社早知道": 20025,
"电报解读": 20026,
"金牌纪要库": 20087,
}
func (a *ArticleService) Find(ePhone string, page *page.Page, searchParams map[string]string) error {
conds := make([]builder.Cond, 0)
class := searchParams["search_like_class"]
if class != "" {
classCode := class_type_reverse[class]
if classCode != 0 {
conds = append(conds, builder.Eq{"type": classCode})
}
}
conds = append(conds, builder.And(builder.Gt{"ctime": time.Now().AddDate(0, 0, -2).Unix()}))
articles := make([]*article.LianV1Article, 0)
page.Content = &articles
err := a.repo.Find(page, conds)
if err != nil {
a.log.Error(err)
return err
}
user, err := a.userRepo.FindByPhone(ePhone)
if err != nil {
a.log.Error(err)
}
articleIds := make([]uint64, 0, len(articles))
for _, v := range articles {
articleIds = append(articleIds, v.Id)
}
purchaseId := make(map[uint64]struct{})
if user != nil {
purchaseData, err := a.purchaseRepo.FindArticleById(articleIds...)
if err != nil {
a.log.Error(err.Error())
}
if purchaseData != nil {
for _, v := range purchaseData {
purchaseId[v.ContentId] = struct{}{}
}
}
}
articleIds = nil
result := make([]*ArticleDto, 0, len(articles))
for _, v := range articles {
t := time.Unix(v.Ctime, 0) // 秒数和纳秒数0 表示没有纳秒部分
m, g := a.getMainGrowthBoard(v.Stocks)
_, lock := purchaseId[v.Id]
result = append(result, &ArticleDto{
EventId: v.Id,
Title: v.Title,
Class: class_type[v.Type],
ReleaseDate: t.Format("2006-01-02"),
ReleaseTime: t.Format("15:04"),
Brief: v.Brief,
MainBoard: m,
GrowthBoard: g,
Unlock: lock,
})
}
articles = nil
page.Content = &result
return nil
}
func (a *ArticleService) FindUnLock(ePhone string, page *page.Page, searchParams map[string]string) error {
user, err := a.userRepo.FindByPhone(ePhone)
if err != nil {
a.log.Error(err)
return err
}
conds := make([]builder.Cond, 0)
class := searchParams["search_like_class"]
if class != "" {
classCode := class_type_reverse[class]
if classCode != 0 {
conds = append(conds, builder.Eq{"type": classCode})
}
}
purchaseData, err := a.purchaseRepo.FindArticlesByUserId(user.Id)
if err != nil {
a.log.Error(err)
return err
}
if len(purchaseData) == 0 {
return nil
}
pId := make([]uint64, 0, len(purchaseData))
for _, v := range purchaseData {
pId = append(pId, v.ContentId)
}
conds = append(conds, builder.In("id"))
articles := make([]*article.LianV1Article, 0)
page.Content = &articles
err = a.repo.Find(page, conds)
if err != nil {
a.log.Error(err)
return err
}
result := make([]*ArticleDto, 0, len(articles))
for _, v := range articles {
t := time.Unix(v.Ctime, 0) // 秒数和纳秒数0 表示没有纳秒部分
m, g := a.getMainGrowthBoard(v.Stocks)
result = append(result, &ArticleDto{
EventId: v.Id,
Title: v.Title,
Class: class_type[v.Type],
ReleaseDate: t.Format("2006-01-02"),
ReleaseTime: t.Format("15:04"),
Brief: v.Brief,
Content: v.Content,
Stocks: v.Stocks,
MainBoard: m,
GrowthBoard: g,
Unlock: false,
})
}
articles = nil
page.Content = &result
return nil
}
func (a *ArticleService) FindFree(page *page.Page, searchParams map[string]string) error {
conds := make([]builder.Cond, 0)
class := searchParams["search_like_class"]
if class != "" {
classCode := class_type_reverse[class]
if classCode != 0 {
conds = append(conds, builder.Eq{"type": classCode})
}
}
conds = append(conds, builder.And(builder.Lt{"ctime": time.Now().AddDate(0, 0, -7).Unix()}))
page.PageSize = 20
articles := make([]*article.LianV1Article, 0)
page.Content = &articles
err := a.repo.Find(page, conds)
if err != nil {
a.log.Error(err)
return err
}
result := make([]*ArticleDto, 0, len(articles))
for _, v := range articles {
t := time.Unix(v.Ctime, 0) // 秒数和纳秒数0 表示没有纳秒部分
m, g := a.getMainGrowthBoard(v.Stocks)
result = append(result, &ArticleDto{
EventId: v.Id,
Title: v.Title,
Class: class_type[v.Type],
ReleaseDate: t.Format("2006-01-02"),
ReleaseTime: t.Format("15:04"),
Brief: v.Brief,
Stocks: v.Stocks,
Content: v.Content,
MainBoard: m,
GrowthBoard: g,
Unlock: true,
})
}
articles = nil
page.Content = &result
return nil
}
func (a *ArticleService) Detail(userPhone string, id uint64) (*ArticleDto, error) {
user, err := a.userRepo.FindByPhone(userPhone)
if err != nil {
a.log.Error(err)
return nil, err
}
p, err := a.purchaseRepo.FindByUserIdAndContent(user.Id, id, purchase.ContentTypeArticle)
if err != nil {
a.log.Error(err)
return nil, err
}
articleDto := &ArticleDto{}
if p == nil {
articleDto.Unlock = false
return articleDto, nil
}
article, err := a.repo.GetArticleById(id)
if err != nil {
a.log.Error(err)
return nil, err
}
t := time.Unix(article.Ctime, 0)
m, g := a.getMainGrowthBoard(article.Stocks)
return &ArticleDto{
EventId: article.Id,
Title: article.Title,
Class: class_type[article.Type],
ReleaseDate: t.Format("2006-01-02"),
ReleaseTime: t.Format("15:04"),
Stocks: article.Stocks,
Brief: article.Brief,
MainBoard: m,
GrowthBoard: g,
Content: article.Content,
Unlock: true,
}, nil
}
func (a *ArticleService) UnLockArticle(ePhone string, aid uint64) (*ArticleDto, error) {
user, err := a.userRepo.FindByPhone(ePhone)
if err != nil {
a.log.Error(err.Error())
return nil, err
}
if user.GiftCount-1 < 0 {
a.log.Errorf("用户【%d】赠送次数不够", user.Id)
return nil, errors.New("赠送次数用尽")
}
ar, err := a.repo.GetArticleById(aid)
if err != nil {
a.log.Error(err.Error())
return nil, err
}
err = a.userRepo.UpdateUserGiftCount(user.Id, user.GiftCount-1)
if err != nil {
a.log.Error(err.Error())
return nil, err
}
pr := &purchase.Purchase{
UserId: user.Id,
ContentId: aid,
ContentType: purchase.ContentTypeArticle,
ContentSource: purchase.ContentSourceGift,
}
err = a.purchaseRepo.Save(pr)
if err != nil {
a.log.Error(err.Error())
return nil, err
}
return &ArticleDto{
Stocks: ar.Stocks,
Content: ar.Content,
Unlock: true,
}, nil
}
func (a ArticleService) getMainGrowthBoard(stocks string) (int, int) {
if stocks == "" {
return 0, 0
}
// 将字符串分割成股票代码数组
stockList := strings.Split(stocks, ",")
mainBoardCount := 0 // 主板数量
growthBoardCount := 0 // 创业板数量
for _, stock := range stockList {
// 去除可能的空格
stock = strings.TrimSpace(stock)
// 检查股票代码长度是否合法sz/sh + 6位数字
if len(stock) < 8 {
continue
}
// 获取股票代码(去除市场前缀)
prefix := strings.ToLower(stock[0:2]) // 转换为小写
code := stock[2:]
// 检查前缀是否合法
if prefix != "sz" && prefix != "sh" {
continue
}
switch {
// 创业板: 300xxx 或 301xxx
case strings.HasPrefix(code, "300") || strings.HasPrefix(code, "301"):
growthBoardCount++
// 主板:
// 深圳主板 00xxxx
// 上海主板 60xxxx
case strings.HasPrefix(code, "000") || strings.HasPrefix(code, "001") ||
strings.HasPrefix(code, "002") || strings.HasPrefix(code, "600") ||
strings.HasPrefix(code, "601") || strings.HasPrefix(code, "603") ||
strings.HasPrefix(code, "605"):
mainBoardCount++
}
}
return mainBoardCount, growthBoardCount
}