feat(image): 全项目应用图片压缩优化
- 将图片显示统一替换为 getCompressedImageUrl 函数处理压缩 - 覆盖 35 个文件,包括 4 个组件和 31 个页面 - 主要组件:LazyImage、ProductCard、OrderCard、SkuSelector 内部自动压缩图片 - 主要页面:购物车、订单、积分、活动、拼团、秒杀、收藏、浏览历史等 - 跳过用户头像、二维码、商品详情大图及所有 Taro.previewImage 调用 - 调整压缩默认宽度为 300,保持质量90,启用压缩功能
This commit is contained in:
@@ -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 调用
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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)}
|
||||||
|
|||||||
@@ -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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -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%' }}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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'>
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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'>
|
||||||
|
|||||||
@@ -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'>
|
||||||
|
|||||||
@@ -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' }}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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'
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -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'
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -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'
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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'
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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'
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -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'
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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!] })}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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' }}>
|
||||||
|
|||||||
@@ -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"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -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'>
|
||||||
|
|||||||
@@ -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' }}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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'>
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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'>
|
||||||
|
|||||||
@@ -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
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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'>
|
||||||
|
|||||||
@@ -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)}
|
||||||
|
|||||||
@@ -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)}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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'>
|
||||||
|
|||||||
@@ -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'>
|
||||||
|
|||||||
@@ -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,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user