فهرست منبع

fix: 增加谷歌商店模板

ansoni 3 ماه پیش
والد
کامیت
ffb421aed6

+ 3 - 3
.idea/bookmarks.json

@@ -1,9 +1,9 @@
 {
   "site_front": [
     {
-      "fileDescriptor": "$/src/app/[locale]/(TabBar)/[[...share]]/@clientWidget/page.tsx",
-      "linenumber": 16,
-      "name": "// pixel 埋点",
+      "fileDescriptor": "$/src/app/[locale]/(doings)/store/page.tsx",
+      "linenumber": 630,
+      "name": "\u003cImage src\u003d{\"/store/ios.png\"} alt\u003d{\"\"} width\u003d{3\u003d00} height\u003d{200} /\u003e",
       "bookmarkType": "DEFAULT"
     }
   ]

+ 20 - 6
.idea/workspace.xml

@@ -5,9 +5,22 @@
   </component>
   <component name="ChangeListManager">
     <list default="true" id="cefcab87-0337-4425-a7d4-cfe46845b330" name="Changes" comment="">
-      <change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/public/store/app.svg" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/public/store/book.svg" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/public/store/child.svg" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/public/store/game.svg" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/public/store/google-play.png" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/public/store/ios.png" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/public/store/whtch.svg" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/app/[locale]/(doings)/store/style.module.scss" afterDir="false" />
       <change beforePath="$PROJECT_DIR$/.idea/bookmarks.json" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/bookmarks.json" afterDir="false" />
       <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/public/next.svg" beforeDir="false" afterPath="$PROJECT_DIR$/public/next.svg" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/app/[locale]/(doings)/store/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/[locale]/(doings)/store/page.tsx" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/styles/iconfont/iconfont.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/styles/iconfont/iconfont.css" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/styles/iconfont/iconfont.ttf" beforeDir="false" afterPath="$PROJECT_DIR$/src/styles/iconfont/iconfont.ttf" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/styles/iconfont/iconfont.woff" beforeDir="false" afterPath="$PROJECT_DIR$/src/styles/iconfont/iconfont.woff" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/styles/iconfont/iconfont.woff2" beforeDir="false" afterPath="$PROJECT_DIR$/src/styles/iconfont/iconfont.woff2" afterDir="false" />
     </list>
     <option name="SHOW_DIALOG" value="false" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -17,7 +30,7 @@
   <component name="Git.Settings">
     <option name="RECENT_BRANCH_BY_REPOSITORY">
       <map>
-        <entry key="$PROJECT_DIR$" value="dev" />
+        <entry key="$PROJECT_DIR$" value="v1.4" />
       </map>
     </option>
     <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
@@ -36,7 +49,7 @@
     "JavaScript Debug.localhost:3000.executor": "Debug",
     "RunOnceActivity.ShowReadmeOnStart": "true",
     "RunOnceActivity.git.unshallow": "true",
-    "git-widget-placeholder": "v1.4",
+    "git-widget-placeholder": "feature-Before",
     "last_opened_file_path": "F:/project/site_front/src/styles/iconfont",
     "node.js.detected.package.eslint": "true",
     "node.js.detected.package.tslint": "true",
@@ -45,7 +58,7 @@
     "nodejs_package_manager_path": "pnpm",
     "npm.dev.executor": "Run",
     "prettierjs.PrettierConfiguration.Package": "F:\\project\\site_front\\node_modules\\prettier",
-    "settings.editor.selected.configurable": "preferences.pluginManager",
+    "settings.editor.selected.configurable": "px2rwdSettings",
     "ts.external.directory.path": "F:\\project\\site_front\\node_modules\\typescript\\lib",
     "vue.rearranger.settings.migration": "true"
   }
@@ -53,6 +66,7 @@
   <component name="RecentsManager">
     <key name="CopyFile.RECENT_KEYS">
       <recent name="F:\project\site_front\src\styles\iconfont" />
+      <recent name="F:\project\site_front\public\store" />
     </key>
     <key name="MoveFile.RECENT_KEYS">
       <recent name="F:\project\site_front\src\app\[locale]\(doings)" />
@@ -77,9 +91,9 @@
       <list>
         <item itemvalue="JavaScript Debug.localhost:3000" />
         <item itemvalue="npm.dev" />
-        <item itemvalue="npm.dev" />
-        <item itemvalue="JavaScript Debug.localhost:3000" />
         <item itemvalue="JavaScript Debug.localhost:3000" />
+        <item itemvalue="npm.dev" />
+        <item itemvalue="npm.dev" />
       </list>
     </recent_temporary>
   </component>

+ 2 - 1
public/next.svg

@@ -1 +1,2 @@
-<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
+<svg width="24" height="24" viewBox="0 0 24 24" fill="#5f6368" xmlns="http://www.w3.org/2000/svg"
+><path fill-rule="evenodd" clip-rule="evenodd" d="M12.4996 6.36584L14.001 7.65237V4H11.001V7.65075L12.4996 6.36584ZM10 2H11.001H14.001H15H16.998C18.6461 2 20.001 3.35397 20.001 5.002V18.998C20.001 20.646 18.6461 22 16.998 22H4V2H10ZM18.001 5.002C18.001 4.459 17.542 4 16.998 4H16.001V12L12.5 9L9.001 12V4H6V20H16.998C17.542 20 18.001 19.541 18.001 18.998V5.002Z"></path></svg>

BIN
public/store/actived.png


+ 1 - 0
public/store/app.svg

@@ -0,0 +1 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="#01875f" xmlns="http://www.w3.org/2000/svg" class="VuUAje ndrlL"><path fill-rule="evenodd" clip-rule="evenodd" d="M15 4H18C19.1 4 20 4.9 20 6V9C20 10.1 19.1 11 18 11H15C13.9 11 13 10.1 13 9V6C13 4.9 13.9 4 15 4ZM9 13H6C4.9 13 4 13.9 4 15V18C4 19.1 4.9 20 6 20H9C10.1 20 11 19.1 11 18V15C11 13.9 10.1 13 9 13ZM18 13H15C13.9 13 13 13.9 13 15V18C13 19.1 13.9 20 15 20H18C19.1 20 20 19.1 20 18V15C20 13.9 19.1 13 18 13ZM9 4H6C4.9 4 4 4.9 4 6V9C4 10.1 4.9 11 6 11H9C10.1 11 11 10.1 11 9V6C11 4.9 10.1 4 9 4Z"></path></svg>

+ 2 - 0
public/store/book.svg

@@ -0,0 +1,2 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="#5f6368" xmlns="http://www.w3.org/2000/svg"
+><path fill-rule="evenodd" clip-rule="evenodd" d="M12.4996 6.36584L14.001 7.65237V4H11.001V7.65075L12.4996 6.36584ZM10 2H11.001H14.001H15H16.998C18.6461 2 20.001 3.35397 20.001 5.002V18.998C20.001 20.646 18.6461 22 16.998 22H4V2H10ZM18.001 5.002C18.001 4.459 17.542 4 16.998 4H16.001V12L12.5 9L9.001 12V4H6V20H16.998C17.542 20 18.001 19.541 18.001 18.998V5.002Z"></path></svg>

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
public/store/child.svg


+ 2 - 0
public/store/game.svg

@@ -0,0 +1,2 @@
+<svg width="24" height="24" viewBox="0 0 21 16" fill="#5f6368" xmlns="http://www.w3.org/2000/svg"
+     class="Y4jiDf"><path fill-rule="evenodd" clip-rule="evenodd" d="M19.3 8.4C19.2169 7.65213 19.0648 6.90427 18.9009 6.09902C18.8676 5.93522 18.8338 5.76904 18.8 5.6L18.8 5.59986C18.7 5.1 18.7 5.09996 18.6 4.7L18.5 4.4C18.2 1.8 16 0 13.3 0H6.7C4.1 0 1.8 1.8 1.4 4.4C1.4 4.43174 1.4 4.4534 1.3968 4.47458C1.38993 4.52014 1.36826 4.56347 1.3 4.7C1.3 5.1 1.3 5.1 1.2 5.6C1.1 6.05 1.025 6.525 0.95 7C0.875 7.475 0.8 7.95 0.7 8.4C0.1 11.9 0 12.5 0 12.7C0 14.2 1.2 15.5 2.8 15.5C3.6 15.5 4.3 15.2 4.8 14.7L7.7 11.9H12.4L15.3 14.8C15.8 15.3 16.5 15.6 17.3 15.6C18.8 15.6 20.1 14.4 20.1 12.8C20.0055 12.5165 19.911 11.9651 19.3946 8.95177L19.3 8.4ZM13 5C13.4971 5 13.9 4.59706 13.9 4.1C13.9 3.60294 13.4971 3.2 13 3.2C12.5029 3.2 12.1 3.60294 12.1 4.1C12.1 4.59706 12.5029 5 13 5ZM15.8 6C15.8 6.49706 15.3971 6.9 14.9 6.9C14.4029 6.9 14 6.49706 14 6C14 5.50294 14.4029 5.1 14.9 5.1C15.3971 5.1 15.8 5.50294 15.8 6ZM10.5 5.4C10.2 5.7 10.2 6.3 10.5 6.6C10.8 6.9 11.4 6.9 11.7 6.6C12 6.3 12 5.7 11.7 5.4C11.4 5.1 10.9 5.1 10.5 5.4ZM13 8.8C13.4971 8.8 13.9 8.39706 13.9 7.9C13.9 7.40294 13.4971 7 13 7C12.5029 7 12.1 7.40294 12.1 7.9C12.1 8.39706 12.5029 8.8 13 8.8ZM6.4 3.5H7.6V5.4H9.5V6.6H7.6V8.5H6.4V6.6H4.5V5.4H6.4V3.5ZM16.5 13.3C16.7 13.5 16.9 13.6 17.2 13.6C17.8 13.6 18.2 13.2 18.2 12.6C18.2 12.7 16.8 4.8 16.8 4.7C16.5 3 15 1.8 13.3 1.8H6.7C4.9 1.8 3.5 3 3.2 4.7C3.2 4.8 1.8 12.7 1.8 12.7C1.8 13.3 2.3 13.7 2.8 13.7C3.1 13.7 3.3 13.6 3.5 13.4L6.9 10H13.1L13.4 10.2L16.5 13.3Z"></path></svg>

BIN
public/store/google-play.png


BIN
public/store/ios.png


BIN
public/store/pwa_install.png


+ 2 - 0
public/store/whtch.svg

@@ -0,0 +1,2 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="#5f6368" xmlns="http://www.w3.org/2000/svg"
+     class="Y4jiDf"><path fill-rule="evenodd" clip-rule="evenodd" d="M3 2V22H21V2H3ZM5 20H19V4H5V20ZM9 7H6V5H9V7ZM18 7H15V5H18V7ZM6 19H9V17H6V19ZM18 19H15V17H18V19ZM15 15H18V13H15V15ZM9 15H6V13H9V15ZM15 11H18V9H15V11ZM9 11H6V9H9V11Z"></path></svg>

+ 275 - 67
src/app/[locale]/(doings)/store/page.tsx

@@ -1,47 +1,127 @@
 "use client";
+import useDesktop from "@/hooks/useDesktop";
 import { server } from "@/utils/client";
-import { Divider, ProgressBar, Rate } from "antd-mobile";
+import { Divider, Mask, Popup, ProgressBar, Rate } from "antd-mobile";
 import clsx from "clsx";
 import Image from "next/image";
 import { useSearchParams } from "next/navigation";
-import { useEffect } from "react";
+import { FC, useEffect, useRef, useState } from "react";
 import { Autoplay } from "swiper/modules";
 import { Swiper, SwiperSlide } from "swiper/react";
-
+import style from "./style.module.scss";
+interface StoreDetailsType {
+    /**
+     * 应用描述
+     */
+    description: string;
+    /**
+     * 应用图标地址
+     */
+    icon_url: string;
+    /**
+     * 安装器参数信息
+     */
+    installer_args: string;
+    /**
+     * 安装器类型:1添加到桌面(苹果)、2苹果商店安装、3pwa快捷安装
+     */
+    installer_type: number;
+    /**
+     * 应用名称
+     */
+    name: string;
+    /**
+     * 预览图片列表
+     */
+    preview_images: string[];
+    /**
+     * 应用标题
+     */
+    title: string;
+    /**
+     * 类型:1谷歌原版(有logo),2谷歌原版(无logo)
+     */
+    type: number;
+}
 const Header = () => {
     return (
-        <div className={"sticky left-0 top-0 z-20 h-[0.4444rem] bg-[#fff] text-[#000] shadow"}>
-            header
+        <div
+            className={
+                "sticky left-0 top-0 z-20 flex h-[0.4844rem] bg-[#fff] text-[#000]" +
+                " items-center shadow"
+            }
+        >
+            <Image
+                src={"/svg/google.svg"}
+                alt={""}
+                width={40}
+                height={40}
+                className={"mx-[10px]"}
+            />
+            <Image src={"/store/google-play.png"} alt={""} width={120} height={60} />
         </div>
     );
 };
 
 const Footer = () => {
+    const items = [
+        { name: "Jogos", icon: "game" },
+        { name: "Apps", icon: "app" },
+        { name: "Filmes", icon: "whtch" },
+        { name: "Livros", icon: "book" },
+        { name: "Crianças", icon: "child" },
+    ];
     return (
-        <div className={"sticky bottom-0 left-0 h-[0.4444rem] bg-[#fff] text-[#000]"}>Footer</div>
+        <div
+            className={
+                "sticky bottom-0 left-0 grid h-[0.5444rem] grid-cols-5 items-center bg-[#fff] text-center" +
+                " border-t border-[#e8eaed] text-[0.125rem] text-[#5f6368]"
+            }
+        >
+            {items.map((item, index) => {
+                return (
+                    <div
+                        key={index}
+                        className={clsx(index === 1 ? "text-[#01875f]" : "", "cursor-pointer")}
+                    >
+                        <Image
+                            src={`/store/${item.icon}.svg`}
+                            alt={""}
+                            className={"mx-auto"}
+                            width={22}
+                            height={22}
+                        />
+                        <p>{item.name}</p>
+                    </div>
+                );
+            })}
+        </div>
     );
 };
 
-const CardView = () => {
-    const images = Array.from({ length: 6 });
+const CardView: FC<{ details: StoreDetailsType | null; onPress: () => void }> = (props) => {
+    const { details, onPress } = props;
 
     const textcls = clsx("text-[14px] font-medium text-[#5f6368]");
+
     return (
-        <div className={"p-[0.1389rem]"}>
-            <div className={"flex"}>
+        <div className={"p-[0.1389rem] text-[#202124]"}>
+            <div className={"flex space-x-[24px]"}>
                 <div className={"flex-shrink-0"}>
-                    <img
-                        src="/doings/activity.png"
-                        alt=""
-                        className={"h-[0.5rem] w-[0.5rem] object-contain"}
-                    />
+                    {details?.icon_url ? (
+                        <img
+                            src={details?.icon_url}
+                            alt=""
+                            className={"h-[0.5rem] w-[0.5rem] object-contain"}
+                        />
+                    ) : (
+                        <div></div>
+                    )}
                 </div>
 
                 <div>
-                    <p className={"text-[#202124]"}>name</p>
-                    <p className={"cursor-pointer text-[#01875f]"}>
-                        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut, quasi.
-                    </p>
+                    <p className={"text-[#202124]"}>{details?.name || ""}</p>
+                    <p className={"cursor-pointer text-[#01875f]"}>{details?.title}</p>
                 </div>
             </div>
 
@@ -51,10 +131,10 @@ const CardView = () => {
                 }
             >
                 <div className={"px-[0.1667rem]"}>
-                    <p className={"font-semibold"}>
-                        4,9<i className={"iconfont icon-star_full"}></i>
+                    <p className={"flex items-center font-semibold"}>
+                        4,9<i className={"iconfont icon-star_full text-[0.0972rem]"}></i>
                     </p>
-                    <p>46K avaliações</p>
+                    <p className={"text-[#5f6368]"}>46K avaliações</p>
                 </div>
                 <div
                     className={
@@ -64,7 +144,7 @@ const CardView = () => {
                     }
                 >
                     <p className={"font-semibold"}>50 mil+</p>
-                    <p>Downloads</p>
+                    <p className={"text-[#5f6368]"}>Downloads</p>
                 </div>
                 <div
                     className={
@@ -74,11 +154,16 @@ const CardView = () => {
                     }
                 >
                     <p className={"inline-block border font-semibold"}>18+</p>
-                    <p>Rated for 18+</p>
+                    <p className={"text-[#5f6368]"}>Rated for 18+</p>
                 </div>
             </div>
 
-            <div className={"rounded-[10px] bg-[#01875f] py-[8px] text-center text-[#fff]"}>
+            <div
+                className={
+                    "cursor-pointer rounded-[10px] bg-[#01875f] py-[8px] text-center text-[#fff]"
+                }
+                onClick={onPress}
+            >
                 Rapid Instalar
             </div>
 
@@ -97,8 +182,6 @@ const CardView = () => {
 
             <div>
                 <Swiper
-                    slidesPerView={3.2}
-                    spaceBetween={30}
                     pagination={{
                         clickable: true,
                     }}
@@ -109,11 +192,9 @@ const CardView = () => {
                     modules={[Autoplay]}
                     className="mySwiper"
                 >
-                    {images.map((prize, index: number) => (
+                    {details?.preview_images?.map((url, index: number) => (
                         <SwiperSlide key={index}>
-                            <div className={"w-[1.1rem]"} style={{ borderRadius: ".1rem" }}>
-                                {index}
-                            </div>
+                            <img src={url} alt={""} className={"h-[1.3rem] w-[100%]"} />
                         </SwiperSlide>
                     ))}
                 </Swiper>
@@ -124,10 +205,7 @@ const CardView = () => {
                     <p>Sobre este jogo</p>
                     <i className={"iconfont icon-xiangyou2 text-[14px]"}></i>
                 </div>
-                <p className={textcls}>
-                    {/*Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet deleniti eveniet*/}
-                    {/*natus voluptates? A aperiam laborum libero officiis quos veritatis?*/}
-                </p>
+                <p className={textcls}>{details?.description}</p>
 
                 <div className={"my-[20px]"}>
                     <p>Atualizado em</p>
@@ -161,7 +239,7 @@ const CardView = () => {
                         </div>
                     </div>
 
-                    <div className={"mt-[20px] flex items-center space-x-[20px]"}>
+                    <div className={"mt-[20px] flex space-x-[20px]"}>
                         <img
                             src={
                                 "https://play-lh.googleusercontent.com/12USW7aflgz466ifDehKTnMoAep_VHxDmKJ6jEBoDZWCSefOC-ThRX14Mqe0r8KF9XCzrpMqJts=s20-rw"
@@ -174,7 +252,7 @@ const CardView = () => {
                         </div>
                     </div>
 
-                    <div className={"mt-[20px] flex items-center space-x-[20px]"}>
+                    <div className={"mt-[20px] flex space-x-[20px]"}>
                         <img
                             src={
                                 "https://play-lh.googleusercontent.com/W5DPtvB8Fhmkn5LbFZki_OHL3ZI1Rdc-AFul19UK4f7np2NMjLE5QquD6H0HAeEJ977u3WH4yaQ=s20-rw"
@@ -186,7 +264,7 @@ const CardView = () => {
                         </div>
                     </div>
 
-                    <div className={"mt-[20px] flex items-center space-x-[20px]"}>
+                    <div className={"mt-[20px] flex space-x-[20px]"}>
                         <img
                             src={
                                 "https://play-lh.googleusercontent.com/ohRyQRA9rNfhp7xLW0MtW1soD8SEX45Oec7MyH3FaxtukWUG_6GKVpvh3JiugzryLi7Bia02HPw=s20-rw"
@@ -204,9 +282,17 @@ const CardView = () => {
                 </div>
             </div>
             <div>
-                <div className={"flex justify-between py-[20px]"}>
-                    <p>Classificações e resenhas</p>
-                    <i className={"iconfont icon-xiangyou2 text-[14px]"}></i>
+                <div className={"py-[20px]"}>
+                    <div className={"flex justify-between"}>
+                        <p className={""}>Classificações e resenhas</p>
+                        <i className={"iconfont icon-xiangyou2 text-[14px]"}></i>
+                    </div>
+                    <span className={"text-[12px]"}>As notas e avaliações são verificadas</span>
+                    <i
+                        className={
+                            "iconfont icon-zhuyi ml-[10px] text-[12px] font-semibold text-[#5f6368]"
+                        }
+                    ></i>
                 </div>
 
                 <div className={"flex space-x-[30px]"}>
@@ -311,7 +397,7 @@ const Comment = () => {
             {users.map((item, index) => (
                 <div key={index} className={"py-[16px]"}>
                     <div className={"flex justify-between"}>
-                        <div className={"flex space-x-[20px]"}>
+                        <div className={"flex items-center space-x-[20px]"}>
                             <Image
                                 src={item.avatar}
                                 alt={item.name}
@@ -321,18 +407,20 @@ const Comment = () => {
                             />
                             <span className={"text-[14px]"}>{item.name}</span>
                         </div>
-                        <i className={"iconfont icon-fenxiang2"}></i>
+                        <i className={"iconfont icon-gengduo1"}></i>
                     </div>
 
                     <div className={"mt-[16px] flex items-center space-x-[10px]"}>
                         <RateStar star={item.precent} small />
                         <p className={"text-[12px] text-[#5f6368]"}>{item.time}</p>
                     </div>
-                    <div className={"mt-[8px] text-[14px] text-[#5f6368]"}>{item.desc}</div>
-                    <p className={"mt-[16px] text-[12px] text-[#5f6368]"}>
+                    <div className={"mt-[8px] text-[0.125rem] text-[#5f6368]"}>{item.desc}</div>
+                    <p className={"mt-[16px] text-[0.1111rem] text-[#5f6368]"}>
                         Essa avaliação foi marcada como útil por {item.sure} pessoas
                     </p>
-                    <div className={"mt-[12px] flex space-x-[20px] text-[12px] text-[#5f6368]"}>
+                    <div
+                        className={"mt-[12px] flex space-x-[20px] text-[0.1111rem] text-[#5f6368]"}
+                    >
                         <p>Você achou isso útil?</p>
                         <div></div>
                         <div
@@ -443,7 +531,8 @@ const Other = () => {
             </div>
 
             <div className={"mt-[10px]"}>
-                <i className={"iconfont icon-star_full mr-[10px]"}></i>Sinalizar como impróprio
+                <i className={"iconfont icon-tongyong-biaojiqizi mr-[10px]"}></i>Sinalizar como
+                impróprio
             </div>
         </>
     );
@@ -452,9 +541,7 @@ const Other = () => {
 const CardFooter = () => {
     return (
         <>
-            <div
-                className={"mt-[36px] text-[0.0972rem] text-[#5f6368] [&>section>p]:cursor-pointer"}
-            >
+            <div className={"mt-[36px] text-[16px] text-[#5f6368] [&>section>p]:cursor-pointer"}>
                 <section>
                     <p>Vales-presente</p>
                     <p>Resgatar</p>
@@ -480,35 +567,156 @@ const CardFooter = () => {
         </>
     );
 };
+
 const getStoreApi = (data: { ch: string }) => {
-    return server.post({
+    return server.post<StoreDetailsType>({
         url: "/v1/api/front/app/store/details",
         data,
     });
 };
+
+const InstallLoading: FC<{
+    details: StoreDetailsType | null;
+    visible: boolean;
+    open: () => void;
+    close: () => void;
+}> = ({ details, visible, open, close }) => {
+    const [count, setCount] = useState(0);
+    const { downloadHandler } = useDesktop("page");
+    const [isVerify, setIsVerify] = useState(true);
+    const [tipModal, setTipModal] = useState(false);
+
+    const timer = useRef<NodeJS.Timeout | number>(0);
+    const installHandler = () => {
+        switch (details?.installer_type) {
+            case 1:
+                setTipModal(true);
+                break;
+            case 2:
+                break;
+            default:
+                downloadHandler();
+        }
+        close();
+    };
+    useEffect(() => {
+        timer.current = setTimeout(() => {
+            if (count >= 100) {
+                clearTimeout(timer.current);
+                setIsVerify(false);
+                return;
+            } else {
+                setCount((count) => count + 1);
+            }
+        }, 80);
+    }, [count]);
+
+    return (
+        <>
+            <Popup
+                visible={tipModal}
+                getContainer={null}
+                onMaskClick={() => {
+                    setTipModal(false);
+                }}
+                onClose={() => {
+                    setTipModal(false);
+                }}
+                bodyStyle={{
+                    borderTopLeftRadius: "8px",
+                    borderTopRightRadius: "8px",
+                }}
+            >
+                <div className={"relative w-[100%] p-[20px]"}>
+                    <Image
+                        src={"/store/ios.png"}
+                        className={"w-[100%] object-contain"}
+                        alt={""}
+                        width={400}
+                        height={200}
+                    />
+                    <div
+                        onClick={() => setTipModal(false)}
+                        className={"absolute right-[20px] top-[30px] h-[50px] w-[50px]"}
+                    ></div>
+                </div>
+            </Popup>
+
+            <Mask visible={visible} onMaskClick={open}>
+                <div className={style.installContainer}>
+                    <div className={"flex"}>
+                        <Image src={"/store/pwa_install.png"} alt={""} width={28} height={20} />
+                        <span className={"ml-[10px] text-[#666]"}>Rapid Instalar</span>
+                    </div>
+                    {isVerify ? (
+                        <>
+                            <div className={style.loadingContainer}>
+                                <div className={style.loading}></div>
+                                <div className={style.loadingText}>{count}%</div>
+                            </div>
+                        </>
+                    ) : (
+                        <div className={"mt-[0.1389rem] flex w-[100%] flex-col items-center"}>
+                            <div
+                                className={
+                                    "flex w-[0.8333rem] items-center justify-center rounded-[20px]" +
+                                    " bg-[rgba(119,250,73,0.3)] p-[5px]"
+                                }
+                            >
+                                <Image
+                                    src={"/store/actived.png"}
+                                    alt={""}
+                                    className={"object-contain"}
+                                    width={14}
+                                    height={12}
+                                />
+                                <span
+                                    className={
+                                        "ml-[5px] text-[0.1111rem] font-semibold text-[#01875f]"
+                                    }
+                                >
+                                    Effective
+                                </span>
+                            </div>
+                            <div
+                                className={
+                                    "mt-[20px] w-[100%] cursor-pointer rounded-[0.1389rem] bg-[#028760] py-[5px]" +
+                                    " text-[14px]" +
+                                    " text-center" +
+                                    " text-[#fff]"
+                                }
+                                onClick={installHandler}
+                            >
+                                Instalar Agora
+                            </div>
+                        </div>
+                    )}
+                </div>
+            </Mask>
+        </>
+    );
+};
+
 const Page = () => {
     const searchparams = useSearchParams();
+    const [details, setDetails] = useState<StoreDetailsType | null>(null);
+    const [visible, setVisible] = useState(false);
     useEffect(() => {
         getStoreApi({ ch: searchparams.get("ch")! }).then((res) => {
-            return {
-                type: 82,
-                name: "关癸霖",
-                title: "击踢脚线全单幸亏油门搂",
-                icon_url: "https://avatars.githubusercontent.com/u/67110323",
-                description: "亲回来点来五月。强量级整该矿列写再具。受办照此。",
-                preview_images: [
-                    "https://loremflickr.com/400/400?lock=4729061696354976",
-                    "https://loremflickr.com/400/400?lock=2057580202751112",
-                ],
-                installer_type: 89,
-                installer_args: "sit ea quis incididunt",
-            };
+            setDetails(res.data);
+            return res.data;
         });
-    });
+    }, []);
     return (
         <div className={"text-[#000]"}>
-            <Header />
-            <CardView />
+            <InstallLoading
+                details={details}
+                visible={visible}
+                open={() => setVisible(true)}
+                close={() => setVisible(false)}
+            />
+            {details?.type === 1 ? <Header /> : null}
+            <CardView details={details} onPress={() => setVisible(true)} />
             <Footer />
         </div>
     );

+ 53 - 0
src/app/[locale]/(doings)/store/style.module.scss

@@ -0,0 +1,53 @@
+
+.installContainer{
+  position: absolute;
+  top: 20%;
+  left: 50%;
+  transform: translate(-50%);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 3rem;
+  background: white;
+  border-radius: 10px;
+  flex-flow: column;
+  padding: 20px;
+}
+
+
+@keyframes rotate-loading {
+  0%  {transform: rotate(0deg);}
+  100% {transform: rotate(360deg)}
+}
+
+.loadingContainer,
+.loading {
+  height: 100px;
+  position: relative;
+  width: 100px;
+  border-radius: 100%;
+}
+
+
+.loadingContainer { margin-top: 20px; }
+
+.loading {
+  border-width: 2px;
+  border-color: transparent #01875f transparent #01875f;
+  animation: rotate-loading 1s linear 0s infinite normal;
+  transform-origin: 50% 50%;
+}
+
+
+.loadingText {
+  //animation: loading-text-opacity 2s linear 0s infinite normal;
+  color: #01875f;
+  font-size: 16px;
+  font-weight: bold;
+  margin-top: 40px;
+  position: absolute;
+  text-align: center;
+  text-transform: uppercase;
+  top: 0;
+  width: 100px;
+}

+ 63 - 7
src/styles/iconfont/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 4617618 */
-  src: url('iconfont.woff2?t=1744351901335') format('woff2'),
-       url('iconfont.woff?t=1744351901335') format('woff'),
-       url('iconfont.ttf?t=1744351901335') format('truetype');
+  src: url('iconfont.woff2?t=1744720863888') format('woff2'),
+       url('iconfont.woff?t=1744720863888') format('woff'),
+       url('iconfont.ttf?t=1744720863888') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,66 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-zhuyi:before {
+  content: "\e662";
+}
+
+.icon-youxi1:before {
+  content: "\e693";
+}
+
+.icon-youxi:before {
+  content: "\e694";
+}
+
+.icon-ertong1:before {
+  content: "\e689";
+}
+
+.icon-ertong21:before {
+  content: "\e68a";
+}
+
+.icon-tongyong-biaojiqizi:before {
+  content: "\e6ec";
+}
+
+.icon-yingyong3:before {
+  content: "\e684";
+}
+
+.icon-yingshi2:before {
+  content: "\e688";
+}
+
+.icon-yingyong21:before {
+  content: "\e68d";
+}
+
+.icon-yingshi:before {
+  content: "\e68e";
+}
+
+.icon-shuji:before {
+  content: "\e68f";
+}
+
+.icon-shuji2:before {
+  content: "\e690";
+}
+
+.icon-ertong2:before {
+  content: "\e691";
+}
+
+.icon-ertong:before {
+  content: "\e692";
+}
+
+.icon-gengduo1:before {
+  content: "\e65d";
+}
+
 .icon-suoding_o:before {
   content: "\eb50";
 }
@@ -25,10 +85,6 @@
   content: "\e65c";
 }
 
-.icon-delete-bin-6-line:before {
-  content: "\e6d9";
-}
-
 .icon-tongzhixiaoxi:before {
   content: "\e65a";
 }

BIN
src/styles/iconfont/iconfont.ttf


BIN
src/styles/iconfont/iconfont.woff


BIN
src/styles/iconfont/iconfont.woff2


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است