Explorar el Código

初步完成Lab5代码

chillqi hace 2 años
padre
commit
87e7b5ebb0

+ 3 - 0
components.d.ts

@@ -8,6 +8,7 @@ export {}
 declare module 'vue' {
   export interface GlobalComponents {
     CommentItem: typeof import('./src/components/CommentItem.vue')['default']
+    ElAlert: typeof import('element-plus/es')['ElAlert']
     ElAside: typeof import('element-plus/es')['ElAside']
     ElButton: typeof import('element-plus/es')['ElButton']
     ElCard: typeof import('element-plus/es')['ElCard']
@@ -30,6 +31,8 @@ declare module 'vue' {
     ElRate: typeof import('element-plus/es')['ElRate']
     ElRow: typeof import('element-plus/es')['ElRow']
     ElSelect: typeof import('element-plus/es')['ElSelect']
+    ElTable: typeof import('element-plus/es')['ElTable']
+    ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
     ElTag: typeof import('element-plus/es')['ElTag']
     Header: typeof import('./src/components/Header.vue')['default']
     OrderItem: typeof import('./src/components/OrderItem.vue')['default']

+ 2 - 2
src/api/_prefix.ts

@@ -9,6 +9,6 @@ export const STORE_MODULE = `${API_MODULE}/stores`
 export const PRODUCT_MODULE = `${API_MODULE}/products`
 //订单模块
 export const ORDER_MODULE= `${API_MODULE}/orders`
+//优惠券模块
+export const COUPON_MODULE= `${API_MODULE}/coupons`
 
-//Lab4新增
-//需要添加优惠券模块的api

+ 50 - 0
src/api/coupon.ts

@@ -0,0 +1,50 @@
+import {axios} from '../utils/request'
+import {COUPON_MODULE} from './_prefix'
+
+type CouponInfo = {
+    type: string,
+    satisfaction?: number,
+    minus?: number,
+    rest?: number
+}
+
+// 获取已有优惠券
+export const getCoupons = () => {
+    return axios.get(`${COUPON_MODULE}/`,)
+        .then(res => {
+            return res
+        })
+}
+
+// 查看优惠券组(剩余数量大于0、未领取过的优惠券组/门店下优惠券组/全部优惠券组)
+export const getCouponGroups = () => {
+    return axios.get(`${COUPON_MODULE}/group`,)
+        .then(res => {
+            return res
+        })
+}
+
+// 创建优惠券
+export const createCoupons = (couponInfo: CouponInfo) => {
+    return axios.post(`${COUPON_MODULE}/`, couponInfo,
+        {headers: {'Content-Type': 'application/json'}})
+        .then(res => {
+            return res
+        })
+}
+
+// 领取优惠券
+export const receiveCouponGroup = (couponGroupId: number) => {
+    return axios.post(`${COUPON_MODULE}/receive/?couponGroupId=${couponGroupId}`)
+        .then(res => {
+            return res
+        })
+}
+
+// 获取门店下可用优惠券
+export const getAvailableCouponsByStoreId = (storeId: number) => {
+    return axios.get(`${COUPON_MODULE}/available/?storeId=${storeId}`)
+        .then(res => {
+            return res
+        })
+}

+ 12 - 4
src/api/order.ts

@@ -23,8 +23,16 @@ export const createOrder = (orderInfo: OrderInfo) => {
 }
 
 // 订单支付(你可能需要修改这个方法,把优惠券加进来)
-export const payOrder = (orderId: number) => {
-    return axios.post(`${ORDER_MODULE}/pay/?orderId=${orderId}`)
+export const payOrder = (orderId: number, couponId: number) => {
+    return axios.post(`${ORDER_MODULE}/pay/?orderId=${orderId}&couponId=${couponId}`)
+        .then(res => {
+            return res
+        })
+}
+
+// 预计算价格
+export const calculateOrder = (orderId: number, couponId: number) => {
+    return axios.get(`${ORDER_MODULE}/calculate/?orderId=${orderId}&couponId=${couponId}`)
         .then(res => {
             return res
         })
@@ -32,7 +40,7 @@ export const payOrder = (orderId: number) => {
 
 // 获取全部订单(用户下订单/门店下订单/全部订单)
 export const getAllOrder = () => {
-    return axios.get(`${ORDER_MODULE}/`, )
+    return axios.get(`${ORDER_MODULE}/`,)
         .then(res => {
             return res
         })
@@ -40,7 +48,7 @@ export const getAllOrder = () => {
 
 // 根据订单Id获取单个订单
 export const getOrderById = (orderId: number) => {
-    return axios.get(`${ORDER_MODULE}/${orderId}`, )
+    return axios.get(`${ORDER_MODULE}/${orderId}`,)
         .then(res => {
             return res
         })

+ 7 - 9
src/components/Header.vue

@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import {router} from '../router'
 import {parseRole} from "../utils"
-import {User, Document, SwitchButton} from "@element-plus/icons-vue"   //图标
+import {User, Document, Discount, SwitchButton} from "@element-plus/icons-vue"   //图标
 
 const role = sessionStorage.getItem('role')    //登录的时候插入的
 
@@ -41,7 +41,7 @@ function logout() {
         <el-tag class="role-tag" size="large">{{ parseRole(role) }}版</el-tag>
       </el-col>
 
-      <el-col :span="16">
+      <el-col :span="15">
       </el-col>
 
       <el-col :span="1" class="header-icon">
@@ -56,13 +56,11 @@ function logout() {
         </router-link>
       </el-col>
 
-<!--      Lab4新增 -->
-<!--      或许你可以在这里新增一个按钮,然后新增一个全部优惠券的界面-->
-<!--      <el-col :span="1" class="header-icon">-->
-<!--        <router-link to="/allCoupon" v-slot="{navigate}">-->
-<!--          <el-icon @click="navigate" :size="35" color="white" ><Discount /></el-icon>-->
-<!--        </router-link>-->
-<!--      </el-col>-->
+      <el-col :span="1" class="header-icon">
+        <router-link to="/allCoupon" v-slot="{navigate}">
+          <el-icon @click="navigate" :size="35" color="white" ><Discount /></el-icon>
+        </router-link>
+      </el-col>
 
       <el-col :span="1" class="header-icon">
         <a @click="logout">

+ 83 - 10
src/components/PayDialog.vue

@@ -1,7 +1,9 @@
 <script setup lang="ts">
 import {ref} from "vue"
-import {getOrderById, payOrder} from "../api/order.ts"
-import {parseOrderType} from "../utils"
+import {calculateOrder, getOrderById, payOrder} from "../api/order.ts"
+import {getAvailableCouponsByStoreId} from "../api/coupon.ts"
+import {parseOrderType, parseCouponType} from "../utils/index.ts"
+import {ElTable} from "element-plus"
 
 const saveOrderId = ref(0)
 const orderDialogVisible = ref(false)
@@ -23,20 +25,25 @@ defineExpose({
 const amount = ref(0)
 const price = ref(0)
 const type = ref('')
+const storeId = ref(0)
 const totalPrice = ref(0)
+const couponId = ref(0)
+const discountPrice = ref(0)
 
 function getOrderDetail(orderId: number) {
   getOrderById(orderId).then(res => {
     amount.value = res.data.result.amount
     type.value = res.data.result.type
     price.value = res.data.result.price
+    storeId.value = res.data.result.storeId
     //根据商品单价和购买数量计算总价
     totalPrice.value = price.value * amount.value
+    discountPrice.value = totalPrice.value
   })
 }
 
 function handleConfirmOrder() {
-  payOrder(saveOrderId.value).then(res => {
+  payOrder(saveOrderId.value, couponId.value).then(res => {
     if (res.data.code === '000') {
       ElMessage({
         message: '订单支付成功!',
@@ -57,6 +64,41 @@ function handleConfirmOrder() {
     orderDialogVisible.value = false
   })
 }
+
+// 处理优惠券
+interface Coupon {
+  id: number
+  groupId: number
+  type: string
+  satisfaction: number
+  minus: number
+}
+
+const availableCouponList = ref<Coupon[]>([])
+const currentRow = ref()
+const singleTableRef = ref<InstanceType<typeof ElTable>>()
+
+
+getAvailableCouponsByStoreId(storeId.value).then(res => {
+  availableCouponList.value = res.data.result
+})
+
+
+const setCurrent = (row?: User) => {
+  singleTableRef.value!.setCurrentRow(row)
+}
+
+const handleCurrentChange = (val: Coupon | undefined) => {
+  if (val) {
+    couponId.value = val.id
+  } else {
+    couponId.value = 0
+  }
+  currentRow.value = val
+  calculateOrder(saveOrderId.value, couponId.value).then(res => {
+    discountPrice.value = res.data.result
+  })
+}
 </script>
 
 
@@ -81,13 +123,44 @@ function handleConfirmOrder() {
           {{ totalPrice }} 元
         </el-form-item>
 
-        <!--你可能会在这里添入优惠券的选用、并展示折扣后总价-->
-<!--        <el-form-item>-->
-<!--          <label for="type">优惠券:</label>-->
-<!--        </el-form-item>-->
-<!--        <el-form-item>-->
-<!--          <label>折扣后金额:</label>-->
-<!--        </el-form-item>-->
+        <el-form-item>
+          <label for="type">优惠券:</label>
+          <el-button @click="setCurrent()">不使用优惠券</el-button>
+          <el-table
+              ref="singleTableRef"
+              :data="availableCouponList"
+              highlight-current-row
+              style="width: 100%"
+              @current-change="handleCurrentChange"
+          >
+            <el-table-column type="index" width="50"/>
+            <el-table-column prop="type" label="类型" width="180">
+              <template #default="scope">
+                <el-tag v-if="scope.row.type === 'FULL_REDUCTION'">
+                  {{ parseCouponType(scope.row.type) }}
+                </el-tag>
+                <el-tag v-if="scope.row.type === 'SPECIAL'" type="success">
+                  {{ parseCouponType(scope.row.type) }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="satisfaction" label="满(元)" width="180">
+              <template #default="scope">
+                {{ scope.row.satisfaction }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="minus" label="减(元)" width="180">
+              <template #default="scope">
+                {{ scope.row.minus }}
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form-item>
+
+        <el-form-item>
+          <label>折扣后金额:</label>
+          {{ discountPrice.toFixed(2) }} 元
+        </el-form-item>
 
       </el-form>
 

+ 8 - 3
src/router/index.ts

@@ -68,9 +68,14 @@ const router = createRouter({
                     title: '全部订单',
                 }
             },
-
-        //  如果优惠券模块有新增界面,记得添加在这里
-
+            {
+                path: '/allCoupon/',
+                name: 'allCoupon',
+                component: () => import('../views/coupon/AllCoupon.vue'),
+                meta: {
+                    title: '优惠券',
+                }
+            },
         ]
     }, {
         path: '/404',

+ 9 - 0
src/utils/index.ts

@@ -56,3 +56,12 @@ export function parseRating(rating: number|null) {
         return Number(rating.toFixed(1))
     }
 }
+
+//将优惠券类型转化为中文显示
+export function parseCouponType(type: string) {
+    if (type === "FULL_REDUCTION") {
+        return "满减"
+    } else if (type === "SPECIAL") {
+        return "蓝鲸券"
+    }
+}

+ 285 - 0
src/views/coupon/AllCoupon.vue

@@ -0,0 +1,285 @@
+<script setup lang="ts">
+import {computed, ref} from "vue";
+import {createCoupons, getCouponGroups, getCoupons, receiveCouponGroup} from "../../api/coupon";
+import {userInfo} from "../../api/user";
+import {parseCouponType, parseOrderType} from "../../utils";
+
+const role = sessionStorage.getItem("role")
+const myCouponList = ref()
+const receiveCouponList = ref()
+const type = ref()
+const satisfaction = ref(undefined)
+const minus = ref(undefined)
+const rest = ref(undefined)
+const storeName = ref()
+
+userInfo().then(res => {
+  storeName.value = res.data.result.storeName
+})
+
+getMyCouponList()
+getReceiveCouponList()
+
+function getMyCouponList() {
+  getCoupons().then(res => {
+    myCouponList.value = res.data.result
+  })
+}
+
+function getReceiveCouponList() {
+  getCouponGroups().then(res => {
+    receiveCouponList.value = res.data.result
+  })
+}
+
+const hasTypeInput = computed(() => type.value != null)
+const hasSatisfactionInput = computed(() => satisfaction.value != '')
+const hasMinusInput = computed(() => minus.value != '')
+const hasRestInput = computed(() => rest.value != '')
+
+const createCouponDisabled = computed(() => {
+  if (type.value === 'FULL_REDUCTION') {
+    return !(hasTypeInput.value && hasSatisfactionInput.value && hasMinusInput.value && hasRestInput.value);
+  } else if (type.value === 'SPECIAL') {
+    return !(hasTypeInput.value && hasRestInput.value);
+  } else {
+    return true;
+  }
+})
+
+const couponDialogVisible = ref(false)
+
+function toCreateCoupon() {
+  couponDialogVisible.value = true
+}
+
+function handleCloseCouponDialog() {
+  type.value = null
+  satisfaction.value = undefined
+  minus.value = undefined
+  rest.value = undefined
+  couponDialogVisible.value = false
+}
+
+function handleCreateCoupon() {
+  const payload = {
+    type: type.value,
+    satisfaction: satisfaction.value,
+    minus: minus.value,
+    rest: rest.value
+  }
+  couponDialogVisible.value = false
+  createCoupons(payload).then(res => {
+    if (res.data.code === '000') {
+      ElMessage({
+        message: '创建优惠券成功!',
+        type: 'success',
+        center: true,
+      })
+      getReceiveCouponList()
+      type.value = ''
+      satisfaction.value = undefined
+      minus.value = undefined
+      rest.value = undefined
+    } else if (res.data.code === '400') {
+      ElMessage({
+        message: res.data.msg,
+        type: 'error',
+        center: true,
+      })
+    }
+  })
+}
+
+function receiveCoupon(couponGroupId: number) {
+  receiveCouponGroup(couponGroupId).then(res => {
+    if (res.data.code === '000') {
+      ElMessage({
+        message: '获取优惠券成功!',
+        type: 'success',
+        center: true,
+      })
+      getMyCouponList()
+      getReceiveCouponList()
+    } else if (res.data.code === '400') {
+      ElMessage({
+        message: res.data.msg,
+        type: 'error',
+        center: true,
+      })
+    }
+  })
+}
+</script>
+
+
+<template>
+  <div>
+    <el-button @click="toCreateCoupon()" v-if="role === 'MANAGER' || role === 'STAFF'"
+               class="create-coupon-button" type="primary" plain>
+      新增优惠券
+    </el-button>
+
+    <el-dialog v-model="couponDialogVisible" title="创建优惠券" :before-close="handleCloseCouponDialog">
+      <el-form label-width="100px" class="create-coupon-form">
+        <el-form-item label="应用范围:">
+          <span v-if="role === 'MANAGER'">全平台</span>
+          <span v-if="role === 'STAFF'">{{ storeName }}</span>
+        </el-form-item>
+
+        <el-form-item label="类型:" for="type">
+          <el-select id="identity"
+                     v-model="type"
+                     placeholder="请选择"
+          >
+            <el-option value="FULL_REDUCTION" label="满减"/>
+            <el-option value="SPECIAL" label="蓝鲸券"/>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="满:" for="satisfaction" v-if="type === 'FULL_REDUCTION'">
+          <el-input id="satisfaction" v-model="satisfaction"
+                    required placeholder="请输入金额" class="create-coupon-dialog-input">
+            <template #append>元</template>
+          </el-input>
+        </el-form-item>
+
+        <el-form-item label="减:" for="minus" v-if="type === 'FULL_REDUCTION'">
+          <el-input id="minus" v-model="minus" required placeholder="请输入金额"
+                    class="create-coupon-dialog-input">
+            <template #append>元</template>
+          </el-input>
+        </el-form-item>
+
+        <el-alert v-if="type === 'SPECIAL'"
+                  title="“蓝鲸券”使用规则:" type="success" :closable="false" class="special-alert">
+          * 0-100元区间打九五折;<br>
+          * 200-300元区间打八五折;<br>
+          * 300-400元区间打八折;<br>
+          * 400-500元区间打七五折;<br>
+          * 500元以上区间打七折。<br>
+        </el-alert>
+
+        <el-form-item label="数量:" for="rest">
+          <el-input id="rest" v-model="rest" required placeholder="请输入数量"
+                    class="create-coupon-dialog-input">
+            <template #append>张</template>
+          </el-input>
+        </el-form-item>
+
+        <el-button @click.prevent="handleCreateCoupon()" :disabled="createCouponDisabled"
+                   type="primary" plain>
+          创建
+        </el-button>
+
+      </el-form>
+    </el-dialog>
+
+    <div class="all-coupon-main">
+      <div>
+        <span class="this-title" v-if="role === 'CUSTOMER'">可获取优惠券</span>
+        <span class="this-title" v-if="role === 'MANAGER'">全部优惠券</span>
+        <span class="this-title" v-if="role === 'STAFF'">门店下优惠券</span>
+        <el-table :data="receiveCouponList" stripe class="coupon-table">
+          <el-table-column type="index" width="50"/>
+          <el-table-column prop="storeName" label="所属商店" width="180"/>
+          <el-table-column prop="type" label="类型" width="180">
+            <template #default="scope">
+              <el-tag v-if="scope.row.type === 'FULL_REDUCTION'">
+                {{ parseCouponType(scope.row.type) }}
+              </el-tag>
+              <el-tag v-if="scope.row.type === 'SPECIAL'" type="success">
+                {{ parseCouponType(scope.row.type) }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column prop="satisfaction" label="满(元)" width="180">
+            <template #default="scope">
+              {{ scope.row.satisfaction }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="minus" label="减(元)" width="180">
+            <template #default="scope">
+              {{ scope.row.minus }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="rest" label="剩余数量(张)" width="180"/>
+          <el-table-column label="操作" v-if="role === 'CUSTOMER'">
+            <template #default="scope">
+              <el-button @click="receiveCoupon(scope.row.id)"
+                         size="small" type="primary" plain>
+                领取
+              </el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+
+      <div v-if="role === 'CUSTOMER'">
+        <span class="this-title">我的优惠券</span>
+        <el-table :data="myCouponList" stripe class="coupon-table">
+          <el-table-column type="index" width="50"/>
+          <el-table-column prop="storeName" label="所属商店" width="180"/>
+          <el-table-column prop="type" label="类型" width="180">
+            <template #default="scope">
+              <el-tag v-if="scope.row.type === 'FULL_REDUCTION'">
+                {{ parseCouponType(scope.row.type) }}
+              </el-tag>
+              <el-tag v-if="scope.row.type === 'SPECIAL'" type="success">
+                {{ parseCouponType(scope.row.type) }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column prop="satisfaction" label="满(元)" width="180">
+            <template #default="scope">
+              {{ scope.row.satisfaction }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="minus" label="减(元)" width="180">
+            <template #default="scope">
+              {{ scope.row.minus }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="used" label="状态" width="180">
+            <template #default="scope">
+              <el-tag v-if="scope.row.used === false" type="success">待使用</el-tag>
+              <el-tag v-if="scope.row.used === true" type="info">已使用</el-tag>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+  </div>
+</template>
+
+
+<style scoped>
+.create-coupon-button {
+  width: 100px;
+  margin-left: 20px;
+  margin-top: 30px;
+}
+
+.create-coupon-form {
+  width: 60%;
+}
+
+.special-alert {
+  margin-bottom: 15px;
+}
+
+.all-coupon-main {
+  margin-left: 80px;
+  margin-top: 30px;
+}
+
+.this-title {
+  font-size: large;
+  margin-top: 20px;
+  margin-bottom: 20px;
+}
+
+.coupon-table {
+  margin-bottom: 30px;
+}
+</style>