Compare commits
3 Commits
06cc059998
...
fdbf26d751
| Author | SHA1 | Date | |
|---|---|---|---|
| fdbf26d751 | |||
| c42f2c651f | |||
| 788236ecc2 |
3
.vscode/launch.json
vendored
3
.vscode/launch.json
vendored
@@ -9,7 +9,8 @@
|
|||||||
"type": "go",
|
"type": "go",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"mode": "auto",
|
"mode": "auto",
|
||||||
"program": "${workspaceFolder}",
|
"cwd": "backend_v1",
|
||||||
|
"program": "${workspaceFolder}/backend_v1/main.go",
|
||||||
"args": [
|
"args": [
|
||||||
"serve"
|
"serve"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,40 +1,39 @@
|
|||||||
# .air.toml - Air 热重载配置文件
|
# .air.toml - Air 热重载配置文件
|
||||||
|
|
||||||
root = "."
|
root = "."
|
||||||
testdata_dir = "testdata"
|
testdata_dir = "testdata"
|
||||||
tmp_dir = "tmp"
|
tmp_dir = "tmp"
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
args_bin = []
|
args_bin = ["serve"]
|
||||||
bin = "./tmp/main"
|
bin = "./tmp/main"
|
||||||
cmd = "go build -o ./tmp/main ."
|
cmd = "go build -o ./tmp/main ."
|
||||||
delay = 1000
|
delay = 1000
|
||||||
exclude_dir = ["assets", "tmp", "vendor", "testdata", "frontend"]
|
exclude_dir = ["assets", "tmp", "vendor", "testdata", "frontend"]
|
||||||
exclude_file = []
|
exclude_file = []
|
||||||
exclude_regex = ["_test.go"]
|
exclude_regex = ["_test.go"]
|
||||||
exclude_unchanged = false
|
exclude_unchanged = false
|
||||||
follow_symlink = false
|
follow_symlink = false
|
||||||
full_bin = ""
|
full_bin = ""
|
||||||
include_dir = []
|
include_dir = []
|
||||||
include_ext = ["go", "tpl", "tmpl", "html", "yaml", "yml", "toml"]
|
include_ext = ["go", "tpl", "tmpl", "html", "yaml", "yml", "toml"]
|
||||||
kill_delay = "0s"
|
kill_delay = "0s"
|
||||||
log = "build-errors.log"
|
log = "build-errors.log"
|
||||||
send_interrupt = false
|
send_interrupt = false
|
||||||
stop_on_root = false
|
stop_on_root = false
|
||||||
|
|
||||||
[color]
|
[color]
|
||||||
app = ""
|
app = ""
|
||||||
build = "yellow"
|
build = "yellow"
|
||||||
main = "magenta"
|
main = "magenta"
|
||||||
runner = "green"
|
runner = "green"
|
||||||
watcher = "cyan"
|
watcher = "cyan"
|
||||||
|
|
||||||
[log]
|
[log]
|
||||||
time = false
|
time = false
|
||||||
|
|
||||||
[misc]
|
[misc]
|
||||||
clean_on_exit = false
|
clean_on_exit = false
|
||||||
|
|
||||||
[screen]
|
[screen]
|
||||||
clear_on_rebuild = false
|
clear_on_rebuild = false
|
||||||
keep_scroll = true
|
keep_scroll = true
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ import (
|
|||||||
|
|
||||||
"quyun/v2/app/commands"
|
"quyun/v2/app/commands"
|
||||||
"quyun/v2/app/errorx"
|
"quyun/v2/app/errorx"
|
||||||
|
web "quyun/v2/app/http"
|
||||||
"quyun/v2/app/jobs"
|
"quyun/v2/app/jobs"
|
||||||
|
"quyun/v2/app/middlewares"
|
||||||
_ "quyun/v2/docs"
|
_ "quyun/v2/docs"
|
||||||
|
"quyun/v2/providers/ali"
|
||||||
"quyun/v2/providers/app"
|
"quyun/v2/providers/app"
|
||||||
"quyun/v2/providers/http"
|
"quyun/v2/providers/http"
|
||||||
"quyun/v2/providers/http/swagger"
|
"quyun/v2/providers/http/swagger"
|
||||||
@@ -28,6 +31,7 @@ func defaultProviders() container.Providers {
|
|||||||
http.DefaultProvider(),
|
http.DefaultProvider(),
|
||||||
jwt.DefaultProvider(),
|
jwt.DefaultProvider(),
|
||||||
job.DefaultProvider(),
|
job.DefaultProvider(),
|
||||||
|
ali.DefaultProvider(),
|
||||||
}...)
|
}...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,8 +42,12 @@ func Command() atom.Option {
|
|||||||
atom.RunE(Serve),
|
atom.RunE(Serve),
|
||||||
atom.Providers(
|
atom.Providers(
|
||||||
defaultProviders().
|
defaultProviders().
|
||||||
|
WithProviders(
|
||||||
|
web.Providers(),
|
||||||
|
).
|
||||||
With(
|
With(
|
||||||
jobs.Provide,
|
jobs.Provide,
|
||||||
|
middlewares.Provide,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -48,11 +56,12 @@ func Command() atom.Option {
|
|||||||
type Service struct {
|
type Service struct {
|
||||||
dig.In
|
dig.In
|
||||||
|
|
||||||
App *app.Config
|
App *app.Config
|
||||||
Job *job.Job
|
Job *job.Job
|
||||||
Http *http.Service
|
Middleware *middlewares.Middlewares
|
||||||
Initials []contracts.Initial `group:"initials"`
|
Http *http.Service
|
||||||
Routes []contracts.HttpRoute `group:"routes"`
|
Initials []contracts.Initial `group:"initials"`
|
||||||
|
Routes []contracts.HttpRoute `group:"routes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func Serve(cmd *cobra.Command, args []string) error {
|
func Serve(cmd *cobra.Command, args []string) error {
|
||||||
@@ -68,9 +77,10 @@ func Serve(cmd *cobra.Command, args []string) error {
|
|||||||
svc.Http.Engine.Use(favicon.New(favicon.Config{
|
svc.Http.Engine.Use(favicon.New(favicon.Config{
|
||||||
Data: []byte{},
|
Data: []byte{},
|
||||||
}))
|
}))
|
||||||
|
svc.Http.Engine.Use(svc.Middleware.DebugMode)
|
||||||
|
|
||||||
group := svc.Http.Engine.Group("")
|
|
||||||
for _, route := range svc.Routes {
|
for _, route := range svc.Routes {
|
||||||
|
group := svc.Http.Engine.Group(route.Path(), route.Middlewares()...).Name(route.Name())
|
||||||
route.Register(group)
|
route.Register(group)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ type medias struct {
|
|||||||
// @Bind pagination query
|
// @Bind pagination query
|
||||||
// @Bind query query
|
// @Bind query query
|
||||||
func (ctl *medias) List(ctx fiber.Ctx, pagination *requests.Pagination, query *ListQuery) (*requests.Pager, error) {
|
func (ctl *medias) List(ctx fiber.Ctx, pagination *requests.Pagination, query *ListQuery) (*requests.Pager, error) {
|
||||||
return services.Medias.List(ctx, pagination, models.MediaQuery.Name.Like(database.WrapLike(*query.Keyword)))
|
return services.Media.List(ctx, pagination, models.MediaQuery.Name.Like(database.WrapLike(*query.Keyword)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show media
|
// Show media
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func (ctl *posts) List(ctx fiber.Ctx, pagination *requests.Pagination, query *Li
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
postIds := lo.Map(pager.Items.([]models.Post), func(item models.Post, _ int) int64 {
|
postIds := lo.Map(pager.Items.([]*models.Post), func(item *models.Post, _ int) int64 {
|
||||||
return item.ID
|
return item.ID
|
||||||
})
|
})
|
||||||
if len(postIds) > 0 {
|
if len(postIds) > 0 {
|
||||||
@@ -48,13 +48,13 @@ func (ctl *posts) List(ctx fiber.Ctx, pagination *requests.Pagination, query *Li
|
|||||||
return pager, err
|
return pager, err
|
||||||
}
|
}
|
||||||
|
|
||||||
items := lo.Map(pager.Items.([]models.Post), func(item models.Post, _ int) PostItem {
|
items := lo.Map(pager.Items.([]*models.Post), func(item *models.Post, _ int) PostItem {
|
||||||
cnt := int64(0)
|
cnt := int64(0)
|
||||||
if v, ok := postCntMap[item.ID]; ok {
|
if v, ok := postCntMap[item.ID]; ok {
|
||||||
cnt = v
|
cnt = v
|
||||||
}
|
}
|
||||||
|
|
||||||
return PostItem{Post: &item, BoughtCount: cnt}
|
return PostItem{Post: item, BoughtCount: cnt}
|
||||||
})
|
})
|
||||||
|
|
||||||
pager.Items = items
|
pager.Items = items
|
||||||
@@ -97,7 +97,7 @@ func (ctl *posts) Create(ctx fiber.Ctx, form *PostForm) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if form.Medias != nil {
|
if form.Medias != nil {
|
||||||
medias, err := services.Medias.GetByIds(ctx, form.Medias)
|
medias, err := services.Media.GetByIds(ctx, form.Medias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ func (ctl *posts) Update(ctx fiber.Ctx, post *models.Post, form *PostForm) error
|
|||||||
post.Tags = types.NewJSONType([]string{})
|
post.Tags = types.NewJSONType([]string{})
|
||||||
|
|
||||||
if form.Medias != nil {
|
if form.Medias != nil {
|
||||||
medias, err := services.Medias.GetByIds(ctx, form.Medias)
|
medias, err := services.Media.GetByIds(ctx, form.Medias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -192,7 +192,7 @@ type PostItem struct {
|
|||||||
// @Router /admin/posts/:id [get]
|
// @Router /admin/posts/:id [get]
|
||||||
// @Bind post path key(id) model(id)
|
// @Bind post path key(id) model(id)
|
||||||
func (ctl *posts) Show(ctx fiber.Ctx, post *models.Post) (*PostItem, error) {
|
func (ctl *posts) Show(ctx fiber.Ctx, post *models.Post) (*PostItem, error) {
|
||||||
medias, err := services.Medias.GetByIds(ctx, lo.Map(post.Assets.Data(), func(asset fields.MediaAsset, _ int) int64 {
|
medias, err := services.Media.GetByIds(ctx, lo.Map(post.Assets.Data(), func(asset fields.MediaAsset, _ int) int64 {
|
||||||
return asset.Media
|
return asset.Media
|
||||||
}))
|
}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -5,5 +5,7 @@ func (r *Routes) Path() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Routes) Middlewares() []any {
|
func (r *Routes) Middlewares() []any {
|
||||||
return []any{}
|
return []any{
|
||||||
|
r.middlewares.AuthAdmin,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ func (s *statistics) statistics(ctx fiber.Ctx) (*StatisticsResponse, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
statistics.Media, err = services.Medias.Count(ctx)
|
statistics.Media, err = services.Media.Count(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ type PreCheckResp struct {
|
|||||||
// @Bind ext path
|
// @Bind ext path
|
||||||
// @Bind mime query
|
// @Bind mime query
|
||||||
func (up *uploads) PreUploadCheck(ctx fiber.Ctx, md5, ext, mime string) (*PreCheckResp, error) {
|
func (up *uploads) PreUploadCheck(ctx fiber.Ctx, md5, ext, mime string) (*PreCheckResp, error) {
|
||||||
_, err := services.Medias.GetByHash(ctx, md5)
|
_, err := services.Media.GetByHash(ctx, md5)
|
||||||
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
preSign, err := up.oss.PreSignUpload(ctx, fmt.Sprintf("%s.%s", md5, ext), mime)
|
preSign, err := up.oss.PreSignUpload(ctx, fmt.Sprintf("%s.%s", md5, ext), mime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -77,7 +77,7 @@ type PostUploadedForm struct {
|
|||||||
// @Router /admin/uploads/post-uploaded-action [post]
|
// @Router /admin/uploads/post-uploaded-action [post]
|
||||||
// @Bind body body
|
// @Bind body body
|
||||||
func (up *uploads) PostUploadedAction(ctx fiber.Ctx, body *PostUploadedForm) error {
|
func (up *uploads) PostUploadedAction(ctx fiber.Ctx, body *PostUploadedForm) error {
|
||||||
m, err := services.Medias.GetByHash(ctx, body.Md5)
|
m, err := services.Media.GetByHash(ctx, body.Md5)
|
||||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ type posts struct {
|
|||||||
// @Param pagination query requests.Pagination false "分页参数"
|
// @Param pagination query requests.Pagination false "分页参数"
|
||||||
// @Param query query ListQuery false "筛选条件"
|
// @Param query query ListQuery false "筛选条件"
|
||||||
// @Success 200 {object} requests.Pager{items=PostItem} "成功"
|
// @Success 200 {object} requests.Pager{items=PostItem} "成功"
|
||||||
// @Router /posts [get]
|
// @Router /v1/posts [get]
|
||||||
// @Bind pagination query
|
// @Bind pagination query
|
||||||
// @Bind query query
|
// @Bind query query
|
||||||
// @Bind user local
|
// @Bind user local
|
||||||
@@ -55,7 +55,11 @@ func (ctl *posts) List(
|
|||||||
tbl, _ := models.PostQuery.QueryContext(ctx)
|
tbl, _ := models.PostQuery.QueryContext(ctx)
|
||||||
conds := []gen.Condition{
|
conds := []gen.Condition{
|
||||||
tbl.Status.Eq(fields.PostStatusPublished),
|
tbl.Status.Eq(fields.PostStatusPublished),
|
||||||
tbl.Title.Like(database.WrapLike(*query.Keyword)),
|
}
|
||||||
|
if query.Keyword != nil && *query.Keyword != "" {
|
||||||
|
conds = append(conds,
|
||||||
|
tbl.Title.Like(database.WrapLike(*query.Keyword)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pager, err := services.Posts.List(ctx, pagination, conds...)
|
pager, err := services.Posts.List(ctx, pagination, conds...)
|
||||||
@@ -64,14 +68,14 @@ func (ctl *posts) List(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
postIds := lo.Map(pager.Items.([]models.Post), func(item models.Post, _ int) int64 { return item.ID })
|
postIds := lo.Map(pager.Items.([]*models.Post), func(item *models.Post, _ int) int64 { return item.ID })
|
||||||
if len(postIds) > 0 {
|
if len(postIds) > 0 {
|
||||||
userBoughtIds, err := services.Users.BatchCheckHasBought(ctx, user.ID, postIds)
|
userBoughtIds, err := services.Users.BatchCheckHasBought(ctx, user.ID, postIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Errorf("BatchCheckHasBought err: %v", err)
|
log.WithError(err).Errorf("BatchCheckHasBought err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
items := lo.FilterMap(pager.Items.([]models.Post), func(item models.Post, _ int) (PostItem, bool) {
|
items := lo.FilterMap(pager.Items.([]*models.Post), func(item *models.Post, _ int) (PostItem, bool) {
|
||||||
medias, err := services.Posts.GetMediasByIds(ctx, item.HeadImages.Data())
|
medias, err := services.Posts.GetMediasByIds(ctx, item.HeadImages.Data())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("GetMediaByIds err: %v", err)
|
log.Errorf("GetMediaByIds err: %v", err)
|
||||||
@@ -132,7 +136,7 @@ type PostItem struct {
|
|||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path int64 true "作品 ID"
|
// @Param id path int64 true "作品 ID"
|
||||||
// @Success 200 {object} PostItem "成功"
|
// @Success 200 {object} PostItem "成功"
|
||||||
// @Router /posts/:id/show [get]
|
// @Router /v1/posts/:id/show [get]
|
||||||
// @Bind post path key(id) model(id)
|
// @Bind post path key(id) model(id)
|
||||||
// @Bind user local
|
// @Bind user local
|
||||||
func (ctl *posts) Show(ctx fiber.Ctx, post *models.Post, user *models.User) (*PostItem, error) {
|
func (ctl *posts) Show(ctx fiber.Ctx, post *models.Post, user *models.User) (*PostItem, error) {
|
||||||
@@ -187,7 +191,7 @@ type PlayUrl struct {
|
|||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path int64 true "作品 ID"
|
// @Param id path int64 true "作品 ID"
|
||||||
// @Success 200 {object} PlayUrl "成功"
|
// @Success 200 {object} PlayUrl "成功"
|
||||||
// @Router /posts/:id/play [get]
|
// @Router /v1/posts/:id/play [get]
|
||||||
// @Bind post path key(id) model(id)
|
// @Bind post path key(id) model(id)
|
||||||
// @Bind user local
|
// @Bind user local
|
||||||
func (ctl *posts) Play(ctx fiber.Ctx, post *models.Post, user *models.User) (*PlayUrl, error) {
|
func (ctl *posts) Play(ctx fiber.Ctx, post *models.Post, user *models.User) (*PlayUrl, error) {
|
||||||
@@ -207,7 +211,7 @@ func (ctl *posts) Play(ctx fiber.Ctx, post *models.Post, user *models.User) (*Pl
|
|||||||
|
|
||||||
for _, asset := range post.Assets.Data() {
|
for _, asset := range post.Assets.Data() {
|
||||||
if asset.Type == "video/mp4" && asset.Metas != nil && asset.Metas.Short == preview {
|
if asset.Type == "video/mp4" && asset.Metas != nil && asset.Metas.Short == preview {
|
||||||
media, err := services.Medias.FindByID(ctx, asset.Media)
|
media, err := services.Media.FindByID(ctx, asset.Media)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Errorf("medias GetByID err: %v", err)
|
log.WithError(err).Errorf("medias GetByID err: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -239,7 +243,7 @@ func (ctl *posts) Play(ctx fiber.Ctx, post *models.Post, user *models.User) (*Pl
|
|||||||
// @Param pagination query requests.Pagination false "分页参数"
|
// @Param pagination query requests.Pagination false "分页参数"
|
||||||
// @Param query query ListQuery false "筛选条件"
|
// @Param query query ListQuery false "筛选条件"
|
||||||
// @Success 200 {object} requests.Pager{items=PostItem} "成功"
|
// @Success 200 {object} requests.Pager{items=PostItem} "成功"
|
||||||
// @Router /posts/mine [get]
|
// @Router /v1/posts/mine [get]
|
||||||
// @Bind pagination query
|
// @Bind pagination query
|
||||||
// @Bind query query
|
// @Bind query query
|
||||||
// @Bind user local
|
// @Bind user local
|
||||||
@@ -253,7 +257,11 @@ func (ctl *posts) Mine(
|
|||||||
|
|
||||||
conds := []gen.Condition{
|
conds := []gen.Condition{
|
||||||
models.PostQuery.Status.Eq(fields.PostStatusPublished),
|
models.PostQuery.Status.Eq(fields.PostStatusPublished),
|
||||||
models.PostQuery.Title.Like(database.WrapLike(*query.Keyword)),
|
}
|
||||||
|
if query.Keyword != nil && *query.Keyword != "" {
|
||||||
|
conds = append(conds,
|
||||||
|
models.PostQuery.Title.Like(database.WrapLike(*query.Keyword)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pager, err := services.Users.PostList(ctx, user.ID, pagination, conds...)
|
pager, err := services.Users.PostList(ctx, user.ID, pagination, conds...)
|
||||||
@@ -265,7 +273,7 @@ func (ctl *posts) Mine(
|
|||||||
postIds := lo.Map(pager.Items.([]*models.Post), func(item *models.Post, _ int) int64 { return item.ID })
|
postIds := lo.Map(pager.Items.([]*models.Post), func(item *models.Post, _ int) int64 { return item.ID })
|
||||||
if len(postIds) > 0 {
|
if len(postIds) > 0 {
|
||||||
items := lo.FilterMap(pager.Items.([]*models.Post), func(item *models.Post, _ int) (PostItem, bool) {
|
items := lo.FilterMap(pager.Items.([]*models.Post), func(item *models.Post, _ int) (PostItem, bool) {
|
||||||
medias, err := services.Medias.GetByIds(ctx, item.HeadImages.Data())
|
medias, err := services.Media.GetByIds(ctx, item.HeadImages.Data())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("GetMediaByIds err: %v", err)
|
log.Errorf("GetMediaByIds err: %v", err)
|
||||||
return PostItem{}, false
|
return PostItem{}, false
|
||||||
@@ -306,7 +314,7 @@ func (ctl *posts) Mine(
|
|||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path int64 true "作品 ID"
|
// @Param id path int64 true "作品 ID"
|
||||||
// @Success 200 {object} wechat.JSAPIPayParams "成功(余额支付返回 AppId=balance)"
|
// @Success 200 {object} wechat.JSAPIPayParams "成功(余额支付返回 AppId=balance)"
|
||||||
// @Router /posts/:id/buy [post]
|
// @Router /v1/posts/:id/buy [post]
|
||||||
// @Bind post path key(id) model(id)
|
// @Bind post path key(id) model(id)
|
||||||
// @Bind user local
|
// @Bind user local
|
||||||
func (ctl *posts) Buy(ctx fiber.Ctx, post *models.Post, user *models.User) (*wechat.JSAPIPayParams, error) {
|
func (ctl *posts) Buy(ctx fiber.Ctx, post *models.Post, user *models.User) (*wechat.JSAPIPayParams, error) {
|
||||||
|
|||||||
@@ -45,15 +45,15 @@ func (r *Routes) Name() string {
|
|||||||
// Each route is registered with its corresponding controller action and parameter bindings.
|
// Each route is registered with its corresponding controller action and parameter bindings.
|
||||||
func (r *Routes) Register(router fiber.Router) {
|
func (r *Routes) Register(router fiber.Router) {
|
||||||
// Register routes for controller: posts
|
// Register routes for controller: posts
|
||||||
r.log.Debugf("Registering route: Get /posts -> posts.List")
|
r.log.Debugf("Registering route: Get /v1/posts -> posts.List")
|
||||||
router.Get("/posts"[len(r.Path()):], DataFunc3(
|
router.Get("/v1/posts"[len(r.Path()):], DataFunc3(
|
||||||
r.posts.List,
|
r.posts.List,
|
||||||
Query[requests.Pagination]("pagination"),
|
Query[requests.Pagination]("pagination"),
|
||||||
Query[ListQuery]("query"),
|
Query[ListQuery]("query"),
|
||||||
Local[*models.User]("user"),
|
Local[*models.User]("user"),
|
||||||
))
|
))
|
||||||
r.log.Debugf("Registering route: Get /posts/:id/play -> posts.Play")
|
r.log.Debugf("Registering route: Get /v1/posts/:id/play -> posts.Play")
|
||||||
router.Get("/posts/:id/play"[len(r.Path()):], DataFunc2(
|
router.Get("/v1/posts/:id/play"[len(r.Path()):], DataFunc2(
|
||||||
r.posts.Play,
|
r.posts.Play,
|
||||||
func(ctx fiber.Ctx) (*models.Post, error) {
|
func(ctx fiber.Ctx) (*models.Post, error) {
|
||||||
v := fiber.Params[int](ctx, "id")
|
v := fiber.Params[int](ctx, "id")
|
||||||
@@ -61,8 +61,8 @@ func (r *Routes) Register(router fiber.Router) {
|
|||||||
},
|
},
|
||||||
Local[*models.User]("user"),
|
Local[*models.User]("user"),
|
||||||
))
|
))
|
||||||
r.log.Debugf("Registering route: Get /posts/:id/show -> posts.Show")
|
r.log.Debugf("Registering route: Get /v1/posts/:id/show -> posts.Show")
|
||||||
router.Get("/posts/:id/show"[len(r.Path()):], DataFunc2(
|
router.Get("/v1/posts/:id/show"[len(r.Path()):], DataFunc2(
|
||||||
r.posts.Show,
|
r.posts.Show,
|
||||||
func(ctx fiber.Ctx) (*models.Post, error) {
|
func(ctx fiber.Ctx) (*models.Post, error) {
|
||||||
v := fiber.Params[int](ctx, "id")
|
v := fiber.Params[int](ctx, "id")
|
||||||
@@ -70,15 +70,15 @@ func (r *Routes) Register(router fiber.Router) {
|
|||||||
},
|
},
|
||||||
Local[*models.User]("user"),
|
Local[*models.User]("user"),
|
||||||
))
|
))
|
||||||
r.log.Debugf("Registering route: Get /posts/mine -> posts.Mine")
|
r.log.Debugf("Registering route: Get /v1/posts/mine -> posts.Mine")
|
||||||
router.Get("/posts/mine"[len(r.Path()):], DataFunc3(
|
router.Get("/v1/posts/mine"[len(r.Path()):], DataFunc3(
|
||||||
r.posts.Mine,
|
r.posts.Mine,
|
||||||
Query[requests.Pagination]("pagination"),
|
Query[requests.Pagination]("pagination"),
|
||||||
Query[ListQuery]("query"),
|
Query[ListQuery]("query"),
|
||||||
Local[*models.User]("user"),
|
Local[*models.User]("user"),
|
||||||
))
|
))
|
||||||
r.log.Debugf("Registering route: Post /posts/:id/buy -> posts.Buy")
|
r.log.Debugf("Registering route: Post /v1/posts/:id/buy -> posts.Buy")
|
||||||
router.Post("/posts/:id/buy"[len(r.Path()):], DataFunc2(
|
router.Post("/v1/posts/:id/buy"[len(r.Path()):], DataFunc2(
|
||||||
r.posts.Buy,
|
r.posts.Buy,
|
||||||
func(ctx fiber.Ctx) (*models.Post, error) {
|
func(ctx fiber.Ctx) (*models.Post, error) {
|
||||||
v := fiber.Params[int](ctx, "id")
|
v := fiber.Params[int](ctx, "id")
|
||||||
@@ -87,13 +87,13 @@ func (r *Routes) Register(router fiber.Router) {
|
|||||||
Local[*models.User]("user"),
|
Local[*models.User]("user"),
|
||||||
))
|
))
|
||||||
// Register routes for controller: users
|
// Register routes for controller: users
|
||||||
r.log.Debugf("Registering route: Get /users/profile -> users.Profile")
|
r.log.Debugf("Registering route: Get /v1/users/profile -> users.Profile")
|
||||||
router.Get("/users/profile"[len(r.Path()):], DataFunc1(
|
router.Get("/v1/users/profile"[len(r.Path()):], DataFunc1(
|
||||||
r.users.Profile,
|
r.users.Profile,
|
||||||
Local[*models.User]("user"),
|
Local[*models.User]("user"),
|
||||||
))
|
))
|
||||||
r.log.Debugf("Registering route: Put /users/username -> users.Update")
|
r.log.Debugf("Registering route: Put /v1/users/username -> users.Update")
|
||||||
router.Put("/users/username"[len(r.Path()):], Func2(
|
router.Put("/v1/users/username"[len(r.Path()):], Func2(
|
||||||
r.users.Update,
|
r.users.Update,
|
||||||
Local[*models.User]("user"),
|
Local[*models.User]("user"),
|
||||||
Body[ProfileForm]("form"),
|
Body[ProfileForm]("form"),
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package http
|
package http
|
||||||
|
|
||||||
func (r *Routes) Path() string {
|
func (r *Routes) Path() string {
|
||||||
return "/http"
|
return "/v1"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Routes) Middlewares() []any {
|
func (r *Routes) Middlewares() []any {
|
||||||
return []any{}
|
return []any{
|
||||||
|
r.middlewares.AuthFrontend,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ type UserInfo struct {
|
|||||||
// @Tags Users
|
// @Tags Users
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} UserInfo "成功"
|
// @Success 200 {object} UserInfo "成功"
|
||||||
// @Router /users/profile [get]
|
// @Router /v1/users/profile [get]
|
||||||
// @Bind user local
|
// @Bind user local
|
||||||
func (ctl *users) Profile(ctx fiber.Ctx, user *models.User) (*UserInfo, error) {
|
func (ctl *users) Profile(ctx fiber.Ctx, user *models.User) (*UserInfo, error) {
|
||||||
return &UserInfo{
|
return &UserInfo{
|
||||||
@@ -51,7 +51,7 @@ type ProfileForm struct {
|
|||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param form body ProfileForm true "请求体"
|
// @Param form body ProfileForm true "请求体"
|
||||||
// @Success 200 {object} any "成功"
|
// @Success 200 {object} any "成功"
|
||||||
// @Router /users/username [put]
|
// @Router /v1/users/username [put]
|
||||||
// @Bind user local
|
// @Bind user local
|
||||||
// @Bind form body
|
// @Bind form body
|
||||||
func (ctl *users) Update(ctx fiber.Ctx, user *models.User, form *ProfileForm) error {
|
func (ctl *users) Update(ctx fiber.Ctx, user *models.User, form *ProfileForm) error {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ func (w *DownloadFromAliOSSWorker) Work(ctx context.Context, job *Job[DownloadFr
|
|||||||
log.Infof("[Start] Working on job with strings: %+v", job.Args)
|
log.Infof("[Start] Working on job with strings: %+v", job.Args)
|
||||||
defer log.Infof("[End] Finished %s", job.Args.Kind())
|
defer log.Infof("[End] Finished %s", job.Args.Kind())
|
||||||
|
|
||||||
media, err := services.Medias.GetByHash(ctx, job.Args.MediaHash)
|
media, err := services.Media.GetByHash(ctx, job.Args.MediaHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error getting media by ID: %v", err)
|
log.Errorf("Error getting media by ID: %v", err)
|
||||||
return JobCancel(err)
|
return JobCancel(err)
|
||||||
|
|||||||
@@ -58,13 +58,13 @@ func (w *PublishDraftPostsWorker) Work(ctx context.Context, job *Job[PublishDraf
|
|||||||
log.Infof("[Start] Working on job with strings: %+v", job.Args)
|
log.Infof("[Start] Working on job with strings: %+v", job.Args)
|
||||||
defer log.Infof("[End] Finished %s", job.Args.Kind())
|
defer log.Infof("[End] Finished %s", job.Args.Kind())
|
||||||
|
|
||||||
media, err := services.Medias.GetByHash(ctx, job.Args.MediaHash)
|
media, err := services.Media.GetByHash(ctx, job.Args.MediaHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error getting media by ID: %v", err)
|
log.Errorf("Error getting media by ID: %v", err)
|
||||||
return JobCancel(err)
|
return JobCancel(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
relationMedias, err := services.Medias.GetRelations(ctx, media.Hash)
|
relationMedias, err := services.Media.GetRelations(ctx, media.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error getting relation medias: %v", err)
|
log.Errorf("Error getting relation medias: %v", err)
|
||||||
return JobCancel(err)
|
return JobCancel(err)
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ func (w *VideoCutWorker) Work(ctx context.Context, job *Job[VideoCut]) error {
|
|||||||
log.Infof("[Start] Working on job with strings: %+v", job.Args)
|
log.Infof("[Start] Working on job with strings: %+v", job.Args)
|
||||||
defer log.Infof("[End] Finished %s", job.Args.Kind())
|
defer log.Infof("[End] Finished %s", job.Args.Kind())
|
||||||
|
|
||||||
media, err := services.Medias.GetByHash(ctx, job.Args.MediaHash)
|
media, err := services.Media.GetByHash(ctx, job.Args.MediaHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error getting media by ID: %v", err)
|
log.Errorf("Error getting media by ID: %v", err)
|
||||||
return JobCancel(err)
|
return JobCancel(err)
|
||||||
@@ -81,7 +81,7 @@ func (w *VideoCutWorker) Work(ctx context.Context, job *Job[VideoCut]) error {
|
|||||||
Short: false,
|
Short: false,
|
||||||
Duration: duration,
|
Duration: duration,
|
||||||
}
|
}
|
||||||
if err := services.Medias.UpdateMetas(ctx, media.ID, metas); err != nil {
|
if err := services.Media.UpdateMetas(ctx, media.ID, metas); err != nil {
|
||||||
log.Errorf("Error updating media metas: %v", err)
|
log.Errorf("Error updating media metas: %v", err)
|
||||||
return errors.Wrap(err, "update media metas")
|
return errors.Wrap(err, "update media metas")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ func (w *VideoExtractHeadImageWorker) Work(ctx context.Context, job *Job[VideoEx
|
|||||||
log.Infof("[Start] Working on job with strings: %+v", job.Args)
|
log.Infof("[Start] Working on job with strings: %+v", job.Args)
|
||||||
defer log.Infof("[End] Finished %s", job.Args.Kind())
|
defer log.Infof("[End] Finished %s", job.Args.Kind())
|
||||||
|
|
||||||
media, err := services.Medias.GetByHash(ctx, job.Args.MediaHash)
|
media, err := services.Media.GetByHash(ctx, job.Args.MediaHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error getting media by ID: %v", err)
|
log.Errorf("Error getting media by ID: %v", err)
|
||||||
return JobCancel(err)
|
return JobCancel(err)
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ func (w *VideoStoreShortWorker) Work(ctx context.Context, job *Job[VideoStoreSho
|
|||||||
log.Infof("[Start] Working on job with strings: %+v", job.Args)
|
log.Infof("[Start] Working on job with strings: %+v", job.Args)
|
||||||
defer log.Infof("[End] Finished %s", job.Args.Kind())
|
defer log.Infof("[End] Finished %s", job.Args.Kind())
|
||||||
|
|
||||||
media, err := services.Medias.GetByHash(ctx, job.Args.MediaHash)
|
media, err := services.Media.GetByHash(ctx, job.Args.MediaHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error getting media by ID: %v", err)
|
log.Errorf("Error getting media by ID: %v", err)
|
||||||
return JobCancel(err)
|
return JobCancel(err)
|
||||||
|
|||||||
73
backend_v1/app/middlewares/mid_auth.go
Normal file
73
backend_v1/app/middlewares/mid_auth.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package middlewares
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"quyun/v2/app/services"
|
||||||
|
"quyun/v2/pkg/utils"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f *Middlewares) AuthFrontend(ctx fiber.Ctx) error {
|
||||||
|
if strings.HasPrefix(ctx.Path(), "/v1/auth/") {
|
||||||
|
return ctx.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.app.IsDevMode() && true {
|
||||||
|
user, err := services.Users.FindByID(ctx.Context(), 1001)
|
||||||
|
if err != nil {
|
||||||
|
return ctx.Send([]byte("User not found"))
|
||||||
|
}
|
||||||
|
ctx.Locals("user", user)
|
||||||
|
return ctx.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
fullUrl := utils.FullURI(ctx)
|
||||||
|
u, err := url.Parse(fullUrl)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
query := u.Query()
|
||||||
|
query.Set("redirect", fullUrl)
|
||||||
|
u.RawQuery = query.Encode()
|
||||||
|
u.Path = "/v1/auth/wechat" // TODO: use phone validation
|
||||||
|
fullUrl = u.String()
|
||||||
|
|
||||||
|
// check cookie exists
|
||||||
|
cookie := ctx.Cookies("token")
|
||||||
|
log.Infof("cookie: %s", cookie)
|
||||||
|
if cookie == "" {
|
||||||
|
log.Infof("auth redirect_uri: %s", fullUrl)
|
||||||
|
if ctx.XHR() {
|
||||||
|
return ctx.SendStatus(fiber.StatusUnauthorized)
|
||||||
|
}
|
||||||
|
return ctx.Redirect().To(fullUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
jwt, err := f.jwt.Parse(cookie)
|
||||||
|
if err != nil {
|
||||||
|
// remove cookie
|
||||||
|
ctx.ClearCookie("token")
|
||||||
|
if ctx.XHR() {
|
||||||
|
return ctx.SendStatus(fiber.StatusUnauthorized)
|
||||||
|
}
|
||||||
|
return ctx.Redirect().To(fullUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := services.Users.FindByID(ctx.Context(), jwt.UserID)
|
||||||
|
if err != nil {
|
||||||
|
// remove cookie
|
||||||
|
ctx.ClearCookie("token")
|
||||||
|
if ctx.XHR() {
|
||||||
|
return ctx.SendStatus(fiber.StatusUnauthorized)
|
||||||
|
}
|
||||||
|
return ctx.Redirect().To(fullUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Locals("user", user)
|
||||||
|
|
||||||
|
return ctx.Next()
|
||||||
|
}
|
||||||
34
backend_v1/app/middlewares/mid_auth_admin.go
Normal file
34
backend_v1/app/middlewares/mid_auth_admin.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package middlewares
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f *Middlewares) AuthAdmin(ctx fiber.Ctx) error {
|
||||||
|
if !strings.HasPrefix(ctx.Path(), "/v1/admin") {
|
||||||
|
return ctx.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.Path() == "/v1/admin/auth" {
|
||||||
|
return ctx.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
token := ctx.Get("Authorization")
|
||||||
|
if token == "" {
|
||||||
|
token = ctx.Query("token")
|
||||||
|
if token == "" {
|
||||||
|
return ctx.Status(fiber.StatusUnauthorized).SendString("Unauthorized")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jwt, err := f.jwt.Parse(token)
|
||||||
|
if err != nil {
|
||||||
|
return ctx.Status(fiber.StatusUnauthorized).SendString("Unauthorized")
|
||||||
|
}
|
||||||
|
if jwt.UserID != -20140202 {
|
||||||
|
return ctx.Status(fiber.StatusForbidden).SendString("Forbidden")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.Next()
|
||||||
|
}
|
||||||
19
backend_v1/app/middlewares/mid_wechat_mp_verify.go
Normal file
19
backend_v1/app/middlewares/mid_wechat_mp_verify.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package middlewares
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f *Middlewares) WechatMpVerify(ctx fiber.Ctx) error {
|
||||||
|
if !strings.HasPrefix(ctx.Path(), "/MP_verify_") {
|
||||||
|
return ctx.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
path := strings.Replace(ctx.Path(), "MP_verify_", "", 1)
|
||||||
|
path = strings.Replace(path, ".txt", "", 1)
|
||||||
|
path = strings.Trim(path, "/")
|
||||||
|
|
||||||
|
return ctx.SendString(path)
|
||||||
|
}
|
||||||
@@ -1,12 +1,17 @@
|
|||||||
package middlewares
|
package middlewares
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"quyun/v2/providers/app"
|
||||||
|
"quyun/v2/providers/jwt"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// @provider
|
// @provider
|
||||||
type Middlewares struct {
|
type Middlewares struct {
|
||||||
log *log.Entry `inject:"false"`
|
log *log.Entry `inject:"false"`
|
||||||
|
app *app.Config
|
||||||
|
jwt *jwt.JWT
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Middlewares) Prepare() error {
|
func (f *Middlewares) Prepare() error {
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
package middlewares
|
package middlewares
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"quyun/v2/providers/app"
|
||||||
|
"quyun/v2/providers/jwt"
|
||||||
|
|
||||||
"go.ipao.vip/atom/container"
|
"go.ipao.vip/atom/container"
|
||||||
"go.ipao.vip/atom/opt"
|
"go.ipao.vip/atom/opt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Provide(opts ...opt.Option) error {
|
func Provide(opts ...opt.Option) error {
|
||||||
if err := container.Container.Provide(func() (*Middlewares, error) {
|
if err := container.Container.Provide(func(
|
||||||
obj := &Middlewares{}
|
app *app.Config,
|
||||||
|
jwt *jwt.JWT,
|
||||||
|
) (*Middlewares, error) {
|
||||||
|
obj := &Middlewares{
|
||||||
|
app: app,
|
||||||
|
jwt: jwt,
|
||||||
|
}
|
||||||
if err := obj.Prepare(); err != nil {
|
if err := obj.Prepare(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// @provider
|
// @provider
|
||||||
type medias struct{}
|
type media struct{}
|
||||||
|
|
||||||
func (m *medias) List(
|
func (m *media) List(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
pagination *requests.Pagination,
|
pagination *requests.Pagination,
|
||||||
conds ...gen.Condition,
|
conds ...gen.Condition,
|
||||||
@@ -39,7 +39,7 @@ func (m *medias) List(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetByIds
|
// GetByIds
|
||||||
func (m *medias) GetByIds(ctx context.Context, ids []int64) ([]*models.Media, error) {
|
func (m *media) GetByIds(ctx context.Context, ids []int64) ([]*models.Media, error) {
|
||||||
if len(ids) == 0 {
|
if len(ids) == 0 {
|
||||||
return []*models.Media{}, nil
|
return []*models.Media{}, nil
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ func (m *medias) GetByIds(ctx context.Context, ids []int64) ([]*models.Media, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetByHash
|
// GetByHash
|
||||||
func (m *medias) GetByHash(ctx context.Context, hash string) (*models.Media, error) {
|
func (m *media) GetByHash(ctx context.Context, hash string) (*models.Media, error) {
|
||||||
tbl, query := models.MediaQuery.QueryContext(ctx)
|
tbl, query := models.MediaQuery.QueryContext(ctx)
|
||||||
item, err := query.
|
item, err := query.
|
||||||
Where(tbl.Hash.Eq(hash)).
|
Where(tbl.Hash.Eq(hash)).
|
||||||
@@ -69,7 +69,7 @@ func (m *medias) GetByHash(ctx context.Context, hash string) (*models.Media, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateMetas
|
// UpdateMetas
|
||||||
func (m *medias) UpdateMetas(ctx context.Context, id int64, metas fields.MediaMetas) error {
|
func (m *media) UpdateMetas(ctx context.Context, id int64, metas fields.MediaMetas) error {
|
||||||
tbl, query := models.MediaQuery.QueryContext(ctx)
|
tbl, query := models.MediaQuery.QueryContext(ctx)
|
||||||
_, err := query.
|
_, err := query.
|
||||||
Where(tbl.ID.Eq(id)).
|
Where(tbl.ID.Eq(id)).
|
||||||
@@ -82,13 +82,13 @@ func (m *medias) UpdateMetas(ctx context.Context, id int64, metas fields.MediaMe
|
|||||||
|
|
||||||
// GetRelationMedias
|
// GetRelationMedias
|
||||||
|
|
||||||
func (m *medias) GetRelations(ctx context.Context, hash string) ([]*models.Media, error) {
|
func (m *media) GetRelations(ctx context.Context, hash string) ([]*models.Media, error) {
|
||||||
tbl, query := models.MediaQuery.QueryContext(ctx)
|
tbl, query := models.MediaQuery.QueryContext(ctx)
|
||||||
return query.Where(tbl.Metas.KeyEq("parent_hash", hash)).Find()
|
return query.Where(tbl.Metas.KeyEq("parent_hash", hash)).Find()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindByID
|
// FindByID
|
||||||
func (m *medias) FindByID(ctx context.Context, id int64) (*models.Media, error) {
|
func (m *media) FindByID(ctx context.Context, id int64) (*models.Media, error) {
|
||||||
tbl, query := models.MediaQuery.QueryContext(ctx)
|
tbl, query := models.MediaQuery.QueryContext(ctx)
|
||||||
item, err := query.Where(tbl.ID.Eq(id)).First()
|
item, err := query.Where(tbl.ID.Eq(id)).First()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -98,7 +98,7 @@ func (m *medias) FindByID(ctx context.Context, id int64) (*models.Media, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Count
|
// Count
|
||||||
func (m *medias) Count(ctx context.Context, conds ...gen.Condition) (int64, error) {
|
func (m *media) Count(ctx context.Context, conds ...gen.Condition) (int64, error) {
|
||||||
_, query := models.MediaQuery.QueryContext(ctx)
|
_, query := models.MediaQuery.QueryContext(ctx)
|
||||||
if len(conds) > 0 {
|
if len(conds) > 0 {
|
||||||
query = query.Where(conds...)
|
query = query.Where(conds...)
|
||||||
@@ -9,8 +9,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Provide(opts ...opt.Option) error {
|
func Provide(opts ...opt.Option) error {
|
||||||
if err := container.Container.Provide(func() (*medias, error) {
|
if err := container.Container.Provide(func() (*media, error) {
|
||||||
obj := &medias{}
|
obj := &media{}
|
||||||
|
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@@ -32,14 +32,14 @@ func Provide(opts ...opt.Option) error {
|
|||||||
}
|
}
|
||||||
if err := container.Container.Provide(func(
|
if err := container.Container.Provide(func(
|
||||||
db *gorm.DB,
|
db *gorm.DB,
|
||||||
medias *medias,
|
media *media,
|
||||||
orders *orders,
|
orders *orders,
|
||||||
posts *posts,
|
posts *posts,
|
||||||
users *users,
|
users *users,
|
||||||
) (contracts.Initial, error) {
|
) (contracts.Initial, error) {
|
||||||
obj := &services{
|
obj := &services{
|
||||||
db: db,
|
db: db,
|
||||||
medias: medias,
|
media: media,
|
||||||
orders: orders,
|
orders: orders,
|
||||||
posts: posts,
|
posts: posts,
|
||||||
users: users,
|
users: users,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ var _db *gorm.DB
|
|||||||
|
|
||||||
// exported CamelCase Services
|
// exported CamelCase Services
|
||||||
var (
|
var (
|
||||||
Medias *medias
|
Media *media
|
||||||
Orders *orders
|
Orders *orders
|
||||||
Posts *posts
|
Posts *posts
|
||||||
Users *users
|
Users *users
|
||||||
@@ -18,7 +18,7 @@ var (
|
|||||||
type services struct {
|
type services struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
// define Services
|
// define Services
|
||||||
medias *medias
|
media *media
|
||||||
orders *orders
|
orders *orders
|
||||||
posts *posts
|
posts *posts
|
||||||
users *users
|
users *users
|
||||||
@@ -28,7 +28,7 @@ func (svc *services) Prepare() error {
|
|||||||
_db = svc.db
|
_db = svc.db
|
||||||
|
|
||||||
// set exported Services here
|
// set exported Services here
|
||||||
Medias = svc.medias
|
Media = svc.media
|
||||||
Orders = svc.orders
|
Orders = svc.orders
|
||||||
Posts = svc.posts
|
Posts = svc.posts
|
||||||
Users = svc.users
|
Users = svc.users
|
||||||
|
|||||||
@@ -56,39 +56,26 @@ func (m *users) PostList(
|
|||||||
// OFFSET(pagination.Offset)
|
// OFFSET(pagination.Offset)
|
||||||
// m.log().Infof("sql: %s", stmt.DebugSql())
|
// m.log().Infof("sql: %s", stmt.DebugSql())
|
||||||
|
|
||||||
// var posts []Posts
|
tbl, query := models.UserPostQuery.QueryContext(ctx)
|
||||||
// err := stmt.QueryContext(ctx, db, &posts)
|
pagePosts, cnt, err := query.Select(tbl.PostID).
|
||||||
// if err != nil {
|
Where(tbl.UserID.Eq(userId)).
|
||||||
// if errors.Is(err, qrm.ErrNoRows) {
|
FindByPage(int(pagination.Offset()), int(pagination.Limit))
|
||||||
// return &requests.Pager{
|
|
||||||
// Items: nil,
|
|
||||||
// Total: 0,
|
|
||||||
// Pagination: *pagination,
|
|
||||||
// }, nil
|
|
||||||
// }
|
|
||||||
// m.log().Errorf("error querying posts: %v", err)
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // total count
|
if err != nil {
|
||||||
// var cnt struct {
|
return nil, err
|
||||||
// Cnt int64
|
}
|
||||||
// }
|
postIds := lo.Map(pagePosts, func(item *models.UserPost, _ int) int64 { return item.PostID })
|
||||||
|
|
||||||
// stmtCnt := tblUserPosts.SELECT(COUNT(tblUserPosts.ID).AS("cnt")).WHERE(tblUserPosts.UserID.EQ(Int64(userId)))
|
postTbl, postQuery := models.PostQuery.QueryContext(ctx)
|
||||||
// m.log().Infof("sql: %s", stmtCnt.DebugSql())
|
items, err := postQuery.Where(postTbl.ID.In(postIds...)).Find()
|
||||||
|
if err != nil {
|
||||||
// if err := stmtCnt.QueryContext(ctx, db, &cnt); err != nil {
|
return nil, err
|
||||||
// m.log().Errorf("error counting users: %v", err)
|
}
|
||||||
// return nil, err
|
return &requests.Pager{
|
||||||
// }
|
Items: items,
|
||||||
|
Total: cnt,
|
||||||
// return &requests.Pager{
|
Pagination: *pagination,
|
||||||
// Items: posts,
|
}, nil
|
||||||
// Total: cnt.Cnt,
|
|
||||||
// Pagination: *pagination,
|
|
||||||
// }, nil
|
|
||||||
return nil, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUsersMapByIDs
|
// GetUsersMapByIDs
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ require (
|
|||||||
github.com/spf13/cobra v1.10.1
|
github.com/spf13/cobra v1.10.1
|
||||||
github.com/stretchr/testify v1.11.1
|
github.com/stretchr/testify v1.11.1
|
||||||
github.com/swaggo/files/v2 v2.0.2
|
github.com/swaggo/files/v2 v2.0.2
|
||||||
go.ipao.vip/atom v1.2.1
|
go.ipao.vip/atom v1.3.1
|
||||||
go.ipao.vip/gen v0.0.0-20250924024520-70c4accdea44
|
go.ipao.vip/gen v0.0.0-20250924024520-70c4accdea44
|
||||||
go.uber.org/dig v1.19.0
|
go.uber.org/dig v1.19.0
|
||||||
golang.org/x/net v0.48.0
|
golang.org/x/net v0.48.0
|
||||||
|
|||||||
@@ -325,8 +325,12 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY
|
|||||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
go.ipao.vip/atom v1.2.0 h1:Be3ZmvYkENQMUl+ITOxvgYi+GrcygplIAYL4aNH9kpA=
|
||||||
|
go.ipao.vip/atom v1.2.0/go.mod h1:woAv+rZf0xd+7mEtKWv4PyazQARFLnrV/qA4qlAK008=
|
||||||
go.ipao.vip/atom v1.2.1 h1:7VlDLSkGNVEZLVM/JVcXXdMTO0+sFsxe1vfIM4Xz8uc=
|
go.ipao.vip/atom v1.2.1 h1:7VlDLSkGNVEZLVM/JVcXXdMTO0+sFsxe1vfIM4Xz8uc=
|
||||||
go.ipao.vip/atom v1.2.1/go.mod h1:woAv+rZf0xd+7mEtKWv4PyazQARFLnrV/qA4qlAK008=
|
go.ipao.vip/atom v1.2.1/go.mod h1:woAv+rZf0xd+7mEtKWv4PyazQARFLnrV/qA4qlAK008=
|
||||||
|
go.ipao.vip/atom v1.3.1 h1:tOh5OBH3vbnNsINhvnesw5kxY9g82hQ1AkeExUUU/+A=
|
||||||
|
go.ipao.vip/atom v1.3.1/go.mod h1:woAv+rZf0xd+7mEtKWv4PyazQARFLnrV/qA4qlAK008=
|
||||||
go.ipao.vip/gen v0.0.0-20250924024520-70c4accdea44 h1:i7zFEsfUYRJQo0mXUWI/RoEkgEdTNmLt0Io2rwhqY9E=
|
go.ipao.vip/gen v0.0.0-20250924024520-70c4accdea44 h1:i7zFEsfUYRJQo0mXUWI/RoEkgEdTNmLt0Io2rwhqY9E=
|
||||||
go.ipao.vip/gen v0.0.0-20250924024520-70c4accdea44/go.mod h1:ip5X9ioxR9hvM/mrsA77KWXFsrMm5oki5rfY5MSkssM=
|
go.ipao.vip/gen v0.0.0-20250924024520-70c4accdea44/go.mod h1:ip5X9ioxR9hvM/mrsA77KWXFsrMm5oki5rfY5MSkssM=
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
import client from './client';
|
|
||||||
|
|
||||||
export const wechatApi = {
|
|
||||||
jsSdk() {
|
|
||||||
return client.get('/wechats/js-sdk', {
|
|
||||||
params: {
|
|
||||||
url: window.location.href.split('#')[0],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import wx from "weixin-js-sdk";
|
import wx from "weixin-js-sdk";
|
||||||
|
|
||||||
export function useWxSDK() {
|
export function useWxSDK() {
|
||||||
|
let ready = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化设置
|
* 初始化设置
|
||||||
*/
|
*/
|
||||||
@@ -24,8 +26,13 @@ export function useWxSDK() {
|
|||||||
});
|
});
|
||||||
wx.ready(() => {
|
wx.ready(() => {
|
||||||
console.log("wx.ready called");
|
console.log("wx.ready called");
|
||||||
|
ready = true;
|
||||||
resolve(true);
|
resolve(true);
|
||||||
});
|
});
|
||||||
|
wx.error(() => {
|
||||||
|
ready = false;
|
||||||
|
resolve(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,39 +42,46 @@ export function useWxSDK() {
|
|||||||
onSuccess = () => { },
|
onSuccess = () => { },
|
||||||
onCancel = () => { }
|
onCancel = () => { }
|
||||||
) {
|
) {
|
||||||
|
if (!ready) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
console.log("setShareInfo called", shareInfo);
|
console.log("setShareInfo called", shareInfo);
|
||||||
wx.updateTimelineShareData({
|
try {
|
||||||
title: shareInfo.title, // 分享标题
|
wx.updateTimelineShareData({
|
||||||
link: shareInfo.link, // 分享链接,可以不是当前页面,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
|
title: shareInfo.title, // 分享标题
|
||||||
imgUrl: shareInfo.imgUrl,
|
link: shareInfo.link, // 分享链接,可以不是当前页面,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
|
||||||
success: function (e) {
|
imgUrl: shareInfo.imgUrl,
|
||||||
console.log("分享朋友圈成功", e);
|
success: function (e) {
|
||||||
// 用户确认分享后执行的回调函数
|
console.log("分享朋友圈成功", e);
|
||||||
onSuccess();
|
// 用户确认分享后执行的回调函数
|
||||||
},
|
onSuccess();
|
||||||
cancel: function (e) {
|
},
|
||||||
console.log("分享朋友圈取消", e);
|
cancel: function (e) {
|
||||||
onCancel();
|
console.log("分享朋友圈取消", e);
|
||||||
// 用户取消分享后执行的回调函数
|
onCancel();
|
||||||
},
|
// 用户取消分享后执行的回调函数
|
||||||
});
|
},
|
||||||
wx.updateAppMessageShareData({
|
});
|
||||||
title: shareInfo.title, // 分享标题
|
wx.updateAppMessageShareData({
|
||||||
desc: shareInfo.desc,
|
title: shareInfo.title, // 分享标题
|
||||||
link: shareInfo.link, // 分享链接,可以不是当前页面,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
|
desc: shareInfo.desc,
|
||||||
imgUrl: shareInfo.imgUrl,
|
link: shareInfo.link, // 分享链接,可以不是当前页面,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
|
||||||
type: "link", // 分享类型,music、video或link,不填默认为link
|
imgUrl: shareInfo.imgUrl,
|
||||||
success: function (e) {
|
type: "link", // 分享类型,music、video或link,不填默认为link
|
||||||
// 用户确认分享后执行的回调函数
|
success: function (e) {
|
||||||
console.log("分享成功", e);
|
// 用户确认分享后执行的回调函数
|
||||||
onSuccess();
|
console.log("分享成功", e);
|
||||||
},
|
onSuccess();
|
||||||
cancel: function (e) {
|
},
|
||||||
// 用户取消分享后执行的回调函数
|
cancel: function (e) {
|
||||||
console.log("分享取消", e);
|
// 用户取消分享后执行的回调函数
|
||||||
onCancel();
|
console.log("分享取消", e);
|
||||||
},
|
onCancel();
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 是否是ios微信 */
|
/** 是否是ios微信 */
|
||||||
@@ -80,4 +94,4 @@ export function useWxSDK() {
|
|||||||
setShareInfo,
|
setShareInfo,
|
||||||
isiOSWechat,
|
isiOSWechat,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { onMounted, onUnmounted, ref } from "vue";
|
|||||||
import { BsChevronLeft } from "vue-icons-plus/bs";
|
import { BsChevronLeft } from "vue-icons-plus/bs";
|
||||||
import { useRoute, useRouter } from "vue-router";
|
import { useRoute, useRouter } from "vue-router";
|
||||||
import { postApi } from "../api/postApi";
|
import { postApi } from "../api/postApi";
|
||||||
import { wechatApi } from "../api/wechatApi";
|
|
||||||
import { useWxSDK } from "../hooks/useWxSDK";
|
import { useWxSDK } from "../hooks/useWxSDK";
|
||||||
|
|
||||||
const wx = useWxSDK();
|
const wx = useWxSDK();
|
||||||
@@ -172,25 +171,6 @@ const handleBack = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
wechatApi
|
|
||||||
.jsSdk()
|
|
||||||
.then((resp) => {
|
|
||||||
wx.initConfig(resp.data).then(() => {
|
|
||||||
wx.setShareInfo({
|
|
||||||
title: article.value.title,
|
|
||||||
desc: article.value.content,
|
|
||||||
link: window.location.href,
|
|
||||||
imgUrl: article.value.head_images[0],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error("Failed to initialize WeChat SDK:", error);
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
await fetchArticle();
|
await fetchArticle();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user