111
This commit is contained in:
parent
0bb2e77016
commit
df63f98947
|
|
@ -34,7 +34,10 @@ func InitializeApp(configConfig *config.Config, allLogger log.AllLogger) (*serve
|
||||||
publishService := service.NewPublishService(configConfig, publishBiz, authBiz, db)
|
publishService := service.NewPublishService(configConfig, publishBiz, authBiz, db)
|
||||||
productImpl := impl.NewProductImpl(db)
|
productImpl := impl.NewProductImpl(db)
|
||||||
productService := service.NewProductService(configConfig, productImpl, authBiz)
|
productService := service.NewProductService(configConfig, productImpl, authBiz)
|
||||||
productSourceService := service.NewProductSourceService(configConfig, productImpl, authBiz)
|
aiBiz := biz.NewAiBiz(platImpl)
|
||||||
|
productSourceImpl := impl.NewProductSourceImpl(db)
|
||||||
|
productBiz := biz.NewProductBiz(productImpl, productSourceImpl)
|
||||||
|
productSourceService := service.NewProductSourceService(configConfig, productImpl, authBiz, aiBiz, productBiz)
|
||||||
appModule := router.NewAppModule(configConfig, appService, loginService, publishService, productService, productSourceService)
|
appModule := router.NewAppModule(configConfig, appService, loginService, publishService, productService, productSourceService)
|
||||||
routerServer := router.NewRouterServer(appModule)
|
routerServer := router.NewRouterServer(appModule)
|
||||||
app := server.NewHTTPServer(routerServer)
|
app := server.NewHTTPServer(routerServer)
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -4,6 +4,7 @@ go 1.25.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
gitea.cdlsxd.cn/self-tools/l_request v1.0.8
|
gitea.cdlsxd.cn/self-tools/l_request v1.0.8
|
||||||
|
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
|
||||||
github.com/go-kratos/kratos/v2 v2.9.2
|
github.com/go-kratos/kratos/v2 v2.9.2
|
||||||
github.com/go-playground/validator/v10 v10.30.2
|
github.com/go-playground/validator/v10 v10.30.2
|
||||||
github.com/go-rod/rod v0.116.2
|
github.com/go-rod/rod v0.116.2
|
||||||
|
|
@ -50,6 +51,7 @@ require (
|
||||||
golang.org/x/crypto v0.49.0 // indirect
|
golang.org/x/crypto v0.49.0 // indirect
|
||||||
golang.org/x/sys v0.42.0 // indirect
|
golang.org/x/sys v0.42.0 // indirect
|
||||||
golang.org/x/text v0.35.0 // indirect
|
golang.org/x/text v0.35.0 // indirect
|
||||||
|
golang.org/x/time v0.15.0 // indirect
|
||||||
google.golang.org/protobuf v1.33.0 // indirect
|
google.golang.org/protobuf v1.33.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.2.8 // indirect
|
gopkg.in/yaml.v2 v2.2.8 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -6,6 +6,8 @@ gitea.cdlsxd.cn/self-tools/l_request v1.0.8/go.mod h1:Qf4hVXm2Eu5vOvwXk8D7U0q/ae
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g=
|
||||||
|
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||||
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
||||||
|
|
@ -166,6 +168,8 @@ golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
||||||
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
||||||
|
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
|
||||||
|
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package third_party
|
package ai_tool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -147,20 +147,6 @@ func (h *Hsyq) RequestHsyqJson(ctx context.Context, key string, modelName string
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// []*model.ChatCompletionMessage{
|
|
||||||
// {
|
|
||||||
// Role: model.ChatMessageRoleSystem,
|
|
||||||
// Content: &model.ChatCompletionMessageContent{
|
|
||||||
// StringValue: volcengine.String("你是豆包,是由字节跳动开发的 AI 人工智能助手"),
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// Role: model.ChatMessageRoleUser,
|
|
||||||
// Content: &model.ChatCompletionMessageContent{
|
|
||||||
// StringValue: volcengine.String("常见的十字花科植物有哪些?"),
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
func (h *Hsyq) RequestHsyqBot(ctx context.Context, key string, botId string, message []*model.ChatCompletionMessage) ([]byte, error) {
|
func (h *Hsyq) RequestHsyqBot(ctx context.Context, key string, botId string, message []*model.ChatCompletionMessage) ([]byte, error) {
|
||||||
req := model.BotChatCompletionRequest{
|
req := model.BotChatCompletionRequest{
|
||||||
BotId: botId,
|
BotId: botId,
|
||||||
|
|
@ -1,4 +1,62 @@
|
||||||
package biz
|
package biz
|
||||||
|
|
||||||
type Ai struct {
|
import (
|
||||||
|
"context"
|
||||||
|
"geo/internal/data/impl"
|
||||||
|
"geo/internal/data/model"
|
||||||
|
"geo/internal/entitys"
|
||||||
|
"geo/pkg"
|
||||||
|
|
||||||
|
volmodle "github.com/volcengine/volcengine-go-sdk/service/arkruntime/model"
|
||||||
|
"github.com/volcengine/volcengine-go-sdk/volcengine"
|
||||||
|
"xorm.io/builder"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AiBiz struct {
|
||||||
|
platImpl *impl.PlatImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAiBiz(platImpl *impl.PlatImpl) *AiBiz {
|
||||||
|
return &AiBiz{
|
||||||
|
platImpl: platImpl,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AiBiz) CreateArticlePrompt(ctx context.Context, data *entitys.BotChat) []*volmodle.ChatCompletionMessage {
|
||||||
|
mes := []*volmodle.ChatCompletionMessage{
|
||||||
|
{
|
||||||
|
Role: volmodle.ChatMessageRoleUser,
|
||||||
|
Content: &volmodle.ChatCompletionMessageContent{
|
||||||
|
StringValue: volcengine.String(pkg.JsonStringIgonErr(data)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
var plats []*model.Plat
|
||||||
|
cond := builder.NewCond().
|
||||||
|
And(builder.Eq{"plat_type": 1}).
|
||||||
|
And(builder.Eq{"status": 1})
|
||||||
|
_, err := a.platImpl.GetListToStruct(ctx, &cond, nil, &plats, "id asc")
|
||||||
|
if err != nil {
|
||||||
|
return mes
|
||||||
|
}
|
||||||
|
var platList = &entitys.PlatList{
|
||||||
|
Desc: "平台列表",
|
||||||
|
PlatItem: make([]*entitys.PlatItem, 0, len(plats)),
|
||||||
|
}
|
||||||
|
for _, plat := range plats {
|
||||||
|
platList.PlatItem = append(platList.PlatItem, &entitys.PlatItem{
|
||||||
|
Platform: plat.Name,
|
||||||
|
PlatformIndex: plat.Index,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(platList.PlatItem) > 0 {
|
||||||
|
mes = append(mes, &volmodle.ChatCompletionMessage{
|
||||||
|
Role: volmodle.ChatMessageRoleAssistant,
|
||||||
|
Content: &volmodle.ChatCompletionMessageContent{
|
||||||
|
StringValue: volcengine.String(pkg.JsonStringIgonErr(platList)),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return mes
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package biz
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"geo/internal/data/impl"
|
||||||
|
"geo/internal/data/model"
|
||||||
|
"geo/internal/entitys"
|
||||||
|
|
||||||
|
"github.com/go-viper/mapstructure/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProductBiz struct {
|
||||||
|
productImpl *impl.ProductImpl
|
||||||
|
productSourceImpl *impl.ProductSourceImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProductBiz(productImpl *impl.ProductImpl, productSourceImpl *impl.ProductSourceImpl) *ProductBiz {
|
||||||
|
return &ProductBiz{
|
||||||
|
productImpl: productImpl,
|
||||||
|
productSourceImpl: productSourceImpl,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ProductBiz) GetBrandInfo(ctx context.Context, productId int32) (*entitys.BrandInfo, error) {
|
||||||
|
var product model.Product
|
||||||
|
err := p.productImpl.GetByKey(ctx, p.productImpl.PrimaryKey(), productId, &product)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var BrandInfo entitys.BrandInfo
|
||||||
|
err = mapstructure.Decode(product, &BrandInfo)
|
||||||
|
|
||||||
|
return &BrandInfo, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ProductBiz) CreateAndUploadArticle(ctx context.Context, content string) error {
|
||||||
|
//var product model.Product
|
||||||
|
//err := p.productImpl.GetByKey(ctx, p.productImpl.PrimaryKey(), productId, &product)
|
||||||
|
//if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
//}
|
||||||
|
//var BrandInfo entitys.BrandInfo
|
||||||
|
//err = mapstructure.Decode(product, &BrandInfo)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -7,4 +7,6 @@ import (
|
||||||
var ProviderSetBiz = wire.NewSet(
|
var ProviderSetBiz = wire.NewSet(
|
||||||
NewPublishBiz,
|
NewPublishBiz,
|
||||||
NewAuthBiz,
|
NewAuthBiz,
|
||||||
|
NewAiBiz,
|
||||||
|
NewProductBiz,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,16 @@ type Config struct {
|
||||||
Server ServerConfig `mapstructure:"server"`
|
Server ServerConfig `mapstructure:"server"`
|
||||||
DB DB `mapstructure:"db"`
|
DB DB `mapstructure:"db"`
|
||||||
Sys Sys `mapstructure:"sys"`
|
Sys Sys `mapstructure:"sys"`
|
||||||
|
Hsyq Hsyq `mapstructure:"hsyq"`
|
||||||
|
Oss Oss `mapstructure:"oss"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Oss struct {
|
||||||
|
AccessKey string `mapstructure:"access_key"`
|
||||||
|
SecretKey string `mapstructure:"secret_key"`
|
||||||
|
Bucket string `mapstructure:"bucket"`
|
||||||
|
Domain string `mapstructure:"domain"`
|
||||||
|
Endpoint string `mapstructure:"endpoint"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerConfig 服务器配置
|
// ServerConfig 服务器配置
|
||||||
|
|
@ -18,6 +28,10 @@ type ServerConfig struct {
|
||||||
Host string `mapstructure:"host"`
|
Host string `mapstructure:"host"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Hsyq struct {
|
||||||
|
ApiKey string `mapstructure:"api_key"`
|
||||||
|
}
|
||||||
|
|
||||||
type DB struct {
|
type DB struct {
|
||||||
Driver string `mapstructure:"driver"`
|
Driver string `mapstructure:"driver"`
|
||||||
Source string `mapstructure:"source"`
|
Source string `mapstructure:"source"`
|
||||||
|
|
@ -70,5 +84,15 @@ func LoadConfig() (*Config, error) {
|
||||||
ChromePath: filepath.Join(BaseDir, "chrome", "chrome.exe"),
|
ChromePath: filepath.Join(BaseDir, "chrome", "chrome.exe"),
|
||||||
ChromeDataDir: filepath.Join(BaseDir, "chrome_data"),
|
ChromeDataDir: filepath.Join(BaseDir, "chrome_data"),
|
||||||
},
|
},
|
||||||
|
Hsyq: Hsyq{
|
||||||
|
ApiKey: "236ba4b6-9daa-4755-b22f-2fd274cd223a",
|
||||||
|
},
|
||||||
|
Oss: Oss{
|
||||||
|
AccessKey: "LTAI5tGGZzjf3tvqWk8SQj2G",
|
||||||
|
SecretKey: "S0NKOAUaYWoK4EGSxrMFmYDzllhvpq",
|
||||||
|
Bucket: "attachment-public",
|
||||||
|
Domain: "https://attachment-public.oss-cn-hangzhou.aliyuncs.com",
|
||||||
|
Endpoint: "https://oss-cn-hangzhou.aliyuncs.com",
|
||||||
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ type Plat struct {
|
||||||
ID int32 `gorm:"column:id;primaryKey" json:"id"`
|
ID int32 `gorm:"column:id;primaryKey" json:"id"`
|
||||||
Name string `gorm:"column:name;not null" json:"name"`
|
Name string `gorm:"column:name;not null" json:"name"`
|
||||||
Index string `gorm:"column:index;not null" json:"index"`
|
Index string `gorm:"column:index;not null" json:"index"`
|
||||||
|
PlatType int32 `gorm:"column:plat_type;not null;default:1" json:"plat_type"`
|
||||||
ImgURL string `gorm:"column:img_url;not null" json:"img_url"`
|
ImgURL string `gorm:"column:img_url;not null" json:"img_url"`
|
||||||
LoginURL string `gorm:"column:login_url;not null" json:"login_url"`
|
LoginURL string `gorm:"column:login_url;not null" json:"login_url"`
|
||||||
EditURL string `gorm:"column:edit_url;not null" json:"edit_url"`
|
EditURL string `gorm:"column:edit_url;not null" json:"edit_url"`
|
||||||
|
|
|
||||||
|
|
@ -40,3 +40,47 @@ const (
|
||||||
NotifyTypePublish NotifyType = 1
|
NotifyTypePublish NotifyType = 1
|
||||||
NotifyTypeToken NotifyType = 1
|
NotifyTypeToken NotifyType = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type BotChat struct {
|
||||||
|
Question string `json:"question"`
|
||||||
|
ArticleType string `json:"article_type"`
|
||||||
|
BrandInfo *BrandInfo `json:"brand_info"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BrandInfo struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Industry string `json:"industry"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
ProductOrService string `json:"product_or_service"`
|
||||||
|
Advantages string `json:"advantages"`
|
||||||
|
Story string `json:"story"`
|
||||||
|
Problem string `json:"problem"`
|
||||||
|
Background string `json:"background"`
|
||||||
|
Case string `json:"case"`
|
||||||
|
Other string `json:"other"`
|
||||||
|
ServiceCope string `json:"service_cope"`
|
||||||
|
TargetAudience string `json:"target_audience"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PlatList struct {
|
||||||
|
Desc string `json:"question"`
|
||||||
|
PlatItem []*PlatItem `json:"plat_item"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PlatItem struct {
|
||||||
|
Platform string `json:"platform"`
|
||||||
|
PlatformIndex string `json:"platform_index"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BotChatResponse struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
WordCount int `json:"wordCount"`
|
||||||
|
Tag []string `json:"tag"`
|
||||||
|
RecommendPlatform []struct {
|
||||||
|
Platform string `json:"platform"`
|
||||||
|
PlatformIndex string `json:"platform_index"`
|
||||||
|
Score string `json:"score"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
} `json:"recommend_platform"`
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,8 +135,9 @@ type (
|
||||||
|
|
||||||
ProductSourceCreateRequest struct {
|
ProductSourceCreateRequest struct {
|
||||||
AccessToken string `json:"access_token" validate:"required" zh:"access_token"`
|
AccessToken string `json:"access_token" validate:"required" zh:"access_token"`
|
||||||
UserIndex string `json:"user_index" validate:"required" zh:"用户索引"`
|
Id int32 `json:"id" validate:"required" zh:"产品id"`
|
||||||
PlatIndex string `json:"plat_index" validate:"required" zh:"平台索引"`
|
Ques string `json:"ques" validate:"required" zh:"问题"`
|
||||||
|
ArticleType string `json:"article_type" validate:"required" zh:"文章类型"`
|
||||||
}
|
}
|
||||||
|
|
||||||
ProductSourceListRequest struct {
|
ProductSourceListRequest struct {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"geo/internal/ai_tool"
|
||||||
"geo/internal/biz"
|
"geo/internal/biz"
|
||||||
"geo/internal/config"
|
"geo/internal/config"
|
||||||
"geo/internal/data/impl"
|
"geo/internal/data/impl"
|
||||||
|
"geo/internal/data/model"
|
||||||
"geo/internal/entitys"
|
"geo/internal/entitys"
|
||||||
|
"github.com/go-viper/mapstructure/v2"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -13,22 +16,44 @@ type ProductSourceService struct {
|
||||||
cfg *config.Config
|
cfg *config.Config
|
||||||
productImpl *impl.ProductImpl
|
productImpl *impl.ProductImpl
|
||||||
authBiz *biz.AuthBiz
|
authBiz *biz.AuthBiz
|
||||||
|
aiBiz *biz.AiBiz
|
||||||
|
productBiz *biz.ProductBiz
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProductSourceService(cfg *config.Config, ProductImpl *impl.ProductImpl, authBiz *biz.AuthBiz) *ProductSourceService {
|
func NewProductSourceService(cfg *config.Config, ProductImpl *impl.ProductImpl, authBiz *biz.AuthBiz, aiBiz *biz.AiBiz, productBiz *biz.ProductBiz) *ProductSourceService {
|
||||||
return &ProductSourceService{
|
return &ProductSourceService{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
productImpl: ProductImpl,
|
productImpl: ProductImpl,
|
||||||
authBiz: authBiz,
|
authBiz: authBiz,
|
||||||
|
aiBiz: aiBiz,
|
||||||
|
productBiz: productBiz,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProductSourceService) Create(c *fiber.Ctx, req *entitys.ProductSourceCreateRequest) error {
|
func (p *ProductSourceService) Create(c *fiber.Ctx, req *entitys.ProductSourceCreateRequest) error {
|
||||||
// 验证token
|
// 验证token
|
||||||
_, _, err := p.authBiz.UserAndTokenValid(c.UserContext(), req.UserIndex, req.AccessToken)
|
_, err := p.authBiz.ValidateAccessToken(c.UserContext(), req.AccessToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
brandInfo, err := p.productBiz.GetBrandInfo(c.UserContext(), req.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
BotChatMes := &entitys.BotChat{
|
||||||
|
Question: req.Ques,
|
||||||
|
ArticleType: req.ArticleType,
|
||||||
|
BrandInfo: brandInfo,
|
||||||
|
}
|
||||||
|
mes := p.aiBiz.CreateArticlePrompt(c.UserContext(), BotChatMes)
|
||||||
|
content, err := ai_tool.NewHsyq().RequestHsyqBot(c.UserContext(), p.cfg.Hsyq.ApiKey, "bot-20260413000114-8bw62", mes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var resp entitys.BotChatResponse
|
||||||
|
if err := json.Unmarshal(content, &resp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
# 成都云算科技有限公司 - 企业信息概览
|
||||||
|
|
||||||
|
## name(品牌/产品/公司名称)
|
||||||
|
成都云算科技有限公司
|
||||||
|
|
||||||
|
## industry(所属行业)
|
||||||
|
软件与信息技术服务业/房地产数字化
|
||||||
|
|
||||||
|
## type(产品类型)
|
||||||
|
数字化精准营销整体解决方案提供商
|
||||||
|
|
||||||
|
## productOrService(主营业务)
|
||||||
|
房地产数字化营销SaaS平台、CRM售楼软件、云置业、云获客、云渠道、云风控、云售楼、云收银、云开盘、云交房、云商业等15大云系列产品,智慧案场解决方案,渠道风控系统,数字楼盘展示,VR看房,线上开盘系统
|
||||||
|
|
||||||
|
## keyword(关键词)
|
||||||
|
房地产数字化营销解决方案,房地产SaaS平台,售楼软件,渠道风控,智慧案场,房企数字化转型
|
||||||
|
|
||||||
|
## advantages(核心优势)
|
||||||
|
十七年房地产数字化深耕经验,行业排名首位;国家高新技术企业认证;拥有8项专利、60多项软件著作权;全国25城布局服务网点,累计服务3000+企业、500+项目;三大体系十五大云产品覆盖营销全场景;提供标准API接口打通阿里云、旷视科技、用友、金蝶等生态;支持PC/iOS/安卓/小程序/H5多终端;7×24小时运维保障;客户含万达集团、中铁二局、中信国安、传化集团等头部企业
|
||||||
|
|
||||||
|
## serviceScope(服务范围)
|
||||||
|
全国范围,总部成都高新区,在重庆、贵阳、昆明、武汉、深圳、南宁、西安等25个核心城市设立直属服务网点
|
||||||
|
|
||||||
|
## targetAudience(目标群体)
|
||||||
|
全国性大型房企、区域龙头开发商、本土中小开发企业、房产代理公司、商业地产运营方;有土地储备待开发的开发商、即将开盘的项目方、对现有数字化系统成本高或效果不满意寻求更换的房企
|
||||||
|
|
||||||
|
## story(发展故事)
|
||||||
|
成都云算科技前身为2008年成立的云算房产软件事业部,初期推出CRM售楼软件切入市场。2013年正式成立公司,2015年获国家高新企业认证,2016年移动端上线,2017年启动SaaS平台建设,2019年云系列产品全面上线,2020-2023年快速扩展至全国25城,2024年实施全国服务计划。十七年从单一软件商成长为覆盖线上拓客、渠道管理、案场运营、交易收款、风险管控、售后交房、商业运营全链条的数字化营销领军企业
|
||||||
|
|
||||||
|
## problem(解决痛点)
|
||||||
|
房企营销普遍面临销售动作失控(管理者看不到过程)、过度依赖个人经验(能力无法复制)、主观数据失真(汇报数据加工过)、沟通成本过高(大量时间用于开会汇报而非销售)等问题,导致营销费效比低、舞弊风险高、决策滞后。典型的低效组织闭环:越失控越依赖人,越依赖人越失真,越失真越沟通,越沟通越失控
|
||||||
|
|
||||||
|
## background(信任背书)
|
||||||
|
国家高新技术企业认证;拥有二级教授、高校博导、行业资深专家组成的顾问团队;项目获多位国家及省级领导视察指导;合作生态含中国电信/移动/联通、阿里云、旷视科技、中国银联、通联支付、法大大、企业微信、钉钉、用友、金蝶云等头部企业;服务客户含万达集团、中铁二局、中信国安、传化集团、中慧实业集团、四川三叶集团、广西华宏地产、南宁威宁集团等
|
||||||
|
|
||||||
|
## case(品牌案例)
|
||||||
|
某全国性房企成都区域项目,使用云算科技数字化营销方案前,渠道舞弊频发、客户归属争议不断、案场数据手工统计滞后。部署云渠道+云风控+云销售系统后,实现渠道报备带看全流程线上化,刷脸核验杜绝虚假带看,客户判客准确率提升至99%,案场数据自动生成日报周报,营销费效比降低25%,项目去化周期缩短30%
|
||||||
|
|
||||||
|
## other(其他信息)
|
||||||
|
公司愿景为‘成为最优质的数字智能服务商’,秉持‘专注、专业、诚信、务实、高效、共赢’理念。提供1+1+1售楼管理体系(线上+外场+内场),智能报表系统覆盖5大类19+项核心报表自动推送,支持刷脸核验、无感抓拍、人证核验等AI能力。总部设于成都市高新区,全国25个核心城市设立直属服务网点,实现就近快速响应
|
||||||
|
|
||||||
|
## target_audience(目标客户群体)
|
||||||
|
全国性大型房企、区域龙头开发商、本土中小开发企业、房产代理公司、商业地产运营方;有土地储备待开发的开发商、即将开盘的项目方、对现有数字化系统成本高或效果不满意寻求更换的房企
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"geo/utils/utils_oss"
|
||||||
|
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ProviderUtils = wire.NewSet(
|
var ProviderUtils = wire.NewSet(
|
||||||
NewGormDb,
|
NewGormDb,
|
||||||
|
utils_oss.NewClient,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
package utils_oss
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"geo/internal/config"
|
||||||
|
|
||||||
|
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||||
|
"github.com/go-kratos/kratos/v2/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
config config.Oss
|
||||||
|
client *oss.Client
|
||||||
|
bucket *oss.Bucket
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient 初始化 OSS 客户端
|
||||||
|
func NewClient(cfg *config.Config) (*Client, error) {
|
||||||
|
client, err := oss.New(cfg.Oss.Endpoint, cfg.Oss.AccessKey, cfg.Oss.SecretKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("oss new client failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bucket, err := client.Bucket(cfg.Oss.Bucket)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("oss get bucket failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Client{
|
||||||
|
config: cfg.Oss,
|
||||||
|
client: client,
|
||||||
|
bucket: bucket,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadBytes 上传字节数组到 OSS
|
||||||
|
// objectKey: OSS 中的文件路径,例如 "ai_scheduler/test.png"
|
||||||
|
// fileBytes: 文件内容
|
||||||
|
// 返回: 文件的访问 URL
|
||||||
|
func (c *Client) UploadBytes(objectKey string, fileBytes []byte) (string, error) {
|
||||||
|
err := c.bucket.PutObject(objectKey, bytes.NewReader(fileBytes))
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("oss PutObject failed: %v", err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造返回 URL
|
||||||
|
var url string
|
||||||
|
if c.config.Domain != "" {
|
||||||
|
url = fmt.Sprintf("%s/%s", c.config.Domain, objectKey)
|
||||||
|
} else {
|
||||||
|
// 这里简单处理协议头
|
||||||
|
url = fmt.Sprintf("https://%s.%s/%s", c.config.Bucket, c.config.Endpoint, objectKey)
|
||||||
|
}
|
||||||
|
return url, nil
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue