panhui 3 년 전
부모
커밋
7d56cc174f

BIN
src/assets/home_icon_redian.png


BIN
src/assets/icon_kefu.png


BIN
src/assets/nav_icon_sousuo.png


+ 3 - 2
src/plugins/list.js

@@ -1,7 +1,7 @@
 import { ref } from 'vue'
 import { ref } from 'vue'
 import { getCurrentInstance } from 'vue'
 import { getCurrentInstance } from 'vue'
 
 
-function useList(url, beforeData = {}, httpType) {
+function useList(url, beforeData = null, httpType) {
     const {
     const {
         appContext: {
         appContext: {
             config: { globalProperties: global }
             config: { globalProperties: global }
@@ -15,6 +15,7 @@ function useList(url, beforeData = {}, httpType) {
     const totalElements = ref(0)
     const totalElements = ref(0)
     const size = ref(20)
     const size = ref(20)
     const list = ref([])
     const list = ref([])
+
     const getData = (isRefresh = false) => {
     const getData = (isRefresh = false) => {
         if (isRefresh) {
         if (isRefresh) {
             page.value = 0
             page.value = 0
@@ -28,7 +29,7 @@ function useList(url, beforeData = {}, httpType) {
         if (beforeData) {
         if (beforeData) {
             data = {
             data = {
                 ...data,
                 ...data,
-                ...beforeData
+                ...beforeData()
             }
             }
         }
         }
 
 

+ 52 - 0
src/plugins/search.js

@@ -0,0 +1,52 @@
+import { ref, computed, nextTick } from 'vue'
+import useList from './list'
+
+function useSearch(url, beforeData = {}, httpType) {
+    const isSearch = ref(false)
+    const search = ref('')
+
+    const { empty, loading, finished, page, totalElements, size, list, getData } = useList(
+        url,
+        () => {
+            return {
+                ...beforeData,
+                search: search.value
+            }
+        },
+        httpType
+    )
+
+    const getSearch = val => {
+        isSearch.value = true
+        search.value = val
+        nextTick(() => {
+            getData(true)
+        })
+    }
+    const onCancel = () => {
+        if (isSearch.value) {
+            isSearch.value = false
+            search.value = ''
+            list.value = []
+        } else {
+            getSearch(search.value)
+        }
+    }
+
+    return {
+        empty,
+        loading,
+        finished,
+        page,
+        totalElements,
+        size,
+        list,
+        getData,
+        isSearch,
+        search,
+        getSearch,
+        onCancel
+    }
+}
+
+export default useSearch

+ 8 - 0
src/router/index.js

@@ -95,6 +95,14 @@ const router = createRouter({
                 pageType: Page.Every
                 pageType: Page.Every
             }
             }
         },
         },
+        {
+            path: '/productSearch',
+            name: 'productSearch',
+            component: () => import('@/views/ProductSearchPage.vue'),
+            meta: {
+                pageType: Page.Every
+            }
+        },
         {
         {
             path: '/setting',
             path: '/setting',
             name: 'setting',
             name: 'setting',

+ 5 - 0
src/styles/main.less

@@ -8,6 +8,11 @@
     --yellow: #ffd563;
     --yellow: #ffd563;
     --red: #ff0000;
     --red: #ff0000;
     --green: #00b016;
     --green: #00b016;
+    --van-empty-padding: 100px 10px;
+    --van-empty-image-size: 200px;
+    --van-empty-description-font-size: 14px;
+    --van-empty-description-color: #8c7af8;
+    --van-empty-description-margin-top: 16px;
 }
 }
 ion-back-button {
 ion-back-button {
     --ion-color-primary: #000;
     --ion-color-primary: #000;

+ 1 - 1
src/views/HomePage.vue

@@ -300,7 +300,7 @@ const getStatus = info => {
     --van-notice-bar-font-size: 13px;
     --van-notice-bar-font-size: 13px;
     border-radius: 4px;
     border-radius: 4px;
     .bar-icon {
     .bar-icon {
-        width: 43px;
+        width: 77px;
         height: 16px;
         height: 16px;
     }
     }
 
 

+ 13 - 11
src/views/ProductListPage.vue

@@ -6,7 +6,7 @@
                     <ion-back-button default-href="#" text="" @click="$router.back()"></ion-back-button>
                     <ion-back-button default-href="#" text="" @click="$router.back()"></ion-back-button>
                 </ion-buttons>
                 </ion-buttons>
                 <ion-title>{{ batchInfo.name }}</ion-title>
                 <ion-title>{{ batchInfo.name }}</ion-title>
-                <ion-buttons slot="end">
+                <ion-buttons slot="end" @click="$router.push('/productSearch?batchId=' + batchId)">
                     <img class="search" src="../assets/search.png" alt="" />
                     <img class="search" src="../assets/search.png" alt="" />
                 </ion-buttons>
                 </ion-buttons>
             </ion-toolbar>
             </ion-toolbar>
@@ -48,18 +48,20 @@ const {
 } = getCurrentInstance()
 } = getCurrentInstance()
 
 
 const batchInfo = ref({})
 const batchInfo = ref({})
+const batchId = route.query.batchId
 
 
-let beforeData = {
-    query: {
-        batchId: route.query.batchId,
-        status: 'IN_STOCK',
-        enabled: true
-    },
-    sort: 'id,desc'
-}
-const { empty, loading, finished, list, getData } = useList('/product/all', beforeData)
+const { empty, loading, finished, list, getData } = useList('/product/all', () => {
+    return {
+        query: {
+            batchId: route.query.batchId,
+            status: 'IN_STOCK',
+            enabled: true
+        },
+        sort: 'id,desc'
+    }
+})
 function getBatch() {
 function getBatch() {
-    global.$http.get('/saleBatch/get/' + route.query.batchId).then(res => {
+    global.$http.get('/saleBatch/get/' + batchId).then(res => {
         batchInfo.value = res
         batchInfo.value = res
     })
     })
 }
 }

+ 153 - 0
src/views/ProductSearchPage.vue

@@ -0,0 +1,153 @@
+<template>
+    <ion-page>
+        <ion-header>
+            <ion-toolbar class="head">
+                <ion-buttons slot="start">
+                    <ion-back-button default-href="#" text="" @click="$router.back()"></ion-back-button>
+                </ion-buttons>
+                <ion-title>{{ batchInfo.name }}</ion-title>
+            </ion-toolbar>
+        </ion-header>
+        <div class="search">
+            <van-search v-model="search" show-action placeholder="请输入搜索关键词" @search="getSearch">
+                <template #left-icon>
+                    <img class="search-icon" src="../assets/nav_icon_sousuo.png" alt="" />
+                </template>
+
+                <template #action>
+                    <div v-if="!isSearch" @click="getSearch(search)">搜索</div>
+                    <div v-else @click="onCancel">取消</div>
+                </template>
+            </van-search>
+        </div>
+        <ion-content>
+            <van-list class="list" v-model:loading="loading" :finished="finished" finished-text="" @load="getData">
+                <div class="product" v-for="(item, index) in list" :key="index">
+                    <product-info list v-model:info="list[index]"></product-info>
+                </div>
+                <van-empty v-if="empty && isSearch" description="没有搜索任何商品哦~" :image="emptyIcon" />
+            </van-list>
+        </ion-content>
+    </ion-page>
+</template>
+
+<script setup>
+import productInfo from '../components/ProductInfo.vue'
+import { ref, getCurrentInstance, onMounted, computed } from 'vue'
+import { useRoute } from 'vue-router'
+import useSearch from '../plugins/search'
+import { isAfter, isBefore, parse, getYear, getMonth, getDate } from 'date-fns'
+import emptyIcon from '../assets/img_empty_order.png'
+
+const route = useRoute()
+const {
+    appContext: {
+        config: { globalProperties: global }
+    }
+} = getCurrentInstance()
+
+const batchInfo = ref({})
+
+let beforeData = {
+    query: {
+        batchId: route.query.batchId,
+        status: 'IN_STOCK',
+        enabled: true
+    },
+    sort: 'id,desc'
+}
+const { empty, loading, finished, list, getData, isSearch, search, getSearch, onCancel } = useSearch(
+    '/product/all',
+    beforeData
+)
+
+const status = computed(() => {
+    let date1 = getYear(new Date()) + '/' + (getMonth(new Date()) + 1) + '/' + getDate(new Date())
+    if (batchInfo.value && batchInfo.value.saleStart) {
+        if (
+            isAfter(new Date(), new Date(date1 + ' ' + batchInfo.value.saleStart)) &&
+            isBefore(new Date(), new Date(date1 + ' ' + batchInfo.value.saleEnd))
+        ) {
+            return '抢购中'
+        } else {
+            return batchInfo.value.saleStart + ' 开抢'
+        }
+    }
+    return ''
+})
+</script>
+
+<style lang="less" scoped>
+.head {
+    height: 50px;
+    --background: #fff;
+    .f();
+    padding: 0;
+    font-size: 16px;
+    .text {
+        flex-grow: 1;
+    }
+}
+
+.header-title {
+    font-size: 16px;
+    font-weight: bold;
+    color: #000000;
+    line-height: 24px;
+}
+
+.list {
+    padding: 12px 0;
+    .product {
+        margin: 0 16px 12px;
+        background: #ffffff;
+        border-radius: 4px;
+    }
+}
+
+.status {
+    .f();
+    justify-content: center;
+    background: var(--green);
+    height: 28px;
+    img {
+        width: 18px;
+        height: 18px;
+    }
+    span {
+        font-size: 12px;
+        color: #ffffff;
+        line-height: 22px;
+        margin-left: 6px;
+    }
+
+    &.hot {
+        background: #ed1e31;
+    }
+}
+
+.search {
+    :deep(.van-search) {
+        --van-search-left-icon-color: #c8c9cc;
+        --van-search-content-background-color: #f6f6f6;
+        --van-search-input-height: 36px;
+        --van-text-color: #c8c9cc;
+        --van-search-action-padding: 0 16px;
+        --van-search-action-text-color: #8c7af8;
+        --van-padding-sm: 4px;
+        --van-padding-base: 0;
+        .van-field__left-icon {
+            .f();
+        }
+
+        .van-search__content {
+            border-radius: 4px;
+        }
+    }
+
+    .search-icon {
+        width: 28px;
+        height: 28px;
+    }
+}
+</style>