|
@@ -0,0 +1,394 @@
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import {useRouter} from "vue-router";
|
|
|
|
|
+import {ref, onMounted} from "vue";
|
|
|
|
|
+import {addStock, getProductById} from "../../api/product.ts";
|
|
|
|
|
+import {Back} from "@element-plus/icons-vue";
|
|
|
|
|
+import {ElTable} from "element-plus";
|
|
|
|
|
+import {createOrder, payOrder} from "../../api/order.ts";
|
|
|
|
|
+import {getAvailableCouponsByStoreId} from "../../api/coupon.ts";
|
|
|
|
|
+
|
|
|
|
|
+const router = useRouter();
|
|
|
|
|
+const role = sessionStorage.getItem("role")
|
|
|
|
|
+const productId = router.currentRoute.value.params.productId;
|
|
|
|
|
+const productVO = ref()
|
|
|
|
|
+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('')
|
|
|
|
|
+const price = ref(0)
|
|
|
|
|
+
|
|
|
|
|
+const photoUrl = ref(0)
|
|
|
|
|
+
|
|
|
|
|
+const amount = ref(1)
|
|
|
|
|
+const totalPrice = ref(price.value)
|
|
|
|
|
+const handleChange = () => {
|
|
|
|
|
+ totalPrice.value = amount.value * price.value
|
|
|
|
|
+}
|
|
|
|
|
+const type = ref()
|
|
|
|
|
+let orderDialogVisible = ref(false)
|
|
|
|
|
+const orderId = ref()
|
|
|
|
|
+const couponId = ref(0)
|
|
|
|
|
+
|
|
|
|
|
+getProductDetail()
|
|
|
|
|
+
|
|
|
|
|
+function getProductDetail() {
|
|
|
|
|
+ getProductById(productId).then(res => {
|
|
|
|
|
+ productVO.value = res.result
|
|
|
|
|
+ storeId.value = productVO.value.storeId
|
|
|
|
|
+ name.value = productVO.value.name
|
|
|
|
|
+ photoUrlList.value = productVO.value.photoUrlList
|
|
|
|
|
+ rating.value = productVO.value.rating
|
|
|
|
|
+ number.value = productVO.value.number
|
|
|
|
|
+ salesAmount.value = productVO.value.salesAmount
|
|
|
|
|
+ stock.value = productVO.value.stock
|
|
|
|
|
+ category.value = productVO.value.category
|
|
|
|
|
+ price.value = productVO.value.price
|
|
|
|
|
+
|
|
|
|
|
+ photoUrl.value = photoUrlList.value[0]
|
|
|
|
|
+ totalPrice.value = price.value
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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 "奢侈品"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const addStockNumber = ref(null)
|
|
|
|
|
+
|
|
|
|
|
+function AddStock() {
|
|
|
|
|
+ if (addStockNumber.value === null) {
|
|
|
|
|
+ ElMessage({
|
|
|
|
|
+ message: "请输入添加库存数!",
|
|
|
|
|
+ type: 'error',
|
|
|
|
|
+ center: true,
|
|
|
|
|
+ })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ addStock(productId, addStockNumber.value).then(res => {
|
|
|
|
|
+ if (res.code === '000') {
|
|
|
|
|
+ ElMessage({
|
|
|
|
|
+ message: '添加库存成功!',
|
|
|
|
|
+ type: 'success',
|
|
|
|
|
+ center: true,
|
|
|
|
|
+ })
|
|
|
|
|
+ addStockNumber.value = null
|
|
|
|
|
+ getProductDetail()
|
|
|
|
|
+ } else if (res.code === '400') {
|
|
|
|
|
+ ElMessage({
|
|
|
|
|
+ message: res.msg,
|
|
|
|
|
+ type: 'error',
|
|
|
|
|
+ center: true,
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function handleCreateOrder() {
|
|
|
|
|
+ const payload = {
|
|
|
|
|
+ productId: productId,
|
|
|
|
|
+ amount: amount.value,
|
|
|
|
|
+ type: type.value
|
|
|
|
|
+ };
|
|
|
|
|
+ createOrder(payload).then(res => {
|
|
|
|
|
+ if (res.code === '000') {
|
|
|
|
|
+ ElMessage({
|
|
|
|
|
+ message: '创建订单成功!',
|
|
|
|
|
+ type: 'success',
|
|
|
|
|
+ center: true,
|
|
|
|
|
+ })
|
|
|
|
|
+ getAvailableCouponList()
|
|
|
|
|
+ orderId.value = res.result.id
|
|
|
|
|
+ orderDialogVisible.value = true
|
|
|
|
|
+ } else if (res.code === '400') {
|
|
|
|
|
+ ElMessage({
|
|
|
|
|
+ message: res.msg,
|
|
|
|
|
+ type: 'error',
|
|
|
|
|
+ center: true,
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const showForm = ref(false);
|
|
|
|
|
+
|
|
|
|
|
+function handleConfirmOrder() {
|
|
|
|
|
+ console.log(couponId.value)
|
|
|
|
|
+ payOrder(orderId.value, couponId.value).then(res => {
|
|
|
|
|
+ console.log(res)
|
|
|
|
|
+ const paymentWindow = window.open('', '_blank');
|
|
|
|
|
+ paymentWindow.document.write(res);
|
|
|
|
|
+ paymentWindow.document.forms[0].submit(); // 提交表单
|
|
|
|
|
+ showForm.value = false; // 隐藏表单
|
|
|
|
|
+ if (res.code === '000') {
|
|
|
|
|
+ ElMessage({
|
|
|
|
|
+ message: '订单支付成功!',
|
|
|
|
|
+ type: 'success',
|
|
|
|
|
+ center: true,
|
|
|
|
|
+ })
|
|
|
|
|
+ orderDialogVisible.value = false
|
|
|
|
|
+ amount.value = 1
|
|
|
|
|
+ type.value = ''
|
|
|
|
|
+ totalPrice.value = price.value
|
|
|
|
|
+ } else if (res.code === '400') {
|
|
|
|
|
+ ElMessage({
|
|
|
|
|
+ message: res.msg,
|
|
|
|
|
+ type: 'error',
|
|
|
|
|
+ center: true,
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ showForm.value = true; // 组件加载后显示表单
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+function parseOrderType(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
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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-image class="logo-image" :src="photoUrl"/>
|
|
|
|
|
+
|
|
|
|
|
+ <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="评分">
|
|
|
|
|
+ <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>
|
|
|
|
|
+
|
|
|
|
|
+ <el-descriptions-item style="font-size: 10px" label="库存">
|
|
|
|
|
+ {{ stock }} 件
|
|
|
|
|
+ </el-descriptions-item>
|
|
|
|
|
+ </el-descriptions>
|
|
|
|
|
+
|
|
|
|
|
+ <el-input class="add-stock-number-input" v-if="role === 'STAFF'"
|
|
|
|
|
+ v-model="addStockNumber" placeholder="请输入添加库存数" />
|
|
|
|
|
+ <el-button class="add-stock-button" @click="AddStock" v-if="role === 'STAFF'"
|
|
|
|
|
+ type="primary" plain>
|
|
|
|
|
+ 新增库存
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-aside>
|
|
|
|
|
+
|
|
|
|
|
+ <el-main>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <span class="buy-product-title">购买商品</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-form ref="form" v-if="showForm">
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <el-form class="buy-form-main">
|
|
|
|
|
+ <el-form-item>
|
|
|
|
|
+ <label for="amount">购买数量:</label>
|
|
|
|
|
+ <el-input-number v-model="amount" :min="1" :max="stock + 10" @change="handleChange"/>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item>
|
|
|
|
|
+ <label for="type">提货方式:</label>
|
|
|
|
|
+ <el-select id="type"
|
|
|
|
|
+ v-model="type"
|
|
|
|
|
+ placeholder="请选择"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option value="PICKUP" label="到店自提"/>
|
|
|
|
|
+ <el-option value="DELIVERY" label="快递到家"/>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item>
|
|
|
|
|
+ <label for="discountPrice">折扣前总价:</label>
|
|
|
|
|
+ {{ totalPrice }} 元
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <el-button class="buy-button"
|
|
|
|
|
+ @click="handleCreateOrder">创建订单
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+
|
|
|
|
|
+ <el-dialog v-model="orderDialogVisible">
|
|
|
|
|
+ <el-form>
|
|
|
|
|
+ <el-form-item>
|
|
|
|
|
+ <label for="amount">购买数量:</label>
|
|
|
|
|
+ {{ amount }} 件
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item>
|
|
|
|
|
+ <label for="discountPrice">折扣前总价:</label>
|
|
|
|
|
+ {{ totalPrice }} 元
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item>
|
|
|
|
|
+ <label for="type">提货方式:</label>
|
|
|
|
|
+ {{ parseOrderType(type) }}
|
|
|
|
|
+ </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">
|
|
|
|
|
+ {{ 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" type="primary" plain>确认支付</el-button>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ </el-main>
|
|
|
|
|
+ </el-container>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+.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 {
|
|
|
|
|
+ margin-top: 15px;
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.add-stock-button {
|
|
|
|
|
+ margin-bottom: 40px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.buy-product-title {
|
|
|
|
|
+ font-size: 30px;
|
|
|
|
|
+ margin-top: 20px;
|
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
|
+ margin-left: 20px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.buy-form-main {
|
|
|
|
|
+ margin-top: 20px;
|
|
|
|
|
+ margin-left: 30px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.buy-button {
|
|
|
|
|
+ margin-left: 30px;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|