xiongzhu 3 năm trước cách đây
mục cha
commit
1a8ef8b008

+ 14 - 1
index.html

@@ -1,9 +1,22 @@
 <!DOCTYPE html>
-<html lang="en">
+<html lang="en" mode="ios">
     <head>
         <meta charset="UTF-8" />
         <link rel="icon" href="/favicon.ico" />
         <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+        <meta name="color-scheme" content="light dark" />
+        <meta
+          name="viewport"
+          content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
+        />
+        <meta name="format-detection" content="telephone=no" />
+        <meta name="msapplication-tap-highlight" content="no" />
+    
+    
+        <!-- add to homescreen for ios -->
+        <meta name="apple-mobile-web-app-capable" content="yes" />
+        <meta name="apple-mobile-web-app-title" content="Ionic App" />
+        <meta name="apple-mobile-web-app-status-bar-style" content="black" />
         <title>拍卖的那个</title>
         <style>
             @font-face {

+ 7 - 7
src/components/OrderInfo.vue

@@ -227,7 +227,7 @@ export default {
                     }, 1000)
                 })
                 .catch(e => {
-                    return this.$toast(e.error)
+                    return this.$toast.error(e.error)
                 })
         },
         confirmReceipt() {
@@ -242,7 +242,7 @@ export default {
                     }, 1000)
                 })
                 .catch(e => {
-                    return this.$toast(e.error)
+                    return this.$toast.error(e.error)
                 })
         },
         addNum(a, b) {
@@ -324,7 +324,7 @@ export default {
                     .catch(e => {
                         this.$toast.clear()
                         this.loading = false
-                        return this.$toast(e.error)
+                        return this.$toast.error(e.error)
                     })
             } else if (this.payType === 'balance') {
                 this.$toast.loading('支付中')
@@ -339,7 +339,7 @@ export default {
                         this.$emit('updateOrder', res)
                     })
                     .catch(e => {
-                        this.$toast(e.error)
+                        this.$toast.error(e.error)
                     })
             }
         },
@@ -361,7 +361,7 @@ export default {
                             }, 1000)
                         })
                         .catch(e => {
-                            return this.$toast(e.error)
+                            return this.$toast.error(e.error)
                         })
                 })
                 .catch(() => {})
@@ -378,7 +378,7 @@ export default {
                     }, 1000)
                 })
                 .catch(e => {
-                    return this.$toast(e.error)
+                    return this.$toast.error(e.error)
                 })
         },
         pay() {
@@ -392,7 +392,7 @@ export default {
                     }, 1000)
                 })
                 .catch(e => {
-                    this.$toast(e.error)
+                    this.$toast.error(e.error)
                 })
         },
         showTip() {

+ 7 - 7
src/components/OrderItem.vue

@@ -230,7 +230,7 @@ export default {
                     }, 1000)
                 })
                 .catch(e => {
-                    return this.$toast(e.error)
+                    return this.$toast.error(e.error)
                 })
         },
         confirmReceipt() {
@@ -245,7 +245,7 @@ export default {
                     }, 1000)
                 })
                 .catch(e => {
-                    return this.$toast(e.error)
+                    return this.$toast.error(e.error)
                 })
         },
         addNum(a, b) {
@@ -327,7 +327,7 @@ export default {
                     .catch(e => {
                         this.$toast.clear()
                         this.loading = false
-                        return this.$toast(e.error)
+                        return this.$toast.error(e.error)
                     })
             } else if (this.payType === 'balance') {
                 this.$toast.loading('支付中')
@@ -342,7 +342,7 @@ export default {
                         this.$emit('updateOrder', res)
                     })
                     .catch(e => {
-                        this.$toast(e.error)
+                        this.$toast.error(e.error)
                     })
             }
         },
@@ -364,7 +364,7 @@ export default {
                             }, 1000)
                         })
                         .catch(e => {
-                            return this.$toast(e.error)
+                            return this.$toast.error(e.error)
                         })
                 })
                 .catch(() => {})
@@ -381,7 +381,7 @@ export default {
                     }, 1000)
                 })
                 .catch(e => {
-                    return this.$toast(e.error)
+                    return this.$toast.error(e.error)
                 })
         },
         pay() {
@@ -395,7 +395,7 @@ export default {
                     }, 1000)
                 })
                 .catch(e => {
-                    this.$toast(e.error)
+                    this.$toast.error(e.error)
                 })
         },
         showTip() {

+ 24 - 2
src/locales/zh.json

@@ -1,15 +1,21 @@
 {
+    "cancel": "取消",
     "login": "登录",
+    "common": {
+        "pullRefresh": "下拉刷新",
+        "loadFinish": "加载完成"
+    },
     "order": {
         "my": "我的订单",
         "detail": "订单详情",
         "payMethod": "支付方式",
         "status": {
+            "ALL": "全部",
             "NOT_PAID": "待付款",
             "CANCELED": "已取消",
             "NOT_CONFIRMED": "待卖家确认收款",
-            "CONFIRMED": "待上架",
-            "SELLING": "出售中",
+            "CONFIRMED": "待委托",
+            "SELLING": "委托中",
             "SOLD_NOT_PAID": "待买家付款",
             "SOLD_NOT_CONFIRMED": "待确认收款",
             "SOLD": "已售出",
@@ -17,6 +23,19 @@
             "SHIPPED": "已发货",
             "RECEIVED": "已收货"
         },
+        "statusDesc": {
+            "NOT_PAID": "请尽快支付,超时未支付订单将自动取消",
+            "CANCELED": "订单已取消,如有疑问请联系客服",
+            "NOT_CONFIRMED": "待卖家确认收款",
+            "CONFIRMED": "待委托,委托后将在24小时内上架",
+            "SELLING": "委托中,如有疑问请联系客服",
+            "SOLD_NOT_PAID": "待买家付款",
+            "SOLD_NOT_CONFIRMED": "待确认收款",
+            "SOLD": "已售出,如有疑问请联系客服",
+            "NOT_SHIPPED": "待发货",
+            "SHIPPED": "已发货",
+            "RECEIVED": "已收货"
+        },
         "payMethodName": {
             "balance": "余额支付"
         },
@@ -39,5 +58,8 @@
     "product": {
         "detail": "商品详情",
         "dailyEarning": "日化收益"
+    },
+    "delegate": {
+        "title": "委托代卖"
     }
 }

+ 3 - 3
src/mixins/phone.js

@@ -41,7 +41,7 @@ export default {
                 })
                 .catch(e => {
                     if (e) {
-                        this.$toast(e.error)
+                        this.$toast.error(e.error)
                         this.captcha = ''
                         this.captchaKey = ''
                     }
@@ -72,7 +72,7 @@ export default {
                 })
                 .catch(e => {
                     if (e) {
-                        this.$toast(e.error)
+                        this.$toast.error(e.error)
                     }
                     return Promise.reject()
                 })
@@ -85,7 +85,7 @@ export default {
                 })
                 .catch(e => {
                     if (e) {
-                        this.$toast(e.error)
+                        this.$toast.error(e.error)
                     }
                     return Promise.reject()
                 })

+ 3 - 3
src/styles/common.less

@@ -8,8 +8,8 @@
     flex-direction: column;
 }
 
-.g() {
+.gt() {
     background: linear-gradient(135deg, #d700ff 0%, #3e22ff 100%);
-    color: var(--ion-color-dark-contrast);
-    border-radius: 4px;
+    -webkit-background-clip: text;
+    -webkit-text-fill-color: transparent;
 }

+ 5 - 9
src/styles/main.less

@@ -10,15 +10,6 @@
     --green: #00b016;
 }
 
-body {
-    min-height: 100vh;
-    font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans',
-        'Droid Sans', 'Helvetica Neue', sans-serif;
-    text-rendering: optimizeLegibility;
-    -webkit-font-smoothing: antialiased;
-    -moz-osx-font-smoothing: grayscale;
-}
-
 ion-content {
     &::-webkit-scrollbar {
         display: none;
@@ -50,3 +41,8 @@ ion-toolbar {
 .van-button {
     --van-button-normal-font-size: 14px;
 }
+.gt {
+    background: linear-gradient(135deg, #d700ff 0%, #3e22ff 100%);
+    -webkit-background-clip: text;
+    -webkit-text-fill-color: transparent;
+}

+ 1 - 1
src/views/ChangeTextPage.vue

@@ -76,7 +76,7 @@ export default {
                 })
                 .catch(e => {
                     if (e) {
-                        this.$toast(e.error)
+                        this.$toast.error(e.error)
                     }
                     return Promise.reject()
                 })

+ 124 - 69
src/views/OrderDetailPage.vue

@@ -1,5 +1,5 @@
 <template>
-    <ion-page>
+    <ion-page ref="page">
         <ion-header>
             <ion-toolbar>
                 <ion-buttons slot="start">
@@ -14,11 +14,19 @@
             </div>
             <div class="top">
                 <div class="status">
-                    <ion-icon :icon="icons.timeOutline"></ion-icon>
+                    <ion-icon :icon="icons.walletOutline" v-if="orderInfo.status == 'NOT_PAID'"></ion-icon>
+                    <ion-icon :icon="icons.closeCircleOutline" v-if="orderInfo.status == 'CANCELED'"></ion-icon>
+                    <ion-icon :icon="icons.albumsOutline" v-if="orderInfo.status == 'CONFIRMED'"></ion-icon>
+                    <ion-icon :icon="icons.timeOutline" v-if="orderInfo.status == 'SELLING'"></ion-icon>
+                    <ion-icon :icon="icons.walletOutline" v-if="orderInfo.status == 'SOLD_NOT_PAID'"></ion-icon>
+                    <ion-icon :icon="icons.checkmarkCircleOutline" v-if="orderInfo.status == 'SOLD'"></ion-icon>
                     <div class="status">
                         {{ $t('order.status.' + orderInfo.status) }}
                     </div>
                 </div>
+                <div class="status-desc">
+                    {{ $t('order.statusDesc.' + orderInfo.status) }}
+                </div>
             </div>
 
             <div class="product">
@@ -54,7 +62,13 @@
             <div class="order-detail">
                 <div class="detail-item">
                     <div class="name">{{ $t('order.payMethod') }}</div>
-                    <div class="val">{{ $t('order.payMethodName.balance') }}</div>
+                    <div class="val">
+                        {{
+                            orderInfo.status === 'NOT_PAID'
+                                ? $t('order.status.' + orderInfo.status)
+                                : $t('order.payMethodName.balance')
+                        }}
+                    </div>
                 </div>
 
                 <div class="time-content">
@@ -72,62 +86,73 @@
                     </div>
                 </div>
             </div>
-
-            <van-popup v-model="show" class="getsold">
-                <div class="title">委托代卖</div>
-                <div class="sold-list">
-                    <div class="sold-item">
-                        <div class="name">原价</div>
-                        <div class="val">¥{{ orderInfo.totalPrice }}</div>
-                    </div>
-                    <div class="sold-item">
-                        <div class="name">加价</div>
-                        <van-stepper v-model="value" input-width="60px" step="1" integer min="1" :max="maxRiseRate" />
+            <ion-modal ref="modal" :is-open="show" :presentingElement="presentingElement">
+                <ion-header>
+                    <ion-toolbar>
+                        <ion-title>{{ $t('delegate.title') }}</ion-title>
+                        <ion-buttons slot="end">
+                            <ion-button @click="show = false">{{ $t('cancel') }}</ion-button>
+                        </ion-buttons>
+                    </ion-toolbar>
+                </ion-header>
+                <div v-if="show" class="getsold">
+                    <div class="sold-list">
+                        <div class="sold-item">
+                            <div class="name">原价</div>
+                            <div class="val">¥{{ orderInfo.totalPrice }}</div>
+                        </div>
+                        <div class="sold-item">
+                            <div class="name">加价</div>
+                            <van-stepper
+                                v-model="value"
+                                input-width="60px"
+                                step="1"
+                                integer
+                                min="1"
+                                :max="maxRiseRate"
+                            />
+                        </div>
+                        <div class="sold-item">
+                            <div class="name">卖价</div>
+                            <div class="val bold">¥{{ soldValue }}</div>
+                        </div>
                     </div>
-                    <div class="sold-item">
-                        <div class="name">卖价</div>
-                        <div class="val bold">¥{{ soldValue }}</div>
+                    <div class="tips">
+                        注:委托平台代卖服务,每次最高可将商品价格提高{{ maxRiseRate }}%,平台会收取{{
+                            serviceValue
+                        }}%的托管服务费用
                     </div>
-                </div>
-                <div class="tips">
-                    注:委托平台代卖服务,每次最高可将商品价格提高{{ maxRiseRate }}%,平台会收取{{
-                        serviceValue
-                    }}%的托管服务费用
-                </div>
 
-                <van-button class="button" :disabled="loading" block type="primary" round @click="sale">
-                    支付手续费 ¥{{ serviceCharge }}</van-button
-                >
-            </van-popup>
+                    <van-button class="button" :disabled="loading" block type="primary" @click="sale">
+                        支付手续费 ¥{{ serviceCharge }}
+                    </van-button>
+                </div>
+            </ion-modal>
         </ion-content>
-        <ion-footer>
+        <ion-footer v-if="orderInfo.status == 'NOT_PAID' || orderInfo.status == 'CONFIRMED'">
             <div class="bottom">
                 <div>
                     <div class="order-button" v-if="orderInfo.status == 'NOT_PAID'">
-                        <span> {{ $t('balance.symbol') }}</span>
-                        <span> {{ $t('order.totalPayment') }}</span>
-                        <van-button class="btn-pay" type="primary" @click="pay">{{ $t('order.payNow') }}</van-button>
-                    </div>
-
-                    <div
-                        class="order-button"
-                        v-else-if="orderInfo.status == 'SOLD_NOT_CONFIRMED' && !orderInfo.delegationId"
-                    >
-                        <!-- <van-button color="#AAACAD" round plain @click="confirmPayment">未收到款</van-button> -->
-                        <!-- <van-button type="primary" round @click="confirmReceipt">确认收款</van-button> -->
+                        <span class="price">
+                            <span class="label">{{ $t('order.totalPayment') }}</span>
+                            <span class="gt sym"> {{ $t('balance.symbol') }}</span>
+                            <span class="gt num">
+                                {{ orderInfo.totalPrice ? orderInfo.totalPrice.toFixed(2) : '' }}</span
+                            >
+                        </span>
+                        <van-button class="btn-pay" type="primary" @click="pay" style="width: 150px">{{
+                            $t('order.payNow')
+                        }}</van-button>
                     </div>
 
                     <div class="order-button" v-else-if="orderInfo.status == 'CONFIRMED'">
                         <!-- <van-button color="#AAACAD" round plain @click="applyShip">申请发货</van-button> -->
-                        <van-button type="primary" round @click="show = true" v-if="delegationActive"
-                            >委托代卖
+                        <van-button type="primary" class="full" @click="show = true" v-if="delegationActive">
+                            {{ $t('delegate.title') }}
+                        </van-button>
+                        <van-button color="#aaacad" class="full" @click="showTip" v-else
+                            >{{ $t('delegate.title') }}
                         </van-button>
-                        <van-button color="#aaacad" round @click="showTip" v-else>委托代卖 </van-button>
-                    </div>
-
-                    <div class="order-button" v-else-if="orderInfo.status == 'SHIPPED'">
-                        <!-- <van-button color="#AAACAD" round plain @click="confirmPayment">未收到款</van-button> -->
-                        <van-button type="primary" round @click="receive"> 确认收货</van-button>
                     </div>
                 </div>
             </div>
@@ -139,11 +164,9 @@ import { mapState } from 'pinia'
 import { useUserStore } from '@/stores/user'
 import { orderStatus } from '../status'
 import { parse } from 'date-fns'
-import { IonIcon } from '@ionic/vue'
-import { timeOutline } from 'ionicons/icons'
+import { timeOutline, walletOutline, albumsOutline, closeCircleOutline, checkmarkCircleOutline } from 'ionicons/icons'
 export default {
     name: 'orderDetail',
-    components: { IonIcon },
     data() {
         return {
             orderStatus,
@@ -159,10 +182,18 @@ export default {
             loading: false,
             payType: 'balance',
             icons: {
-                timeOutline
-            }
+                timeOutline,
+                walletOutline,
+                albumsOutline,
+                closeCircleOutline,
+                checkmarkCircleOutline
+            },
+            presentingElement: null
         }
     },
+    mounted() {
+        this.presentingElement = this.$refs.page.$el
+    },
     computed: {
         ...mapState(useUserStore, ['user']),
         pic() {
@@ -193,7 +224,7 @@ export default {
         this.$http
             .get('/order/get/' + this.$route.query.id)
             .then(res => {
-                this.orderInfo = { ...res, status: 'NOT_PAID' }
+                this.orderInfo = { ...res, status: 'CONFIRMED' }
                 if (res.productId) {
                     return this.$http.get('/product/get/' + res.productId)
                 }
@@ -296,7 +327,7 @@ export default {
                     }, 1000)
                 })
                 .catch(e => {
-                    return this.$toast(e.error)
+                    return this.$toast.error(e.error)
                 })
         },
         confirmReceipt() {
@@ -317,7 +348,7 @@ export default {
                     }, 1000)
                 })
                 .catch(e => {
-                    return this.$toast(e.error)
+                    return this.$toast.error(e.error)
                 })
         },
         sale() {
@@ -376,7 +407,7 @@ export default {
                     .catch(e => {
                         this.$toast.clear()
                         this.loading = false
-                        return this.$toast(e.error)
+                        return this.$toast.error(e.error)
                     })
             } else if (this.payType === 'balance') {
                 this.$toast.loading('支付中')
@@ -391,7 +422,7 @@ export default {
                         this.getInfo()
                     })
                     .catch(e => {
-                        this.$toast(e.error)
+                        this.$toast.error(e.error)
                     })
             }
         },
@@ -419,7 +450,7 @@ export default {
                             }, 1000)
                         })
                         .catch(e => {
-                            return this.$toast(e.error)
+                            return this.$toast.error(e.error)
                         })
                 })
                 .catch(() => {})
@@ -442,7 +473,7 @@ export default {
                     }, 1000)
                 })
                 .catch(e => {
-                    return this.$toast(e.error)
+                    return this.$toast.error(e.error)
                 })
         },
         pay() {
@@ -456,7 +487,7 @@ export default {
                     }, 1000)
                 })
                 .catch(e => {
-                    this.$toast(e.error)
+                    this.$toast.error(e.error)
                 })
         }
     }
@@ -492,7 +523,7 @@ export default {
             margin-right: 6px;
         }
     }
-    .desc {
+    .status-desc {
         margin-top: 6px;
         font-size: 14px;
     }
@@ -648,26 +679,51 @@ export default {
 .order-button {
     height: 50px;
     display: flex;
-    justify-content: flex-end;
-    align-items: center;
+    .f();
     padding: 0 15px;
     width: 100%;
-
+    .price {
+        .f();
+        align-items: baseline;
+        flex-grow: 1;
+        .label {
+            font-size: 14px;
+            color: var(--ion-color-step-400);
+            margin-right: 4px;
+        }
+        .sym {
+            font-weight: bold;
+            font-size: 14px;
+        }
+        .num {
+            font-weight: bold;
+            font-size: 24px;
+        }
+    }
     .van-button {
         width: 110px;
         height: 39px;
         line-height: 39px;
         margin-left: 10px;
     }
+    .full {
+        flex-grow: 1;
+        margin-left: 12px;
+        margin-right: 12px;
+    }
 }
 .bottom {
     width: 100%;
     background-color: var(--ion-color-dark-contrast);
 }
+ion-backdrop {
+    opacity: 0.3;
+    background: var(--ion-color-step-950);
+}
 .getsold {
-    width: 300px;
-    height: 405px;
-    background: rgba(255, 255, 255, 1);
+    // width: 300px;
+    // height: 405px;
+    background: var(--ion-background-color);
     border-radius: 4px;
     padding: 15px 20px;
     box-sizing: border-box;
@@ -682,11 +738,10 @@ export default {
     .sold-item {
         display: flex;
         align-items: center;
-        height: 28px;
         padding: 22px 0 10px;
         border-bottom: 1px solid #f2f4f5;
         .name {
-            font-size: 18px;
+            font-size: 14px;
             font-weight: bold;
             color: rgba(0, 0, 0, 1);
             line-height: 25px;

+ 71 - 8
src/views/OrderPage.vue

@@ -9,10 +9,23 @@
             </ion-toolbar>
         </ion-header>
         <ion-content :fullscreen="true">
-            <van-tabs v-model:active="status" :line-height="2">
-                <van-tab v-for="item in statusOptions" :title="item.title" :name="item.value" :key="item.value">
-                </van-tab>
-            </van-tabs>
+            <ion-item-divider class="tabs" sticky>
+                <div class="tabs-wrapper">
+                    <div class="tabs">
+                        <div
+                            class="tab"
+                            v-for="item in statusOptions"
+                            :key="item.value"
+                            :class="{ active: status === item.value }"
+                            @click="status = item.value"
+                        >
+                            {{ $t('order.status.' + item.value) }}
+                        </div>
+                        <div class="line" :style="{ left: linePosition + 'px' }"></div>
+                    </div>
+                </div>
+            </ion-item-divider>
+            <div class="tabs-placeholder"></div>
             <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="loadmore">
                 <order-item v-for="item in list" :key="item.id" :info="item"></order-item>
             </van-list>
@@ -24,6 +37,8 @@ import { mapState } from 'pinia'
 import { useUserStore } from '@/stores/user'
 import OrderItem from '@/components/OrderItem.vue'
 import { parse } from 'date-fns'
+import { useWindowSize } from '@vueuse/core'
+
 export default {
     name: 'OrderPage',
     components: { OrderItem },
@@ -36,18 +51,24 @@ export default {
             finished: false,
             statusOptions: [
                 { title: '全部', value: 'ALL' },
-                { title: '待付', value: 'NOT_PAID' },
+                { title: '待付', value: 'NOT_PAID' },
                 { title: '待上架', value: 'CONFIRMED' },
                 { title: '已上架', value: 'SELLING' },
                 { title: '已售出', value: 'SOLD' }
             ],
             status: 'ALL',
             page: 0,
-            size: 20
+            size: 20,
+            windowSize: useWindowSize()
         }
     },
     computed: {
-        ...mapState(useUserStore, ['user'])
+        ...mapState(useUserStore, ['user']),
+        linePosition() {
+            const { width } = this.windowSize
+            const tabSize = width / this.statusOptions.length
+            return this.statusOptions.findIndex(i => i.value == this.status) * tabSize + (tabSize - 36) / 2
+        }
     },
     created() {
         if (this.$route.query.status) {
@@ -134,4 +155,46 @@ export default {
     }
 }
 </script>
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+ion-content {
+    position: relative;
+}
+ion-item-divider.tabs {
+    padding: 0;
+    background: none;
+    --padding-start: 0;
+    --padding-end: 0;
+    --inner-padding-start: 0;
+    --inner-padding-end: 0;
+}
+.tabs-wrapper {
+    height: 40px;
+    position: sticky;
+    width: 100%;
+    .tabs {
+        .f();
+        height: 40px;
+        background: var(--ion-color-step-0);
+        position: relative;
+        .tab {
+            height: 40px;
+            flex-basis: 0;
+            flex-grow: 1;
+            .f();
+            font-size: 13px;
+            justify-content: center;
+            &.active {
+                .gt();
+            }
+        }
+        .line {
+            width: 36px;
+            height: 2px;
+            position: absolute;
+            bottom: 0;
+            background: #ed1e31 linear-gradient(135deg, #d700ff 0%, #3e22ff 100%);
+            transition: left 0.2s;
+        }
+    }
+}
+</style>

+ 1 - 1
src/views/RegisterPage.vue

@@ -182,7 +182,7 @@ export default {
                 })
                 .catch(e => {
                     if (e) {
-                        this.$toast(e.error)
+                        this.$toast.error(e.error)
                     }
                 })
         }

+ 1 - 1
src/views/SettingPage.vue

@@ -185,7 +185,7 @@ export default {
                     })
                     .catch(e => {
                         if (e) {
-                            this.$toast(e.error)
+                            this.$toast.error(e.error)
                         }
                         return Promise.reject()
                     })

+ 3 - 0
vite.config.js

@@ -6,6 +6,9 @@ import viteImagemin from 'vite-plugin-imagemin'
 
 // https://vitejs.dev/config/
 export default defineConfig({
+    server: {
+        host: '0.0.0.0'
+    },
     plugins: [
         vue(),
         viteImagemin({