287 lines
7.0 KiB
Go
287 lines
7.0 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"geo/internal/ai_tool"
|
|
"geo/internal/biz"
|
|
"geo/internal/config"
|
|
"geo/internal/data/impl"
|
|
"geo/internal/data/model"
|
|
"geo/internal/entitys"
|
|
"geo/pkg"
|
|
"geo/tmpl/dataTemp"
|
|
"geo/tmpl/errcode"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/go-viper/mapstructure/v2"
|
|
"github.com/gofiber/fiber/v2"
|
|
"xorm.io/builder"
|
|
)
|
|
|
|
type ProductService struct {
|
|
cfg *config.Config
|
|
productImpl *impl.ProductImpl
|
|
authBiz *biz.AuthBiz
|
|
productBiz *biz.ProductBiz
|
|
aiBiz *biz.AiBiz
|
|
}
|
|
|
|
func NewProductService(
|
|
cfg *config.Config,
|
|
ProductImpl *impl.ProductImpl,
|
|
authBiz *biz.AuthBiz,
|
|
productBiz *biz.ProductBiz,
|
|
aiBiz *biz.AiBiz,
|
|
collect *impl.CollectImpl,
|
|
collectTask *impl.CollectTaskImpl,
|
|
) *ProductService {
|
|
return &ProductService{
|
|
cfg: cfg,
|
|
productImpl: ProductImpl,
|
|
authBiz: authBiz,
|
|
productBiz: productBiz,
|
|
aiBiz: aiBiz,
|
|
}
|
|
}
|
|
|
|
func (p *ProductService) Add(c *fiber.Ctx, req *entitys.CreateProductRequest) error {
|
|
_, _, err := p.authBiz.UserAndTokenValid(c.UserContext(), req.UserIndex, req.AccessToken)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var data model.Product
|
|
err = mapstructure.Decode(req, &data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = p.productImpl.Add(c.UserContext(), &data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (p *ProductService) Detail(c *fiber.Ctx, req *entitys.ProductDetailRequest) error {
|
|
_, err := p.authBiz.ValidateAccessToken(c.UserContext(), req.AccessToken)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var detail model.Product
|
|
cond := builder.NewCond().
|
|
And(builder.Eq{"id": req.Id})
|
|
err = p.productImpl.GetOneBySearchStruct(c.UserContext(), &cond, &detail)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return pkg.HandleResponse(c, detail)
|
|
}
|
|
|
|
func (p *ProductService) List(c *fiber.Ctx, req *entitys.ProductListRequest) error {
|
|
_, _, err := p.authBiz.UserAndTokenValid(c.UserContext(), req.UserIndex, req.AccessToken)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
page := req.Page
|
|
if page < 1 {
|
|
page = 1
|
|
}
|
|
pageSize := req.PageSize
|
|
if pageSize < 1 {
|
|
pageSize = 20
|
|
}
|
|
if pageSize > 100 {
|
|
pageSize = 100
|
|
}
|
|
var list []*model.Product
|
|
cond := builder.NewCond().
|
|
And(builder.Eq{"user_index": req.UserIndex}).
|
|
And(builder.Eq{"status": 1})
|
|
total, err := p.productImpl.GetListToStruct(c.UserContext(), &cond, &dataTemp.ReqPageBo{Page: page, Limit: pageSize}, &list, "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return pkg.SuccessWithPageMsg(c, list, total.Total, page, pageSize)
|
|
}
|
|
|
|
func (p *ProductService) Update(c *fiber.Ctx, req *entitys.ProductUpdateRequest) error {
|
|
_, err := p.authBiz.ValidateAccessToken(c.UserContext(), req.AccessToken)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var data model.Product
|
|
err = mapstructure.Decode(req, &data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = p.productImpl.UpdateByKey(c.UserContext(), p.productImpl.PrimaryKey(), req.Id, &data)
|
|
return nil
|
|
}
|
|
|
|
func (p *ProductService) Del(c *fiber.Ctx, req *entitys.ProductDelRequest) error {
|
|
_, err := p.authBiz.ValidateAccessToken(c.UserContext(), req.AccessToken)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = p.productImpl.DeleteByKey(c.UserContext(), p.productImpl.PrimaryKey(), req.Id)
|
|
return nil
|
|
}
|
|
|
|
func (p *ProductService) ImgUpload(c *fiber.Ctx) error {
|
|
access := c.FormValue("access_token", "")
|
|
if access == "" {
|
|
return errcode.ParamErr("access_token未找到")
|
|
}
|
|
// 验证token
|
|
_, err := p.authBiz.ValidateAccessToken(c.UserContext(), access)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fileHeader, err := c.FormFile("file")
|
|
if err != nil {
|
|
return errcode.ParamErr("未找到上传文件")
|
|
}
|
|
file, err := fileHeader.Open()
|
|
if err != nil {
|
|
return errcode.ParamErrf("无法打开文件:%S", err.Error())
|
|
}
|
|
defer file.Close()
|
|
|
|
fileBytes, err := io.ReadAll(file)
|
|
if err != nil {
|
|
return errcode.ParamErrf("读取文件失败:%s", err.Error())
|
|
}
|
|
|
|
// 获取文件扩展名
|
|
ext := pkg.GetFileExtension(fileHeader.Filename)
|
|
|
|
// 根据图片类型生成文件名
|
|
fileName := pkg.GenerateImageFileName(ext)
|
|
|
|
url, err := p.productBiz.SourceUpload(c.UserContext(), fileBytes, fileName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return pkg.HandleResponse(c, fiber.Map{"url": url})
|
|
}
|
|
|
|
func (p *ProductService) CreateProductInfoByDocx(c *fiber.Ctx) error {
|
|
access := c.FormValue("access_token", "")
|
|
if access == "" {
|
|
return errcode.ParamErr("access_token未找到")
|
|
}
|
|
userIndex := c.FormValue("user_index", "")
|
|
if userIndex == "" {
|
|
return errcode.ParamErr("user_index未找到")
|
|
}
|
|
// 验证token
|
|
_, err := p.authBiz.ValidateAccessToken(c.UserContext(), access)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fileHeader, err := c.FormFile("file")
|
|
if err != nil {
|
|
return errcode.ParamErr("未找到上传文件")
|
|
}
|
|
|
|
file, err := fileHeader.Open()
|
|
if err != nil {
|
|
return errcode.ParamErrf("无法打开文件:%s", err.Error())
|
|
}
|
|
defer file.Close()
|
|
|
|
// 创建临时文件
|
|
tempFile, err := os.CreateTemp("", "upload_*.docx")
|
|
if err != nil {
|
|
return errcode.ParamErrf("创建临时文件失败:%s", err.Error())
|
|
}
|
|
defer tempFile.Close()
|
|
|
|
// 获取临时文件的绝对路径
|
|
absPath, err := filepath.Abs(tempFile.Name())
|
|
if err != nil {
|
|
return errcode.ParamErrf("获取文件绝对路径失败:%s", err.Error())
|
|
}
|
|
|
|
// 将上传的文件内容复制到临时文件
|
|
_, err = io.Copy(tempFile, file)
|
|
if err != nil {
|
|
return errcode.ParamErrf("保存文件失败:%s", err.Error())
|
|
}
|
|
|
|
// 确保文件内容已写入磁盘
|
|
err = tempFile.Sync()
|
|
if err != nil {
|
|
return errcode.ParamErrf("同步文件失败:%s", err.Error())
|
|
}
|
|
markContent, err := pkg.ExtractWordContent(absPath, "markdown")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var productInfo entitys.ProductInfo
|
|
mes := p.aiBiz.CreateProjectInfoPrompt(c.UserContext(), markContent)
|
|
err = ai_tool.NewHsyq().RequestHsyqBotToJson(c.UserContext(), p.cfg.Hsyq.ApiKey, p.cfg.AiBot.ProductInfo, mes, &productInfo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return pkg.HandleResponse(c, productInfo)
|
|
}
|
|
|
|
type CollectInfo struct {
|
|
AIPlatformIndex string `json:"ai_platform_index"`
|
|
ContentHtml string `json:"content_html"`
|
|
ShareUrl string `json:"share_url"`
|
|
Source []Source `json:"source"`
|
|
}
|
|
|
|
type Source struct {
|
|
Title string `json:"name"`
|
|
Url string `json:"url"`
|
|
PlatformName string `json:"platform"`
|
|
PlatformIcon string `json:"Platform_icon"`
|
|
}
|
|
|
|
func (p *ProductService) Collect(c *fiber.Ctx, req *entitys.ProductCollectRequest) error {
|
|
|
|
return nil
|
|
_, err := p.authBiz.ValidateAccessToken(c.UserContext(), req.AccessToken)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
productInfo, err := p.productBiz.GetProduct(c.UserContext(), req.ProductId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
collect := ai_tool.NewCollect(p.cfg.Collect.ApiKey)
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*120)
|
|
defer cancel()
|
|
for _, v := range req.Platform {
|
|
go func() {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
}
|
|
}()
|
|
request := ai_tool.CreateReq{
|
|
Keywords: strings.Join(req.Keywords, ","),
|
|
Question: req.Question,
|
|
Platform: v,
|
|
ThirdID: "11",
|
|
}
|
|
_, _err := collect.Create(ctx, &request)
|
|
if _err != nil {
|
|
return
|
|
}
|
|
|
|
}()
|
|
}
|
|
return pkg.HandleResponse(c, productInfo)
|
|
}
|