feat(image): 全项目应用图片压缩优化

- 将图片显示统一替换为 getCompressedImageUrl 函数处理压缩
- 覆盖 35 个文件,包括 4 个组件和 31 个页面
- 主要组件:LazyImage、ProductCard、OrderCard、SkuSelector 内部自动压缩图片
- 主要页面:购物车、订单、积分、活动、拼团、秒杀、收藏、浏览历史等
- 跳过用户头像、二维码、商品详情大图及所有 Taro.previewImage 调用
- 调整压缩默认宽度为 300,保持质量90,启用压缩功能
This commit is contained in:
2026-07-06 12:21:39 +08:00
parent c3dd04fa03
commit 082646a613
41 changed files with 95 additions and 50 deletions

View File

@@ -87,3 +87,9 @@
- **默认参数**: `width=750, quality=90, enabled=true` - **默认参数**: `width=750, quality=90, enabled=true`
- **安全处理**: 空 URL 返回空串、已含 `x-oss-process` 不重复拼接、根据已有 query 参数自动选 `?`/`&` 分隔符 - **安全处理**: 空 URL 返回空串、已含 `x-oss-process` 不重复拼接、根据已有 query 参数自动选 `?`/`&` 分隔符
- **使用约定**: 列表/卡片等缩略图场景使用此函数;预览大图(`Taro.previewImage`)直接用原 URL不调用此函数 - **使用约定**: 列表/卡片等缩略图场景使用此函数;预览大图(`Taro.previewImage`)直接用原 URL不调用此函数
## 全项目应用 getCompressedImageUrl
- **修改范围**: 35 个文件4 个组件 + 31 个页面文件)
- **组件**: LazyImage、ProductCard、OrderCard、SkuSelector — 组件内部自动压缩
- **页面**: shop/cart/checkout/category/index/seckill-list/group-buy-list/group-buy-detail, order/detail/evaluate/evaluate-detail/after-sale-*, order-list, user/favorite-list/history-list/benefit-*, points/*, store/goods/orders, index/index/article-list, activity/event/*, group-buy-list/detail, seckill-list/detail, history-list, favorite-list
- **跳过(不压缩)**: 头像(user/user, user/member, user/profile, user/index, user/team, store/center)、二维码(share, user/promotion)、商品详情大图/轮播(shop/product-detail, shop/seckill-detail)、所有 Taro.previewImage 调用

View File

@@ -5,6 +5,7 @@ import type { ShopGoods, ShopGoodsSku } from '@/api/shop/shopGoods/model'
import type { ShopGoodsSpec } from '@/api/shop/shopGoodsSpec/model' import type { ShopGoodsSpec } from '@/api/shop/shopGoodsSpec/model'
import Price from '@/components/common/Price' import Price from '@/components/common/Price'
import { isVipMember } from '@/utils/vip' import { isVipMember } from '@/utils/vip'
import { getCompressedImageUrl } from '@/utils/image'
interface SkuSelectorProps { interface SkuSelectorProps {
visible: boolean visible: boolean
@@ -256,7 +257,7 @@ const SkuSelector: React.FC<SkuSelectorProps> = ({
{/* 商品信息 */} {/* 商品信息 */}
<View className='flex gap-3 pb-4 border-b border-gray-100'> <View className='flex gap-3 pb-4 border-b border-gray-100'>
<Image className='w-20 h-20 rounded-md bg-gray-100' src={currentImage} mode='aspectFill' /> <Image className='w-20 h-20 rounded-md bg-gray-100' src={getCompressedImageUrl(currentImage)} mode='aspectFill' />
<View className='flex-1'> <View className='flex-1'>
<Price price={currentPrice} size='large' /> <Price price={currentPrice} size='large' />
<Text className='text-xs text-gray-500 block' style={{ marginTop: '4px' }}>: {currentStock}</Text> <Text className='text-xs text-gray-500 block' style={{ marginTop: '4px' }}>: {currentStock}</Text>

View File

@@ -1,6 +1,7 @@
import { View, Image, Text } from '@tarojs/components'; import { View, Image, Text } from '@tarojs/components';
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { useIntersectionObserver } from '@tarojs/taro'; import { useIntersectionObserver } from '@tarojs/taro';
import { getCompressedImageUrl } from '@/utils/image';
interface LazyImageProps { interface LazyImageProps {
src: string; src: string;
@@ -46,7 +47,7 @@ export default function LazyImage({ src, placeholder, className, style, mode = '
)} )}
{(inView || loaded) && ( {(inView || loaded) && (
<Image <Image
src={src} src={getCompressedImageUrl(src)}
className={`w-full h-full ${loaded ? 'block' : 'hidden'}`} className={`w-full h-full ${loaded ? 'block' : 'hidden'}`}
mode={mode} mode={mode}
onLoad={() => setLoaded(true)} onLoad={() => setLoaded(true)}

View File

@@ -3,6 +3,7 @@ import { View, Text, Image } from '@tarojs/components'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import type { ShopOrder } from '@/api/shop/shopOrder/model' import type { ShopOrder } from '@/api/shop/shopOrder/model'
import Price from '../Price' import Price from '../Price'
import { getCompressedImageUrl } from '@/utils/image'
interface OrderCardProps { interface OrderCardProps {
order: ShopOrder order: ShopOrder
@@ -67,7 +68,7 @@ const OrderCard: React.FC<OrderCardProps> = ({ order, onClick }) => {
{item.image ? ( {item.image ? (
<Image <Image
className='w-full h-full' className='w-full h-full'
src={item.image} src={getCompressedImageUrl(item.image)}
mode='aspectFill' mode='aspectFill'
/> />
) : ( ) : (
@@ -104,7 +105,7 @@ const OrderCard: React.FC<OrderCardProps> = ({ order, onClick }) => {
<View className='flex flex-row items-start mb-3'> <View className='flex flex-row items-start mb-3'>
<View className='w-16 h-16 rounded-md bg-gray-100 flex-shrink-0 flex items-center justify-center overflow-hidden'> <View className='w-16 h-16 rounded-md bg-gray-100 flex-shrink-0 flex items-center justify-center overflow-hidden'>
{coverImage ? ( {coverImage ? (
<Image className='w-full h-full' src={coverImage} mode='aspectFill' /> <Image className='w-full h-full' src={getCompressedImageUrl(coverImage)} mode='aspectFill' />
) : ( ) : (
<Text className='text-xs text-gray-400'></Text> <Text className='text-xs text-gray-400'></Text>
)} )}

View File

@@ -4,6 +4,7 @@ import Taro from '@tarojs/taro'
import Price from '../Price' import Price from '../Price'
import { isGuest } from '@/utils/auth' import { isGuest } from '@/utils/auth'
import { isVipMember } from '@/utils/vip' import { isVipMember } from '@/utils/vip'
import { getCompressedImageUrl } from '@/utils/image'
import type { ShopGoods } from '@/api/shop/shopGoods/model' import type { ShopGoods } from '@/api/shop/shopGoods/model'
interface ProductCardProps { interface ProductCardProps {
@@ -25,7 +26,7 @@ const ProductCard: React.FC<ProductCardProps> = ({ product, onClick }) => {
<View className='w-full' style={{ paddingTop: '100%', position: 'relative' }}> <View className='w-full' style={{ paddingTop: '100%', position: 'relative' }}>
<Image <Image
className='absolute top-0 left-0 w-full h-full' className='absolute top-0 left-0 w-full h-full'
src={product.image || product.files || ''} src={getCompressedImageUrl(product.image || product.files || '')}
mode='aspectFit' mode='aspectFit'
lazyLoad lazyLoad
style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%' }} style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%' }}

View File

@@ -3,6 +3,7 @@ import { View, Text, ScrollView, Image } from '@tarojs/components'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import { getShopActivity, signUpActivity, cancelSignUpActivity, getSignUpStatus } from '@/api/shop/shopActivity' import { getShopActivity, signUpActivity, cancelSignUpActivity, getSignUpStatus } from '@/api/shop/shopActivity'
import type { ShopActivity, ActivityStatus } from '@/api/shop/shopActivity/model' import type { ShopActivity, ActivityStatus } from '@/api/shop/shopActivity/model'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '活动详情', navigationBarTitleText: '活动详情',
@@ -137,7 +138,7 @@ const ActivityDetailPage: React.FC = () => {
<ScrollView scrollY className='flex-1'> <ScrollView scrollY className='flex-1'>
{/* 活动头图 */} {/* 活动头图 */}
{activity.image ? ( {activity.image ? (
<Image src={activity.image} className='w-full' style={{ height: '192px' }} mode='aspectFill' /> <Image src={getCompressedImageUrl(activity.image)} className='w-full' style={{ height: '192px' }} mode='aspectFill' />
) : ( ) : (
<View className='w-full flex items-center justify-center' style={{ height: '192px', background: 'linear-gradient(to right, #fb923c, #ef4444)' }}> <View className='w-full flex items-center justify-center' style={{ height: '192px', background: 'linear-gradient(to right, #fb923c, #ef4444)' }}>
<Text className='text-6xl'>🎉</Text> <Text className='text-6xl'>🎉</Text>

View File

@@ -3,6 +3,7 @@ import { View, Text, ScrollView, Image } from '@tarojs/components'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import { getShopEvent, getRegistrationStatus, getEventStatusLabel } from '@/api/shop/shopEvent' import { getShopEvent, getRegistrationStatus, getEventStatusLabel } from '@/api/shop/shopEvent'
import type { ShopEvent, RegistrationStatus, EventFormField } from '@/api/shop/shopEvent' import type { ShopEvent, RegistrationStatus, EventFormField } from '@/api/shop/shopEvent'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ navigationBarTitleText: '赛事详情' }) definePageConfig({ navigationBarTitleText: '赛事详情' })
@@ -85,7 +86,7 @@ const EventDetailPage: React.FC = () => {
<ScrollView scrollY className='flex-1'> <ScrollView scrollY className='flex-1'>
{/* 封面 */} {/* 封面 */}
{event.image ? ( {event.image ? (
<Image src={event.image} className='w-full' style={{ height: '200px' }} mode='aspectFill' /> <Image src={getCompressedImageUrl(event.image)} className='w-full' style={{ height: '200px' }} mode='aspectFill' />
) : ( ) : (
<View className='w-full flex items-center justify-center' style={{ height: '200px', background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }}> <View className='w-full flex items-center justify-center' style={{ height: '200px', background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }}>
<Text className='text-6xl'>🏆</Text> <Text className='text-6xl'>🏆</Text>

View File

@@ -5,6 +5,7 @@ import { pageShopEvent, getEventStatusLabel } from '@/api/shop/shopEvent'
import type { ShopEvent } from '@/api/shop/shopEvent' import type { ShopEvent } from '@/api/shop/shopEvent'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import LoadMore from '@/components/common/LoadMore' import LoadMore from '@/components/common/LoadMore'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ navigationBarTitleText: '赛事报名' }) definePageConfig({ navigationBarTitleText: '赛事报名' })
@@ -84,7 +85,7 @@ const EventListPage: React.FC = () => {
> >
{/* 封面 */} {/* 封面 */}
{event.image ? ( {event.image ? (
<Image src={event.image} className='w-full' style={{ height: '160px' }} mode='aspectFill' /> <Image src={getCompressedImageUrl(event.image)} className='w-full' style={{ height: '160px' }} mode='aspectFill' />
) : ( ) : (
<View className='w-full flex items-center justify-center' style={{ height: '140px', background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }}> <View className='w-full flex items-center justify-center' style={{ height: '140px', background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }}>
<Text className='text-5xl'>🏆</Text> <Text className='text-5xl'>🏆</Text>

View File

@@ -5,6 +5,7 @@ import { listShopGoodsFavorite } from '@/api/shop/shopGoodsFavorite'
import type { ShopGoodsFavorite } from '@/api/shop/shopGoodsFavorite/model' import type { ShopGoodsFavorite } from '@/api/shop/shopGoodsFavorite/model'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import LoadMore from '@/components/common/LoadMore' import LoadMore from '@/components/common/LoadMore'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '我的收藏', navigationBarTitleText: '我的收藏',
@@ -69,7 +70,7 @@ const FavoriteListPage: React.FC = () => {
<Image <Image
className='w-full' className='w-full'
style={{ height: '160px' }} style={{ height: '160px' }}
src={item.goodsImage} src={getCompressedImageUrl(item.goodsImage)}
mode='aspectFill' mode='aspectFill'
/> />
<View className='p-2'> <View className='p-2'>

View File

@@ -7,6 +7,7 @@ import type { ShopGroupBuy, ShopGroupBuyRecord } from '@/api/shop/shopGroupBuy/m
import type { ShopGoods } from '@/api/shop/shopGoods/model' import type { ShopGoods } from '@/api/shop/shopGoods/model'
import type { ShopGoodsSku } from '@/api/shop/shopGoodsSku/model' import type { ShopGoodsSku } from '@/api/shop/shopGoodsSku/model'
import SkuSelector from '@/components/business/SkuSelector' import SkuSelector from '@/components/business/SkuSelector'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '拼团详情', navigationBarTitleText: '拼团详情',
@@ -184,7 +185,7 @@ const GroupBuyDetailPage: React.FC = () => {
<View className="bg-white p-4 flex gap-3"> <View className="bg-white p-4 flex gap-3">
<Image <Image
className="w-24 h-24 rounded-md bg-gray-100" className="w-24 h-24 rounded-md bg-gray-100"
src={groupBuy.goodsImage || groupBuy.product?.image || ''} src={getCompressedImageUrl(groupBuy.goodsImage || groupBuy.product?.image || '')}
mode="aspectFill" mode="aspectFill"
/> />
<View className="flex-1 flex flex-col justify-between"> <View className="flex-1 flex flex-col justify-between">

View File

@@ -4,6 +4,7 @@ import Taro from '@tarojs/taro'
import { pageShopGroupBuy } from '@/api/shop/shopGroupBuy' import { pageShopGroupBuy } from '@/api/shop/shopGroupBuy'
import type { ShopGroupBuy } from '@/api/shop/shopGroupBuy/model' import type { ShopGroupBuy } from '@/api/shop/shopGroupBuy/model'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '拼团活动', navigationBarTitleText: '拼团活动',
@@ -72,7 +73,7 @@ const GroupBuyListPage: React.FC = () => {
> >
<Image <Image
className='w-24 h-24 rounded-md bg-gray-100 flex-shrink-0' className='w-24 h-24 rounded-md bg-gray-100 flex-shrink-0'
src={item.goodsImage || item.product?.image || ''} src={getCompressedImageUrl(item.goodsImage || item.product?.image || '')}
mode='aspectFill' mode='aspectFill'
/> />
<View className='flex-1 flex flex-col justify-between'> <View className='flex-1 flex flex-col justify-between'>

View File

@@ -3,6 +3,7 @@ import { View, Text, Image, ScrollView } from '@tarojs/components'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import LoadMore from '@/components/common/LoadMore' import LoadMore from '@/components/common/LoadMore'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '浏览历史', navigationBarTitleText: '浏览历史',
@@ -82,7 +83,7 @@ const BrowseHistoryPage: React.FC = () => {
<Image <Image
className='w-full' className='w-full'
style={{ height: '160px' }} style={{ height: '160px' }}
src={item.image} src={getCompressedImageUrl(item.image || '')}
mode='aspectFill' mode='aspectFill'
/> />
<View className='p-2'> <View className='p-2'>

View File

@@ -5,6 +5,7 @@ import { listCmsArticle } from '@/api/cms/cmsArticle'
import type { CmsArticle } from '@/api/cms/cmsArticle/model' import type { CmsArticle } from '@/api/cms/cmsArticle/model'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import { useScrollHeight } from '@/hooks/useScrollHeight' import { useScrollHeight } from '@/hooks/useScrollHeight'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '活动列表', navigationBarTitleText: '活动列表',
@@ -83,7 +84,7 @@ const ArticleListPage: React.FC = () => {
{item.coverImage && ( {item.coverImage && (
<Image <Image
className='w-full' className='w-full'
src={item.coverImage} src={getCompressedImageUrl(item.coverImage)}
mode='aspectFill' mode='aspectFill'
style={{ height: '160px' }} style={{ height: '160px' }}
/> />

View File

@@ -10,6 +10,7 @@ import type { CmsAd } from '@/api/cms/cmsAd/model'
import type { CmsArticle } from '@/api/cms/cmsArticle/model' import type { CmsArticle } from '@/api/cms/cmsArticle/model'
import type { ShopGoods } from '@/api/shop/shopGoods/model' import type { ShopGoods } from '@/api/shop/shopGoods/model'
import Price from '@/components/common/Price' import Price from '@/components/common/Price'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '首页', navigationBarTitleText: '首页',
@@ -131,7 +132,7 @@ const IndexPage: React.FC = () => {
<SwiperItem key={item.adId}> <SwiperItem key={item.adId}>
<Image <Image
className='w-full h-full' className='w-full h-full'
src={item.imageList?.[0]?.url || item.image || ''} src={getCompressedImageUrl(item.imageList?.[0]?.url || item.image || '', { width: 750, quality: 90})}
mode='aspectFill' mode='aspectFill'
onClick={() => { onClick={() => {
if (item.path) Taro.navigateTo({ url: item.path }) if (item.path) Taro.navigateTo({ url: item.path })
@@ -230,7 +231,7 @@ const IndexPage: React.FC = () => {
{item.image ? ( {item.image ? (
<Image <Image
style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%' }} style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%' }}
src={item.image} src={getCompressedImageUrl(item.image)}
mode='aspectFill' mode='aspectFill'
/> />
) : ( ) : (

View File

@@ -5,6 +5,7 @@ import { listShopPointsOrder, cancelShopPointsOrder } from '@/api/shop/shopPoint
import type { ShopPointsOrder, PointsOrderStatus } from '@/api/shop/shopPointsOrder' import type { ShopPointsOrder, PointsOrderStatus } from '@/api/shop/shopPointsOrder'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import LoadMore from '@/components/common/LoadMore' import LoadMore from '@/components/common/LoadMore'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '积分订单', navigationBarTitleText: '积分订单',
@@ -161,7 +162,7 @@ const PointsOrderListPage: React.FC = () => {
<View key={idx} className='flex items-center gap-2 mb-2'> <View key={idx} className='flex items-center gap-2 mb-2'>
<View className='w-12 h-12 bg-gray-100 rounded-lg flex items-center justify-center flex-shrink-0'> <View className='w-12 h-12 bg-gray-100 rounded-lg flex items-center justify-center flex-shrink-0'>
<Image <Image
src={item.goodsImage} src={getCompressedImageUrl(item.goodsImage)}
className='w-10 h-10 rounded' className='w-10 h-10 rounded'
mode='aspectFill' mode='aspectFill'
/> />

View File

@@ -5,6 +5,7 @@ import { Button, Uploader } from '@nutui/nutui-react-taro'
import { getShopOrder } from '@/api/shop/shopOrder' import { getShopOrder } from '@/api/shop/shopOrder'
import type { ShopOrder } from '@/api/shop/shopOrder/model' import type { ShopOrder } from '@/api/shop/shopOrder/model'
import Price from '@/components/common/Price' import Price from '@/components/common/Price'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '申请售后', navigationBarTitleText: '申请售后',
@@ -243,7 +244,7 @@ const AfterSaleApplyPage: React.FC = () => {
{/* 商品图片 */} {/* 商品图片 */}
<Image <Image
className='w-16 h-16 rounded-lg' className='w-16 h-16 rounded-lg'
src={item.image || ''} src={getCompressedImageUrl(item.image || '')}
mode='aspectFill' mode='aspectFill'
/> />

View File

@@ -5,6 +5,7 @@ import { Button } from '@nutui/nutui-react-taro'
import { getAfterSaleDetail, cancelAfterSale, formatAfterSaleStatus, AFTER_SALE_TYPE_MAP } from '@/api/shop/shopAfterSale' import { getAfterSaleDetail, cancelAfterSale, formatAfterSaleStatus, AFTER_SALE_TYPE_MAP } from '@/api/shop/shopAfterSale'
import type { AfterSaleDetail } from '@/api/shop/shopAfterSale' import type { AfterSaleDetail } from '@/api/shop/shopAfterSale'
import Price from '@/components/common/Price' import Price from '@/components/common/Price'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '售后详情', navigationBarTitleText: '售后详情',
@@ -214,7 +215,7 @@ const AfterSaleDetailPage: React.FC = () => {
<Image <Image
key={idx} key={idx}
className='w-20 h-20 rounded-lg' className='w-20 h-20 rounded-lg'
src={url} src={getCompressedImageUrl(url)}
mode='aspectFill' mode='aspectFill'
/> />
))} ))}

View File

@@ -7,6 +7,7 @@ import { listShopOrderGoodsByOrderId } from '@/api/shop/shopOrderGoods'
import type { ShopOrder } from '@/api/shop/shopOrder/model' import type { ShopOrder } from '@/api/shop/shopOrder/model'
import { OrderStatus, OrderStatusText } from '@/types/order' import { OrderStatus, OrderStatusText } from '@/types/order'
import Price from '@/components/common/Price' import Price from '@/components/common/Price'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '订单详情', navigationBarTitleText: '订单详情',
@@ -301,7 +302,7 @@ const OrderDetailPage: React.FC = () => {
> >
<View className='w-16 h-16 rounded-md bg-gray-100 flex-shrink-0 overflow-hidden'> <View className='w-16 h-16 rounded-md bg-gray-100 flex-shrink-0 overflow-hidden'>
{item.image ? ( {item.image ? (
<Image className='w-full h-full' src={item.image} mode='aspectFill' /> <Image className='w-full h-full' src={getCompressedImageUrl(item.image)} mode='aspectFill' />
) : ( ) : (
<View className='w-full h-full flex items-center justify-center'> <View className='w-full h-full flex items-center justify-center'>
<Text className='text-xs text-gray-400'></Text> <Text className='text-xs text-gray-400'></Text>

View File

@@ -3,6 +3,7 @@ import { View, Text, ScrollView, Image } from '@tarojs/components'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import { getShopEvaluation, likeShopEvaluation } from '@/api/shop/shopEvaluation' import { getShopEvaluation, likeShopEvaluation } from '@/api/shop/shopEvaluation'
import type { ShopEvaluation } from '@/api/shop/shopEvaluation/model' import type { ShopEvaluation } from '@/api/shop/shopEvaluation/model'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '评价详情', navigationBarTitleText: '评价详情',
@@ -110,7 +111,7 @@ const EvaluateDetailPage: React.FC = () => {
<View className='flex items-center gap-2'> <View className='flex items-center gap-2'>
<View className='w-12 h-12 bg-gray-100 rounded-lg flex items-center justify-center flex-shrink-0 overflow-hidden'> <View className='w-12 h-12 bg-gray-100 rounded-lg flex items-center justify-center flex-shrink-0 overflow-hidden'>
{evaluation.goodsImage ? ( {evaluation.goodsImage ? (
<Image src={evaluation.goodsImage} className='w-12 h-12' mode='aspectFill' /> <Image src={getCompressedImageUrl(evaluation.goodsImage)} className='w-12 h-12' mode='aspectFill' />
) : ( ) : (
<Text className='text-2xl'>🛍</Text> <Text className='text-2xl'>🛍</Text>
)} )}
@@ -138,7 +139,7 @@ const EvaluateDetailPage: React.FC = () => {
className='w-24 h-24 bg-gray-100 rounded-lg overflow-hidden' className='w-24 h-24 bg-gray-100 rounded-lg overflow-hidden'
onClick={() => handleImagePreview(index)} onClick={() => handleImagePreview(index)}
> >
<Image src={img} className='w-24 h-24' mode='aspectFill' /> <Image src={getCompressedImageUrl(img)} className='w-24 h-24' mode='aspectFill' />
</View> </View>
))} ))}
</View> </View>

View File

@@ -4,6 +4,7 @@ import Taro from '@tarojs/taro'
import { Button } from '@nutui/nutui-react-taro' import { Button } from '@nutui/nutui-react-taro'
import { useUser } from '@/hooks/useUser' import { useUser } from '@/hooks/useUser'
import { submitGoodsComment } from '@/api/shop/shopGoodsComment' import { submitGoodsComment } from '@/api/shop/shopGoodsComment'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '商品评价', navigationBarTitleText: '商品评价',
@@ -124,7 +125,7 @@ const EvaluatePage: React.FC = () => {
{images.map((img, idx) => ( {images.map((img, idx) => (
<View key={idx} className='relative'> <View key={idx} className='relative'>
<Image <Image
src={img} src={getCompressedImageUrl(img)}
className='w-20 h-20 rounded-lg' className='w-20 h-20 rounded-lg'
mode='aspectFill' mode='aspectFill'
/> />

View File

@@ -4,6 +4,7 @@ import Taro from '@tarojs/taro'
import { Button } from '@nutui/nutui-react-taro' import { Button } from '@nutui/nutui-react-taro'
import { useUser } from '@/hooks/useUser' import { useUser } from '@/hooks/useUser'
import { submitGoodsComment } from '@/api/shop/shopGoodsComment' import { submitGoodsComment } from '@/api/shop/shopGoodsComment'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '商品评价', navigationBarTitleText: '商品评价',
@@ -124,7 +125,7 @@ const EvaluatePage: React.FC = () => {
{images.map((img, idx) => ( {images.map((img, idx) => (
<View key={idx} className='relative'> <View key={idx} className='relative'>
<Image <Image
src={img} src={getCompressedImageUrl(img)}
className='w-20 h-20 rounded-lg' className='w-20 h-20 rounded-lg'
mode='aspectFill' mode='aspectFill'
/> />

View File

@@ -6,6 +6,7 @@ import { pageShopPointsProduct } from '@/api/shop/shopPointsProduct'
import type { ShopPointsProduct } from '@/api/shop/shopPointsProduct/model' import type { ShopPointsProduct } from '@/api/shop/shopPointsProduct/model'
import { getUserPointsInfo, type UserPointsInfo } from '@/api/system/user/points' import { getUserPointsInfo, type UserPointsInfo } from '@/api/system/user/points'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import { getCompressedImageUrl } from '@/utils/image'
const PointsPage: React.FC = () => { const PointsPage: React.FC = () => {
const { user } = useUser() const { user } = useUser()
@@ -81,7 +82,7 @@ const PointsPage: React.FC = () => {
> >
<View className='w-full aspect-square bg-orange-50 flex items-center justify-center overflow-hidden'> <View className='w-full aspect-square bg-orange-50 flex items-center justify-center overflow-hidden'>
{item.productImage ? ( {item.productImage ? (
<Image src={item.productImage} className='w-full h-full' mode='aspectFill' /> <Image src={getCompressedImageUrl(item.productImage)} className='w-full h-full' mode='aspectFill' />
) : ( ) : (
<Text className='text-xs text-gray-300'></Text> <Text className='text-xs text-gray-300'></Text>
)} )}

View File

@@ -5,6 +5,7 @@ import { listShopPointsOrder, cancelShopPointsOrder } from '@/api/shop/shopPoint
import type { ShopPointsOrder, PointsOrderStatus } from '@/api/shop/shopPointsOrder' import type { ShopPointsOrder, PointsOrderStatus } from '@/api/shop/shopPointsOrder'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import LoadMore from '@/components/common/LoadMore' import LoadMore from '@/components/common/LoadMore'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '积分订单', navigationBarTitleText: '积分订单',
@@ -163,7 +164,7 @@ const PointsOrderListPage: React.FC = () => {
<View key={idx} className='flex items-center gap-2 mb-2'> <View key={idx} className='flex items-center gap-2 mb-2'>
<View className='w-12 h-12 bg-gray-100 rounded-lg flex items-center justify-center flex-shrink-0'> <View className='w-12 h-12 bg-gray-100 rounded-lg flex items-center justify-center flex-shrink-0'>
<Image <Image
src={item.goodsImage} src={getCompressedImageUrl(item.goodsImage)}
className='w-10 h-10 rounded' className='w-10 h-10 rounded'
mode='aspectFill' mode='aspectFill'
/> />

View File

@@ -4,6 +4,7 @@ import Taro, { useRouter, useShareAppMessage } from '@tarojs/taro'
import { getShopPointsProduct } from '@/api/shop/shopPointsProduct' import { getShopPointsProduct } from '@/api/shop/shopPointsProduct'
import type { ShopPointsProduct } from '@/api/shop/shopPointsProduct/model' import type { ShopPointsProduct } from '@/api/shop/shopPointsProduct/model'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '积分商品', navigationBarTitleText: '积分商品',
@@ -95,7 +96,7 @@ const PointsProductDetail: React.FC = () => {
<Image <Image
className='w-full' className='w-full'
style={{ height: '375px' }} style={{ height: '375px' }}
src={product.productImage} src={getCompressedImageUrl(product.productImage)}
mode='aspectFill' mode='aspectFill'
onClick={() => Taro.previewImage({ current: product.productImage, urls: [product.productImage!] })} onClick={() => Taro.previewImage({ current: product.productImage, urls: [product.productImage!] })}
/> />

View File

@@ -5,6 +5,7 @@ import { listShopPointsProduct, pageShopPointsProduct } from '@/api/shop/shopPoi
import type { ShopPointsProduct } from '@/api/shop/shopPointsProduct/model' import type { ShopPointsProduct } from '@/api/shop/shopPointsProduct/model'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import LoadMore from '@/components/common/LoadMore' import LoadMore from '@/components/common/LoadMore'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '积分商城', navigationBarTitleText: '积分商城',
@@ -106,7 +107,7 @@ const PointsProductListPage: React.FC = () => {
<View className='w-full aspect-square bg-orange-50 relative'> <View className='w-full aspect-square bg-orange-50 relative'>
<Image <Image
className='w-full h-full' className='w-full h-full'
src={product.productImage || ''} src={getCompressedImageUrl(product.productImage || '')}
mode='aspectFill' mode='aspectFill'
/> />
<View className='absolute top-1 right-1 px-2 rounded-full bg-black bg-opacity-50' style={{ paddingTop: '2px', paddingBottom: '2px' }}> <View className='absolute top-1 right-1 px-2 rounded-full bg-black bg-opacity-50' style={{ paddingTop: '2px', paddingBottom: '2px' }}>

View File

@@ -7,6 +7,7 @@ import type { ShopSeckill } from '@/api/shop/shopSeckill/model'
import type { ShopGoods } from '@/api/shop/shopGoods/model' import type { ShopGoods } from '@/api/shop/shopGoods/model'
import type { ShopGoodsSku } from '@/api/shop/shopGoodsSku/model' import type { ShopGoodsSku } from '@/api/shop/shopGoodsSku/model'
import SkuSelector from '@/components/business/SkuSelector' import SkuSelector from '@/components/business/SkuSelector'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '秒杀详情', navigationBarTitleText: '秒杀详情',
@@ -176,7 +177,7 @@ const SeckillDetailPage: React.FC = () => {
{seckill.goodsImage || seckill.product?.image ? ( {seckill.goodsImage || seckill.product?.image ? (
<Image <Image
className="w-full h-full" className="w-full h-full"
src={seckill.goodsImage || seckill.product?.image} src={getCompressedImageUrl(seckill.goodsImage || seckill.product?.image)}
mode="aspectFill" mode="aspectFill"
/> />
) : ( ) : (

View File

@@ -4,6 +4,7 @@ import Taro from '@tarojs/taro'
import { pageShopSeckill } from '@/api/shop/shopSeckill' import { pageShopSeckill } from '@/api/shop/shopSeckill'
import type { ShopSeckill } from '@/api/shop/shopSeckill/model' import type { ShopSeckill } from '@/api/shop/shopSeckill/model'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '限时秒杀', navigationBarTitleText: '限时秒杀',
@@ -94,7 +95,7 @@ const SeckillListPage: React.FC = () => {
> >
<Image <Image
className='w-24 h-24 rounded-md bg-gray-100 flex-shrink-0' className='w-24 h-24 rounded-md bg-gray-100 flex-shrink-0'
src={item.goodsImage || item.product?.image || ''} src={getCompressedImageUrl(item.goodsImage || item.product?.image || '')}
mode='aspectFill' mode='aspectFill'
/> />
<View className='flex-1 flex flex-col justify-between'> <View className='flex-1 flex flex-col justify-between'>

View File

@@ -8,6 +8,7 @@ import type { ShopGoods } from '@/api/shop/shopGoods/model'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import Loading from '@/components/common/Loading' import Loading from '@/components/common/Loading'
import { isGuest } from '@/utils/auth' import { isGuest } from '@/utils/auth'
import { getCompressedImageUrl } from '@/utils/image'
import { requireLogin } from '@/utils/login-guard' import { requireLogin } from '@/utils/login-guard'
import { isVipMember } from '@/utils/vip' import { isVipMember } from '@/utils/vip'
@@ -102,7 +103,7 @@ const CartPage: React.FC = () => {
> >
<Image <Image
className='w-full rounded-md bg-gray-100' className='w-full rounded-md bg-gray-100'
src={goods.image || ''} src={getCompressedImageUrl(goods.image || '')}
mode='aspectFill' mode='aspectFill'
style={{ height: '90px' }} style={{ height: '90px' }}
/> />
@@ -169,7 +170,7 @@ const CartPage: React.FC = () => {
</View> </View>
<Image <Image
className="w-20 h-20 rounded-md bg-gray-100 flex-shrink-0" className="w-20 h-20 rounded-md bg-gray-100 flex-shrink-0"
src={item.goodsImage || item.product?.image || ''} src={getCompressedImageUrl(item.goodsImage || item.product?.image || '')}
mode="aspectFill" mode="aspectFill"
/> />
<View className="flex-1 flex flex-col justify-between"> <View className="flex-1 flex flex-col justify-between">
@@ -221,7 +222,7 @@ const CartPage: React.FC = () => {
> >
<Image <Image
className="w-full rounded-md bg-gray-100" className="w-full rounded-md bg-gray-100"
src={goods.image || ''} src={getCompressedImageUrl(goods.image || '')}
mode="aspectFill" mode="aspectFill"
style={{ height: '90px' }} style={{ height: '90px' }}
/> />

View File

@@ -8,6 +8,7 @@ import type { ShopGoodsCategory } from '@/api/shop/shopGoodsCategory/model'
import type { ShopGoods, ShopGoodsParam } from '@/api/shop/shopGoods/model' import type { ShopGoods, ShopGoodsParam } from '@/api/shop/shopGoods/model'
import { isGuest } from '@/utils/auth' import { isGuest } from '@/utils/auth'
import { isVipMember } from '@/utils/vip' import { isVipMember } from '@/utils/vip'
import { getCompressedImageUrl } from '@/utils/image'
import { requireLogin } from '@/utils/login-guard' import { requireLogin } from '@/utils/login-guard'
import LoadMore from '@/components/common/LoadMore' import LoadMore from '@/components/common/LoadMore'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
@@ -215,7 +216,7 @@ const CategoryPage: React.FC = () => {
<View className='w-20 h-20 rounded-lg bg-gray-100 overflow-hidden flex-shrink-0'> <View className='w-20 h-20 rounded-lg bg-gray-100 overflow-hidden flex-shrink-0'>
<Image <Image
className='w-full h-full' className='w-full h-full'
src={item.image || item.files || ''} src={getCompressedImageUrl(item.image || item.files || '')}
mode='aspectFill' mode='aspectFill'
lazyLoad lazyLoad
/> />

View File

@@ -14,6 +14,7 @@ import type { ShopGoods } from '@/api/shop/shopGoods/model'
import type { ShopUserCoupon } from '@/api/shop/shopUserCoupon/model' import type { ShopUserCoupon } from '@/api/shop/shopUserCoupon/model'
import type { OrderGoodsItem, OrderCreateRequest } from '@/api/shop/shopOrder/model' import type { OrderGoodsItem, OrderCreateRequest } from '@/api/shop/shopOrder/model'
import { isVipMember } from '@/utils/vip' import { isVipMember } from '@/utils/vip'
import { getCompressedImageUrl } from '@/utils/image'
// 满减门槛配置 // 满减门槛配置
const THRESHOLDS = [ const THRESHOLDS = [
@@ -344,7 +345,7 @@ const CheckoutPage: React.FC = () => {
<View key={`${item.goodsId}-${item.skuId}-${idx}`} className='flex gap-3 py-3 border-b border-gray-50'> <View key={`${item.goodsId}-${item.skuId}-${idx}`} className='flex gap-3 py-3 border-b border-gray-50'>
<Image <Image
className='w-16 h-16 rounded-md bg-gray-100' className='w-16 h-16 rounded-md bg-gray-100'
src={item.goodsImage || item.product?.image || item.sku?.image || ''} src={getCompressedImageUrl(item.goodsImage || item.product?.image || item.sku?.image || '')}
mode='aspectFill' mode='aspectFill'
/> />
<View className='flex-1'> <View className='flex-1'>
@@ -495,7 +496,7 @@ const CheckoutPage: React.FC = () => {
> >
<Image <Image
className='w-full h-20 rounded bg-gray-100' className='w-full h-20 rounded bg-gray-100'
src={product.image || ''} src={getCompressedImageUrl(product.image || '')}
mode='aspectFill' mode='aspectFill'
/> />
<Text className='text-xs text-gray-700 block line-clamp-1 mt-1'> <Text className='text-xs text-gray-700 block line-clamp-1 mt-1'>

View File

@@ -7,6 +7,7 @@ import type { ShopGroupBuy, ShopGroupBuyRecord } from '@/api/shop/shopGroupBuy/m
import type { ShopGoods } from '@/api/shop/shopGoods/model' import type { ShopGoods } from '@/api/shop/shopGoods/model'
import type { ShopGoodsSku } from '@/api/shop/shopGoodsSku/model' import type { ShopGoodsSku } from '@/api/shop/shopGoodsSku/model'
import SkuSelector from '@/components/business/SkuSelector' import SkuSelector from '@/components/business/SkuSelector'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '拼团详情', navigationBarTitleText: '拼团详情',
@@ -184,7 +185,7 @@ const GroupBuyDetailPage: React.FC = () => {
<View className="bg-white p-4 flex gap-3"> <View className="bg-white p-4 flex gap-3">
<Image <Image
className="w-24 h-24 rounded-md bg-gray-100" className="w-24 h-24 rounded-md bg-gray-100"
src={groupBuy.goodsImage || groupBuy.product?.image || ''} src={getCompressedImageUrl(groupBuy.goodsImage || groupBuy.product?.image || '')}
mode="aspectFill" mode="aspectFill"
/> />
<View className="flex-1 flex flex-col justify-between"> <View className="flex-1 flex flex-col justify-between">

View File

@@ -4,6 +4,7 @@ import Taro from '@tarojs/taro'
import { pageShopGroupBuy } from '@/api/shop/shopGroupBuy' import { pageShopGroupBuy } from '@/api/shop/shopGroupBuy'
import type { ShopGroupBuy } from '@/api/shop/shopGroupBuy/model' import type { ShopGroupBuy } from '@/api/shop/shopGroupBuy/model'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '拼团活动', navigationBarTitleText: '拼团活动',
@@ -72,7 +73,7 @@ const GroupBuyListPage: React.FC = () => {
> >
<Image <Image
className='w-24 h-24 rounded-md bg-gray-100 flex-shrink-0' className='w-24 h-24 rounded-md bg-gray-100 flex-shrink-0'
src={item.goodsImage || item.product?.image || ''} src={getCompressedImageUrl(item.goodsImage || item.product?.image || '')}
mode='aspectFill' mode='aspectFill'
/> />
<View className='flex-1 flex flex-col justify-between'> <View className='flex-1 flex flex-col justify-between'>

View File

@@ -8,6 +8,7 @@ import type { ShopGoodsCategory } from '@/api/shop/shopGoodsCategory/model'
import type { ShopGoods, ShopGoodsParam } from '@/api/shop/shopGoods/model' import type { ShopGoods, ShopGoodsParam } from '@/api/shop/shopGoods/model'
import { isGuest } from '@/utils/auth' import { isGuest } from '@/utils/auth'
import { isVipMember } from '@/utils/vip' import { isVipMember } from '@/utils/vip'
import { getCompressedImageUrl } from '@/utils/image'
import { requireLogin } from '@/utils/login-guard' import { requireLogin } from '@/utils/login-guard'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import LoadMore from '@/components/common/LoadMore' import LoadMore from '@/components/common/LoadMore'
@@ -269,7 +270,7 @@ const ShopPage: React.FC = () => {
<View className='w-20 h-20 rounded-lg bg-gray-100 overflow-hidden flex-shrink-0'> <View className='w-20 h-20 rounded-lg bg-gray-100 overflow-hidden flex-shrink-0'>
<Image <Image
className='w-full h-full' className='w-full h-full'
src={item.image || item.files || ''} src={getCompressedImageUrl(item.image || item.files || '')}
mode='aspectFill' mode='aspectFill'
lazyLoad lazyLoad
/> />

View File

@@ -4,6 +4,7 @@ import Taro from '@tarojs/taro'
import { pageShopSeckill } from '@/api/shop/shopSeckill' import { pageShopSeckill } from '@/api/shop/shopSeckill'
import type { ShopSeckill } from '@/api/shop/shopSeckill/model' import type { ShopSeckill } from '@/api/shop/shopSeckill/model'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '限时秒杀', navigationBarTitleText: '限时秒杀',
@@ -94,7 +95,7 @@ const SeckillListPage: React.FC = () => {
> >
<Image <Image
className='w-24 h-24 rounded-md bg-gray-100 flex-shrink-0' className='w-24 h-24 rounded-md bg-gray-100 flex-shrink-0'
src={item.goodsImage || item.product?.image || ''} src={getCompressedImageUrl(item.goodsImage || item.product?.image || '')}
mode='aspectFill' mode='aspectFill'
/> />
<View className='flex-1 flex flex-col justify-between'> <View className='flex-1 flex flex-col justify-between'>

View File

@@ -6,6 +6,7 @@ import { listShopGoodsCategory } from '@/api/shop/shopGoodsCategory'
import { uploadFile } from '@/api/system/file' import { uploadFile } from '@/api/system/file'
import type { ShopGoods, ShopGoodsParam } from '@/api/shop/shopGoods/model' import type { ShopGoods, ShopGoodsParam } from '@/api/shop/shopGoods/model'
import type { ShopGoodsCategory } from '@/api/shop/shopGoodsCategory/model' import type { ShopGoodsCategory } from '@/api/shop/shopGoodsCategory/model'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '商品管理', navigationBarTitleText: '商品管理',
@@ -317,7 +318,7 @@ export default function StoreGoodsPage() {
{goods.image ? ( {goods.image ? (
<Image <Image
className='w-20 h-20 rounded-lg bg-gray-50 flex-shrink-0' className='w-20 h-20 rounded-lg bg-gray-50 flex-shrink-0'
src={goods.image} src={getCompressedImageUrl(goods.image,{ width: 120, quality: 90 })}
mode='aspectFill' mode='aspectFill'
onClick={() => Taro.previewImage({ urls: [goods.image!] })} onClick={() => Taro.previewImage({ urls: [goods.image!] })}
/> />
@@ -541,7 +542,7 @@ export default function StoreGoodsPage() {
<View className='bg-gray-50 rounded-xl p-4 mb-5 flex items-center gap-3'> <View className='bg-gray-50 rounded-xl p-4 mb-5 flex items-center gap-3'>
<View className='relative' onClick={handleUploadImage}> <View className='relative' onClick={handleUploadImage}>
{editGoods.image ? ( {editGoods.image ? (
<Image className='w-16 h-16 rounded-lg' src={editGoods.image} mode='aspectFill' /> <Image className='w-16 h-16 rounded-lg' src={getCompressedImageUrl(editGoods.image)} mode='aspectFill' />
) : ( ) : (
<View className='w-16 h-16 rounded-lg bg-gray-200 flex items-center justify-center'> <View className='w-16 h-16 rounded-lg bg-gray-200 flex items-center justify-center'>
<Text className='text-2xl text-gray-300'>📷</Text> <Text className='text-2xl text-gray-300'>📷</Text>
@@ -567,7 +568,7 @@ export default function StoreGoodsPage() {
<View className='flex flex-wrap gap-3'> <View className='flex flex-wrap gap-3'>
{editForm.files.map((file, index) => ( {editForm.files.map((file, index) => (
<View key={file.url + index} className='relative w-20 h-20'> <View key={file.url + index} className='relative w-20 h-20'>
<Image className='w-20 h-20 rounded-lg bg-gray-100' src={file.url} mode='aspectFill' /> <Image className='w-20 h-20 rounded-lg bg-gray-100' src={getCompressedImageUrl(file.url)} mode='aspectFill' />
<View <View
className='absolute -top-1.5 -right-1.5 w-5 h-5 bg-red-500 rounded-full flex items-center justify-center' className='absolute -top-1.5 -right-1.5 w-5 h-5 bg-red-500 rounded-full flex items-center justify-center'
onClick={() => handleRemoveBanner(index)} onClick={() => handleRemoveBanner(index)}

View File

@@ -5,6 +5,7 @@ import {pageShopOrder, updateShopOrder, removeShopOrder} from '@/api/shop/shopOr
import type {ShopOrder, ShopOrderParam} from '@/api/shop/shopOrder/model' import type {ShopOrder, ShopOrderParam} from '@/api/shop/shopOrder/model'
import {TenantId} from '@/config/app' import {TenantId} from '@/config/app'
import {useNewOrderDetector} from '@/hooks/useNewOrderDetector' import {useNewOrderDetector} from '@/hooks/useNewOrderDetector'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '订单管理', navigationBarTitleText: '订单管理',
@@ -359,7 +360,7 @@ export default function StoreOrdersPage() {
{orderGoods.map((goods: any, idx: number) => ( {orderGoods.map((goods: any, idx: number) => (
<View key={idx} className='flex items-center gap-3 mb-3'> <View key={idx} className='flex items-center gap-3 mb-3'>
{goods.coverImage && ( {goods.coverImage && (
<Image className='w-16 h-16 rounded-lg bg-gray-50' src={goods.coverImage} <Image className='w-16 h-16 rounded-lg bg-gray-50' src={getCompressedImageUrl(goods.coverImage)}
mode='aspectFill'/> mode='aspectFill'/>
)} )}
<View className='flex-1'> <View className='flex-1'>
@@ -396,7 +397,7 @@ export default function StoreOrdersPage() {
<Image <Image
key={i} key={i}
className='w-20 h-20 rounded-lg bg-gray-100' className='w-20 h-20 rounded-lg bg-gray-100'
src={img} src={getCompressedImageUrl(img)}
mode='aspectFill' mode='aspectFill'
onClick={() => Taro.previewImage({ onClick={() => Taro.previewImage({
current: img, current: img,
@@ -549,7 +550,7 @@ export default function StoreOrdersPage() {
<View className='flex flex-wrap gap-3 mb-6'> <View className='flex flex-wrap gap-3 mb-6'>
{proofImages.map((url, idx) => ( {proofImages.map((url, idx) => (
<View key={idx} className='relative'> <View key={idx} className='relative'>
<Image className='w-20 h-20 rounded-lg bg-gray-50' src={url} mode='aspectFill'/> <Image className='w-20 h-20 rounded-lg bg-gray-50' src={getCompressedImageUrl(url)} mode='aspectFill'/>
<View <View
className='absolute -top-2 -right-2 w-5 h-5 bg-red-500 rounded-full flex items-center justify-center' className='absolute -top-2 -right-2 w-5 h-5 bg-red-500 rounded-full flex items-center justify-center'
onClick={() => removeProofImage(idx)} onClick={() => removeProofImage(idx)}

View File

@@ -5,6 +5,7 @@ import { getBenefitPackageDetail, exchangeBenefitPackage } from '@/api/shop/shop
import { getDefaultAddress } from '@/api/shop/shopUserAddress'; import { getDefaultAddress } from '@/api/shop/shopUserAddress';
import { getUserBalance } from '@/api/system/user/balance'; import { getUserBalance } from '@/api/system/user/balance';
import './index.scss'; import './index.scss';
import { getCompressedImageUrl } from '@/utils/image';
definePageConfig({ definePageConfig({
navigationBarTitleText: '确认兑换', navigationBarTitleText: '确认兑换',
@@ -113,7 +114,7 @@ export default function BenefitExchangeConfirmPage() {
{/* 权益包信息 */} {/* 权益包信息 */}
<View className="pkg-info-card"> <View className="pkg-info-card">
{pkg.coverImage && ( {pkg.coverImage && (
<Image className="pkg-img" src={pkg.coverImage} mode="aspectFill" /> <Image className="pkg-img" src={getCompressedImageUrl(pkg.coverImage)} mode="aspectFill" />
)} )}
<View className="pkg-detail"> <View className="pkg-detail">
<Text className="pkg-name">{pkg.name}</Text> <Text className="pkg-name">{pkg.name}</Text>

View File

@@ -4,6 +4,7 @@ import { useState, useEffect } from 'react';
import { getBenefitPackageList } from '@/api/shop/shopMemberBenefit'; import { getBenefitPackageList } from '@/api/shop/shopMemberBenefit';
import EmptyState from '@/components/common/EmptyState'; import EmptyState from '@/components/common/EmptyState';
import './index.scss'; import './index.scss';
import { getCompressedImageUrl } from '@/utils/image';
definePageConfig({ definePageConfig({
navigationBarTitleText: '会员权益包', navigationBarTitleText: '会员权益包',
@@ -54,7 +55,7 @@ export default function BenefitPackagesPage() {
{list.map((pkg) => ( {list.map((pkg) => (
<View key={pkg.id} className="pkg-card"> <View key={pkg.id} className="pkg-card">
{pkg.coverImage && ( {pkg.coverImage && (
<Image className="pkg-cover" src={pkg.coverImage} mode="aspectFill" /> <Image className="pkg-cover" src={getCompressedImageUrl(pkg.coverImage)} mode="aspectFill" />
)} )}
<View className="pkg-body"> <View className="pkg-body">
<View className="pkg-header"> <View className="pkg-header">

View File

@@ -5,6 +5,7 @@ import { listShopGoodsFavorite } from '@/api/shop/shopGoodsFavorite'
import type { ShopGoodsFavorite } from '@/api/shop/shopGoodsFavorite/model' import type { ShopGoodsFavorite } from '@/api/shop/shopGoodsFavorite/model'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import LoadMore from '@/components/common/LoadMore' import LoadMore from '@/components/common/LoadMore'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '我的收藏', navigationBarTitleText: '我的收藏',
@@ -69,7 +70,7 @@ const FavoriteListPage: React.FC = () => {
<Image <Image
className='w-full' className='w-full'
style={{ height: '160px' }} style={{ height: '160px' }}
src={item.goodsImage} src={getCompressedImageUrl(item.goodsImage)}
mode='aspectFill' mode='aspectFill'
/> />
<View className='p-2'> <View className='p-2'>

View File

@@ -3,6 +3,7 @@ import { View, Text, Image, ScrollView } from '@tarojs/components'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import LoadMore from '@/components/common/LoadMore' import LoadMore from '@/components/common/LoadMore'
import { getCompressedImageUrl } from '@/utils/image'
definePageConfig({ definePageConfig({
navigationBarTitleText: '浏览历史', navigationBarTitleText: '浏览历史',
@@ -82,7 +83,7 @@ const BrowseHistoryPage: React.FC = () => {
<Image <Image
className='w-full' className='w-full'
style={{ height: '160px' }} style={{ height: '160px' }}
src={item.image} src={getCompressedImageUrl(item.image)}
mode='aspectFill' mode='aspectFill'
/> />
<View className='p-2'> <View className='p-2'>

View File

@@ -14,7 +14,7 @@ export interface ImageCompressOptions {
* 默认压缩参数 * 默认压缩参数
*/ */
const DEFAULT_OPTIONS: Required<ImageCompressOptions> = { const DEFAULT_OPTIONS: Required<ImageCompressOptions> = {
width: 750, width: 300,
quality: 90, quality: 90,
enabled: true, enabled: true,
}; };