diff --git a/backend/src/VendingMachine.Api/Program.cs b/backend/src/VendingMachine.Api/Program.cs index 14da4690..ce4cfa15 100644 --- a/backend/src/VendingMachine.Api/Program.cs +++ b/backend/src/VendingMachine.Api/Program.cs @@ -41,7 +41,13 @@ builder.Services.AddAuthentication(options => builder.Services.AddAuthorization(); // Controllers -builder.Services.AddControllers(); +builder.Services.AddControllers() + .AddJsonOptions(options => + { + // 支持枚举字符串序列化/反序列化 + options.JsonSerializerOptions.Converters.Add(new System.Text.Json.Serialization.JsonStringEnumConverter()); + options.JsonSerializerOptions.PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase; + }); // CORS 配置(支持移动端和管理后台跨域请求) builder.Services.AddCors(options => diff --git a/mobile/i18n/en.js b/mobile/i18n/en.js index 0443dbc9..56b9330d 100644 --- a/mobile/i18n/en.js +++ b/mobile/i18n/en.js @@ -37,6 +37,7 @@ export default { stamps: 'Stamps', qrcode: 'QR Code', guide: 'Guide', + redeemableCoupons: 'Redeemable Coupons', redeemBtn: 'Redeem', redeemSuccess: 'Redeemed successfully', redeemFail: 'Insufficient points', diff --git a/mobile/i18n/zh-CN.js b/mobile/i18n/zh-CN.js index 90e0da4e..15d04495 100644 --- a/mobile/i18n/zh-CN.js +++ b/mobile/i18n/zh-CN.js @@ -37,6 +37,7 @@ export default { stamps: '节日印花', qrcode: '会员二维码', guide: '使用说明', + redeemableCoupons: '可兑换优惠券', redeemBtn: '兑换', redeemSuccess: '兑换成功', redeemFail: '积分不足,无法兑换', diff --git a/mobile/i18n/zh-TW.js b/mobile/i18n/zh-TW.js index e2859a27..76fa2573 100644 --- a/mobile/i18n/zh-TW.js +++ b/mobile/i18n/zh-TW.js @@ -37,6 +37,7 @@ export default { stamps: '節日印花', qrcode: '會員二維碼', guide: '使用說明', + redeemableCoupons: '可兌換優惠券', redeemBtn: '兌換', redeemSuccess: '兌換成功', redeemFail: '積分不足,無法兌換', diff --git a/mobile/pages.json b/mobile/pages.json index 4843f7b3..63936a87 100644 --- a/mobile/pages.json +++ b/mobile/pages.json @@ -76,14 +76,14 @@ { "pagePath": "pages/index/index", "text": "首页", - "iconPath": "static/tab-home.png", - "selectedIconPath": "static/tab-home-active.png" + "iconPath": "static/tab/ic_home.png", + "selectedIconPath": "static/tab/ic_home_s.png" }, { "pagePath": "pages/mine/mine", "text": "我的", - "iconPath": "static/tab-mine.png", - "selectedIconPath": "static/tab-mine-active.png" + "iconPath": "static/tab/ic_me.png", + "selectedIconPath": "static/tab/ic_me_s.png" } ] } diff --git a/mobile/pages/index/index.vue b/mobile/pages/index/index.vue index 2e76de2d..c353788d 100644 --- a/mobile/pages/index/index.vue +++ b/mobile/pages/index/index.vue @@ -1,33 +1,70 @@ @@ -58,7 +92,6 @@ import { getRedeemableCoupons, redeemCoupon } from '../../api/coupon.js' import { useUserStore } from '../../stores/user.js' import { navigateBanner } from '../../utils/navigation.js' import { resolveImageUrl } from '../../utils/image.js' -import CouponCard from '../../components/CouponCard.vue' import RedeemPopup from '../../components/RedeemPopup.vue' import CouponGuidePopup from '../../components/CouponGuidePopup.vue' @@ -77,17 +110,6 @@ const showRedeem = ref(false) const selectedCoupon = ref(null) const showQrcode = ref(false) -// 入口标签映射 -function getEntryLabel(key) { - const map = { - membership: t('home.membership'), - stamps: t('home.stamps'), - qrcode: t('home.qrcode'), - guide: t('home.guide') - } - return map[key] || key -} - // Banner点击导航 function onBannerClick(banner) { navigateBanner(banner) @@ -124,9 +146,7 @@ async function handleQrcodeEntry() { } else { uni.navigateTo({ url: '/pages/membership/membership' }) } - } catch (e) { - // 错误已由请求模块统一处理 - } + } catch (e) {} } // 使用说明入口 @@ -135,9 +155,14 @@ async function handleGuideEntry() { const res = await getCouponGuide() guideContent.value = res.data?.content || res.data || '' showGuide.value = true - } catch (e) { - // 错误已由请求模块统一处理 - } + } catch (e) {} +} + +// 格式化到期时间 +function formatExpire(dateStr) { + if (!dateStr) return '无限制' + const d = new Date(dateStr) + return `${d.getFullYear()}年${d.getMonth() + 1}月${d.getDate()}日` } // 点击兑换按钮 @@ -154,11 +179,9 @@ async function onRedeemConfirm() { showRedeem.value = false selectedCoupon.value = null uni.showToast({ title: t('home.redeemSuccess'), icon: 'none' }) - // 刷新优惠券列表 await loadCoupons() } catch (e) { showRedeem.value = false - // 错误提示已由请求模块统一处理(积分不足、已下架等由后端message返回) } } @@ -167,21 +190,21 @@ async function loadBanners() { try { const res = await getBanners() banners.value = res.data || [] - } catch (e) { /* 错误已统一处理 */ } + } catch (e) {} } async function loadEntries() { try { const res = await getEntries() entries.value = res.data || [] - } catch (e) { /* 错误已统一处理 */ } + } catch (e) {} } async function loadCoupons() { try { const res = await getRedeemableCoupons() coupons.value = res.data || [] - } catch (e) { /* 错误已统一处理 */ } + } catch (e) {} } onMounted(() => { @@ -194,47 +217,183 @@ onMounted(() => { diff --git a/mobile/static/ic_qrcode.png b/mobile/static/ic_qrcode.png new file mode 100644 index 00000000..a7e9bb94 Binary files /dev/null and b/mobile/static/ic_qrcode.png differ diff --git a/mobile/static/ic_stamp.png b/mobile/static/ic_stamp.png new file mode 100644 index 00000000..58b6bc29 Binary files /dev/null and b/mobile/static/ic_stamp.png differ diff --git a/mobile/static/ic_vip.png b/mobile/static/ic_vip.png new file mode 100644 index 00000000..6fbb5088 Binary files /dev/null and b/mobile/static/ic_vip.png differ diff --git a/mobile/static/tab/ic_home.png b/mobile/static/tab/ic_home.png new file mode 100644 index 00000000..4bd3b208 Binary files /dev/null and b/mobile/static/tab/ic_home.png differ diff --git a/mobile/static/tab/ic_home_s.png b/mobile/static/tab/ic_home_s.png new file mode 100644 index 00000000..a2212913 Binary files /dev/null and b/mobile/static/tab/ic_home_s.png differ diff --git a/mobile/static/tab/ic_me.png b/mobile/static/tab/ic_me.png new file mode 100644 index 00000000..c074e5bf Binary files /dev/null and b/mobile/static/tab/ic_me.png differ diff --git a/mobile/static/tab/ic_me_s.png b/mobile/static/tab/ic_me_s.png new file mode 100644 index 00000000..c85a9895 Binary files /dev/null and b/mobile/static/tab/ic_me_s.png differ