This commit is contained in:
parent
eb02238c60
commit
7eda42b8a7
|
|
@ -28,21 +28,22 @@ func InitializeApp(configConfig *config.Config, allLogger log.AllLogger) (*serve
|
|||
platImpl := impl.NewPlatImpl(db)
|
||||
publishImpl := impl.NewPublishImpl(db)
|
||||
loginRelationImpl := impl.NewLoginRelationImpl(db)
|
||||
articleTypeImpl := impl.NewArticleTypeImpl(db)
|
||||
publishBiz := biz.NewPublishBiz(configConfig, publishImpl, userImpl, platImpl, tokenImpl, loginRelationImpl)
|
||||
authBiz := biz.NewAuthBiz(configConfig, tokenImpl, userImpl)
|
||||
appService := service.NewAppService(configConfig, tokenImpl, userImpl, platImpl, publishBiz, authBiz, loginRelationImpl)
|
||||
loginService := service.NewLoginService(configConfig, publishBiz, authBiz)
|
||||
publishService := service.NewPublishService(configConfig, publishBiz, authBiz, db)
|
||||
productImpl := impl.NewProductImpl(db)
|
||||
productService := service.NewProductService(configConfig, productImpl, authBiz)
|
||||
aiBiz := biz.NewAiBiz(platImpl)
|
||||
productSourceImpl := impl.NewProductSourceImpl(db)
|
||||
oss, err := utils_oss.NewClient(configConfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
productBiz := biz.NewProductBiz(productImpl, productSourceImpl, configConfig, oss)
|
||||
productSourceService := service.NewProductSourceService(configConfig, productImpl, authBiz, aiBiz, productBiz, productSourceImpl)
|
||||
productService := service.NewProductService(configConfig, productImpl, authBiz, productBiz)
|
||||
aiBiz := biz.NewAiBiz(platImpl)
|
||||
productSourceService := service.NewProductSourceService(configConfig, productImpl, authBiz, aiBiz, productBiz, productSourceImpl, publishBiz, articleTypeImpl)
|
||||
appModule := router.NewAppModule(configConfig, appService, loginService, publishService, productService, productSourceService)
|
||||
routerServer := router.NewRouterServer(appModule)
|
||||
app := server.NewHTTPServer(routerServer)
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ func (p *ProductBiz) CreateAndUploadArticle(ctx context.Context, content string,
|
|||
mdAbs := filepath.Join(p.cfg.Sys.MdDir, fileName)
|
||||
// 创建并写入文件
|
||||
file, err := os.Create(mdAbs)
|
||||
defer os.Remove(mdAbs)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("创建文件失败: %w", err)
|
||||
}
|
||||
|
|
@ -66,6 +67,7 @@ func (p *ProductBiz) CreateAndUploadArticle(ctx context.Context, content string,
|
|||
}
|
||||
|
||||
docxPath, err := pkg.Md2wordFix(mdAbs, p.cfg.Sys.MdDir, imgs)
|
||||
defer os.Remove(docxPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -76,7 +78,7 @@ func (p *ProductBiz) CreateAndUploadArticle(ctx context.Context, content string,
|
|||
return "", err
|
||||
}
|
||||
|
||||
url, err := p.oss.UploadBytes(docxName, fileByte)
|
||||
url, err := p.SourceUpload(ctx, fileByte, docxName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("上传文件失败: %w", err)
|
||||
}
|
||||
|
|
@ -89,7 +91,7 @@ func (p *ProductBiz) AddSource(ctx context.Context, source *model.ProductSource)
|
|||
}
|
||||
|
||||
func (p *ProductBiz) SourceUpload(ctx context.Context, file []byte, fileName string) (string, error) {
|
||||
url, err := p.oss.UploadBytes(fileName, file)
|
||||
url, err := p.oss.UploadBytes(p.cfg.Oss.FilePath+fileName, file)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("上传文件失败: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ type Oss struct {
|
|||
Bucket string `mapstructure:"bucket"`
|
||||
Domain string `mapstructure:"domain"`
|
||||
Endpoint string `mapstructure:"endpoint"`
|
||||
FilePath string `mapstructure:"filepath"`
|
||||
}
|
||||
|
||||
// ServerConfig 服务器配置
|
||||
|
|
@ -95,6 +96,7 @@ func LoadConfig() (*Config, error) {
|
|||
Bucket: "attachment-public",
|
||||
Domain: "https://attachment-public.oss-cn-hangzhou.aliyuncs.com",
|
||||
Endpoint: "https://oss-cn-hangzhou.aliyuncs.com",
|
||||
FilePath: "geo/",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ func (p *PublishImpl) GetListWithUser(ctx context.Context, tokenID int32, page,
|
|||
`).
|
||||
Joins("LEFT JOIN user u ON p.user_index COLLATE utf8mb4_unicode_ci = u.user_index").
|
||||
Joins("LEFT JOIN plat pl ON p.plat_index COLLATE utf8mb4_unicode_ci = pl.index").
|
||||
Where("u.token_id = ?", tokenID)
|
||||
Where("u.token_id = ?", tokenID).Order("publish_time desc")
|
||||
|
||||
// 添加过滤条件
|
||||
if userIndex, ok := filters["user_index"]; ok && userIndex != "" {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ type Product struct {
|
|||
Background string `gorm:"column:background;comment:信任背书" json:"background"` // 信任背书
|
||||
Case string `gorm:"column:case;comment:品牌案例" json:"case"` // 品牌案例
|
||||
Other string `gorm:"column:other;comment:其他信息" json:"other"` // 其他信息
|
||||
ServiceCope string `gorm:"column:service_cope;comment:服务范围" json:"service_cope"` // 服务范围
|
||||
ServiceScope string `gorm:"column:service_scope;comment:服务范围" json:"service_scope"` // 服务范围
|
||||
TargetAudience string `gorm:"column:target_audience;comment:目标客户群体" json:"target_audience"` // 目标客户群体
|
||||
Imgs string `gorm:"column:imgs;comment:图片" json:"imgs"` // 图片
|
||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ const TableNamePublish = "publish"
|
|||
type Publish struct {
|
||||
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"`
|
||||
TokenID int32 `gorm:"column:token_id;not null" json:"token_id"`
|
||||
SourceID int32 `gorm:"column:source_id;not null" json:"source_id"`
|
||||
UserIndex string `gorm:"column:user_index;not null;comment:关联user.user_index" json:"user_index"` // 关联user.user_index
|
||||
RequestID string `gorm:"column:request_id;not null;comment:日志id" json:"request_id"` // 日志id
|
||||
Title string `gorm:"column:title;not null" json:"title"`
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@ type (
|
|||
UserIndex string `json:"user_index" validate:"required" zh:"用户索引"`
|
||||
}
|
||||
|
||||
PlatListRequest struct {
|
||||
AccessToken string `json:"access_token" validate:"required" zh:"access_token"`
|
||||
PlatType int `json:"plat_type" zh:"平台类型"`
|
||||
}
|
||||
|
||||
PublishRecordsRequest struct {
|
||||
AccessToken string `json:"access_token" validate:"required" zh:"access_token"`
|
||||
Records []PublishRecordItem `json:"records" validate:"required" zh:"发布记录"`
|
||||
|
|
@ -100,7 +105,8 @@ type (
|
|||
Background string `json:"background" zh:"信任背书"`
|
||||
Case string `json:"case" zh:"品牌案例"`
|
||||
Other string `json:"other" zh:"其他信息"`
|
||||
ServiceCope string `json:"service_cope" zh:"服务范围"`
|
||||
ServiceScope string `json:"service_scope" zh:"服务范围"`
|
||||
Imgs string `json:"imgs" zh:"图片"`
|
||||
TargetAudience string `json:"target_audience" zh:"目标客户群体"`
|
||||
}
|
||||
|
||||
|
|
@ -111,6 +117,11 @@ type (
|
|||
PageSize int `json:"page_size"`
|
||||
}
|
||||
|
||||
ProductDetailRequest struct {
|
||||
AccessToken string `json:"access_token" validate:"required" zh:"access_token"`
|
||||
Id int32 `json:"id" validate:"required" zh:"id"`
|
||||
}
|
||||
|
||||
ProductUpdateRequest struct {
|
||||
AccessToken string `json:"access_token" validate:"required" zh:"access_token"`
|
||||
Id int32 `json:"id" validate:"required" zh:"id"`
|
||||
|
|
@ -125,6 +136,7 @@ type (
|
|||
Case string `json:"case" zh:"品牌案例"`
|
||||
Other string `json:"other" zh:"其他信息"`
|
||||
ServiceCope string `json:"service_cope" zh:"服务范围"`
|
||||
Imgs string `json:"imgs" zh:"图片"`
|
||||
TargetAudience string `json:"target_audience" zh:"目标客户群体"`
|
||||
}
|
||||
|
||||
|
|
@ -133,6 +145,11 @@ type (
|
|||
Id int32 `json:"id" validate:"required" zh:"产品id"`
|
||||
}
|
||||
|
||||
ImageUploadRequest struct {
|
||||
AccessToken string `json:"access_token" validate:"required" zh:"access_token"`
|
||||
Id int32 `json:"id" validate:"required" zh:"产品id"`
|
||||
}
|
||||
|
||||
ProductSourceCreateRequest struct {
|
||||
AccessToken string `json:"access_token" validate:"required" zh:"access_token"`
|
||||
ProductId int32 `json:"product_id" validate:"required" zh:"产品id"`
|
||||
|
|
@ -153,14 +170,21 @@ type (
|
|||
}
|
||||
|
||||
ProductSourceUpdateRequest struct {
|
||||
AccessToken string `json:"access_token" validate:"required" zh:"access_token"`
|
||||
SourceId int32 `json:"source_id" validate:"required" zh:"资源id"`
|
||||
Title string `json:"title" zh:"标题"`
|
||||
Tag []string `json:"tag" zh:"标题"`
|
||||
AccessToken string `json:"access_token" validate:"required" zh:"access_token"`
|
||||
SourceId int32 `json:"source_id" validate:"required" zh:"资源id"`
|
||||
Title *string `json:"title" zh:"标题"`
|
||||
Tag *[]string `json:"tag" zh:"标题"`
|
||||
}
|
||||
|
||||
ProductSourceDelRequest struct {
|
||||
AccessToken string `json:"access_token" validate:"required" zh:"access_token"`
|
||||
SourceId int32 `json:"source_id" validate:"required" zh:"资源id"`
|
||||
}
|
||||
|
||||
ProductPublishRequest struct {
|
||||
AccessToken string `json:"access_token" validate:"required" zh:"access_token"`
|
||||
SourceId int32 `json:"source_id" validate:"required" zh:"资源id"`
|
||||
Plat []string `json:"plat" validate:"required" zh:"平台"`
|
||||
PublishTime string `json:"publish_time" validate:"required" zh:"发布时间"`
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -29,23 +29,6 @@ func (p *BaijiahaoPublisher) CheckLoginStatus() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (p *BaijiahaoPublisher) CheckLogin() (bool, string) {
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.Sleep(3)
|
||||
p.WaitForPageReady(5)
|
||||
|
||||
if p.CheckLoginStatus() {
|
||||
p.SaveCookies()
|
||||
return true, "已登录"
|
||||
}
|
||||
return false, "未登录"
|
||||
}
|
||||
|
||||
func (p *BaijiahaoPublisher) WaitLogin() (bool, string) {
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
|
|
|
|||
|
|
@ -333,10 +333,6 @@ func (p *BasePublisher) CheckLoginStatus() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (b *BasePublisher) CheckLogin() (bool, string) {
|
||||
return false, "需要实现"
|
||||
}
|
||||
|
||||
func (b *BasePublisher) PublishNote() (bool, string) {
|
||||
return false, "需要实现"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,25 +19,6 @@ func NewCSDNPublisher(ctx context.Context, task *TaskParams, cfg *config.Config,
|
|||
return &CSDNPublisher{NewBasePublisher(ctx, task, cfg, logger)}
|
||||
}
|
||||
|
||||
func (p *CSDNPublisher) CheckLogin() (bool, string) {
|
||||
p.LogInfo("检查登录状态...")
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Close()
|
||||
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.Sleep(2)
|
||||
p.WaitForPageReady(3)
|
||||
|
||||
if p.CheckLoginStatus() {
|
||||
p.SaveCookies()
|
||||
return true, "已登录"
|
||||
}
|
||||
return false, "未登录"
|
||||
}
|
||||
|
||||
func (p *CSDNPublisher) WaitLogin() (bool, string) {
|
||||
p.LogInfo("开始等待登录...")
|
||||
|
||||
|
|
|
|||
|
|
@ -21,25 +21,6 @@ func NewDouyinSpPublisher(ctx context.Context, task *TaskParams, cfg *config.Con
|
|||
return &DouyinSpPublisher{NewBasePublisher(ctx, task, cfg, logger)}
|
||||
}
|
||||
|
||||
func (p *DouyinSpPublisher) CheckLogin() (bool, string) {
|
||||
p.LogInfo("检查登录状态...")
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Close()
|
||||
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.Sleep(3)
|
||||
p.WaitForPageReady(5)
|
||||
|
||||
if p.CheckLoginStatus() {
|
||||
p.SaveCookies()
|
||||
return true, "已登录"
|
||||
}
|
||||
return false, "未登录"
|
||||
}
|
||||
|
||||
func (p *DouyinSpPublisher) CheckLoginStatus() bool {
|
||||
currentURL := p.GetCurrentURL()
|
||||
if strings.Contains(currentURL, p.LoginedURL) {
|
||||
|
|
|
|||
|
|
@ -20,25 +20,6 @@ func NewJianshuPublisher(ctx context.Context, task *TaskParams, cfg *config.Conf
|
|||
return &JianshuPublisher{NewBasePublisher(ctx, task, cfg, logger)}
|
||||
}
|
||||
|
||||
func (p *JianshuPublisher) CheckLogin() (bool, string) {
|
||||
p.LogInfo("检查登录状态...")
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Close()
|
||||
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.Sleep(3)
|
||||
p.WaitForPageReady(5)
|
||||
|
||||
if p.CheckLoginStatus() {
|
||||
p.SaveCookies()
|
||||
return true, "已登录"
|
||||
}
|
||||
return false, "未登录"
|
||||
}
|
||||
|
||||
func (p *JianshuPublisher) CheckLoginStatus() bool {
|
||||
currentURL := p.GetCurrentURL()
|
||||
if strings.Contains(currentURL, p.LoginURL) {
|
||||
|
|
|
|||
|
|
@ -20,25 +20,6 @@ func NewSohuPublisher(ctx context.Context, task *TaskParams, cfg *config.Config,
|
|||
return &SohuPublisher{NewBasePublisher(ctx, task, cfg, logger)}
|
||||
}
|
||||
|
||||
func (p *SohuPublisher) CheckLogin() (bool, string) {
|
||||
p.LogInfo("检查登录状态...")
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Close()
|
||||
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.Sleep(3)
|
||||
p.WaitForPageReady(5)
|
||||
|
||||
if p.CheckLoginStatus() {
|
||||
p.SaveCookies()
|
||||
return true, "已登录"
|
||||
}
|
||||
return false, "未登录"
|
||||
}
|
||||
|
||||
func (p *SohuPublisher) CheckLoginStatus() bool {
|
||||
currentURL := p.GetCurrentURL()
|
||||
if strings.Contains(currentURL, p.LoginURL) {
|
||||
|
|
|
|||
|
|
@ -23,25 +23,6 @@ func NewShipinhaoVideoPublisher(ctx context.Context, task *TaskParams, config *c
|
|||
}
|
||||
}
|
||||
|
||||
func (p *ShipinhaoVideoPublisher) CheckLogin() (bool, string) {
|
||||
p.LogInfo("检查登录状态...")
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Close()
|
||||
|
||||
p.Page.MustNavigate(p.LoginedURL)
|
||||
p.Sleep(3)
|
||||
p.WaitForPageReady(5)
|
||||
|
||||
if p.CheckLoginStatus() {
|
||||
p.SaveCookies()
|
||||
return true, "已登录"
|
||||
}
|
||||
return false, "未登录"
|
||||
}
|
||||
|
||||
func (p *ShipinhaoVideoPublisher) CheckLoginStatus() bool {
|
||||
currentURL := p.GetCurrentURL()
|
||||
if strings.Contains(currentURL, "login") || strings.Contains(currentURL, "passport") {
|
||||
|
|
|
|||
|
|
@ -21,25 +21,6 @@ func NewToutiaoPublisher(ctx context.Context, task *TaskParams, cfg *config.Conf
|
|||
return &ToutiaoPublisher{NewBasePublisher(ctx, task, cfg, logger)}
|
||||
}
|
||||
|
||||
func (p *ToutiaoPublisher) CheckLogin() (bool, string) {
|
||||
p.LogInfo("检查登录状态...")
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Close()
|
||||
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.Sleep(2)
|
||||
p.WaitForPageReady(5)
|
||||
|
||||
if p.CheckLoginStatus() {
|
||||
p.SaveCookies()
|
||||
return true, "已登录"
|
||||
}
|
||||
return false, "未登录"
|
||||
}
|
||||
|
||||
func (p *ToutiaoPublisher) CheckLoginStatus() bool {
|
||||
currentURL := p.GetCurrentURL()
|
||||
// 如果在登录页面,未登录
|
||||
|
|
|
|||
|
|
@ -28,25 +28,6 @@ func NewWangyiPublisher(ctx context.Context, task *TaskParams, cfg *config.Confi
|
|||
}
|
||||
}
|
||||
|
||||
func (p *WangyiPublisher) CheckLogin() (bool, string) {
|
||||
p.LogInfo("检查登录状态...")
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Page.Close()
|
||||
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.Sleep(3)
|
||||
p.WaitForPageReady(5)
|
||||
|
||||
if p.CheckLoginStatus() {
|
||||
p.SaveCookies()
|
||||
return true, "已登录"
|
||||
}
|
||||
return false, "未登录"
|
||||
}
|
||||
|
||||
func (p *WangyiPublisher) CheckLoginStatus() bool {
|
||||
currentURL := p.GetCurrentURL()
|
||||
|
||||
|
|
|
|||
|
|
@ -21,25 +21,6 @@ func NewXiaohongshuPublisher(ctx context.Context, task *TaskParams, cfg *config.
|
|||
return &XiaohongshuPublisher{NewBasePublisher(ctx, task, cfg, logger)}
|
||||
}
|
||||
|
||||
func (p *XiaohongshuPublisher) CheckLogin() (bool, string) {
|
||||
p.LogInfo("检查登录状态...")
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Close()
|
||||
|
||||
p.Page.MustNavigate(p.LoginedURL)
|
||||
p.Sleep(3)
|
||||
//p.WaitForPageReady(5)
|
||||
|
||||
if p.CheckLoginStatus() {
|
||||
p.SaveCookies()
|
||||
return true, "已登录"
|
||||
}
|
||||
return false, "未登录"
|
||||
}
|
||||
|
||||
func (p *XiaohongshuPublisher) WaitLogin() (bool, string) {
|
||||
p.LogInfo("开始等待登录...")
|
||||
|
||||
|
|
|
|||
|
|
@ -29,25 +29,6 @@ func NewXiaohongshuVideoPublisher(ctx context.Context, task *TaskParams, cfg *co
|
|||
}
|
||||
}
|
||||
|
||||
func (p *XiaohongshuVideoPublisher) CheckLogin() (bool, string) {
|
||||
p.LogInfo("检查登录状态...")
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Page.Close()
|
||||
|
||||
p.Page.MustNavigate(p.LoginedURL)
|
||||
p.Sleep(3)
|
||||
p.WaitForPageReady(5)
|
||||
|
||||
if p.CheckLoginStatus() {
|
||||
p.SaveCookies()
|
||||
return true, "已登录"
|
||||
}
|
||||
return false, "未登录"
|
||||
}
|
||||
|
||||
func (p *XiaohongshuVideoPublisher) WaitLogin() (bool, string) {
|
||||
p.LogInfo("开始等待登录...")
|
||||
|
||||
|
|
|
|||
|
|
@ -20,25 +20,6 @@ func NewZhihuPublisher(ctx context.Context, task *TaskParams, cfg *config.Config
|
|||
return &ZhihuPublisher{NewBasePublisher(ctx, task, cfg, logger)}
|
||||
}
|
||||
|
||||
func (p *ZhihuPublisher) CheckLogin() (bool, string) {
|
||||
p.LogInfo("检查登录状态...")
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Page.Close()
|
||||
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.Sleep(3)
|
||||
p.WaitForPageReady(5)
|
||||
|
||||
if p.CheckLoginStatus() {
|
||||
p.SaveCookies()
|
||||
return true, "已登录"
|
||||
}
|
||||
return false, "未登录"
|
||||
}
|
||||
|
||||
func (p *ZhihuPublisher) CheckLoginStatus() bool {
|
||||
currentURL := p.GetCurrentURL()
|
||||
if strings.Contains(currentURL, p.LoginURL) {
|
||||
|
|
|
|||
|
|
@ -53,12 +53,17 @@ func (m *AppModule) Register(router fiber.Router) {
|
|||
|
||||
router.Post("/product/add", vali(m.productService.Add, &entitys.CreateProductRequest{}))
|
||||
router.Post("/product/list", vali(m.productService.List, &entitys.ProductListRequest{}))
|
||||
router.Post("/product/detail", vali(m.productService.Detail, &entitys.ProductDetailRequest{}))
|
||||
router.Post("/product/update", vali(m.productService.Update, &entitys.ProductUpdateRequest{}))
|
||||
router.Post("/product/del", vali(m.productService.Del, &entitys.ProductDelRequest{}))
|
||||
router.Post("/img/upload", m.productService.ImgUpload)
|
||||
|
||||
router.Post("/plat/list", vali(m.appService.PlatList, &entitys.PlatListRequest{}))
|
||||
router.Get("/product/word/article_type_list", m.productSourceService.ArticalTypeList)
|
||||
router.Post("/product/word/create", vali(m.productSourceService.Create, &entitys.ProductSourceCreateRequest{}))
|
||||
router.Post("/product/source/list", vali(m.productSourceService.List, &entitys.ProductSourceListRequest{}))
|
||||
router.Post("/product/source/upload", m.productSourceService.UploadSource)
|
||||
router.Post("/product/source/update", vali(m.productSourceService.Update, &entitys.ProductSourceUpdateRequest{}))
|
||||
router.Post("/product/source/del", vali(m.productSourceService.Del, &entitys.ProductSourceDelRequest{}))
|
||||
router.Post("/product/source/publish", vali(m.productSourceService.Publish, &entitys.ProductPublishRequest{}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package service
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"xorm.io/builder"
|
||||
|
||||
|
|
@ -191,3 +190,21 @@ func (a *AppService) GetApp(c *fiber.Ctx, req *entitys.GetAppRequest) error {
|
|||
|
||||
return pkg.HandleResponse(c, result)
|
||||
}
|
||||
|
||||
func (a *AppService) PlatList(c *fiber.Ctx, req *entitys.PlatListRequest) error {
|
||||
_, err := a.authBiz.ValidateAccessToken(c.UserContext(), req.AccessToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cond := builder.NewCond().
|
||||
And(builder.Eq{"status": 1})
|
||||
if req.PlatType != 0 {
|
||||
cond.And(builder.Eq{"plat_type": req.PlatType})
|
||||
}
|
||||
list, err := a.platImpl.GetRange(c.UserContext(), &cond)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return pkg.HandleResponse(c, list)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,10 @@ import (
|
|||
"geo/internal/entitys"
|
||||
"geo/pkg"
|
||||
"geo/tmpl/dataTemp"
|
||||
|
||||
"geo/tmpl/errcode"
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"io"
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
|
|
@ -18,13 +19,15 @@ type ProductService struct {
|
|||
cfg *config.Config
|
||||
productImpl *impl.ProductImpl
|
||||
authBiz *biz.AuthBiz
|
||||
productBiz *biz.ProductBiz
|
||||
}
|
||||
|
||||
func NewProductService(cfg *config.Config, ProductImpl *impl.ProductImpl, authBiz *biz.AuthBiz) *ProductService {
|
||||
func NewProductService(cfg *config.Config, ProductImpl *impl.ProductImpl, authBiz *biz.AuthBiz, productBiz *biz.ProductBiz) *ProductService {
|
||||
return &ProductService{
|
||||
cfg: cfg,
|
||||
productImpl: ProductImpl,
|
||||
authBiz: authBiz,
|
||||
productBiz: productBiz,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -45,6 +48,21 @@ func (p *ProductService) Add(c *fiber.Ctx, req *entitys.CreateProductRequest) er
|
|||
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 {
|
||||
|
|
@ -95,3 +113,42 @@ func (p *ProductService) Del(c *fiber.Ctx, req *entitys.ProductDelRequest) error
|
|||
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})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,12 +25,23 @@ type ProductSourceService struct {
|
|||
cfg *config.Config
|
||||
productImpl *impl.ProductImpl
|
||||
productSourceImpl *impl.ProductSourceImpl
|
||||
articleTypeImpl *impl.ArticleTypeImpl
|
||||
authBiz *biz.AuthBiz
|
||||
aiBiz *biz.AiBiz
|
||||
productBiz *biz.ProductBiz
|
||||
publishBiz *biz.PublishBiz
|
||||
}
|
||||
|
||||
func NewProductSourceService(cfg *config.Config, ProductImpl *impl.ProductImpl, authBiz *biz.AuthBiz, aiBiz *biz.AiBiz, productBiz *biz.ProductBiz, productSource *impl.ProductSourceImpl) *ProductSourceService {
|
||||
func NewProductSourceService(
|
||||
cfg *config.Config,
|
||||
ProductImpl *impl.ProductImpl,
|
||||
authBiz *biz.AuthBiz,
|
||||
aiBiz *biz.AiBiz,
|
||||
productBiz *biz.ProductBiz,
|
||||
productSource *impl.ProductSourceImpl,
|
||||
publishBiz *biz.PublishBiz,
|
||||
articleTypeImpl *impl.ArticleTypeImpl,
|
||||
) *ProductSourceService {
|
||||
return &ProductSourceService{
|
||||
cfg: cfg,
|
||||
productImpl: ProductImpl,
|
||||
|
|
@ -38,6 +49,8 @@ func NewProductSourceService(cfg *config.Config, ProductImpl *impl.ProductImpl,
|
|||
aiBiz: aiBiz,
|
||||
productBiz: productBiz,
|
||||
productSourceImpl: productSource,
|
||||
publishBiz: publishBiz,
|
||||
articleTypeImpl: articleTypeImpl,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -175,11 +188,11 @@ func (p *ProductSourceService) Update(c *fiber.Ctx, req *entitys.ProductSourceUp
|
|||
return err
|
||||
}
|
||||
var update = &model.ProductSource{}
|
||||
if req.Title != "" {
|
||||
update.Title = req.Title
|
||||
if req.Title != nil {
|
||||
update.Title = *req.Title
|
||||
}
|
||||
if len(req.Tag) > 0 {
|
||||
update.Tag = strings.Join(req.Tag, ",")
|
||||
if req.Tag != nil {
|
||||
update.Tag = strings.Join(*req.Tag, ",")
|
||||
}
|
||||
|
||||
return p.productBiz.UpdateSourceById(c.UserContext(), req.SourceId, update)
|
||||
|
|
@ -194,3 +207,63 @@ func (p *ProductSourceService) Del(c *fiber.Ctx, req *entitys.ProductSourceDelRe
|
|||
|
||||
return p.productBiz.DelSourceById(c.UserContext(), req.SourceId)
|
||||
}
|
||||
|
||||
func (p *ProductSourceService) Publish(c *fiber.Ctx, req *entitys.ProductPublishRequest) error {
|
||||
// 验证token
|
||||
tokenInfo, err := p.authBiz.ValidateAccessToken(c.UserContext(), req.AccessToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var source model.ProductSource
|
||||
err = p.productSourceImpl.GetByKey(c.UserContext(), p.productSourceImpl.PrimaryKey(), req.SourceId, &source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var product model.Product
|
||||
err = p.productImpl.GetByKey(c.UserContext(), p.productImpl.PrimaryKey(), source.ProductId, &product)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if product.Imgs == "" {
|
||||
return errcode.NotFound("请先上传产品图片")
|
||||
}
|
||||
ptime, err := time.Parse(time.DateTime, req.PublishTime)
|
||||
if err != nil {
|
||||
return errcode.ParamErr("发布时间格式错误")
|
||||
}
|
||||
var validRecords = make([]*model.Publish, 0, len(req.Plat))
|
||||
for _, v := range req.Plat {
|
||||
validRecords = append(validRecords, &model.Publish{
|
||||
UserIndex: product.UserIndex,
|
||||
SourceID: req.SourceId,
|
||||
RequestID: fmt.Sprintf("%s_%d", pkg.GenerateRandomLowerString(3), time.Now().UnixNano()),
|
||||
Title: source.Title,
|
||||
Tag: source.Tag,
|
||||
Type: source.SourceType,
|
||||
PlatIndex: v,
|
||||
URL: source.SourceURL,
|
||||
PublishTime: ptime,
|
||||
Img: strings.Split(product.Imgs, ",")[0],
|
||||
TokenID: tokenInfo.ID,
|
||||
})
|
||||
|
||||
}
|
||||
err = p.publishBiz.BatchInsertPublish(c.UserContext(), validRecords)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return pkg.HandleResponse(c, fiber.Map{
|
||||
"total": len(validRecords),
|
||||
})
|
||||
}
|
||||
|
||||
func (p *ProductSourceService) ArticalTypeList(c *fiber.Ctx) error {
|
||||
cond := builder.NewCond().
|
||||
And(builder.Eq{"status": 1})
|
||||
list, err := p.articleTypeImpl.GetRange(c.UserContext(), &cond)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return pkg.HandleResponse(c, list)
|
||||
}
|
||||
|
|
|
|||
17
pkg/func.go
17
pkg/func.go
|
|
@ -353,3 +353,20 @@ func ReadDocxToBytes(filePath string) ([]byte, error) {
|
|||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// getFileExtension 获取文件扩展名
|
||||
func GetFileExtension(filename string) string {
|
||||
parts := strings.Split(filename, ".")
|
||||
if len(parts) < 2 {
|
||||
return ".jpg" // 默认扩展名
|
||||
}
|
||||
return "." + parts[len(parts)-1]
|
||||
}
|
||||
|
||||
// generateImageFileName 根据图片类型生成文件名
|
||||
func GenerateImageFileName(ext string) string {
|
||||
// 生成唯一标识
|
||||
timestamp := time.Now().UnixNano() / 1e6 // 毫秒级时间戳
|
||||
randomNum := GenerateRandomLowerString(3) // 随机数
|
||||
return fmt.Sprintf("img_%d%s%s", timestamp, randomNum, ext)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
package pkg
|
||||
|
||||
import (
|
||||
"math/rand/v2"
|
||||
)
|
||||
|
||||
// GenerateRandomStringCustom 使用自定义字符集
|
||||
func GenerateRandomStringCustom(n int, charset string) string {
|
||||
result := make([]byte, n)
|
||||
for i := range result {
|
||||
result[i] = charset[rand.IntN(len(charset))]
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
|
||||
// 纯数字字符串
|
||||
func GenerateRandomNumberString(n int) string {
|
||||
return GenerateRandomStringCustom(n, "0123456789")
|
||||
}
|
||||
|
||||
// 纯小写字母
|
||||
func GenerateRandomLowerString(n int) string {
|
||||
return GenerateRandomStringCustom(n, "abcdefghijklmnopqrstuvwxyz")
|
||||
}
|
||||
|
||||
// 纯大写字母
|
||||
func GenerateRandomUpperString(n int) string {
|
||||
return GenerateRandomStringCustom(n, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
}
|
||||
|
||||
// 使用自定义随机源(例如固定种子)
|
||||
func GenerateRandomStringWithSeed(n int, seed uint64) string {
|
||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
|
||||
rng := rand.New(rand.NewPCG(seed, seed))
|
||||
result := make([]byte, n)
|
||||
for i := range result {
|
||||
result[i] = charset[rng.IntN(len(charset))]
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
|
|
@ -36,3 +36,22 @@ func SuccessWithPageMsg(c *fiber.Ctx, list interface{}, total int64, page, pageS
|
|||
}
|
||||
return HandleResponse(c, response)
|
||||
}
|
||||
|
||||
func HandleResponseWithErr(c *fiber.Ctx, data interface{}, errs error) (err error) {
|
||||
if errs != nil {
|
||||
err = errs
|
||||
return
|
||||
}
|
||||
switch data.(type) {
|
||||
case error:
|
||||
err = data.(error)
|
||||
case int, int32, int64, float32, float64, string, bool:
|
||||
c.Response().SetBody([]byte(fmt.Sprintf("%s", data)))
|
||||
case []byte:
|
||||
c.Response().SetBody(data.([]byte))
|
||||
default:
|
||||
dataByte, _ := json.Marshal(data)
|
||||
c.Response().SetBody(dataByte)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue