细节修改

This commit is contained in:
18631081161 2026-04-08 21:03:13 +08:00
parent 2f4c27834a
commit bf989067c1
7 changed files with 29 additions and 7 deletions

View File

@ -77,7 +77,12 @@ if (app.Environment.IsDevelopment())
} }
app.UseStaticFiles(); // 提供 wwwroot 下的静态文件(上传的图片等) app.UseStaticFiles(); // 提供 wwwroot 下的静态文件(上传的图片等)
app.UseHttpsRedirection();
// 仅在非开发环境启用HTTPS重定向避免本地调试时请求被重定向导致连接失败
if (!app.Environment.IsDevelopment())
{
app.UseHttpsRedirection();
}
app.UseCors(); app.UseCors();
app.UseMiddleware<ExceptionHandlingMiddleware>(); app.UseMiddleware<ExceptionHandlingMiddleware>();
app.UseMiddleware<LanguageMiddleware>(); app.UseMiddleware<LanguageMiddleware>();

View File

@ -5,7 +5,7 @@
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": true, "dotnetRunMessages": true,
"launchBrowser": false, "launchBrowser": false,
"applicationUrl": "http://localhost:5082", "applicationUrl": "http://0.0.0.0:5082",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
} }

View File

@ -1,7 +1,8 @@
import { getStorage, removeStorage, TOKEN_KEY, LOCALE_KEY } from '../utils/storage.js' import { getStorage, removeStorage, TOKEN_KEY, LOCALE_KEY } from '../utils/storage.js'
// 后端API基础地址 // 后端API基础地址
export const BASE_URL = 'https://api.vendingmachine.com' // MuMu模拟器需使用宿主机局域网IP生产环境替换为正式域名
export const BASE_URL = 'http://192.168.21.7:5082'
/** /**
* 统一请求封装自动注入Token和语言请求头统一处理响应和错误 * 统一请求封装自动注入Token和语言请求头统一处理响应和错误

View File

@ -3,7 +3,7 @@
<!-- Banner轮播图 --> <!-- Banner轮播图 -->
<swiper class="banner-swiper" autoplay circular indicator-dots> <swiper class="banner-swiper" autoplay circular indicator-dots>
<swiper-item v-for="banner in banners" :key="banner.id" @click="onBannerClick(banner)"> <swiper-item v-for="banner in banners" :key="banner.id" @click="onBannerClick(banner)">
<image class="banner-image" :src="banner.imageUrl" mode="aspectFill" /> <image class="banner-image" :src="resolveImageUrl(banner.imageUrl)" mode="aspectFill" />
</swiper-item> </swiper-item>
</swiper> </swiper>
@ -15,7 +15,7 @@
class="entry-item" class="entry-item"
@click="onEntryClick(entry)" @click="onEntryClick(entry)"
> >
<image class="entry-image" :src="entry.imageUrl" mode="aspectFit" /> <image class="entry-image" :src="resolveImageUrl(entry.imageUrl)" mode="aspectFit" />
<text class="entry-label">{{ getEntryLabel(entry.key) }}</text> <text class="entry-label">{{ getEntryLabel(entry.key) }}</text>
</view> </view>
</view> </view>
@ -57,6 +57,7 @@ import { getBanners, getEntries, getCouponGuide } from '../../api/content.js'
import { getRedeemableCoupons, redeemCoupon } from '../../api/coupon.js' import { getRedeemableCoupons, redeemCoupon } from '../../api/coupon.js'
import { useUserStore } from '../../stores/user.js' import { useUserStore } from '../../stores/user.js'
import { navigateBanner } from '../../utils/navigation.js' import { navigateBanner } from '../../utils/navigation.js'
import { resolveImageUrl } from '../../utils/image.js'
import CouponCard from '../../components/CouponCard.vue' import CouponCard from '../../components/CouponCard.vue'
import RedeemPopup from '../../components/RedeemPopup.vue' import RedeemPopup from '../../components/RedeemPopup.vue'
import CouponGuidePopup from '../../components/CouponGuidePopup.vue' import CouponGuidePopup from '../../components/CouponGuidePopup.vue'

View File

@ -66,6 +66,7 @@ import { ref, computed, onMounted } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useMembershipStore } from '../../stores/membership.js' import { useMembershipStore } from '../../stores/membership.js'
import { getMembershipBanner } from '../../api/content.js' import { getMembershipBanner } from '../../api/content.js'
import { resolveImageUrl } from '../../utils/image.js'
const { t } = useI18n() const { t } = useI18n()
const membershipStore = useMembershipStore() const membershipStore = useMembershipStore()
@ -123,7 +124,7 @@ async function onSubscribe(product) {
async function loadData() { async function loadData() {
try { try {
const res = await getMembershipBanner() const res = await getMembershipBanner()
bannerUrl.value = res.data?.imageUrl || res.data || '' bannerUrl.value = resolveImageUrl(res.data?.imageUrl || res.data || '')
} catch (e) { /* 错误已统一处理 */ } } catch (e) { /* 错误已统一处理 */ }
try { try {

View File

@ -45,6 +45,7 @@
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { getStampBanner } from '../../api/content.js' import { getStampBanner } from '../../api/content.js'
import { resolveImageUrl } from '../../utils/image.js'
import { getStampCoupons, redeemStampCoupon } from '../../api/coupon.js' import { getStampCoupons, redeemStampCoupon } from '../../api/coupon.js'
import { useUserStore } from '../../stores/user.js' import { useUserStore } from '../../stores/user.js'
import { resolveStampRedeemButton } from '../../utils/stamps.js' import { resolveStampRedeemButton } from '../../utils/stamps.js'
@ -110,7 +111,7 @@ async function onRedeemConfirm() {
async function loadBanner() { async function loadBanner() {
try { try {
const res = await getStampBanner() const res = await getStampBanner()
bannerUrl.value = res.data?.imageUrl || res.data || '' bannerUrl.value = resolveImageUrl(res.data?.imageUrl || res.data || '')
} catch (e) { /* 错误已统一处理 */ } } catch (e) { /* 错误已统一处理 */ }
} }

13
mobile/utils/image.js Normal file
View File

@ -0,0 +1,13 @@
import { BASE_URL } from '../api/request.js'
/**
* 将后端返回的相对路径图片URL转换为完整URL
* 如果已经是完整URLhttp/https开头则直接返回
* @param {string} url - 图片路径
* @returns {string} 完整的图片URL
*/
export function resolveImageUrl(url) {
if (!url) return ''
if (url.startsWith('http://') || url.startsWith('https://')) return url
return `${BASE_URL}${url}`
}