diff --git a/src/main/java/com/swyp/picke/domain/oauth/jwt/JwtFilter.java b/src/main/java/com/swyp/picke/domain/oauth/jwt/JwtFilter.java index 0f3477e7..40e5d210 100644 --- a/src/main/java/com/swyp/picke/domain/oauth/jwt/JwtFilter.java +++ b/src/main/java/com/swyp/picke/domain/oauth/jwt/JwtFilter.java @@ -43,6 +43,9 @@ public class JwtFilter extends OncePerRequestFilter { "/api/v1/notices", // 공지사항 "/api/test", // 테스트용 "/result", // 공유 링크 리다이렉트 + "/report", // 철학자 리포트 딥링크 + "/battle", // 배틀 딥링크 + "/.well-known", // Android App Links 인증 "/api/v1/resources" // 이미지, 오디오 파일 (Presigned URL) ); diff --git a/src/main/java/com/swyp/picke/domain/share/controller/ShareApiController.java b/src/main/java/com/swyp/picke/domain/share/controller/ShareApiController.java new file mode 100644 index 00000000..6bdcd53e --- /dev/null +++ b/src/main/java/com/swyp/picke/domain/share/controller/ShareApiController.java @@ -0,0 +1,32 @@ +package com.swyp.picke.domain.share.controller; + +import com.swyp.picke.global.common.response.ApiResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +@RestController +@RequestMapping("/api/v1/share") +@RequiredArgsConstructor +public class ShareApiController { + + @Value("${picke.baseUrl}") + private String baseUrl; + + @GetMapping("/report") + public ApiResponse> getReportShareUrl(@RequestParam Long reportId) { + String shareUrl = baseUrl + "/report/" + reportId; + return ApiResponse.onSuccess(Map.of("shareUrl", shareUrl)); + } + + @GetMapping("/battle") + public ApiResponse> getBattleShareUrl(@RequestParam Long battleId) { + String shareUrl = baseUrl + "/battle/" + battleId; + return ApiResponse.onSuccess(Map.of("shareUrl", shareUrl)); + } +} diff --git a/src/main/java/com/swyp/picke/domain/share/controller/ShareController.java b/src/main/java/com/swyp/picke/domain/share/controller/ShareController.java index 8ab75402..3ef17c37 100644 --- a/src/main/java/com/swyp/picke/domain/share/controller/ShareController.java +++ b/src/main/java/com/swyp/picke/domain/share/controller/ShareController.java @@ -1,16 +1,45 @@ package com.swyp.picke.domain.share.controller; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.servlet.view.RedirectView; @Controller public class ShareController { - @GetMapping("/result/{userId}") - public String result(@PathVariable Long userId, Model model) { - model.addAttribute("userId", userId); - return "share/result"; + //출시 이후 URL 필요 + @Value("${picke.store.android:https://play.google.com/store/apps/details?id=com.swyp.picke}") + private String androidStoreUrl; + + @GetMapping("/report/{reportId}") + public Object report(@PathVariable Long reportId, HttpServletRequest request, Model model) { + String ua = request.getHeader("User-Agent"); + if (ua == null) ua = ""; + ua = ua.toLowerCase(); + + if (ua.contains("android")) { + return new RedirectView(androidStoreUrl); + } else { + model.addAttribute("reportId", reportId); + return "share/report"; + } + } + + @GetMapping("/battle/{battleId}") + public Object battle(@PathVariable Long battleId, HttpServletRequest request, Model model) { + String ua = request.getHeader("User-Agent"); + if (ua == null) ua = ""; + ua = ua.toLowerCase(); + + if (ua.contains("android")) { + return new RedirectView(androidStoreUrl); + } else { + model.addAttribute("battleId", battleId); + return "share/battle"; + } } } diff --git a/src/main/java/com/swyp/picke/global/config/SecurityConfig.java b/src/main/java/com/swyp/picke/global/config/SecurityConfig.java index 3e29ab22..379c1266 100644 --- a/src/main/java/com/swyp/picke/global/config/SecurityConfig.java +++ b/src/main/java/com/swyp/picke/global/config/SecurityConfig.java @@ -43,6 +43,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { "/js/**", "/css/**", "/favicon.ico", "/api/v1/admin/login", "/api/v1/admin", "/result/**", + "/report/**", + "/battle/**", + "/.well-known/**", "/api/v1/resources/images/**", "/api/v1/resources/audio/**", "/api/v1/admob/reward/**" diff --git a/src/main/resources/static/.well-known/assetlinks.json b/src/main/resources/static/.well-known/assetlinks.json new file mode 100644 index 00000000..4e5d52a6 --- /dev/null +++ b/src/main/resources/static/.well-known/assetlinks.json @@ -0,0 +1,13 @@ +[ + { + "relation": ["delegate_permission/common.handle_all_urls"], + "target": { + "namespace": "android_app", + "package_name": "com.picke.app", + "sha256_cert_fingerprints": [ + "8C:DA:C0:E5:4A:F3:24:AE:C4:AA:37:01:76:8E:CE:DA:D4:EE:0A:CB:09:29:45:45:A8:B4:BA:A6:F8:16:E8:BF", + "17:D6:B0:C3:F7:94:09:B3:62:78:C8:9B:1B:21:D0:C7:D9:AC:E0:0E:C8:8A:B3:5A:31:78:4D:50:A9:58:FB:45" + ] + } + } +] diff --git a/src/main/resources/templates/share/battle.html b/src/main/resources/templates/share/battle.html new file mode 100644 index 00000000..c9f872ff --- /dev/null +++ b/src/main/resources/templates/share/battle.html @@ -0,0 +1,33 @@ + + + + + + Pické - 배틀 + + + + + + + +
+
🦉
+

Pické

+

+ 배틀에 참여하려면
모바일 앱에서 확인하세요. +

+
+

앱을 설치하고 배틀에 참여해보세요

+ +
+
+ + + diff --git a/src/main/resources/templates/share/report.html b/src/main/resources/templates/share/report.html new file mode 100644 index 00000000..b7e692a6 --- /dev/null +++ b/src/main/resources/templates/share/report.html @@ -0,0 +1,33 @@ + + + + + + Pické - 철학자 리포트 + + + + + + + +
+
🦉
+

Pické

+

+ 친구의 철학자 리포트를 보려면
모바일 앱에서 확인하세요. +

+
+

앱을 설치하고 리포트를 확인해보세요

+ +
+
+ + + diff --git a/src/main/resources/templates/share/result.html b/src/main/resources/templates/share/result.html deleted file mode 100644 index b75c451f..00000000 --- a/src/main/resources/templates/share/result.html +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - Pické - 철학자 유형 결과 - - - - - - - -
- - - - - - - -
- - - - -