diff --git a/model/gmodel/fs_product_logic.go b/model/gmodel/fs_product_logic.go index 12617ca3..6413c0d6 100755 --- a/model/gmodel/fs_product_logic.go +++ b/model/gmodel/fs_product_logic.go @@ -11,6 +11,11 @@ func (m *FsProductModel) TableName() string { return m.name } +func (t *FsProductModel) FindAll(ctx context.Context) (resp []FsProduct, err error) { + err = t.db.WithContext(ctx).Model(&FsProduct{}).Find(&resp).Error + return resp, err +} + func (p *FsProductModel) FindOne(ctx context.Context, id int64, fields ...string) (resp *FsProduct, err error) { db := p.db.WithContext(ctx).Model(&FsProduct{}).Where("`id` = ? ", id) if len(fields) != 0 { diff --git a/model/gmodel/fs_product_model3d_light_logic.go b/model/gmodel/fs_product_model3d_light_logic.go index 76fb12b3..c9c77270 100755 --- a/model/gmodel/fs_product_model3d_light_logic.go +++ b/model/gmodel/fs_product_model3d_light_logic.go @@ -2,6 +2,10 @@ package gmodel import "context" +func (t *FsProductModel3dLightModel) FindAll(ctx context.Context) (resp []FsProductModel3dLight, err error) { + err = t.db.WithContext(ctx).Model(&FsProductModel3dLight{}).Limit(10).Find(&resp).Error + return resp, err +} func (l *FsProductModel3dLightModel) FindOne(ctx context.Context, id int64) (resp *FsProductModel3dLight, err error) { err = l.db.WithContext(ctx).Model(&FsProductModel3dLight{}).Where("`id` = ? and `status` = ?", id, 1).Take(&resp).Error return resp, err diff --git a/model/gmodel/fs_product_model3d_logic.go b/model/gmodel/fs_product_model3d_logic.go index cc7a6959..756f3594 100755 --- a/model/gmodel/fs_product_model3d_logic.go +++ b/model/gmodel/fs_product_model3d_logic.go @@ -19,6 +19,11 @@ type StepPriceJsonStruct struct { MinBuyUnitsNum int64 `json:"min_buy_units_num"` } +func (t *FsProductModel3dModel) FindAll(ctx context.Context) (resp []FsProductModel3d, err error) { + err = t.db.WithContext(ctx).Model(&FsProductModel3d{}).Find(&resp).Error + return resp, err +} + func (d *FsProductModel3dModel) FindOne(ctx context.Context, id int64, fields ...string) (resp *FsProductModel3d, err error) { db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).Where("`id` = ? and `status` =? ", id, 1) if len(fields) > 0 { diff --git a/model/gmodel/fs_product_template_tags_logic.go b/model/gmodel/fs_product_template_tags_logic.go index 8c931575..d143e08a 100755 --- a/model/gmodel/fs_product_template_tags_logic.go +++ b/model/gmodel/fs_product_template_tags_logic.go @@ -4,6 +4,11 @@ import ( "context" ) +func (t *FsProductTemplateTagsModel) FindAll(ctx context.Context) (resp []FsProductTemplateTags, err error) { + err = t.db.WithContext(ctx).Model(&FsProductTemplateTags{}).Find(&resp).Error + return resp, err +} + func (pt *FsProductTemplateTagsModel) GetListByIds(ctx context.Context, ids []int64) (resp []FsProductTemplateTags, err error) { if len(ids) == 0 { return diff --git a/model/gmodel/fs_product_template_v2_logic.go b/model/gmodel/fs_product_template_v2_logic.go index 3bacf94b..46e73745 100755 --- a/model/gmodel/fs_product_template_v2_logic.go +++ b/model/gmodel/fs_product_template_v2_logic.go @@ -4,6 +4,11 @@ import ( "context" ) +func (t *FsProductTemplateV2Model) FindAll(ctx context.Context) (resp []FsProductTemplateV2, err error) { + err = t.db.WithContext(ctx).Model(&FsProductTemplateV2{}).Find(&resp).Error + return resp, err +} + func (t *FsProductTemplateV2Model) FindAllByProductIds(ctx context.Context, productIds []int64, sort string, fields ...string) (resp []FsProductTemplateV2, err error) { if len(productIds) == 0 { return diff --git a/model/gmodel/fs_tool_logs_logic.go b/model/gmodel/fs_tool_logs_logic.go index 35237a04..1a4ca200 100644 --- a/model/gmodel/fs_tool_logs_logic.go +++ b/model/gmodel/fs_tool_logs_logic.go @@ -1,3 +1,9 @@ package gmodel +import "context" + // TODO: 使用model的属性做你想做的 +func (t *FsToolLogsModel) FindAll(ctx context.Context) (resp []FsToolLogs, err error) { + err = t.db.WithContext(ctx).Model(&FsToolLogs{}).Limit(10).Find(&resp).Error + return resp, err +} diff --git a/server/resource/internal/config/config.go b/server/resource/internal/config/config.go index 90142fce..57be6194 100644 --- a/server/resource/internal/config/config.go +++ b/server/resource/internal/config/config.go @@ -24,4 +24,10 @@ type Config struct { Version string Urls []string } + AliyunOSS struct { + AccessKeyId string + AccessKeySecret string + BasePath string + Endpoint string + } } diff --git a/server/resource/internal/handler/resourcebackuphandler.go b/server/resource/internal/handler/resourcebackuphandler.go new file mode 100644 index 00000000..ad5a4b11 --- /dev/null +++ b/server/resource/internal/handler/resourcebackuphandler.go @@ -0,0 +1,35 @@ +package handler + +import ( + "net/http" + "reflect" + + "fusenapi/utils/basic" + + "fusenapi/server/resource/internal/logic" + "fusenapi/server/resource/internal/svc" + "fusenapi/server/resource/internal/types" +) + +func ResourceBackupHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var req types.ResourceBackupReq + userinfo, err := basic.RequestParse(w, r, svcCtx, &req) + if err != nil { + return + } + + // 创建一个业务逻辑层实例 + l := logic.NewResourceBackupLogic(r.Context(), svcCtx) + + rl := reflect.ValueOf(l) + basic.BeforeLogic(w, r, rl) + + resp := l.ResourceBackup(&req, userinfo) + + if !basic.AfterLogic(w, r, rl, resp) { + basic.NormalAfterLogic(w, r, resp) + } + } +} diff --git a/server/resource/internal/handler/routes.go b/server/resource/internal/handler/routes.go index 304c232f..7c2b22c1 100644 --- a/server/resource/internal/handler/routes.go +++ b/server/resource/internal/handler/routes.go @@ -32,6 +32,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/resource/logo-resize", Handler: LogoResizeHandler(serverCtx), }, + { + Method: http.MethodPost, + Path: "/api/resource/backup", + Handler: ResourceBackupHandler(serverCtx), + }, }, ) } diff --git a/server/resource/internal/logic/resourcebackuplogic.go b/server/resource/internal/logic/resourcebackuplogic.go new file mode 100644 index 00000000..3c9119ac --- /dev/null +++ b/server/resource/internal/logic/resourcebackuplogic.go @@ -0,0 +1,186 @@ +package logic + +import ( + "fusenapi/utils/auth" + "fusenapi/utils/basic" + "fusenapi/utils/file" + "fusenapi/utils/s3url_to_s3id" + "regexp" + "strings" + "time" + + "context" + + "fusenapi/server/resource/internal/svc" + "fusenapi/server/resource/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type ResourceBackupLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewResourceBackupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ResourceBackupLogic { + return &ResourceBackupLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +// 处理进入前逻辑w,r +// func (l *ResourceBackupLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { +// } + +func (l *ResourceBackupLogic) ResourceBackup(req *types.ResourceBackupReq, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + var urls = make(map[string]string, 1000) + switch req.TableName { + case "fs_product_template_v2": + // 查询所有数据 + resList, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAll(l.ctx) + if err != nil { + l.Logger.Errorf("查询所有数据失败, err: %v", err) + return resp.SetStatus(basic.CodeApiErr) + } + + for _, data := range resList { + if data.MaterialImg != nil { + urls[s3url_to_s3id.GetS3ResourceIdFormUrl(*data.MaterialImg)] = *data.MaterialImg + } + if data.TemplateInfo != nil && *data.TemplateInfo != "" { + regexStr(*data.TemplateInfo, &urls) + } + } + case "fs_product": + // 查询所有数据 + resList, err := l.svcCtx.AllModels.FsProduct.FindAll(l.ctx) + if err != nil { + l.Logger.Errorf("查询所有数据失败, err: %v", err) + return resp.SetStatus(basic.CodeApiErr) + } + + for _, data := range resList { + if data.Cover != nil && *data.Cover != "" { + urls[s3url_to_s3id.GetS3ResourceIdFormUrl(*data.Cover)] = *data.Cover + } + if data.CoverImg != nil && *data.CoverImg != "" { + urls[s3url_to_s3id.GetS3ResourceIdFormUrl(*data.CoverImg)] = *data.CoverImg + } + } + case "fs_product_template_tags": + // 查询所有数据 + resList, err := l.svcCtx.AllModels.FsProductTemplateTags.FindAll(l.ctx) + if err != nil { + l.Logger.Errorf("查询所有数据失败, err: %v", err) + return resp.SetStatus(basic.CodeApiErr) + } + + for _, data := range resList { + if data.Cover != nil && *data.Cover != "" { + urls[s3url_to_s3id.GetS3ResourceIdFormUrl(*data.Cover)] = *data.Cover + } + } + case "fs_product_model3d": + // 查询所有数据 + resList, err := l.svcCtx.AllModels.FsProductModel3d.FindAll(l.ctx) + if err != nil { + l.Logger.Errorf("查询所有数据失败, err: %v", err) + return resp.SetStatus(basic.CodeApiErr) + } + + for _, data := range resList { + if data.ModelInfo != nil && *data.ModelInfo != "" { + regexStr(*data.ModelInfo, &urls) + } + } + case "fs_product_model3d_light": + // 查询所有数据 + resList, err := l.svcCtx.AllModels.FsProductModel3dLight.FindAll(l.ctx) + if err != nil { + l.Logger.Errorf("查询所有数据失败, err: %v", err) + return resp.SetStatus(basic.CodeApiErr) + } + + for _, data := range resList { + if data.Info != nil && *data.Info != "" { + regexStr(*data.Info, &urls) + } + } + case "fs_tool_logs": + // 查询所有数据 + resList, err := l.svcCtx.AllModels.FsToolLogs.FindAll(l.ctx) + if err != nil { + l.Logger.Errorf("查询所有数据失败, err: %v", err) + return resp.SetStatus(basic.CodeApiErr) + } + + for _, data := range resList { + if data.Cover != nil && *data.Cover != "" { + urls[s3url_to_s3id.GetS3ResourceIdFormUrl(*data.Cover)] = *data.Cover + } + if data.Img != nil && *data.Img != "" { + urls[s3url_to_s3id.GetS3ResourceIdFormUrl(*data.Img)] = *data.Img + } + } + } + // 上传文件 + var upload = file.Upload{ + Ctx: l.ctx, + MysqlConn: l.svcCtx.MysqlConn, + AwsSession: l.svcCtx.AwsSession, + } + upload.UploadType = "oss" + upload.AliyunOSS.AccessKeyId = l.svcCtx.Config.AliyunOSS.AccessKeyId + upload.AliyunOSS.AccessKeySecret = l.svcCtx.Config.AliyunOSS.AccessKeySecret + upload.AliyunOSS.Endpoint = l.svcCtx.Config.AliyunOSS.Endpoint + upload.AliyunOSS.BasePath = l.svcCtx.Config.AliyunOSS.BasePath + for k, v := range urls { + var resourceId = k + time.AfterFunc(time.Second*1, func() { + err := upload.UploadFileByUrl(resourceId, v, 2) + if err != nil { + l.Logger.Errorf("更新文件镜像备份, err: %v, key: %v, val:%v", err, k, v) + } + }) + } + return resp.SetStatus(basic.CodeOK) +} + +func regexStr(unquotedStr string, urls *map[string]string) error { + // 创建一个正则表达式 + regex := regexp.MustCompile(`"https:\\/\\/s3\.(.*?)"`) + // 查找符合正则表达式的字符串 + matches := regex.FindAllString(unquotedStr, -1) + var urlsData = *urls + // 打印匹配到的字符串 + for _, match := range matches { + var matchStr = match + // 将字符串去转义 + matchStr = strings.Replace(matchStr, "\"", "", -1) + matchStr = strings.Replace(matchStr, "\\", "", -1) + urlsData[s3url_to_s3id.GetS3ResourceIdFormUrl(matchStr)] = matchStr + } + + regex02 := regexp.MustCompile(`"https:\\/\\/fusenstorage\.s3\.(.*?)"`) + // 查找符合正则表达式的字符串 + matches02 := regex02.FindAllString(unquotedStr, -1) + // 打印匹配到的字符串 + for _, match := range matches02 { + var matchStr = match + // 将字符串去转义 + matchStr = strings.Replace(matchStr, "\"", "", -1) + matchStr = strings.Replace(matchStr, "\\", "", -1) + urlsData[s3url_to_s3id.GetS3ResourceIdFormUrl(matchStr)] = matchStr + } + return nil +} + +// 处理逻辑后 w,r 如:重定向, resp 必须重新处理 +// func (l *ResourceBackupLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { +// // httpx.OkJsonCtx(r.Context(), w, resp) +// } diff --git a/server/resource/internal/types/types.go b/server/resource/internal/types/types.go index 4e8f26c9..199742bd 100644 --- a/server/resource/internal/types/types.go +++ b/server/resource/internal/types/types.go @@ -5,6 +5,10 @@ import ( "fusenapi/utils/basic" ) +type ResourceBackupReq struct { + TableName string `json:"table_name"` +} + type LogoResizeReq struct { ResourceId string `form:"resource_id"` Width int64 `form:"width"` diff --git a/server_api/resource.api b/server_api/resource.api index f3fd9f2b..7986dd5a 100644 --- a/server_api/resource.api +++ b/server_api/resource.api @@ -25,8 +25,17 @@ service resource { @handler LogoResizeHandler post /api/resource/logo-resize(LogoResizeReq) returns (response); + + @handler ResourceBackupHandler + post /api/resource/backup(ResourceBackupReq) returns (response); } +type ( + ResourceBackupReq { + TableName string `json:"table_name"` + } +) + type ( LogoResizeReq { ResourceId string `form:"resource_id"`