xiongzhu 1 year ago
parent
commit
dce5a4e34f
5 changed files with 92 additions and 6 deletions
  1. 1 0
      package.json
  2. 36 3
      src/components/PlayView.vue
  3. 3 0
      src/events/index.ts
  4. 47 3
      src/views/SeriesView.vue
  5. 5 0
      yarn.lock

+ 1 - 0
package.json

@@ -31,6 +31,7 @@
     "eruda": "^3.0.1",
     "ionicons": "^7.0.0",
     "less": "^4.2.0",
+    "mitt": "^3.0.1",
     "pinia": "^2.1.7",
     "qrcode": "^1",
     "qs": "^6.12.0",

+ 36 - 3
src/components/PlayView.vue

@@ -44,7 +44,7 @@
                     />
                 </template>
                 <div class="tool-bar flex">
-                    <div class="px-2 flex items-center" @click="router.back()">
+                    <div class="px-2 flex items-center" @click.stop="router.back()">
                         <IonIcon
                             :icon="chevronBack"
                             class="text-2xl opacity-80 h-10"
@@ -197,7 +197,16 @@
     </div>
 </template>
 <script setup lang="ts">
-import { Ref, computed, nextTick, onMounted, reactive, ref, watch } from "vue";
+import {
+    Ref,
+    computed,
+    nextTick,
+    onBeforeUnmount,
+    onMounted,
+    reactive,
+    ref,
+    watch,
+} from "vue";
 import {
     IonIcon,
     IonSpinner,
@@ -222,6 +231,7 @@ import {
 } from "ionicons/icons";
 import http from "@/plugins/http";
 import { watchThrottled } from "@vueuse/core";
+import emitter from "@/events";
 
 const props = defineProps({
     active: Boolean,
@@ -326,8 +336,18 @@ useDrag(dragHandler, {
         capture: true,
     },
 });
+function onPaymentSuccess() {
+    console.log("onPaymentSuccess");
+    setTimeout(() => {
+        getEpisode();
+    }, 100);
+}
 onMounted(() => {
     getEpisode();
+    emitter.on("payment-success", onPaymentSuccess);
+});
+onBeforeUnmount(() => {
+    emitter.off("payment-success", onPaymentSuccess);
 });
 watch(
     () => props.episode,
@@ -346,7 +366,20 @@ watch(
     }
 );
 
-function onPlay() {
+async function onPlay() {
+    if (needPay.value) {
+        try {
+            http.get(`/episodes/${props.episode?.id}`).then((res) => {
+                if (res.playUrl) {
+                    playUrl.value = res.playUrl;
+                } else {
+                    needPay.value = true;
+                }
+            });
+        } catch (error) {
+            console.error(error);
+        }
+    }
     if (playUrl.value) {
         playing.value = true;
     } else if (needPay.value) {

+ 3 - 0
src/events/index.ts

@@ -0,0 +1,3 @@
+import mitt from "mitt";
+const emitter = mitt();
+export default emitter;

+ 47 - 3
src/views/SeriesView.vue

@@ -107,6 +107,7 @@
                         color="tertiary"
                         expand="block"
                         class="mx-4 mt-8 font-bold"
+                        @click="onClickPay"
                     >
                         ${{ plans[selectedPlan].price }} Pay Now
                     </IonButton>
@@ -129,7 +130,7 @@
                 <IonContent>
                     <iframe
                         class="h-full w-full border-none"
-                        src="https://shorts.izouma.com/stripe-checkout"
+                        :src="payUrl"
                     ></iframe>
                 </IonContent>
             </IonModal>
@@ -166,7 +167,12 @@ import { useElementBounding } from "@vueuse/core";
 import { useRoute } from "vue-router";
 import http from "@/plugins/http";
 import { close, chevronBack } from "ionicons/icons";
+import toast from "@/plugins/toast";
+import { useUserStore } from "@/store/user";
+import { storeToRefs } from "pinia";
+import emitter from "@/events";
 
+const { user } = storeToRefs(useUserStore());
 const el = ref<HTMLElement | null>(null);
 const { x, y, top, right, bottom, left, width, height } =
     useElementBounding(el);
@@ -238,19 +244,57 @@ const plans = [
         title: "7 Days",
         desc: "Unlimited",
         price: 0.99,
+        value: 7,
     },
     {
         title: "1 Month",
         desc: "Unlimited",
         price: 19.99,
+        value: 30,
     },
     {
         title: "3 Months",
         desc: "Unlimited",
         price: 49.99,
+        value: 90,
     },
 ];
 const selectedPlan = ref(0);
-const showCheckoutModal = ref(true);
+const showCheckoutModal = ref(false);
+window.addEventListener("message", async (event) => {
+    console.log(event);
+    if (event.data === "success") {
+        await http.post("/memberships", {
+            userId: user.value!.id,
+            expireAt: new Date(
+                new Date().getTime() +
+                    plans[selectedPlan.value].value * 24 * 60 * 60 * 1000
+            ),
+        });
+        toast("Payment successful", {
+            type: "success",
+        });
+        showCheckoutModal.value = false;
+        emitter.emit('payment-success')
+    } else if (event.data === "fail") {
+        toast("Payment failed", {
+            type: "error",
+        });
+        showCheckoutModal.value = false;
+    }
+});
+
+const payUrl = ref("http://192.168.50.202:5174/stripe-checkout/");
+function onClickPay() {
+    showPayModal.value = false;
+    setTimeout(() => {
+        payUrl.value = "http://192.168.50.202:5174/stripe-checkout/";
+        showCheckoutModal.value = true;
+    }, 200);
+}
 </script>
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+.pay-modal {
+    --height: 50vh;
+}
+</style>

+ 5 - 0
yarn.lock

@@ -4896,6 +4896,11 @@ minizlib@^2.1.1:
     minipass "^3.0.0"
     yallist "^4.0.0"
 
+mitt@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1"
+  integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==
+
 mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
   version "0.5.3"
   resolved "https://registry.npmmirror.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"