Kaynağa Gözat

提交代码

zlwu 10 ay önce
ebeveyn
işleme
9336ef8e6e

+ 156 - 46
frontend/src/pages/FirstLoginRewardPage.tsx

@@ -25,6 +25,8 @@ const closeBtn = getOssUrl('close-btn.png');
 // const saveIcon = getOssUrl('save.png'); // 已注释,未使用
 const saveBtnImage = 'https://lyrria-pro.oss-cn-beijing.aliyuncs.com/share-done-claim-gift.png';
 const claimGiftBtnImage = 'https://lyrria-pro.oss-cn-beijing.aliyuncs.com/claim-the-gift.png';
+const chevronLeftImage = 'https://lyrria-pro.oss-cn-beijing.aliyuncs.com/Chevron-L.png';
+const chevronRightImage = 'https://lyrria-pro.oss-cn-beijing.aliyuncs.com/Chevron-R.png';
 import { shareImages as fallbackShareImages } from '@/data/shareImages';
 import { getShareImages, type ShareImageItem } from '@/utils/api';
 
@@ -70,6 +72,24 @@ export const FirstLoginRewardPage = () => {
     fetchShareImages();
   }, []);
 
+  // 预加载分享图片
+  useEffect(() => {
+    if (shareImages.length === 0) {
+      return;
+    }
+
+    const preloadImages = () => {
+      shareImages.forEach((item) => {
+        if (item.url) {
+          const img = new Image();
+          img.src = item.url;
+        }
+      });
+    };
+
+    preloadImages();
+  }, [shareImages]);
+
   const handleBack = () => {
     navigate('/chatbot');
   };
@@ -172,6 +192,18 @@ export const FirstLoginRewardPage = () => {
     touchStartXRef.current = null;
   };
 
+  const handlePreviousImage = () => {
+    if (activeShareIndex > 0) {
+      setActiveShareIndex((prev) => prev - 1);
+    }
+  };
+
+  const handleNextImage = () => {
+    if (activeShareIndex < shareImages.length - 1) {
+      setActiveShareIndex((prev) => prev + 1);
+    }
+  };
+
   useEffect(() => {
     if (showShareModal) {
       const previousOverflow = document.body.style.overflow;
@@ -266,7 +298,7 @@ export const FirstLoginRewardPage = () => {
               color: '#FFFFFF',
               fontSize: px2vmin(14),
               textAlign: 'center',
-              // width: px2vmin(270),
+              width: px2vmin(230),
             }}
           >
             哇,是一顶小帽子,谢谢你!要到新年了,快来分享我的新装扮并解锁限定新年背景吧
@@ -284,6 +316,7 @@ export const FirstLoginRewardPage = () => {
               border: 'none',
               padding: 0,
               background: 'none',
+              width: px2vmin(279),
               height: px2vmin(56),
             }}
           >
@@ -291,6 +324,7 @@ export const FirstLoginRewardPage = () => {
               src={shareBtn}
               alt="Share"
               style={{
+                width: '100%',
                 height: '100%',
                 display: 'block',
               }}
@@ -324,17 +358,61 @@ export const FirstLoginRewardPage = () => {
             >
               {shareImages.length > 0 && (
                 <div
-                  onTouchStart={handleTouchStart}
-                  onTouchEnd={handleTouchEnd}
                   style={{
                     position: 'relative',
-                    width: px2vmin(311),
                     display: 'flex',
+                    alignItems: 'center',
                     justifyContent: 'center',
-                    overflow: 'visible',
-                    pointerEvents: 'auto',
                   }}
                 >
+                  {/* 图片容器 */}
+                  <div
+                    onTouchStart={handleTouchStart}
+                    onTouchEnd={handleTouchEnd}
+                    style={{
+                      position: 'relative',
+                      width: px2vmin(311),
+                      display: 'flex',
+                      justifyContent: 'center',
+                      overflow: 'visible',
+                      pointerEvents: 'auto',
+                    }}
+                  >
+                  {/* 左侧按钮 */}
+                  {activeShareIndex > 0 && (
+                    <button
+                      type="button"
+                      onClick={handlePreviousImage}
+                      style={{
+                        position: 'absolute',
+                        left: px2vmin(-12),
+                        top: '50%',
+                        transform: 'translateY(-50%)',
+                        zIndex: 10001,
+                        border: 'none',
+                        padding: 0,
+                        background: 'none',
+                        width: px2vmin(24),
+                        height: px2vmin(24),
+                        cursor: 'pointer',
+                        pointerEvents: 'auto',
+                        display: 'flex',
+                        alignItems: 'center',
+                        justifyContent: 'center',
+                      }}
+                      aria-label="Previous image"
+                    >
+                      <img
+                        src={chevronLeftImage}
+                        alt="Previous"
+                        style={{
+                          width: '100%',
+                          height: '100%',
+                          display: 'block',
+                        }}
+                      />
+                    </button>
+                  )}
                   <button
                     type="button"
                     onClick={handleShareClose}
@@ -342,7 +420,7 @@ export const FirstLoginRewardPage = () => {
                       position: 'absolute',
                       right: 0,
                       top: 0,
-                      transform: 'translate(-50%, -130%)',
+                      transform: 'translate(-10%, -130%)',
                       width: px2vmin(30),
                       height: px2vmin(30),
                       padding: 0,
@@ -377,8 +455,6 @@ export const FirstLoginRewardPage = () => {
                           position: 'absolute',
                           height: 'auto',
                           maxWidth: '100%',
-                          transform: 'rotate(-1.55deg)',
-                          transformOrigin: 'right bottom',
                           opacity: 1,
                           pointerEvents: 'none',
                           zIndex: 0,
@@ -394,8 +470,6 @@ export const FirstLoginRewardPage = () => {
                           position: 'absolute',
                           height: 'auto',
                           maxWidth: '100%',
-                          transform: 'rotate(1.55deg)',
-                          transformOrigin: 'left bottom',
                           opacity: 1,
                           pointerEvents: 'none',
                           zIndex: 0,
@@ -416,45 +490,82 @@ export const FirstLoginRewardPage = () => {
                       }}
                     />
                   </div>
-                </div>
-              )}
 
-              {shareImages.length > 0 && (
-                <div
-                  style={{
-                    position: 'absolute',
-                    top: px2vmin(514),
-                    left: '50%',
-                    transform: 'translateX(-50%)',
-                    display: 'flex',
-                    alignItems: 'center',
-                    gap: px2vmin(8),
-                    pointerEvents: 'auto',
-                  }}
-                >
-                  {shareImages.map((item, index) => {
-                    const isActive = index === activeShareIndex;
-                    return (
-                      <button
-                        key={item.id}
-                        type="button"
-                        aria-label={`Select share image ${index + 1}`}
-                        onClick={() => setActiveShareIndex(index)}
+                  {/* 右侧按钮 */}
+                  {activeShareIndex < shareImages.length - 1 && (
+                    <button
+                      type="button"
+                      onClick={handleNextImage}
+                      style={{
+                        position: 'absolute',
+                        right: px2vmin(-12),
+                        top: '50%',
+                        transform: 'translateY(-50%)',
+                        zIndex: 10001,
+                        border: 'none',
+                        padding: 0,
+                        background: 'none',
+                        width: px2vmin(24),
+                        height: px2vmin(24),
+                        cursor: 'pointer',
+                        pointerEvents: 'auto',
+                        display: 'flex',
+                        alignItems: 'center',
+                        justifyContent: 'center',
+                      }}
+                      aria-label="Next image"
+                    >
+                      <img
+                        src={chevronRightImage}
+                        alt="Next"
                         style={{
-                          width: isActive ? px2vmin(24) : px2vmin(6),
-                          height: px2vmin(6),
-                          borderRadius: isActive ? px2vmin(20) : px2vmin(6),
-                          background: isActive ? 'rgba(169, 132, 228, 1)' : 'rgba(232, 222, 248, 1)',
-                          border: 'none',
-                          padding: 0,
+                          width: '100%',
+                          height: '100%',
+                          display: 'block',
                         }}
                       />
-                    );
-                  })}
+                    </button>
+                  )}
                 </div>
-              )}
-            </div>
+              </div>
+            )}
+
+            {shareImages.length > 0 && (
+              <div
+                style={{
+                  position: 'absolute',
+                  top: px2vmin(514),
+                  left: '50%',
+                  transform: 'translateX(-50%)',
+                  display: 'flex',
+                  alignItems: 'center',
+                  gap: px2vmin(8),
+                  pointerEvents: 'auto',
+                }}
+              >
+                {shareImages.map((item, index) => {
+                  const isActive = index === activeShareIndex;
+                  return (
+                    <button
+                      key={item.id}
+                      type="button"
+                      aria-label={`Select share image ${index + 1}`}
+                      onClick={() => setActiveShareIndex(index)}
+                      style={{
+                        width: isActive ? px2vmin(24) : px2vmin(6),
+                        height: px2vmin(6),
+                        borderRadius: isActive ? px2vmin(20) : px2vmin(6),
+                        background: isActive ? 'rgba(169, 132, 228, 1)' : 'rgba(232, 222, 248, 1)',
+                        border: 'none',
+                        padding: 0,
+                      }}
+                    />
+                  );
+                })}
+              </div>
+            )}
           </div>
+        </div>
 
           {/* 底部弹窗 */}
           {shareImages.length > 0 && (
@@ -503,7 +614,6 @@ export const FirstLoginRewardPage = () => {
                 <div
                   style={{
                     color: '#FFFFFF',
-                    fontSize: px2vmin(14),
                     textAlign: 'center',
                     lineHeight: px2vmin(14),
                     marginBottom: px2vmin(18),
@@ -521,7 +631,7 @@ export const FirstLoginRewardPage = () => {
                     padding: 0,
                     background: 'none',
                     // width: px2vmin(118),
-                    height: px2vmin(40),
+                    height: px2vmin(35),
                     cursor: 'pointer',
                   }}
                 >

+ 2 - 2
frontend/src/pages/GreetingPage.tsx

@@ -425,8 +425,8 @@ export const GreetingPage = () => {
             top: px2vh(layout.confirmButtonTop),
             left: '50%',
             transform: 'translateX(-50%)',
-            // 设计稿:宽 163、高 56,使用 vw/vh 中的较小值
-            width: px2vmin(163),
+            // 设计稿:宽 279、高 56,使用 vw/vh 中的较小值
+            width: px2vmin(279),
             height: px2vmin(56),
             borderRadius: px2vw(100),
             backgroundImage: `url(${ConfirmBtnImage})`,

+ 1 - 1
frontend/src/pages/LumiNamingPage.tsx

@@ -266,7 +266,7 @@ export const LumiNamingPage = () => {
             top: px2vh(layout.confirmButtonTop),
             left: '50%',
             transform: 'translateX(-50%)',
-            width: px2vmin(163),
+            width: px2vmin(279),
             height: px2vmin(56),
             borderRadius: px2vw(100),
             backgroundImage: `url(${ConfirmBtnImage})`,