Quellcode durchsuchen

正在准备lab3,出了点问题

chillqi vor 2 Jahren
Ursprung
Commit
374418129f

+ 3 - 0
components.d.ts

@@ -29,11 +29,14 @@ declare module 'vue' {
     ElMain: typeof import('element-plus/es')['ElMain']
     ElOption: typeof import('element-plus/es')['ElOption']
     ElRate: typeof import('element-plus/es')['ElRate']
+    ElResult: typeof import('element-plus/es')['ElResult']
     ElRow: typeof import('element-plus/es')['ElRow']
     ElSelect: typeof import('element-plus/es')['ElSelect']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
     ElTag: typeof import('element-plus/es')['ElTag']
+    ElUpload: typeof import('element-plus/es')['ElUpload']
     Header: typeof import('./src/components/Header.vue')['default']
+    OrderItem: typeof import('./src/components/OrderItem.vue')['default']
     ProductItem: typeof import('./src/components/ProductItem.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']

+ 1 - 2
src/api/_prefix.ts

@@ -9,5 +9,4 @@ export const STORE_MODULE = `${API_MODULE}/stores`
 export const PRODUCT_MODULE = `${API_MODULE}/products`
 
 //Lab3新增
-//订单模块
-export const ORDER_MODULE = `${API_MODULE}/orders`
+//需要添加订单模块的api

+ 0 - 4
src/api/orders.ts

@@ -1,4 +0,0 @@
-// Lab3新增
-// 开发时请解除3-4行的注释
-// import {axios} from '../utils/request'
-// import {ORDER_MODULE} from './_prefix'

+ 5 - 1
src/api/product.ts

@@ -2,7 +2,11 @@ import {axios} from '../utils/request'
 import {PRODUCT_MODULE} from './_prefix'
 
 type ProductInfo = {
-
+    storeId: number,
+    name: string,
+    category: string,
+    price: number,
+    photoUrlList: [string]
 }
 
 // 创建商品

+ 4 - 2
src/api/store.ts

@@ -2,7 +2,9 @@ import {axios} from '../utils/request'
 import {STORE_MODULE} from './_prefix'
 
 type StoreInfo = {
-
+    name: string,
+    location: string,
+    logoUrl: string
 }
 
 // 创建商店
@@ -16,7 +18,7 @@ export const createStore = (storeInfo: StoreInfo) => {
 
 // 获取全部商店
 export const getAllStore = () => {
-    return axios.get(`${STORE_MODULE}/`, )
+    return axios.get(`${STORE_MODULE}/all`, )
         .then(res => {
             return res
         })

+ 8 - 0
src/components/Header.vue

@@ -50,6 +50,14 @@ function logout() {
         </router-link>
       </el-col>
 
+<!--      Lab3新增-->
+<!--      添加下面这个按键,点击进入订单列表界面-->
+<!--      <el-col :span="1" class="header-icon">-->
+<!--        <router-link to="/allOrder" v-slot="{navigate}">-->
+<!--          <el-icon @click="navigate" :size="35" color="white" ><Document /></el-icon>-->
+<!--        </router-link>-->
+<!--      </el-col>-->
+
       <el-col :span="1" class="header-icon">
         <a @click="logout">
           <el-icon :size="35" color="white" ><SwitchButton /></el-icon>

+ 8 - 40
src/components/ProductItem.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import {ref} from "vue"
 import {getProductById} from "../api/product.ts"
+import {parseCategory} from "../utils"
 
 // 使用props接收父界面传来的数据
 const props = defineProps({
@@ -13,8 +14,6 @@ const props = defineProps({
 const storeId = ref(0)
 const name = ref('')
 const photoUrlList = ref([])
-const rating = ref(0)
-const number = ref(0)
 const salesAmount = ref(0)
 const stock = ref(0)
 const category = ref()
@@ -22,36 +21,16 @@ const price = ref()
 const photoUrl = ref('')
 
 getProductById(props.productId).then(res => {
-  storeId.value = res.result.storeId
-  name.value = res.result.name
-  photoUrlList.value = res.result.photoUrlList
-  rating.value = res.result.rating
-  number.value = res.result.number
-  salesAmount.value = res.result.salesAmount
-  stock.value = res.result.stock
-  category.value = res.result.category
-  price.value = res.result.price
+  storeId.value = res.data.result.storeId
+  name.value = res.data.result.name
+  photoUrlList.value = res.data.result.photoUrlList
+  salesAmount.value = res.data.result.salesAmount
+  stock.value = res.data.result.stock
+  category.value = res.data.result.category
+  price.value = res.data.result.price
 
   photoUrl.value = photoUrlList.value[0]
 })
-
-function parseCategory(category) {
-  if (category === 'FOOD') {
-    return "食品"
-  } else if (category === 'CLOTHES') {
-    return "服饰"
-  } else if (category === 'FURNITURE') {
-    return "家具"
-  } else if (category === 'ELECTRONICS') {
-    return "电子产品"
-  } else if (category === 'ENTERTAINMENT') {
-    return "娱乐"
-  } else if (category === 'SPORTS') {
-    return "体育产品"
-  } else if (category === 'LUXURY') {
-    return "奢侈品"
-  }
-}
 </script>
 
 
@@ -69,17 +48,6 @@ function parseCategory(category) {
         <el-descriptions-item style="font-size: 10px" label="价格">
           {{ price }} 元
         </el-descriptions-item>
-        <el-descriptions-item style="font-size: 10px" label="评分">
-          <el-rate
-              v-model="rating"
-              disabled
-              show-score
-              text-color="#ff9900"
-              score-template="{value} 分"
-              size="small"
-          />
-          (共 {{ number }} 人打分)
-        </el-descriptions-item>
         <el-descriptions-item style="font-size: 10px" label="销量">
           {{ salesAmount }} 件
         </el-descriptions-item>

+ 42 - 2
src/components/StoreItem.vue

@@ -1,13 +1,53 @@
-<!--Lab2新增-->
-<!--商店列表父组件中的单个商店子组件-->
 <script setup lang="ts">
+import {ref} from "vue"
+import {getStoreById} from "../api/store.ts"
 
+// 使用props接收父界面传来的数据
+const props = defineProps({
+  storeId: {
+    type: Number,
+    required: true
+  }
+})
+
+const name = ref('')
+const logoUrl = ref('')
+const location = ref('')
+
+getStoreById(props.storeId).then(res => {
+  name.value = res.data.result.name
+  logoUrl.value = res.data.result.logoUrl
+  location.value = res.data.result.location
+})
 </script>
 
+
 <template>
+  <el-card class="store-item-card" :body-style="{ padding: '0px' }" shadow="hover">
+    <el-image class="logo-image" :src="logoUrl"/>
 
+    <div style="padding: 14px">
+      <h1> {{ name }} </h1>
+      <el-descriptions :column="1">
+        <el-descriptions-item style="font-size: 10px" label="地址">
+          {{ location }}
+        </el-descriptions-item>
+      </el-descriptions>
+    </div>
+  </el-card>
 </template>
 
+
 <style scoped>
+.store-item-card {
+  margin: 20px;
+  border-radius: 8px;
+  min-width: 25%;
+  max-width: 30px;
+}
 
+.logo-image {
+  height: 250px;
+  display: block;
+}
 </style>

+ 39 - 18
src/router/index.ts

@@ -24,14 +24,12 @@ const router = createRouter({
                 component: () => import('../views/user/Dashboard.vue'),
                 meta: {title: '个人信息'}
             },
-            //以下为Lab2新增,添加了商店模块的界面,请大家自己添加商品模块的界面
             {
                 path: '/allStore',
                 name: 'allStore',
                 component: () => import('../views/store/AllStore.vue'),
                 meta: {title: '商品列表界面/主页'}
             },
-            //你也可以把创建商店界面设置成一个弹窗
             {
                 path: '/createStore',
                 name: 'createStore',
@@ -46,7 +44,25 @@ const router = createRouter({
                 name: 'storeDetail',
                 component: () => import('../views/store/StoreDetail.vue'),
                 meta: {title: '店铺详情'}
+            },
+            {
+                path: '/createProduct/:storeId',
+                name: 'createProduct',
+                component: () => import('../views/product/CreateProduct.vue'),
+                meta: {
+                    title: '创建商品',
+                    permission: ['STAFF']
+                }
+            },
+            {
+                path: '/productDetail/:productId',
+                name: 'productDetail',
+                component: () => import('../views/product/ProductDetail.vue'),
+                meta: {title: '商品详情'}
             }
+
+            // Lab3新增
+            // 需要把订单模块生成的新界面添加到这里
         ]
     }, {
         path: '/404',
@@ -60,31 +76,36 @@ const router = createRouter({
 })
 
 router.beforeEach((to, _, next) => {
-    const token: string | null = sessionStorage.getItem('token');
+    const token: string | null = sessionStorage.getItem('token')
     const role: string | null = sessionStorage.getItem('role')
+    const storeId: string | null = sessionStorage.getItem('storeId')
 
     if (to.meta.title) {
         document.title = to.meta.title
     }
 
-    if (token) {
-        if (to.meta.permission) {
-            if (to.meta.permission.includes(role!)) {
-                next()
-            } else {
-                next('/404')
-            }
-        } else {
-            next()
-        }
-    } else {
-        if (to.path === '/login') {
+    if (!token) {
+        if (to.path === '/login' || to.path === '/register') {
             next();
-        } else if (to.path === '/register') {
-            next()
         } else {
-            next('/login')
+            next('/login');
         }
+        return;
+    }
+
+    if (!to.meta.permission) {
+        next();
+        return;
+    }
+
+    if (!to.meta.permission.includes(role!)) {
+        next('/404');
+        return;
+    }
+
+    if (to.name === 'createProduct' && to.params.storeId !== storeId) {
+        next('/404');
+        return;
     }
 })
 

+ 18 - 1
src/utils/index.ts

@@ -17,5 +17,22 @@ export function parseTime(time: string) {
     return times[0] + " " + times[1]
 }
 
-
+//将商品品类转化为中文显示
+export function parseCategory(category: string) {
+    if (category === 'FOOD') {
+        return "食品"
+    } else if (category === 'CLOTHES') {
+        return "服饰"
+    } else if (category === 'FURNITURE') {
+        return "家具"
+    } else if (category === 'ELECTRONICS') {
+        return "电子产品"
+    } else if (category === 'ENTERTAINMENT') {
+        return "娱乐"
+    } else if (category === 'SPORTS') {
+        return "体育产品"
+    } else if (category === 'LUXURY') {
+        return "奢侈品"
+    }
+}
 

+ 135 - 8
src/views/product/CreateProduct.vue

@@ -1,22 +1,149 @@
-<!--Lab2新增-创建商品界面-->
-<!--你可以选择把创建商品改成一个弹窗或其他界面的一个部分。
-这样的话,就不需要有这样一个views下的创建商品文件了,因为views下的文件一般会是一个单独的界面。
-但如果你觉得这一个部分的代码较多,合到其他文件里会使那个文件太长,
-可以在product文件夹下创建一个components子文件夹,里面存放product模块下产生的组件界面。把这个创建商品子组件放在里面。
-这个传递数据的过程可能需要用到props-->
-
 <script setup lang="ts">
+import {ref, computed} from "vue"
+import {router} from '../../router'
+import {Back, UploadFilled} from "@element-plus/icons-vue"
+import {createProduct} from "../../api/product.ts"
+import {uploadImage} from "../../api/tools.ts"
+
+const storeId = Number(router.currentRoute.value.params.storeId)
+const name = ref('')
+const category = ref()
+const price = ref()
+const photoUrlList = ref([''])
+
+const imageFileList = ref([])
+
+const hasNameInput = computed(() => name.value != '')
+const hasCategoryInput = computed(() => category.value != null)
+const hasPriceInput = computed(() => price.value != '')
+const hasImageFile = computed(() => imageFileList.value.length != 0)
+const createProductDisabled = computed(() => {
+  return !(hasNameInput.value && hasCategoryInput.value && hasPriceInput.value && hasImageFile.value);
+})
 
-//这边是需要实现上传至少2张图片。可以从CreateStore里提供的代码改,也可以自己搜了写。
+function handleCreateProduct() {
+  console.log(photoUrlList.value)
+  const payload = {
+    storeId: storeId,
+    name: name.value,
+    category: category.value,
+    price: price.value,
+    photoUrlList: photoUrlList.value
+  };
+  createProduct(payload).then(res => {
+    if (res.data.code === '000') {
+      ElMessage({
+        message: '添加商品成功!',
+        type: 'success',
+        center: true,
+      })
+      name.value = '';
+      category.value = '';
+      price.value = '';
+      photoUrlList.value = [];
+      imageFileList.value = [];
+    } else if (res.data.code === '400') {
+      ElMessage({
+        message: res.data.msg,
+        type: 'error',
+        center: true,
+      })
+    }
+  })
+}
 
+function handleChange(file: any, fileList: any) {
+  imageFileList.value = fileList
+  let formData = new FormData();
+  formData.append('file', file.raw);
+  uploadImage(formData).then(res => {
+    photoUrlList.value.push(res.data.result);
+  });
+}
+
+function uploadHttpRequest() {
+  return new XMLHttpRequest()
+}
+
+function toBackPage() {
+  router.push("/storeDetail/" + storeId)
+}
 </script>
 
 
 <template>
+  <el-main>
+    <el-button @click="toBackPage()" type="primary" circle plain>
+      <el-icon>
+        <Back/>
+      </el-icon>
+    </el-button>
+
+    <h1 class="create-product-title">新建商品</h1>
+
+    <el-form label-position="left" label-width="90px" size="large" class="create-product-form">
+
+      <el-form-item label="商品名">
+        <el-input id="name" v-model="name"
+                  required
+                  placeholder="请输入商品名"/>
+      </el-form-item>
+
+      <el-form-item label="品类">
+        <el-select id="category" v-model="category" placeholder="请选择">
+          <el-option value="FOOD" label="食品"/>
+          <el-option value="CLOTHES" label="服饰"/>
+          <el-option value="FURNITURE" label="家具"/>
+          <el-option value="ELECTRONICS" label="电子产品"/>
+          <el-option value="ENTERTAINMENT" label="娱乐"/>
+          <el-option value="SPORTS" label="体育产品"/>
+          <el-option value="LUXURY" label="奢侈品"/>
+        </el-select>
+      </el-form-item>
+
+      <el-form-item label="单价">
+        <el-input id="price" v-model="price"
+                  required
+                  placeholder="请输入商品单价,单位(元)"/>
+      </el-form-item>
+
+      <el-form-item label="商品照片">
+        <el-upload
+            v-model:file-list="imageFileList"
+            :on-change="handleChange"
+            :on-remove="handleChange"
+            class="upload-demo"
+            list-type="picture"
+            :http-request="uploadHttpRequest"
+            drag>
+          <el-icon class="el-icon--upload">
+            <upload-filled/>
+          </el-icon>
+          <div class="el-upload__text">
+            将文件拖到此处或单击此处上传。
+          </div>
+        </el-upload>
+
+      </el-form-item>
 
+      <el-form-item>
+        <el-button @click.prevent="handleCreateProduct()" :disabled="createProductDisabled"
+                   type="primary" plain>
+          创建商品
+        </el-button>
+      </el-form-item>
+    </el-form>
+  </el-main>
 </template>
 
 
 <style scoped>
+.create-product-title {
+  margin-left: 25%;
+}
 
+.create-product-form {
+  margin-left: 25%;
+  width: 50%;
+}
 </style>

+ 157 - 2
src/views/product/ProductDetail.vue

@@ -1,18 +1,130 @@
-<!--Lab2新增-商品详情界面-->
 <script setup lang="ts">
+import {ref, computed} from "vue"
+import {router} from '../../router'
+import {Back} from "@element-plus/icons-vue"
+import {addStock, getProductById} from "../../api/product.ts"
+import {parseCategory} from "../../utils";
 
+const role = sessionStorage.getItem("role")
+
+const productId = Number(router.currentRoute.value.params.productId)
+const actualStoreId = Number(sessionStorage.getItem("storeId"))
+const productVO = ref()
+const storeId = ref(0)
+const name = ref('')
+const photoUrlList = ref([])
+const stock = ref(0)
+const category = ref('')
+const price = ref(0)
+
+const addStockNumber = ref()
+
+const hasAddStockInput = computed(() => addStockNumber.value != null)
+const addStockDisabled = computed(() => {
+  return !(hasAddStockInput.value)
+})
+
+getProductDetail()
+
+function getProductDetail() {
+  getProductById(productId).then(res => {
+    productVO.value = res.data.result
+    storeId.value = productVO.value.storeId
+    name.value = productVO.value.name
+    photoUrlList.value = productVO.value.photoUrlList
+    stock.value = productVO.value.stock
+    category.value = productVO.value.category
+    price.value = productVO.value.price
+
+    console.log(storeId)
+    console.log(actualStoreId)
+  })
+}
+
+// 添加库存按钮
+function AddStock() {
+  addStock(productId, addStockNumber.value).then(res => {
+    if (res.data.code === '000') {
+      ElMessage({
+        message: '添加库存成功!',
+        type: 'success',
+        center: true,
+      })
+      addStockNumber.value = null
+      getProductDetail()
+    } else if (res.data.code === '400') {
+      ElMessage({
+        message: res.data.msg,
+        type: 'error',
+        center: true,
+      })
+    }
+  })
+}
+
+function toBackPage() {
+  router.push("/storeDetail/" + storeId.value)
+}
 </script>
 
 
 <template>
   <el-container>
-    <!--希望把商品详情的一部分内容放在这个侧边栏里,你要真不想放也没事-->
     <el-aside width="25%" class="page-aside">
+      <div class="product-detail-aside">
+        <el-button @click="toBackPage()"
+                   type="primary" circle plain class="back-button">
+          <el-icon>
+            <Back/>
+          </el-icon>
+        </el-button>
+
+        <el-carousel trigger="click" arrow="always" indicator-position="outside">
+          <el-carousel-item v-for="item in photoUrlList" :key="item">
+            <el-image class="logo-image" :src="item" />
+          </el-carousel-item>
+        </el-carousel>
 
+        <span class="product-title">{{ name }}</span>
+
+        <el-descriptions :column="1">
+          <el-descriptions-item style="font-size: 10px" label="品类">
+            {{ parseCategory(category) }}
+          </el-descriptions-item>
+
+          <el-descriptions-item style="font-size: 10px" label="价格">
+            {{ price }} 元
+          </el-descriptions-item>
+
+          <el-descriptions-item style="font-size: 10px" label="库存">
+            {{ stock }} 件
+          </el-descriptions-item>
+        </el-descriptions>
+      </div>
     </el-aside>
 
     <el-main>
+<!--      对于顾客,他可以在这里拥有一个创建订单按钮,点击后创建订单,弹出一个订单的弹窗。-->
+<!--      他可以在弹窗中查看订单详情,并支付订单;也可以关闭弹窗,之后再在订单列表界面支付那个订单。-->
+<!--      我们期待你在这里做一个弹窗,学会弹窗的用法。-->
+<!--      当然,有其他形式的实现也可以。-->
 
+      <div v-if="role === 'STAFF' && storeId === actualStoreId">
+        <div>
+          <span class="main-title">添加库存</span>
+        </div>
+        <div class="add-stock-main">
+          <el-input class="add-stock-number-input"
+                    v-model="addStockNumber" placeholder="请输入添加库存数">
+            <template #append>件</template>
+          </el-input>
+          <br>
+          <el-button @click="AddStock" :disabled="addStockDisabled"
+                     class="add-stock-button" type="primary" plain>
+            新增库存
+          </el-button>
+        </div>
+      </div>
     </el-main>
   </el-container>
 </template>
@@ -22,4 +134,47 @@
 .page-aside {
   border-right: lightgrey solid 1px;
 }
+
+.back-button {
+  margin-top: 20px;
+  margin-bottom: 20px;
+}
+
+.product-title {
+  font-size: 30px;
+  margin-bottom: 20px;
+}
+
+.product-detail-aside {
+  width: 80%;
+  margin-left: 10%;
+  display: flex;
+  flex-direction: column;
+  justify-content: start;
+}
+
+.logo-image {
+  width: 100%;
+}
+
+.add-stock-number-input {
+  width: 300px;
+  margin-bottom: 20px;
+}
+
+.add-stock-button {
+  margin-bottom: 40px;
+}
+
+.main-title {
+  font-size: 30px;
+  margin-top: 20px;
+  margin-bottom: 20px;
+  margin-left: 20px;
+}
+
+.add-stock-main {
+  margin-top: 20px;
+  margin-left: 30px;
+}
 </style>

+ 1 - 1
src/views/store/AllStore.vue

@@ -11,7 +11,7 @@ const storeList = ref()
 // 获取商店列表
 getAllStore().then(res => {
   console.log(res)
-  storeList.value = res.result
+  storeList.value = res.data.result
 })
 
 // 点击创建商店按钮,跳转到创建商店界面

+ 74 - 12
src/views/store/CreateStore.vue

@@ -1,18 +1,51 @@
-<!--Lab2新增-创建商店界面-->
-<!--你可以选择把创建商店改成一个弹窗或其他界面的一个部分。
-这样的话,就不需要有这样一个views下的创建商店文件了,因为views下的文件一般会是一个单独的界面。
-但如果你觉得这一个部分的代码较多,合到其他文件里会使那个文件太长,
-可以在store文件夹下创建一个components子文件夹,里面存放store模块下产生的组件界面。把这个创建商店子组件放在里面
-这个传递数据的过程可能需要用到props-->
-
 <script setup lang="ts">
-import {ref} from 'vue'
-import {uploadImage} from '../../api/tools'
+import {computed, ref} from 'vue'
+import {router} from '../../router'
+import {Back, UploadFilled} from "@element-plus/icons-vue"
+import {createStore} from "../../api/store.ts"
+import {uploadImage} from "../../api/tools.ts"
 
-//这里为大家提供上传且仅能上传1张图片的代码实现。
+// 输入框值(需要前端阻拦不合法输入)
+const name = ref('')
+const location = ref('')
 const imageFileList = ref([])
 const logoUrl = ref('')
 
+const hasNameInput = computed(() => name.value != '')
+const hasLocationInput = computed(() => location.value != '')
+const hasImageFile = computed(() => logoUrl.value != '')
+const createDisabled = computed(() => {
+  return !(hasNameInput.value && hasLocationInput.value && hasImageFile.value)
+})
+
+// 创建商店按钮触发
+function handleCreateStore() {
+  const payload = {
+    name: name.value,
+    location: location.value,
+    logoUrl: logoUrl.value
+  };
+  createStore(payload).then(res => {
+    if (res.data.code === '000') {
+      ElMessage({
+        message: '添加商户成功!',
+        type: 'success',
+        center: true,
+      })
+      name.value = ''
+      location.value = ''
+      logoUrl.value = ''
+      imageFileList.value.splice(0)
+    } else if (res.data.code === '400') {
+      ElMessage({
+        message: res.data.msg,
+        type: 'error',
+        center: true,
+      })
+    }
+  })
+}
+
 function handleChange(file: any, fileList: any) {
   imageFileList.value = fileList
   let formData = new FormData()
@@ -29,13 +62,30 @@ function handleExceed() {
 function uploadHttpRequest() {
   return new XMLHttpRequest()
 }
+
+function toBackPage() {
+  router.push("/allStore")
+}
 </script>
 
 
 <template>
   <el-main>
+    <el-button @click="toBackPage()" type="primary" circle plain>
+      <el-icon><Back/></el-icon>
+    </el-button>
+
+    <h1 class="create-store-title">新建商店</h1>
 
-    <el-form>
+    <el-form label-position="left" label-width="90px" size="large" class="create-store-form">
+
+      <el-form-item label="商店名">
+        <el-input id="name" v-model="name" required placeholder="请输入商店名"/>
+      </el-form-item>
+
+      <el-form-item label="商店地址">
+        <el-input id="location" v-model="location" required placeholder="楼层-门牌号 如:3楼-305"/>
+      </el-form-item>
 
       <el-form-item label="商店Logo">
         <el-upload
@@ -57,12 +107,24 @@ function uploadHttpRequest() {
         </el-upload>
       </el-form-item>
 
+      <el-form-item>
+        <el-button @click.prevent="handleCreateStore()" :disabled="createDisabled"
+                   type="primary" plain>
+          创建商店
+        </el-button>
+      </el-form-item>
     </el-form>
-
   </el-main>
 </template>
 
 
 <style scoped>
+.create-store-title {
+  margin-left: 25%;
+}
 
+.create-store-form {
+  margin-left: 25%;
+  width: 50%;
+}
 </style>

+ 113 - 3
src/views/store/StoreDetail.vue

@@ -1,20 +1,88 @@
-<!--Lab2新增-商店详情界面-->
 <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"
 
+const role = sessionStorage.getItem("role")
+// 从当前router地址中获得storeId参数值
+const storeId = router.currentRoute.value.params.storeId
+const actualStoreId = sessionStorage.getItem("storeId")
+const storeVO = ref()
+const name = ref('')
+const logoUrl = ref('')
+const location = ref('')
+const productList = ref()
+
+console.log(storeId === actualStoreId)
+console.log(actualStoreId)
+
+getStoreById(Number(storeId)).then(res => {
+  storeVO.value = res.data.result
+  name.value = storeVO.value.name
+  logoUrl.value = storeVO.value.logoUrl
+  location.value = storeVO.value.location
+})
+
+getProductsByStoreId(Number(storeId)).then(res => {
+  productList.value = res.data.result
+})
+
+function toCreateProductPage() {
+  router.push("/createProduct/" + storeId)
+}
+
+function toProductDetailPage(productId: number) {
+  router.push("/productDetail/" + productId)
+}
+
+function toBackPage() {
+  router.push("/allStore")
+}
 </script>
 
 
 <template>
   <el-container>
-    <!--希望把商店详情的一部分内容放在这个侧边栏里,你要真不想放也没事-->
     <el-aside width="25%" class="page-aside">
+      <div class="store-detail-main">
+        <el-button @click="toBackPage()"
+                   type="primary" circle plain class="back-button">
+          <el-icon>
+            <Back/>
+          </el-icon>
+        </el-button>
+
+        <el-image class="logo-image" :src="logoUrl"/>
+
+        <span class="store-title">{{ name }}</span>
 
+        <el-descriptions :column="1">
+          <el-descriptions-item style="font-size: 10px" label="地址">
+            {{ location }}
+          </el-descriptions-item>
+        </el-descriptions>
+
+        <el-button class="create-product-button" type="primary" plain
+                   @click="toCreateProductPage()" v-if="role === 'STAFF' && storeId === actualStoreId">新增商品
+        </el-button>
+      </div>
     </el-aside>
 
     <el-main>
-
+      <div>
+        <span class="product-list-title">商品列表</span>
+      </div>
+      <div class="all-product-main">
+        <productItem class="product-item-list"
+                     v-for="productVO in productList" :productId="productVO.id"
+                     @click="toProductDetailPage(productVO.id)"/>
+      </div>
     </el-main>
   </el-container>
+
 </template>
 
 
@@ -22,4 +90,46 @@
 .page-aside {
   border-right: lightgrey solid 1px;
 }
+
+.back-button {
+  margin-top: 20px;
+  margin-bottom: 20px;
+}
+
+.store-title {
+  font-size: 30px;
+  margin-bottom: 20px;
+}
+
+.store-detail-main {
+  width: 80%;
+  margin-left: 10%;
+  display: flex;
+  flex-direction: column;
+  justify-content: start;
+}
+
+.logo-image {
+  width: 100%;
+}
+
+.create-product-button {
+  margin-top: 20px;
+}
+
+.product-list-title {
+  font-size: 30px;
+  margin-top: 20px;
+  margin-bottom: 20px;
+  margin-left: 20px;
+}
+
+.all-product-main {
+  display: flex;
+  flex-direction: row;
+  padding: 20px;
+  flex-flow: wrap;
+  align-content: start;
+  justify-content: start;
+}
 </style>

+ 4 - 5
src/views/user/Login.vue

@@ -39,11 +39,10 @@ function handleLogin() {
       userInfo().then(res => {
         sessionStorage.setItem('name', res.data.result.name)
         sessionStorage.setItem('role', res.data.result.role)
-
-        // Lab2中新增,需要为用户填入storeId,以便判断商店工作人员操作的是否是自己的商店/商店下商品
-        // sessionStorage.setItem('storeId', res.data.result.storeId)
-
-        router.push({path: "/dashboard"})
+        if (res.data.result.role === 'STAFF') {
+          sessionStorage.setItem('storeId', res.data.result.storeId)
+        }
+        router.push({path: "/allStore"})
       })
     } else if (res.data.code === '400') {
       ElMessage({