Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat]フィルタありのactivitesのAPI実装 #812

Merged
merged 11 commits into from
Jul 6, 2024
46 changes: 46 additions & 0 deletions api/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,52 @@ const docTemplate = `{
}
},
},
"/activities/filtered_details": {
"get": {
tags: ["activity"],
"description": "activitiesとsponsor,sponsorStyle,userの一覧を取得",
"parameters": [
{
"name": "is_done",
"in": "query",
"description": "Filter by done status.[true, false, all]",
"required": false,
"schema": {
"type": "string",
"enum": ["true", "false", "all"]
}
},
{
"name": "sponsor_style_id",
"in": "query",
"description": "Filter by sponsor style IDs. ex.) 1,3,6,...",
"required": false,
"schema": {
"type": "array",
"items": {
"type": "integer"
}
},
"style": "form",
"explode": true
},
{
"name": "keyword",
"in": "query",
"description": "Filter by keyword",
"required": false,
"schema": {
"type": "string"
}
},
],
"responses": {
"200": {
"description": "activitiesとsponsor,sponsorStyle,userの一覧の取得",
}
}
},
},
"/activities/{id}": {
"get": {
tags: ["activity"],
Expand Down
12 changes: 12 additions & 0 deletions api/externals/controller/activity_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type ActivityController interface {
DestroyActivity(echo.Context) error
IndexActivityDetail(echo.Context) error
IndexActivityDetailsByPeriod(echo.Context) error
IndexFilteredActivityDetail(echo.Context) error
}

func NewActivityController(u usecase.ActivityUseCase) ActivityController {
Expand Down Expand Up @@ -104,3 +105,14 @@ func (a *activityController) IndexActivityDetailsByPeriod(c echo.Context) error
}
return c.JSON(http.StatusOK, activities)
}

func (a *activityController) IndexFilteredActivityDetail(c echo.Context) error {
isDone := c.QueryParam("is_done")
sponsorStyleIDs := c.QueryParams()["sponsor_style_id"]
keyword := c.QueryParam("keyword")
activities, err := a.u.GetFilteredActivityDetail(c.Request().Context(), isDone, sponsorStyleIDs, keyword)
if err != nil {
return err
}
return c.JSON(http.StatusOK, activities)
}
55 changes: 55 additions & 0 deletions api/externals/repository/activity_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package repository
import (
"context"
"database/sql"
"strings"

"github.com/NUTFes/FinanSu/api/drivers/db"
"github.com/NUTFes/FinanSu/api/externals/repository/abstract"
Expand All @@ -24,6 +25,7 @@ type ActivityRepository interface {
FindSponsorStyle(context.Context, string) (*sql.Rows, error)
AllDetailsByPeriod(context.Context, string) (*sql.Rows, error)
FindActivityInformation(context.Context, string) (*sql.Rows, error)
FindFilteredDetail(context.Context, string, []string, string) (*sql.Rows, error)
}

func NewActivityRepository(c db.Client, ac abstract.Crud) ActivityRepository {
Expand Down Expand Up @@ -185,3 +187,56 @@ func (ar *activityRepository) AllDetailsByPeriod(c context.Context, year string)

return ar.crud.Read(c, query)
}

// activityに紐づくsponserとusersをフィルタを考慮して取得する
func (ar *activityRepository) FindFilteredDetail(c context.Context, isDone string, sponsorStyleIDs []string, keyword string) (*sql.Rows, error) {
query := `
SELECT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
SELECT
SELECT

activities.*,
sponsors.*,
users.*
FROM
activities
INNER JOIN
sponsors
ON
activities.sponsor_id = sponsors.id
INNER JOIN
users
ON
activities.user_id = users.id
INNER JOIN
activity_styles
ON
activities.id = activity_styles.activity_id
INNER JOIN
sponsor_styles
ON
activity_styles.sponsor_style_id = sponsor_styles.id
WHERE
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
WHERE
WHERE

スペースを消してください

1=1 `
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここっているんですかね?
おそらくWHEREがないとエラーが出るから付けてるかと思います
何も条件がない場合にWHEREをつける形とかだとできますかね

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

今回フィルタに使用している要素がすべて任意で外すことができるため、どの要素からWHEREが始まるかわからないため、1=1の常にTRUEの条件を設定し、そのあとにそれぞれのフィルタを加えるように実装しています。


// keywordフィルタを追加
if keyword != "" {
query += ` AND
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
query += ` AND
query += ` AND

sponsors.name LIKE '%` + keyword + `%'`
}

// isDoneフィルタを追加
if isDone != "" {
if isDone != "all" {
query += ` AND
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
query += ` AND
query += ` AND

activities.is_done = ` + isDone
}
}

// sponsorStyleIDsフィルタを追加
if len(sponsorStyleIDs) > 0 {
// プレースホルダーを生成
placeholders := strings.Join(sponsorStyleIDs, ",")
query += ` AND
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
query += ` AND
query += ` AND

sponsor_styles.id IN (` + placeholders + `)`
}

return ar.crud.Read(c, query)
}
98 changes: 98 additions & 0 deletions api/internals/usecase/activity_usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type ActivityUseCase interface {
DestroyActivity(context.Context, string) error
GetActivityDetail(context.Context) ([]domain.ActivityDetail, error)
GetActivityDetailsByPeriod(context.Context, string) ([]domain.ActivityDetail, error)
GetFilteredActivityDetail(context.Context, string, []string, string) ([]domain.ActivityDetail, error)
}

func NewActivityUseCase(rep rep.ActivityRepository) ActivityUseCase {
Expand Down Expand Up @@ -353,3 +354,100 @@ func (a *activityUseCase) GetActivityDetailsByPeriod(c context.Context, year str
}
return activities, nil
}

func (a *activityUseCase) GetFilteredActivityDetail(c context.Context, isDone string, sponsorStyleIDs []string, keyword string) ([]domain.ActivityDetail, error) {

activity := domain.ActivityDetail{}
var activities []domain.ActivityDetail
styleDetail := domain.StyleDetail{}
var styleDetails []domain.StyleDetail
activityInformation := domain.ActivityInformation{}
var activityInformations []domain.ActivityInformation

// クエリー実行
rows, err := a.rep.FindFilteredDetail(c, isDone, sponsorStyleIDs, keyword)
if err != nil {
return nil, err
}
defer rows.Close()

for rows.Next() {
err := rows.Scan(
&activity.Activity.ID,
&activity.Activity.UserID,
&activity.Activity.IsDone,
&activity.Activity.SponsorID,
&activity.Activity.Feature,
&activity.Activity.Expense,
&activity.Activity.Remark,
&activity.Activity.Design,
&activity.Activity.Url,
&activity.Activity.CreatedAt,
&activity.Activity.UpdatedAt,
&activity.Sponsor.ID,
&activity.Sponsor.Name,
&activity.Sponsor.Tel,
&activity.Sponsor.Email,
&activity.Sponsor.Address,
&activity.Sponsor.Representative,
&activity.Sponsor.CreatedAt,
&activity.Sponsor.UpdatedAt,
&activity.User.ID,
&activity.User.Name,
&activity.User.BureauID,
&activity.User.RoleID,
&activity.User.IsDeleted,
&activity.User.CreatedAt,
&activity.User.UpdatedAt,
)
if err != nil {
return nil, errors.Wrapf(err, "cannot connect SQL")
}

rows, err := a.rep.FindActivityInformation(c, strconv.Itoa(int(activity.Activity.ID)))
for rows.Next(){
err := rows.Scan(
&activityInformation.ID,
&activityInformation.ActivityId,
&activityInformation.BucketName,
&activityInformation.FileName,
&activityInformation.FileType,
&activityInformation.DesignProgress,
&activityInformation.FileInformation,
&activityInformation.CreatedAt,
&activityInformation.UpdatedAt,
)
if err != nil {
return nil, err
}
activityInformations = append(activityInformations, activityInformation)
}
activity.ActivityInformation = activityInformations
activityInformations = nil

rows, err = a.rep.FindSponsorStyle(c, strconv.Itoa(int(activity.Activity.ID)))
for rows.Next(){
err := rows.Scan(
&styleDetail.ActivityStyle.ID,
&styleDetail.ActivityStyle.ActivityID,
&styleDetail.ActivityStyle.SponsoStyleID,
&styleDetail.ActivityStyle.CreatedAt,
&styleDetail.ActivityStyle.UpdatedAt,
&styleDetail.SponsorStyle.ID,
&styleDetail.SponsorStyle.Style,
&styleDetail.SponsorStyle.Feature,
&styleDetail.SponsorStyle.Price,
&styleDetail.SponsorStyle.CreatedAt,
&styleDetail.SponsorStyle.UpdatedAt,
)
if err != nil {
return nil, err
}
styleDetails = append(styleDetails, styleDetail)
}
activity.StyleDetail = styleDetails
activities = append(activities, activity)
styleDetails = nil
}
return activities, nil
}
1 change: 1 addition & 0 deletions api/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func (r router) ProvideRouter(e *echo.Echo) {
e.DELETE("/activities/:id", r.activityController.DestroyActivity)
e.GET("/activities/details", r.activityController.IndexActivityDetail)
e.GET("/activities/details/:year",r.activityController.IndexActivityDetailsByPeriod)
e.GET("/activities/filtered_details", r.activityController.IndexFilteredActivityDetail)

// activityInformationsのRoute
e.GET("/activity_informations", r.activityInformationController.IndexActivityInformation)
Expand Down
Loading