Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

Nivek 2 лет назад
Родитель
Сommit
11e8942bda

+ 2 - 0
components.d.ts

@@ -28,6 +28,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']
     Footer: typeof import('./src/components/Footer.vue')['default']
     Header: typeof import('./src/components/Header.vue')['default']

+ 2 - 0
src/api/_prefix.ts

@@ -10,3 +10,5 @@ export const PRODUCT_MODULE= `${API_MODULE}/products`
 export const ORDER_MODULE= `${API_MODULE}/orders`
 //图片模块
 export const IMAGE_MODULE= `${API_MODULE}/images`
+//优惠券模块
+export const COUPON_MODULE= `${API_MODULE}/coupons`

+ 38 - 0
src/api/coupon.ts

@@ -0,0 +1,38 @@
+import {axios} from '../utils/request'
+import {COUPON_MODULE} from './_prefix'
+
+export const getCoupons = () => {
+    return axios.get(`${COUPON_MODULE}/`, )
+        .then(res => {
+            return res;
+        })
+}
+
+export const getCouponGroups = () => {
+    return axios.get(`${COUPON_MODULE}/group`, )
+        .then(res => {
+            return res;
+        })
+}
+
+export const createCoupons = payload => {
+    return axios.post(`${COUPON_MODULE}/`, payload,
+        {headers: {'Content-Type': 'application/json'}})
+        .then(res => {
+            return res;
+        })
+}
+
+export const receiveCouponGroup = couponGroupId => {
+    return axios.post(`${COUPON_MODULE}/receive/?couponGroupId=${couponGroupId}`)
+        .then(res => {
+            return res;
+        })
+}
+
+export const getAvailableCouponsByStoreId = storeId => {
+    return axios.get(`${COUPON_MODULE}/available/?storeId=${storeId}`)
+        .then(res => {
+            return res;
+        })
+}

+ 2 - 2
src/api/order.ts

@@ -11,8 +11,8 @@ export const createOrder = payload => {
 }
 
 //订单支付
-export const payOrder = orderId => {
-    return axios.post(`${ORDER_MODULE}/pay/?orderId=${orderId}&couponId=0`)
+export const payOrder = (orderId, couponId) => {
+    return axios.post(`${ORDER_MODULE}/pay/?orderId=${orderId}&couponId=${couponId}`)
         .then(res => {
             return res;
         })

+ 7 - 2
src/components/Header.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import {CirclePlus, UserFilled, SwitchButton, Document} from "@element-plus/icons-vue";
+import {CirclePlus, UserFilled, Discount, SwitchButton, Document} from "@element-plus/icons-vue";
 import {router} from '../router'
 
 // const searchContent = ref('')
@@ -62,13 +62,18 @@ const currentIdentity = sessionStorage.getItem('role')
         </router-link>
       </el-col>
 
-
       <el-col :span="1" class="header-icon">
         <router-link to="/customer/allOrder" v-slot="{navigate}" v-if="currentIdentity === 'CUSTOMER'">
           <el-icon @click="navigate" :size="35" color="white" ><Document /></el-icon>
         </router-link>
       </el-col>
 
+      <el-col :span="1" class="header-icon">
+        <router-link to="/customer/coupon" 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="/dashboard" v-slot="{navigate}">
           <el-icon @click="navigate" :size="35" color="white" ><UserFilled /></el-icon>

+ 10 - 0
src/router/index.ts

@@ -46,6 +46,16 @@ const router = createRouter({
                     permission: ['STAFF', 'MANAGER']
                 }
             },
+            {
+                path: '/customer/coupon/',
+                name: 'manageCoupon',
+                component: () => import('../views/customer/ManageCoupon.vue'),
+            },
+            {
+                path: '/staff/coupon/',
+                name: 'releaseCoupon',
+                component: () => import('../views/staff/AllCoupon.vue'),
+            },
             {
                 path: '/productDetail/:productId',
                 name: 'productDetail',

+ 63 - 13
src/views/common/OrderItem.vue

@@ -1,6 +1,8 @@
 <script setup lang="ts">
 import {deliverOrder, getOrder, getOrderById, payOrder, commentOrder} from "../../api/order.ts";
 import {ref, computed} from "vue";
+import {getAvailableCouponsByStoreId} from "../../api/coupon.ts";
+import {ElTable} from "element-plus";
 
 const props = defineProps({
   orderId: {
@@ -23,6 +25,9 @@ const rating = ref(0)
 const status = ref('')
 const createTime= ref('')
 const finishTime = ref('')
+const storeId = ref(0)
+
+const couponId = ref(0)
 
 getOrderDetail()
 
@@ -39,10 +44,10 @@ function getOrderDetail() {
     status.value = res.result.status
     createTime.value = res.result.createTime
     finishTime.value = res.result.finishTime
+    storeId.value = res.result.storeId
   })
 }
 
-
 // 对于变化的内容使用计算属性返回响应式结果
 const statusText = computed(() => {
   switch (status.value) {
@@ -84,10 +89,11 @@ function parseType() {
 
 function handlePay() {
   orderDialogVisible.value = true
+  getAvailableCouponList()
 }
 
 function handleConfirmOrder() {
-  payOrder(props.orderId).then(res => {
+  payOrder(props.orderId, couponId.value).then(res => {
     if (res.code === '000') {
       ElMessage({
         message: '订单支付成功!',
@@ -145,7 +151,6 @@ function handleGet() {
   })
 }
 
-
 function handleComment() {
   commentDialogVisible.value = true
 }
@@ -177,7 +182,6 @@ function handleSendComment() {
   })
 }
 
-
 function switchButtonFunction() {
     switch (status.value) {
       case 'UNPAID': handlePay(); break;
@@ -188,7 +192,45 @@ function switchButtonFunction() {
     }
 }
 
+// 处理优惠券
+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>>()
+
+function getAvailableCouponList() {
+  getAvailableCouponsByStoreId(storeId.value).then(res => {
+    availableCouponList.value = res.result
+  })
+}
 
+const handleCurrentChange = (val: Coupon | undefined) => {
+  if (val) {
+    couponId.value = val.id
+  } else {
+    couponId.value = 0
+  }
+  currentRow.value = val
+}
+
+const setCurrent = (row?: User) => {
+  singleTableRef.value!.setCurrentRow(row)
+}
+
+function handleCouponType(type) {
+  if (type === "FULL_REDUCTION") {
+    return "满减"
+  } else if (type === "SPECIAL") {
+    return "折扣"
+  }
+}
 </script>
 
 <template>
@@ -242,7 +284,6 @@ function switchButtonFunction() {
           {{ content }}
         </el-descriptions-item >
       </el-descriptions>
-
     </el-card>
 
     <el-dialog v-model="orderDialogVisible">
@@ -260,14 +301,23 @@ function switchButtonFunction() {
           {{ parseType() }}
         </el-form-item>
         <el-form-item>
-          <label for="type">优惠券:</label>
-          <!--          <el-select id="type"-->
-          <!--                     v-model="type"-->
-          <!--                     placeholder="请选择"-->
-          <!--          >-->
-          <!--            <el-option value="DELIVERY">到店自提</el-option>-->
-          <!--            <el-option value="PICKUP">快递到家</el-option>-->
-          <!--          </el-select>-->
+          <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">
+                {{ handleCouponType(scope.row.type) }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="satisfaction" label="满(元)" width="180"/>
+            <el-table-column prop="minus" label="减(元)" width="180"/>
+          </el-table>
         </el-form-item>
       </el-form>
       <el-button @click="handleConfirmOrder">确认支付</el-button>

+ 79 - 21
src/views/customer/BuyProduct.vue

@@ -1,8 +1,10 @@
 <script setup lang="ts">
 import {useRouter} from "vue-router";
-import {ref} from "vue";
+import {ref, reactive, toRefs, toRaw} from "vue";
 import {getProductById} from "../../api/product.ts";
 import {createOrder, payOrder} from "../../api/order.ts";
+import {getAvailableCouponsByStoreId} from "../../api/coupon.ts";
+import {ElTable} from "element-plus";
 
 const router = useRouter();
 const productId = router.currentRoute.value.params.productId;
@@ -21,7 +23,6 @@ getProductDetail()
 
 function getProductDetail() {
   getProductById(productId).then(res => {
-    console.log(res.result)
     productVO.value = res.result
     storeId.value = productVO.value.storeId
     name.value = productVO.value.name
@@ -35,18 +36,15 @@ function getProductDetail() {
   })
 }
 
-
 const amount = ref(1)
 const totalPrice = ref(price)
 const handleChange = () => {
   totalPrice.value = amount.value * price.value
 }
-
 const type = ref()
-
 let orderDialogVisible = ref(false)
-
 const orderId = ref()
+const couponId = ref(0)
 
 function handleCreateOrder() {
   const payload = {
@@ -61,6 +59,7 @@ function handleCreateOrder() {
         type: 'success',
         center: true,
       })
+      getAvailableCouponList()
       orderId.value = res.result.id
       orderDialogVisible.value = true
     } else if (res.code === '400') {
@@ -74,7 +73,9 @@ function handleCreateOrder() {
 }
 
 function handleConfirmOrder() {
-  payOrder(orderId.value).then(res => {
+  console.log(couponId.value)
+  payOrder(orderId.value, couponId.value).then(res => {
+    console.log(res.code)
     if (res.code === '000') {
       ElMessage({
         message: '订单支付成功!',
@@ -95,6 +96,54 @@ function handleConfirmOrder() {
   })
 }
 
+function handleOrderType(type) {
+  if (type === "PICKUP") {
+    return "到店自提"
+  } else if (type === "DELIVERY") {
+    return "快递到家"
+  }
+}
+
+function handleCouponType(type) {
+  if (type === "FULL_REDUCTION") {
+    return "满减"
+  } else if (type === "SPECIAL") {
+    return "折扣"
+  }
+}
+
+// 处理优惠券
+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>>()
+
+function getAvailableCouponList() {
+  getAvailableCouponsByStoreId(storeId.value).then(res => {
+    availableCouponList.value = res.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
+}
+
 </script>
 
 <template>
@@ -102,7 +151,7 @@ function handleConfirmOrder() {
     <el-form class="buy-form-main">
       <el-form-item>
         <label for="amount">商品单价:</label>
-        {{price}}
+        {{ price }}
       </el-form-item>
       <el-form-item>
         <label for="amount">购买数量:</label>
@@ -114,8 +163,8 @@ function handleConfirmOrder() {
                    v-model="type"
                    placeholder="请选择"
         >
-          <el-option value="DELIVERY" label="到店自提" />
-          <el-option value="PICKUP" label="快递到家" />
+          <el-option value="PICKUP" label="到店自提"/>
+          <el-option value="DELIVERY" label="快递到家"/>
         </el-select>
       </el-form-item>
       <el-form-item>
@@ -131,7 +180,7 @@ function handleConfirmOrder() {
       <el-form>
         <el-form-item>
           <label for="amount">购买数量:</label>
-          {{amount}}
+          {{ amount }}
         </el-form-item>
         <el-form-item>
           <label for="discountPrice">折扣前总价:</label>
@@ -139,20 +188,29 @@ function handleConfirmOrder() {
         </el-form-item>
         <el-form-item>
           <label for="type">提货方式:</label>
-          {{ type }}
+          {{ handleOrderType(type) }}
         </el-form-item>
         <el-form-item>
-          <label for="type">优惠券:</label>
-<!--          <el-select id="type"-->
-<!--                     v-model="type"-->
-<!--                     placeholder="请选择"-->
-<!--          >-->
-<!--            <el-option value="DELIVERY">到店自提</el-option>-->
-<!--            <el-option value="PICKUP">快递到家</el-option>-->
-<!--          </el-select>-->
+          <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">
+                {{ handleCouponType(scope.row.type) }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="satisfaction" label="满(元)" width="180"/>
+            <el-table-column prop="minus" label="减(元)" width="180"/>
+          </el-table>
         </el-form-item>
       </el-form>
-      <el-button @click="handleConfirmOrder">确认支付</el-button>
+      <el-button @click="handleConfirmOrder" type="primary" plain>确认支付</el-button>
     </el-dialog>
   </div>
 </template>

+ 111 - 0
src/views/customer/ManageCoupon.vue

@@ -0,0 +1,111 @@
+<script setup lang="ts">
+import {ref} from "vue";
+import {getCouponGroups, getCoupons, receiveCouponGroup} from "../../api/coupon.ts";
+
+const myCouponList = ref()
+const receiveCouponList = ref()
+const type = ref()
+const satisfaction = ref()
+const minus = ref()
+const rest = ref()
+
+getMyCouponList()
+getReceiveCouponList()
+
+function getMyCouponList() {
+  getCoupons().then(res => {
+    myCouponList.value = res.result
+  })
+}
+
+function getReceiveCouponList() {
+  getCouponGroups().then(res => {
+    receiveCouponList.value = res.result
+  })
+}
+
+function handleType(type) {
+  if (type === "FULL_REDUCTION") {
+    return "满减"
+  } else if (type === "SPECIAL") {
+    return "折扣"
+  }
+}
+
+function receiveCoupon(couponGroupId) {
+  receiveCouponGroup(couponGroupId).then(res => {
+    if (res.code === '000') {
+      ElMessage({
+        message: '获取优惠券成功!',
+        type: 'success',
+        center: true,
+      })
+      getMyCouponList()
+      getReceiveCouponList()
+    } else if (res.code === '400') {
+      ElMessage({
+        message: res.msg,
+        type: 'error',
+        center: true,
+      })
+    }
+  })
+}
+</script>
+
+<template>
+  <div class="all-coupon-main">
+    <span class="this-title">我的优惠券</span>
+    <el-table :data="myCouponList" stripe class="coupon-table">
+      <el-table-column type="index" width="50" />
+      <el-table-column prop="type" label="类型" width="180">
+        <template #default="scope">
+          {{ handleType(scope.row.type) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="satisfaction" label="满(元)" width="180" />
+      <el-table-column prop="minus" label="减(元)" width="180" />
+      <el-table-column prop="storeId" label="所属商店" width="180" />
+      <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>
+
+    <span class="this-title">获取优惠券</span>
+    <el-table :data="receiveCouponList" stripe class="coupon-table">
+      <el-table-column type="index" width="50" />
+      <el-table-column prop="type" label="类型" width="180">
+        <template #default="scope">
+          {{ handleType(scope.row.type) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="satisfaction" label="满(元)" width="180" />
+      <el-table-column prop="minus" label="减(元)" width="180" />
+      <el-table-column prop="rest" label="数量(张)" width="180" />
+      <el-table-column label="操作">
+        <template #default="scope">
+          <el-button @click="receiveCoupon(scope.row.id)" type="primary" plain>领取</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<style scoped>
+.all-coupon-main {
+  margin-left: 20px;
+  margin-top: 20px;
+}
+
+.this-title {
+  font-size: large;
+  margin-bottom: 20px;
+}
+
+.coupon-table {
+  margin-bottom: 30px;
+}
+</style>

+ 0 - 1
src/views/manager/CreateStore.vue

@@ -117,7 +117,6 @@ function handleCreateStore() {
             <label for="location">商店地址</label>
             <el-input id="location" v-model="location"
                    required
-
                    placeholder="楼层-门牌号 如:3楼-305" />
           </el-form-item>
 

+ 1 - 7
src/views/portal/AllStore.vue

@@ -6,7 +6,6 @@ import {getAllStore} from "../../api/store.ts"
 import {useRouter} from "vue-router"
 
 const router = useRouter()
-const userId = router.currentRoute.value.params.userId
 
 let storeList = ref()
 
@@ -18,19 +17,14 @@ function getStoreList() {
   })
 }
 
-function toStoreDetailPage(storeId) {
+function toStoreDetailPage(storeId: Number) {
   router.push("/storeDetail/" + storeId);
 }
 
-function toAllOrderPage() {
-  router.push("/customer/allOrder");
-}
 </script>
 
 <template>
   <el-main class="store-item-list">
-<!--    我挪到header去了 -->
-<!--    <el-button @click="toAllOrderPage">全部订单</el-button>-->
     <StoreItem
                v-for="storeVO in storeList" :storeId="storeVO.id"
                @click="toStoreDetailPage(storeVO.id)" />

+ 0 - 1
src/views/portal/StoreDetail.vue

@@ -69,7 +69,6 @@ function toProductDetailPage(productId) {
       <productItem class="product-item-list"
                    v-for="productVO in productList" :productId="productVO.id"
                    @click="toProductDetailPage(productVO.id)" />
-
     </div>
   </div>
 </template>

+ 166 - 0
src/views/staff/AllCoupon.vue

@@ -0,0 +1,166 @@
+<script setup lang="ts">
+import {ref} from "vue";
+import {createCoupons, getCouponGroups, receiveCouponGroup} from "../../api/coupon.ts";
+
+const couponList = ref()
+const type = ref()
+const satisfaction = ref()
+const minus = ref()
+const rest = ref()
+
+
+getCouponList()
+
+function getCouponList() {
+  getCouponGroups().then(res => {
+    couponList.value = res.result
+  })
+}
+
+let couponDialogVisible = ref(false)
+
+function toCreateCoupon() {
+  couponDialogVisible.value = true
+}
+
+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.code === '000') {
+      ElMessage({
+        message: '创建优惠券成功!',
+        type: 'success',
+        center: true,
+      })
+      type.value = ''
+      satisfaction.value = null
+      minus.value = null
+      rest.value = null
+    } else if (res.code === '400') {
+      ElMessage({
+        message: res.msg,
+        type: 'error',
+        center: true,
+      })
+    }
+  })
+}
+
+function handleType(type) {
+  if (type === "FULL_REDUCTION") {
+    return "满减"
+  } else if (type === "SPECIAL") {
+    return "折扣"
+  }
+}
+
+function receiveCoupon(couponGroupId) {
+  receiveCouponGroup(couponGroupId).then(res => {
+    console.log(res)
+    if (res.code === '000') {
+      ElMessage({
+        message: '获取优惠券成功!',
+        type: 'success',
+        center: true,
+      })
+      getCouponList()
+    } else if (res.code === '400') {
+      ElMessage({
+        message: res.msg,
+        type: 'error',
+        center: true,
+      })
+    }
+  })
+}
+</script>
+
+<template>
+  <el-button class="create-coupon-button" type="primary" plain
+             @click="toCreateCoupon()">新增优惠券
+  </el-button>
+
+  <div class="all-coupon-main">
+    <el-table :data="couponList" style="width: 100%" stripe>
+      <el-table-column type="index" width="50" />
+      <el-table-column prop="type" label="类型" width="180">
+        <template #default="scope">
+          {{ handleType(scope.row.type) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="satisfaction" label="满(元)" width="180" />
+      <el-table-column prop="minus" label="减(元)" width="180" />
+      <el-table-column prop="rest" label="数量(张)" width="180" />
+      <el-table-column label="操作">
+        <template #default="scope">
+          <el-button @click="receiveCoupon(scope.row.id)" type="primary" plain>领取</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+
+  <el-dialog v-model="couponDialogVisible" title="创建优惠券">
+    <el-form>
+      <el-form-item>
+        <label for="type">类型:</label>
+        <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">满:</label>
+        <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">减:</label>
+        <el-input id="minus" v-model="minus" required placeholder="请输入金额"
+                  class="create-coupon-dialog-input">
+          <template #append>元</template>
+        </el-input>
+      </el-form-item>
+      <el-form-item>
+        <label for="rest">数量:</label>
+        <el-input id="rest" v-model="rest" required placeholder="请输入数量"
+                  class="create-coupon-dialog-input">
+          <template #append>张</template>
+        </el-input>
+      </el-form-item>
+
+      <el-form-item>
+        <button @click.prevent="handleCreateCoupon()">
+          添加
+        </button>
+      </el-form-item>
+    </el-form>
+  </el-dialog>
+</template>
+
+<style scoped>
+.create-coupon-button {
+  width: 100px;
+  margin-left: 20px;
+  margin-top: 30px;
+}
+
+.all-coupon-main {
+  margin-left: 20px;
+  margin-top: 20px;
+}
+
+.create-coupon-dialog-input {
+  width: 200px;
+}
+</style>