daShangDao_psiServer/service/book.go
2026-07-01 18:07:51 +08:00

224 lines
5.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"gorm.io/datatypes"
"io"
"log"
"net/http"
"psi/database"
"psi/models"
systemReq "psi/models/request"
systemRes "psi/models/response"
"strconv"
"strings"
"time"
)
type BookService struct{}
// GetBookInfo 获取图书信息
func (s *BookService) GetBookInfo(req systemReq.BookRequest) (*systemRes.ESBook, error) {
// 调用ES接口
isbn := req.Isbn
log.Printf("[GetBookInfo] 请求 ISBN: %s", isbn)
apiURL := fmt.Sprintf("https://book.center.yushutx.com/api/es/searchByISBNtoPsi?isbn=%s", isbn)
resp, err := http.Get(apiURL)
if err != nil {
return nil, fmt.Errorf("[ERROR] 请求 ES 接口失败:%v\n", err)
}
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return nil, fmt.Errorf("[ERROR] 读取响应失败:%v\n", err)
}
log.Printf("[GetBookInfo] ES 返回原始数据: %s", string(body))
var esResp systemRes.GetEsBookResponse
if err := json.Unmarshal(body, &esResp); err != nil {
return nil, fmt.Errorf("[ERROR] 解析响应失败:%v\n", err)
}
// 如果ES接口没有返回数据返回空对象
if esResp.Data.BookName.Value == "" && esResp.Data.ISBN == "" {
log.Printf("[GetBookInfo] ES 无数据,返回 nil")
return nil, nil
}
log.Printf("[GetBookInfo] 解析成功, 书名: %s, ISBN: %s", esResp.Data.BookName.Value, esResp.Data.ISBN)
return &esResp.Data, nil
}
func (s *BookService) GetSuitBook(req systemReq.BookRequest) (*systemRes.SuitBookResponse, error) {
var books []models.BookInfo
if err := database.DB.Where("isbn = ? AND type IN (2, 3)", req.Isbn).Find(&books).Error; err != nil {
return nil, fmt.Errorf("[ERROR] 查询书籍信息失败:%v\n", err)
}
if len(books) == 0 {
return nil, nil
}
response := &systemRes.SuitBookResponse{
WithFid: make([]models.BookInfo, 0),
WithoutFid: make([]models.BookInfo, 0),
}
for _, book := range books {
if book.Fid == 0 {
response.WithoutFid = append(response.WithoutFid, book)
} else {
response.WithFid = append(response.WithFid, book)
}
}
return response, nil
}
func (s *BookService) GetProCode(req systemReq.GetCodeRequest) (string, error) {
input := req.BookName + req.Author + req.Publisher
hash := md5.Sum([]byte(input))
hexStr := hex.EncodeToString(hash[:])
code := hexStr[:20]
return strings.ToUpper(code), nil
}
func (s *BookService) SyncBook(req systemReq.AddBookRequest) (int64, string, error) {
if req.Fid == 0 {
var existingBook models.BookInfo
err := database.DB.Where("fid = 0 AND isbn = ?", req.Isbn).First(&existingBook).Error
if err == nil {
return existingBook.ID, fmt.Sprintf("%s-%s", req.Isbn, req.FIsbn), nil
}
}
bookID, err := s.doBook(req)
if err != nil {
return 0, "", fmt.Errorf("[ERROR] 保存书籍信息失败:%v\n", err)
}
return bookID, fmt.Sprintf("%s-%s", req.Isbn, req.FIsbn), nil
}
// GetNoIsbnBook 获取无书号书籍
func (s *BookService) GetNoIsbnBook(req systemReq.GetNoIsbnBookRequest) (*systemRes.NoIsbnBookResponse, error) {
query := database.DB.Model(&models.BookInfo{}).Where("type = ?", 4)
if req.BookName != "" {
query = query.Where("book_name LIKE ?", "%"+req.BookName+"%")
}
if req.Author != "" {
query = query.Where("author LIKE ?", "%"+req.Author+"%")
}
if req.Publisher != "" {
query = query.Where("publishing LIKE ?", "%"+req.Publisher+"%")
}
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, fmt.Errorf("查询无书号书总数失败: %v", err)
}
var books []models.BookInfo
if err := query.Order("id DESC").Find(&books).Error; err != nil {
return nil, fmt.Errorf("查询无书号书列表失败: %v", err)
}
if books == nil {
books = make([]models.BookInfo, 0)
}
return &systemRes.NoIsbnBookResponse{
Total: total,
List: books,
}, nil
}
func (s *BookService) doBook(data systemReq.AddBookRequest) (int64, error) {
var liveImage datatypes.JSON
if len(data.LiveImage) > 0 {
jsonBytes, _ := json.Marshal(data.LiveImage)
liveImage = jsonBytes
} else {
liveImage = datatypes.JSON("[]")
}
catIdByJson := datatypes.JSON(`{"xian_yu_cat_id": "", "kong_fu_zi_cat_id": "", "pin_duo_duo_cat_id": ""}`)
if data.CatID != "" {
var catObj map[string]string
if err := json.Unmarshal([]byte(data.CatID), &catObj); err == nil {
filtered := make(map[string]string)
for k, v := range catObj {
if strings.TrimSpace(v) != "" {
filtered[k] = v
}
}
if len(filtered) > 0 {
filteredBytes, _ := json.Marshal(filtered)
catIdByJson = filteredBytes
}
}
}
// publication_time 兼容秒级和毫秒级时间戳,格式化为 "年-月"
var publicationDate string
if data.PublicationTime > 0 {
ts := data.PublicationTime
if ts > 1e12 { // 毫秒级时间戳
ts /= 1000
}
publicationDate = time.Unix(ts, 0).Format("2006-01")
}
book := models.BookInfo{
Fid: data.Fid,
Type: data.Type,
ISBN: data.Isbn,
FISBN: data.FIsbn,
BookName: data.BookName,
FBookName: data.FBookName,
Author: data.Author,
Publishing: data.Publisher,
PublicationTime: data.PublicationTime,
PublicationDate: publicationDate,
Binding: data.BindingLayout,
PagesCount: data.PageCount,
WordsCount: data.WordCount,
Format: data.BookFormat,
Price: data.FixPrice,
CatID: catIdByJson,
LiveImage: liveImage,
}
bookID, err := s.createBook(book)
if err != nil {
return 0, err
}
return bookID, nil
}
func (s *BookService) createBook(book models.BookInfo) (int64, error) {
if err := database.DB.Create(&book).Error; err != nil {
return 0, fmt.Errorf("创建书籍信息失败:%w", err)
}
return book.ID, nil
}
func (s *BookService) parseIntOrString(value string) int {
value = strings.TrimSpace(value)
if value == "" {
return 0
}
intVal, err := strconv.Atoi(value)
if err != nil {
return 0
}
return intVal
}