Nivek преди 2 години
родител
ревизия
feffe9ef22
променени са 7 файла, в които са добавени 171 реда и са изтрити 6 реда
  1. 2 0
      components.d.ts
  2. 14 0
      src/api/product.ts
  3. 88 4
      src/components/Header.vue
  4. 6 0
      src/router/index.ts
  5. 1 1
      src/views/Home.vue
  6. 56 0
      src/views/product/ProductSearchResult.vue
  7. 4 1
      src/views/store/StoreDetail.vue

+ 2 - 0
components.d.ts

@@ -21,6 +21,8 @@ declare module 'vue' {
     ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
     ElDialog: typeof import('element-plus/es')['ElDialog']
     ElDivider: typeof import('element-plus/es')['ElDivider']
+    ElDrawer: typeof import('element-plus/es')['ElDrawer']
+    ElDropdown: typeof import('element-plus/es')['ElDropdown']
     ElForm: typeof import('element-plus/es')['ElForm']
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
     ElHeader: typeof import('element-plus/es')['ElHeader']

+ 14 - 0
src/api/product.ts

@@ -9,6 +9,12 @@ type ProductInfo = {
     photoUrlList: string[]
 }
 
+type SearchInfo = {
+    name: string | null,
+    category: string | null,
+    price: number | null,      // 最高价格
+}
+
 // 创建商品
 export const createProduct = (productInfo: ProductInfo) => {
     return axios.post(`${PRODUCT_MODULE}/`, productInfo,
@@ -48,4 +54,12 @@ export const getCommentsById = (productId: number) => {
         .then(res => {
             return res;
         })
+}
+
+export const searchByCondition = (searchInfo: SearchInfo) => {
+    return axios.post(`${PRODUCT_MODULE}/condition`, searchInfo,
+        {headers: {'Content-Type': 'application/json'}})
+        .then(res => {
+            return res;
+        })
 }

+ 88 - 4
src/components/Header.vue

@@ -1,10 +1,43 @@
 <script setup lang="ts">
-import {router} from '../router'
-import {parseRole} from "../utils"
+import {parseRole, parseCategory} from "../utils"
 import {User, Document, Discount, SwitchButton} from "@element-plus/icons-vue"   //图标
+import { ref, computed } from "vue"
+import { Search } from "@element-plus/icons-vue"
+import {useRouter} from "vue-router";
+
+const router = useRouter()
 
 const role = sessionStorage.getItem('role')    //登录的时候插入的
 
+const searchValue = ref(null)
+const typeValue = ref(null)
+const priceValue = ref(null)
+const possibleCategories = ['FOOD','CLOTHES','ELECTRONICS','FURNITURE','ENTERTAINMENT', 'SPORTS', 'LUXURY']
+
+const drawer = ref()
+const searchDisabled = computed(() => !(searchValue.value != null || typeValue.value != null || priceValue.value != null))
+
+
+function openSearchBar() {
+  drawer.value = true
+}
+
+function closeSearchBar() {
+  drawer.value = false
+}
+
+function search() {
+  drawer.value = false
+  router.push({
+    name: "searchResult",
+    query: {
+      name: searchValue.value,
+      category: typeValue.value,
+      price: priceValue.value,
+    }
+  })
+}
+
 //退出登录
 function logout() {
   ElMessageBox.confirm(
@@ -28,8 +61,49 @@ function logout() {
 
 
 <template>
+
+  <el-drawer
+      v-model="drawer"
+      direction="ttb"
+  >
+    <template #default>
+      <el-form label-position="top" :inline="true">
+
+        <el-form-item label="商品名称">
+          <el-input
+              v-model="searchValue"
+              @keyup.enter.native="search"
+              placeholder="不限"
+              size="large"
+              style="width: 300px"
+          >
+          </el-input>
+
+        </el-form-item>
+        <el-form-item label="商品品类">
+          <el-select v-model="typeValue" placeholder="任意" style="width: 300px" size="large">
+            <el-option v-for = "item in possibleCategories" :key="item" :label="parseCategory(item)" :value="item"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="商品最高价格">
+          <el-input-number v-model="priceValue" placeholder="不限" size="large" style="width: 300px">
+
+          </el-input-number>
+        </el-form-item>
+      </el-form>
+
+    </template>
+
+    <template #footer>
+      <div style="flex: auto">
+        <el-button @click="closeSearchBar">取消</el-button>
+        <el-button type="primary" @click="search" :disabled="searchDisabled">搜索</el-button>
+      </div>
+    </template>
+  </el-drawer>
+
   <el-header class="custom-header" height="20">
-    <el-row :gutter="10">
+    <el-row :gutter="20">
 
       <el-col :span="3" class="header-icon">
         <router-link to="/allStore" v-slot="{navigate}" class="no-link">
@@ -41,7 +115,16 @@ function logout() {
         <el-tag class="role-tag" size="large">{{ parseRole(role) }}版</el-tag>
       </el-col>
 
-      <el-col :span="15">
+      <el-col :span="14"></el-col>
+
+
+<!--      <el-col :span="13" class="search-holder">-->
+
+
+<!--      </el-col>-->
+
+      <el-col :span="1" class="header-icon">
+          <el-icon @click="openSearchBar" :size="35" color="white" style="cursor: pointer" ><Search /></el-icon>
       </el-col>
 
       <el-col :span="1" class="header-icon">
@@ -106,4 +189,5 @@ function logout() {
   align-items:center;
   justify-content: center;
 }
+
 </style>

+ 6 - 0
src/router/index.ts

@@ -30,6 +30,12 @@ const router = createRouter({
                 component: () => import('../views/store/AllStore.vue'),
                 meta: {title: '商品列表界面/主页'}
             },
+            {
+                path: '/searchResult',
+                name: 'searchResult',
+                component: () => import('../views/product/ProductSearchResult.vue'),
+                meta: {title: '商品检索结果'}
+            },
             {
                 path: '/createStore',
                 name: 'createStore',

+ 1 - 1
src/views/Home.vue

@@ -5,7 +5,7 @@ import Header from "../components/Header.vue"
 
 <template>
   <Header/>
-  <router-view />
+  <router-view :key="$route.fullPath"/>
 </template>
 
 

+ 56 - 0
src/views/product/ProductSearchResult.vue

@@ -0,0 +1,56 @@
+<script setup lang="ts">
+import {Back} from "@element-plus/icons-vue";
+import {searchByCondition} from "../../api/product.ts";
+import { ref } from "vue"
+import {useRoute, useRouter} from "vue-router";
+import ProductItem from "../../components/ProductItem.vue";
+
+
+const productList = ref()
+
+const route = useRoute()
+const router = useRouter()
+
+let name = route.query.name === null ? null : String(route.query.name)
+let category = route.query.category === null ? null : String(route.query.category)
+let price = route.query.price === null ? null : Number(route.query.price)
+
+const payload = {
+  name: name,
+  category: category,
+  price: price,
+}
+
+searchByCondition(payload).then(res => {
+    console.log(payload)
+    productList.value = res.data.result
+    console.log(productList.value)
+  }
+)
+
+function toBackPage() {
+  router.push("/allStore")
+}
+
+</script>
+
+<template>
+  <el-container>
+    <el-main>
+      <el-button @click="toBackPage()"
+                 type="primary" circle plain class="back-button">
+        <el-icon>
+          <Back/>
+        </el-icon>
+      </el-button>
+
+      <ProductItem v-for = "productVO in productList" :productId="productVO.id"/>
+
+    </el-main>
+
+  </el-container>
+</template>
+
+<style scoped>
+
+</style>

+ 4 - 1
src/views/store/StoreDetail.vue

@@ -1,11 +1,14 @@
 <script setup lang="ts">
 import {ref} from "vue"
-import {router} from '../../router'
 import {getStoreById} from "../../api/store.ts"
 import {getProductsByStoreId} from "../../api/product.ts"
 import {Back} from "@element-plus/icons-vue"
 import ProductItem from "../../components/ProductItem.vue"
 import {parseRating} from "../../utils";
+import {useRouter} from "vue-router";
+
+const router = useRouter()
+
 
 const role = sessionStorage.getItem("role")
 // 从当前router地址中获得storeId参数值