diff --git a/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/13e4881d89c84f948592364753559f8b.webp b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/13e4881d89c84f948592364753559f8b.webp new file mode 100644 index 00000000..3c01a9ed Binary files /dev/null and b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/13e4881d89c84f948592364753559f8b.webp differ diff --git a/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/1e673b259a444d07b10897a652119911.webp b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/1e673b259a444d07b10897a652119911.webp new file mode 100644 index 00000000..cac718fc Binary files /dev/null and b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/1e673b259a444d07b10897a652119911.webp differ diff --git a/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/39189a7a8b1f4647b18dd0ff14d278e6.webp b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/39189a7a8b1f4647b18dd0ff14d278e6.webp new file mode 100644 index 00000000..03bce5bf Binary files /dev/null and b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/39189a7a8b1f4647b18dd0ff14d278e6.webp differ diff --git a/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/39999cd25b3d45958ef4f5461781c23f.webp b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/39999cd25b3d45958ef4f5461781c23f.webp new file mode 100644 index 00000000..8e3c3498 Binary files /dev/null and b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/39999cd25b3d45958ef4f5461781c23f.webp differ diff --git a/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/49df5fa2d26446fea3a4ecb74da92b6c.webp b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/49df5fa2d26446fea3a4ecb74da92b6c.webp new file mode 100644 index 00000000..3c01a9ed Binary files /dev/null and b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/49df5fa2d26446fea3a4ecb74da92b6c.webp differ diff --git a/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/66f22d79a8f1407ab4e6828e2765107e.webp b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/66f22d79a8f1407ab4e6828e2765107e.webp new file mode 100644 index 00000000..69e7029a Binary files /dev/null and b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/66f22d79a8f1407ab4e6828e2765107e.webp differ diff --git a/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/8db4beb8fdd648e4a15f4465eed2907f.webp b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/8db4beb8fdd648e4a15f4465eed2907f.webp new file mode 100644 index 00000000..ffcef308 Binary files /dev/null and b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/8db4beb8fdd648e4a15f4465eed2907f.webp differ diff --git a/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/c874ff71ba6c4bc697350e79fab2c596.webp b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/c874ff71ba6c4bc697350e79fab2c596.webp new file mode 100644 index 00000000..1cb0453e Binary files /dev/null and b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/c874ff71ba6c4bc697350e79fab2c596.webp differ diff --git a/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/eb421f94c1744372855fa09d7d344f09.webp b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/eb421f94c1744372855fa09d7d344f09.webp new file mode 100644 index 00000000..5eaeb56d Binary files /dev/null and b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/eb421f94c1744372855fa09d7d344f09.webp differ diff --git a/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/f5632583104f4e638845cb46020771ee.jpg b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/f5632583104f4e638845cb46020771ee.jpg new file mode 100644 index 00000000..f7a5b186 Binary files /dev/null and b/backend/src/VendingMachine.Api/wwwroot/uploads/2026/04/f5632583104f4e638845cb46020771ee.jpg differ diff --git a/mobile/components/CouponGuidePopup.vue b/mobile/components/CouponGuidePopup.vue index 7ce93376..78a7db10 100644 --- a/mobile/components/CouponGuidePopup.vue +++ b/mobile/components/CouponGuidePopup.vue @@ -1,13 +1,17 @@ @@ -42,7 +46,7 @@ function handleClose() { left: 0; right: 0; bottom: 0; - background-color: rgba(0, 0, 0, 0.5); + background-color: rgba(0, 0, 0, 0.4); display: flex; align-items: center; justify-content: center; @@ -59,32 +63,38 @@ function handleClose() { flex-direction: column; } +.popup-header { + display: flex; + align-items: center; + justify-content: center; + position: relative; + margin-bottom: 36rpx; +} + .popup-title { font-size: 34rpx; font-weight: 600; color: #333; - text-align: center; - display: block; - margin-bottom: 30rpx; +} + +.close-btn { + width: 48rpx; + height: 48rpx; + display: flex; + align-items: center; + justify-content: center; + position: absolute; + right: 0; +} + +.close-icon { + width: 36rpx; + height: 36rpx; } .popup-body { flex: 1; - max-height: 50vh; - margin-bottom: 30rpx; -} - -.close-btn { - height: 80rpx; - background-color: #007aff; - border-radius: 40rpx; - display: flex; - align-items: center; - justify-content: center; -} - -.close-btn-text { - font-size: 28rpx; - color: #ffffff; + max-height: 55vh; + padding-bottom: 40rpx; } diff --git a/mobile/components/RedeemPopup.vue b/mobile/components/RedeemPopup.vue index e71736ab..4acef498 100644 --- a/mobile/components/RedeemPopup.vue +++ b/mobile/components/RedeemPopup.vue @@ -4,7 +4,7 @@ {{ t('redeem.title') }} {{ coupon.name }} - {{ t('redeem.pointsNeeded', { points: coupon.requiredPoints }) }} + {{ t('redeem.pointsLabel') }}{{ coupon.pointsCost ?? coupon.requiredPoints ?? 0 }} @@ -112,7 +112,7 @@ function handleCancel() { } .confirm-btn { - background-color: #007aff; + background: linear-gradient(135deg, #d4a855, #c9a96e); } .btn-text { diff --git a/mobile/i18n/en.js b/mobile/i18n/en.js index 56b9330d..e6675429 100644 --- a/mobile/i18n/en.js +++ b/mobile/i18n/en.js @@ -28,7 +28,8 @@ export default { agreementPrefix: 'I have read and agree to the', userAgreement: 'User Agreement', and: 'and', - privacyPolicy: 'Privacy Policy' + privacyPolicy: 'Privacy Policy', + autoRegisterTip: 'Unregistered phone numbers will be automatically registered upon login' }, // Home page home: { @@ -109,6 +110,7 @@ export default { redeem: { title: 'Confirm Redeem', pointsNeeded: 'Points needed: {points}', + pointsLabel: 'Points needed: ', confirmBtn: 'Confirm' }, // Content pages diff --git a/mobile/i18n/zh-CN.js b/mobile/i18n/zh-CN.js index 15d04495..372fa2b1 100644 --- a/mobile/i18n/zh-CN.js +++ b/mobile/i18n/zh-CN.js @@ -28,7 +28,8 @@ export default { agreementPrefix: '我已阅读并同意', userAgreement: '用户协议', and: '和', - privacyPolicy: '隐私政策' + privacyPolicy: '隐私政策', + autoRegisterTip: '未注册的手机登录后将自动创建账号' }, // 首页 home: { @@ -109,6 +110,7 @@ export default { redeem: { title: '确认兑换', pointsNeeded: '所需积分:{points}', + pointsLabel: '所需积分:', confirmBtn: '确定兑换' }, // 内容页 diff --git a/mobile/i18n/zh-TW.js b/mobile/i18n/zh-TW.js index 76fa2573..6447e5fc 100644 --- a/mobile/i18n/zh-TW.js +++ b/mobile/i18n/zh-TW.js @@ -28,7 +28,8 @@ export default { agreementPrefix: '我已閱讀並同意', userAgreement: '用戶協議', and: '和', - privacyPolicy: '隱私政策' + privacyPolicy: '隱私政策', + autoRegisterTip: '未註冊的手機登入後將自動創建帳號' }, // 首頁 home: { @@ -109,6 +110,7 @@ export default { redeem: { title: '確認兌換', pointsNeeded: '所需積分:{points}', + pointsLabel: '所需積分:', confirmBtn: '確定兌換' }, // 內容頁 diff --git a/mobile/pages.json b/mobile/pages.json index 63936a87..f7a3799f 100644 --- a/mobile/pages.json +++ b/mobile/pages.json @@ -9,7 +9,8 @@ { "path": "pages/login/login", "style": { - "navigationBarTitleText": "登录" + "navigationStyle": "custom", + "navigationBarTitleText": "登录注册" } }, { diff --git a/mobile/pages/index/index.vue b/mobile/pages/index/index.vue index c353788d..abd901ae 100644 --- a/mobile/pages/index/index.vue +++ b/mobile/pages/index/index.vue @@ -39,7 +39,7 @@ {{ t('home.redeemableCoupons') || '可兑换优惠券' }} - + {{ t('home.guide') }} @@ -56,7 +56,7 @@ 兑换条件: - {{ coupon.requiredPoints }}积分 + {{ coupon.pointsCost ?? 0 }}积分 @@ -122,6 +122,10 @@ async function onEntryClick(entry) { uni.navigateTo({ url: '/pages/membership/membership' }) break case 'stamps': + if (!userStore.isLoggedIn) { + uni.navigateTo({ url: '/pages/login/login' }) + return + } uni.navigateTo({ url: '/pages/stamps/stamps' }) break case 'qrcode': @@ -325,9 +329,9 @@ onMounted(() => { display: flex; align-items: center; } -.guide-icon { - font-size: 28rpx; - color: #999; +.guide-icon-img { + width: 28rpx; + height: 28rpx; margin-right: 6rpx; } .guide-text { diff --git a/mobile/pages/login/login.vue b/mobile/pages/login/login.vue index f82be2e4..902e6e02 100644 --- a/mobile/pages/login/login.vue +++ b/mobile/pages/login/login.vue @@ -1,301 +1,385 @@ + .check-icon { + width: 32rpx; + height: 32rpx; + } + + .agreement-text { + flex: 1; + font-size: 24rpx; + color: #999; + line-height: 1.6; + } + + .agreement-link { + font-size: 24rpx; + color: #c9a96e; + } + \ No newline at end of file diff --git a/mobile/static/ic_back.png b/mobile/static/ic_back.png new file mode 100644 index 00000000..afd31285 Binary files /dev/null and b/mobile/static/ic_back.png differ diff --git a/mobile/static/ic_check.png b/mobile/static/ic_check.png new file mode 100644 index 00000000..ea65f39a Binary files /dev/null and b/mobile/static/ic_check.png differ diff --git a/mobile/static/ic_checked.png b/mobile/static/ic_checked.png new file mode 100644 index 00000000..7189cd57 Binary files /dev/null and b/mobile/static/ic_checked.png differ diff --git a/mobile/static/ic_close.png b/mobile/static/ic_close.png new file mode 100644 index 00000000..34dada16 Binary files /dev/null and b/mobile/static/ic_close.png differ diff --git a/mobile/static/ic_explain.png b/mobile/static/ic_explain.png new file mode 100644 index 00000000..9529f3f9 Binary files /dev/null and b/mobile/static/ic_explain.png differ