mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-11-10 02:49:03 +08:00
Merge branch 'master' into salesman
This commit is contained in:
@@ -248,6 +248,7 @@ import Promotion from "@/components/goodsDetail/Promotion";
|
||||
import Search from "@/components/Search";
|
||||
import * as APICart from "@/api/cart";
|
||||
import * as APIMember from "@/api/member";
|
||||
import { isECoupon } from "@/constants/goodsType";
|
||||
export default {
|
||||
name: "Cart",
|
||||
beforeRouteEnter(to, from, next) {
|
||||
@@ -407,11 +408,20 @@ export default {
|
||||
},
|
||||
// 跳转支付页面
|
||||
pay() {
|
||||
if (this.checkedNum) {
|
||||
this.$router.push({ path: "/pay", query: { way: "CART" } });
|
||||
} else {
|
||||
if (!this.checkedNum) {
|
||||
Message.warning("请至少选择一件商品");
|
||||
return;
|
||||
}
|
||||
const hasECoupon = this.cartList.some((shop) =>
|
||||
(shop.skuList || []).some(
|
||||
(goods) => goods.checked && isECoupon(goods.goodsSku && goods.goodsSku.goodsType)
|
||||
)
|
||||
);
|
||||
if (hasECoupon) {
|
||||
Message.warning("电子卡券请使用立即购买,不可通过购物车结算");
|
||||
return;
|
||||
}
|
||||
this.$router.push({ path: "/pay", query: { way: "CART" } });
|
||||
},
|
||||
// 展示优惠券
|
||||
showCoupon(storeId, index) {
|
||||
|
||||
@@ -140,8 +140,8 @@ export default {
|
||||
if (!this.goodsMsg.data.intro) {
|
||||
this.goodsMsg.data.intro = ''
|
||||
}
|
||||
// 判断是否收藏
|
||||
if (this.Cookies.getItem("userInfo")) {
|
||||
// 判断是否收藏(须同时有 token,避免未登录/ token 失效时误跳登录页)
|
||||
if (this.Cookies.getItem("accessToken") && this.Cookies.getItem("userInfo")) {
|
||||
isStoreCollection("STORE", this.goodsMsg.data.storeId).then((res) => {
|
||||
if (res.success && res.result) {
|
||||
this.storeCollected = true;
|
||||
|
||||
@@ -80,9 +80,16 @@
|
||||
>
|
||||
自营
|
||||
</el-tag>
|
||||
<!-- E_COUPON 卡密商品类型标识 -->
|
||||
<el-tag
|
||||
class="goods-show-tag goods-show-tag-physical goods-show-tag-ecoupon"
|
||||
v-if="item.goodsType === 'E_COUPON'"
|
||||
>
|
||||
电子卡券
|
||||
</el-tag>
|
||||
<el-tag
|
||||
class="goods-show-tag goods-show-tag-physical"
|
||||
v-if="item.goodsType === 'VIRTUAL_GOODS'"
|
||||
v-else-if="item.goodsType === 'VIRTUAL_GOODS'"
|
||||
>
|
||||
虚拟
|
||||
</el-tag>
|
||||
@@ -118,6 +125,7 @@ import { Message } from "@/utils/message";
|
||||
import { ArrowDown, ArrowUp } from '@element-plus/icons-vue';
|
||||
import GoodsClassNav from "@/components/nav/GoodsClassNav";
|
||||
import * as apiGoods from "@/api/goods";
|
||||
import { isBuyerLoggedIn, redirectToLogin } from "@/utils/buyerLogin";
|
||||
export default {
|
||||
name: "GoodsList",
|
||||
beforeRouteEnter(to, from, next) {
|
||||
@@ -194,12 +202,15 @@ export default {
|
||||
this.getGoodsList();
|
||||
},
|
||||
goGoodsDetail(skuId, goodsId) {
|
||||
// 跳转商品详情
|
||||
let routeUrl = this.$router.resolve({
|
||||
const location = {
|
||||
path: "/goodsDetail",
|
||||
query: { skuId, goodsId },
|
||||
});
|
||||
window.open(routeUrl.href, "_blank");
|
||||
};
|
||||
if (!isBuyerLoggedIn()) {
|
||||
redirectToLogin(this.$router, location);
|
||||
return;
|
||||
}
|
||||
window.open(this.$router.resolve(location).href, "_blank");
|
||||
},
|
||||
goShopPage(id) {
|
||||
if (!id) {
|
||||
@@ -281,13 +292,24 @@ export default {
|
||||
}
|
||||
|
||||
.goods-show-tag {
|
||||
height: 18px;
|
||||
width: 32px;
|
||||
line-height: 14px;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0 3px;
|
||||
justify-content: center;
|
||||
height: 18px;
|
||||
min-width: 32px;
|
||||
width: auto;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
padding: 0 4px;
|
||||
box-sizing: border-box;
|
||||
|
||||
:deep(.el-tag__content) {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-show-tag-ecoupon {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.goods-show-tag-self {
|
||||
|
||||
@@ -197,6 +197,7 @@ export default {
|
||||
mobile: "",
|
||||
},
|
||||
verifyStatus: false, // 是否图片验证通过
|
||||
codeSent: false, // 是否已成功发送短信验证码
|
||||
ruleInline: {
|
||||
// 验证规则
|
||||
username: [{required: true, message: "请输入用户名"}],
|
||||
@@ -237,7 +238,15 @@ export default {
|
||||
if (this.type) {
|
||||
this.$refs.verify?.init();
|
||||
} else {
|
||||
let data = JSON.parse(JSON.stringify(this.formSms));
|
||||
if (!this.verifyStatus) {
|
||||
Message.warning("请先完成安全验证");
|
||||
return;
|
||||
}
|
||||
if (!this.codeSent) {
|
||||
Message.warning("请先获取短信验证码");
|
||||
return;
|
||||
}
|
||||
const data = JSON.parse(JSON.stringify(this.formSms));
|
||||
apiLogin.smsLogin(data).then((res) => {
|
||||
this.hideVerify();
|
||||
if (res.success) {
|
||||
@@ -262,7 +271,7 @@ export default {
|
||||
} else {
|
||||
Message.error(res.message);
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -285,6 +294,7 @@ export default {
|
||||
sendSms(params).then((res) => {
|
||||
if (res.success) {
|
||||
Message.success("验证码发送成功");
|
||||
this.codeSent = true;
|
||||
let that = this;
|
||||
this.interval = setInterval(() => {
|
||||
that.time--;
|
||||
@@ -292,6 +302,7 @@ export default {
|
||||
that.time = 60;
|
||||
that.codeMsg = "重新发送";
|
||||
that.verifyStatus = false;
|
||||
that.codeSent = false;
|
||||
clearInterval(that.interval);
|
||||
} else {
|
||||
that.codeMsg = that.time;
|
||||
@@ -300,7 +311,7 @@ export default {
|
||||
} else {
|
||||
Message.warning(res.message);
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
},
|
||||
verifyChange(con) {
|
||||
@@ -453,11 +464,19 @@ export default {
|
||||
this.$refs.formSms.resetFields();
|
||||
}
|
||||
this.verifyStatus = false;
|
||||
this.codeSent = false;
|
||||
this.hideVerify();
|
||||
clearInterval(this.interval);
|
||||
this.codeMsg = "发送验证码";
|
||||
this.time = 60;
|
||||
},
|
||||
"formSms.mobile"() {
|
||||
this.codeSent = false;
|
||||
this.verifyStatus = false;
|
||||
clearInterval(this.interval);
|
||||
this.codeMsg = "发送验证码";
|
||||
this.time = 60;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -72,8 +72,8 @@
|
||||
<el-button @click="handleCancelOrder(order.sn)" type="danger" v-if="order.allowOperationVO.cancel" size="small">取消订单</el-button>
|
||||
<el-button @click="goPay(order.sn)" size="small" type="success" v-if="order.allowOperationVO.pay">去支付</el-button>
|
||||
<el-button @click="received(order.sn)" size="small" type="primary" v-if="order.allowOperationVO.rog">确认收货</el-button>
|
||||
<!-- 售后 -->
|
||||
<el-button v-if="order.groupAfterSaleStatus && (order.groupAfterSaleStatus.includes('NOT_APPLIED')|| order.groupAfterSaleStatus.includes('PART_AFTER_SALE'))"
|
||||
<!-- 售后(E_COUPON 卡密已交付不支持售后 FR-B-04) -->
|
||||
<el-button v-if="order.orderType !== 'E_COUPON' && order.groupAfterSaleStatus && (order.groupAfterSaleStatus.includes('NOT_APPLIED')|| order.groupAfterSaleStatus.includes('PART_AFTER_SALE'))"
|
||||
@click="applyAfterSale(order.orderItems)" size="small">申请售后</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -141,8 +141,8 @@
|
||||
<el-button @click="handleCancelOrder(order.sn)" type="danger" v-if="order.allowOperationVO.cancel" size="small">取消订单</el-button>
|
||||
<el-button @click="goPay(order.sn)" size="small" type="success" v-if="order.allowOperationVO.pay">去支付</el-button>
|
||||
<el-button @click="received(order.sn)" size="small" type="primary" v-if="order.allowOperationVO.rog">确认收货</el-button>
|
||||
<!-- 售后 -->
|
||||
<el-button v-if="order.groupAfterSaleStatus && (order.groupAfterSaleStatus.includes('NOT_APPLIED')|| order.groupAfterSaleStatus.includes('PART_AFTER_SALE'))"
|
||||
<!-- 售后(E_COUPON 不支持买家售后 FR-B-04) -->
|
||||
<el-button v-if="order.orderType !== 'E_COUPON' && order.groupAfterSaleStatus && (order.groupAfterSaleStatus.includes('NOT_APPLIED')|| order.groupAfterSaleStatus.includes('PART_AFTER_SALE'))"
|
||||
@click="applyAfterSale(order.orderItems)" size="small">申请售后</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
>取消订单</el-button>
|
||||
<el-button v-if="order.allowOperationVO.showLogistics || orderPackage.length > 0 || logistics" type="info" @click="logisticsList()" size="small">查看物流</el-button>
|
||||
</el-card>
|
||||
<p class="verificationCode" v-if="order.order.verificationCode">
|
||||
<p class="verificationCode" v-if="order.order.verificationCode && !isECouponOrder">
|
||||
核验码:<span>{{ order.order.verificationCode }}</span>
|
||||
</p>
|
||||
<div class="order-card">
|
||||
@@ -51,7 +51,7 @@
|
||||
></el-step>
|
||||
</el-steps>
|
||||
</div>
|
||||
<div class="order-card" v-if="order.order.deliveryMethod === 'LOGISTICS' && order.order.orderType !== 'VIRTUAL'">
|
||||
<div class="order-card" v-if="order.order.deliveryMethod === 'LOGISTICS' && !isNonPhysicalOrder">
|
||||
<h3>收货人信息</h3>
|
||||
<p>收货人:{{ order.order.consigneeName }}</p>
|
||||
<p>手机号码:{{ $filters.secrecyMobile( order.order.consigneeMobile ) }}</p>
|
||||
@@ -70,7 +70,7 @@
|
||||
<p>支付方式:{{ order.paymentMethodValue }}</p>
|
||||
<p>付款状态:{{ order.payStatusValue }}</p>
|
||||
</div>
|
||||
<div class="order-card" v-if="!order.order.verificationCode && order.order.orderType !== 'VIRTUAL'">
|
||||
<div class="order-card" v-if="!order.order.verificationCode && !isNonPhysicalOrder">
|
||||
<h3>配送信息</h3>
|
||||
<p>配送方式:{{ order.deliveryMethodValue }}</p>
|
||||
<p v-if="order.order.deliveryMethod === 'LOGISTICS'">配送状态:{{ order.deliverStatusValue }}</p>
|
||||
@@ -132,6 +132,51 @@
|
||||
</template>
|
||||
<div v-else style="color: #999; margin-left: 5px">未开发票</div>
|
||||
</div>
|
||||
<!-- 卡密信息(当前订单 orderItems;满赠赠品卡密在赠品子单详情查看) -->
|
||||
<div class="order-card ecoupon-card-keys" v-if="hasCardKeySection">
|
||||
<h3>卡密信息</h3>
|
||||
<div
|
||||
v-for="line in cardKeyFulfillLines"
|
||||
:key="line.key"
|
||||
class="ecoupon-fulfill-block"
|
||||
>
|
||||
<el-alert
|
||||
v-if="line.status !== 'DELIVERED'"
|
||||
:type="cardKeyFulfillAlertType(line.status)"
|
||||
show-icon
|
||||
:closable="false"
|
||||
:title="resolveCardKeyFulfillMessage(line)"
|
||||
class="mb_10"
|
||||
/>
|
||||
<template v-else-if="line.cardKeys.length">
|
||||
<div class="ecoupon-card-keys-mobile">
|
||||
<el-button type="primary" @click="cardKeyDialogVisible = true">查看卡密</el-button>
|
||||
</div>
|
||||
<div class="ecoupon-card-keys-pc">
|
||||
<el-table border :data="lineCardKeyRows(line)" style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="cardNo" label="卡号" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column prop="cardSecret" label="卡密" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="allocatedTime" label="发卡时间" width="170" />
|
||||
<el-table-column label="操作" width="120" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button v-if="row" link type="primary" @click="copyCardKey(row)">复制</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="ecouponCardKeyRows.length"
|
||||
class="mt_10 ecoupon-card-keys-pc"
|
||||
size="small"
|
||||
@click="copyAllCardKeys"
|
||||
>
|
||||
复制全部卡密
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 订单商品 -->
|
||||
<div class="goods">
|
||||
<div class="shop-name">
|
||||
@@ -144,8 +189,8 @@
|
||||
<th width="15%">货号</th>
|
||||
<th width="10%">单价</th>
|
||||
<th width="5%">数量</th>
|
||||
<th width="10%">退款状态</th>
|
||||
<th width="10%">实际退款金额</th>
|
||||
<th width="10%" v-if="!isECouponOrder">退款状态</th>
|
||||
<th width="10%" v-if="!isECouponOrder">实际退款金额</th>
|
||||
<th width="10%">小计</th>
|
||||
<th width="10%">操作</th>
|
||||
</tr>
|
||||
@@ -170,8 +215,8 @@
|
||||
<td>{{ goods.id }}</td>
|
||||
<td>{{ $filters.unitPrice(goods.goodsPrice, "¥") }}</td>
|
||||
<td>{{ goods.num }}</td>
|
||||
<td>{{refundPriceList(goods.isRefund)}}</td>
|
||||
<td>{{ $filters.unitPrice(goods.refundPrice, "¥") }}</td>
|
||||
<td v-if="!isECouponOrder">{{refundPriceList(goods.isRefund)}}</td>
|
||||
<td v-if="!isECouponOrder">{{ $filters.unitPrice(goods.refundPrice, "¥") }}</td>
|
||||
<td>{{ $filters.unitPrice((goods.goodsPrice * goods.num), "¥") }}</td>
|
||||
<td class="order-item-actions">
|
||||
<el-button
|
||||
@@ -192,8 +237,9 @@
|
||||
>
|
||||
<el-button
|
||||
v-if="
|
||||
goods.afterSaleStatus.includes('NOT_APPLIED') ||
|
||||
goods.afterSaleStatus.includes('PART_AFTER_SALE')
|
||||
!isECouponOrder &&
|
||||
(goods.afterSaleStatus.includes('NOT_APPLIED') ||
|
||||
goods.afterSaleStatus.includes('PART_AFTER_SALE'))
|
||||
"
|
||||
@click="applyAfterSale(goods.sn)"
|
||||
type="default"
|
||||
@@ -213,7 +259,7 @@
|
||||
<div>
|
||||
<span>商品总价:</span><span>{{ $filters.unitPrice(order.order.goodsPrice, "¥") }}</span><br />
|
||||
</div>
|
||||
<div v-if="order.order.orderType !== 'VIRTUAL'">
|
||||
<div v-if="!isECouponOrder">
|
||||
<span>运费:</span><span>+{{ $filters.unitPrice(order.order.freightPrice, "¥") }}</span><br />
|
||||
</div>
|
||||
<div v-if="order.order.priceDetailDTO.couponPrice">
|
||||
@@ -319,6 +365,19 @@
|
||||
<el-button @click="logisticsModal = false">取消</el-button>
|
||||
</div></template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 移动端查看卡密 -->
|
||||
<el-dialog v-model="cardKeyDialogVisible" title="卡密信息" width="92%" class="card-key-mobile-dialog">
|
||||
<div v-for="(row, idx) in ecouponCardKeyRows" :key="idx" class="card-key-mobile-item">
|
||||
<p><strong>卡号:</strong>{{ row.cardNo }}</p>
|
||||
<p><strong>卡密:</strong>{{ row.cardSecret }}</p>
|
||||
<el-button size="small" link type="primary" @click="copyCardKey(row)">复制</el-button>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="copyAllCardKeys">复制全部</el-button>
|
||||
<el-button type="primary" @click="cardKeyDialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</UserCenterLayout>
|
||||
|
||||
</div>
|
||||
@@ -333,6 +392,19 @@ import {
|
||||
getPackage
|
||||
} from "@/api/order.js";
|
||||
import { afterSaleReason, receiptDetail } from "@/api/member";
|
||||
import {
|
||||
isECouponOrder as checkECouponOrder,
|
||||
collectCardKeyFulfillLines,
|
||||
orderHasCardKeySection,
|
||||
flattenOrderCardKeys,
|
||||
cardKeyFulfillAlertType,
|
||||
resolveCardKeyFulfillMessage,
|
||||
} from "@/constants/goodsType";
|
||||
|
||||
/**
|
||||
* 订单详情:E_COUPON 展示 orderItems[].cardKeys,屏蔽售后/物流(FR-B-03 / FR-B-04)。
|
||||
* 移动端已完成订单用 Dialog 查看卡密(原型 P-09 / D-01)。
|
||||
*/
|
||||
export default {
|
||||
name: "order-detail",
|
||||
data() {
|
||||
@@ -340,6 +412,7 @@ export default {
|
||||
order: {}, // 订单详情数据
|
||||
progressList: [], // 订单流程
|
||||
logistics: "", // 物流数据
|
||||
cardKeyDialogVisible: false,
|
||||
cancelParams: {
|
||||
// 取消售后参数
|
||||
orderSn: "",
|
||||
@@ -352,7 +425,63 @@ export default {
|
||||
logisticsModal: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
/** 电子卡券订单:无物流/核验码,卡密数据来自 API-B-01 orderItems[].cardKeys */
|
||||
isECouponOrder() {
|
||||
return checkECouponOrder(this.order?.order?.orderType);
|
||||
},
|
||||
isVirtualOrder() {
|
||||
return this.order?.order?.orderType === "VIRTUAL";
|
||||
},
|
||||
isNonPhysicalOrder() {
|
||||
return this.isVirtualOrder || this.isECouponOrder;
|
||||
},
|
||||
/** 是否展示卡密区块(仅当前订单 orderItems) */
|
||||
hasCardKeySection() {
|
||||
return orderHasCardKeySection({
|
||||
orderItems: this.order.orderItems,
|
||||
isECouponOrder: this.isECouponOrder,
|
||||
});
|
||||
},
|
||||
cardKeyFulfillLines() {
|
||||
return collectCardKeyFulfillLines(this.order.orderItems);
|
||||
},
|
||||
ecouponCardKeyRows() {
|
||||
return flattenOrderCardKeys(this.order.orderItems, false);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
cardKeyFulfillAlertType,
|
||||
resolveCardKeyFulfillMessage,
|
||||
lineCardKeyRows(line) {
|
||||
return line.cardKeys || [];
|
||||
},
|
||||
copyCardKey(row) {
|
||||
const text = `卡号:${row.cardNo || ""}\n卡密:${row.cardSecret || ""}`;
|
||||
this.copyText(text);
|
||||
},
|
||||
copyAllCardKeys() {
|
||||
const text = this.ecouponCardKeyRows
|
||||
.map((row, i) => `${i + 1}. 卡号:${row.cardNo || ""} 卡密:${row.cardSecret || ""}`)
|
||||
.join("\n");
|
||||
this.copyText(text || "");
|
||||
},
|
||||
copyText(text) {
|
||||
if (!text) return;
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
Message.success("已复制到剪贴板");
|
||||
});
|
||||
} else {
|
||||
const ta = document.createElement("textarea");
|
||||
ta.value = text;
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(ta);
|
||||
Message.success("已复制到剪贴板");
|
||||
}
|
||||
},
|
||||
isVatSpecialReceipt (receipt) {
|
||||
if (!receipt) return false;
|
||||
const rt = receipt.receiptType != null ? String(receipt.receiptType).trim() : "";
|
||||
@@ -660,6 +789,38 @@ table {
|
||||
color: $theme_color;
|
||||
}
|
||||
}
|
||||
|
||||
.ecoupon-card-keys-mobile {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ecoupon-fulfill-block + .ecoupon-fulfill-block {
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px dashed #eee;
|
||||
}
|
||||
|
||||
.ecoupon-card-keys-pc {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.card-key-mobile-item {
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
p {
|
||||
margin: 4px 0;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.ecoupon-card-keys-mobile {
|
||||
display: block;
|
||||
}
|
||||
.ecoupon-card-keys-pc {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
/** 订单进度条 */
|
||||
.progress {
|
||||
margin: 15px 0;
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
<el-divider />
|
||||
<div class="content width_1200_auto">
|
||||
<!-- 收货地址 -->
|
||||
<div class="address" v-if="selectedDeliverMethod === 'LOGISTICS' && goodsType !== 'VIRTUAL_GOODS'">
|
||||
<!-- 收货地址(E_COUPON / VIRTUAL 免地址,见 isVirtualLikeCheckout) -->
|
||||
<div class="address" v-if="selectedDeliverMethod === 'LOGISTICS' && !isVirtualLikeCheckout">
|
||||
<div class="card-head">
|
||||
<span>收货人信息</span>
|
||||
<span @click="goAddressManage">管理收货人地址</span>
|
||||
@@ -94,7 +95,7 @@
|
||||
</div>
|
||||
<div>
|
||||
</div>
|
||||
<div class="goods-content" v-if="goodsType !== 'VIRTUAL_GOODS'">
|
||||
<div class="goods-content" v-if="!isVirtualLikeCheckout">
|
||||
<div class="card-head mt_20 mb_20">
|
||||
<span>配送方式</span>
|
||||
</div>
|
||||
@@ -150,8 +151,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 发票信息 -->
|
||||
<div class="invoice">
|
||||
<!-- 发票信息(E_COUPON 虚拟型结算不开发票) -->
|
||||
<div class="invoice" v-if="!isECouponCheckout">
|
||||
<div class="card-head mt_20 mb_20">
|
||||
<span class="relative">发票信息<span class="inv-tips">
|
||||
<el-icon><Warning /></el-icon>开企业抬头发票须填写纳税人识别号,以免影响报销
|
||||
@@ -283,13 +284,13 @@
|
||||
<!-- 底部支付栏 -->
|
||||
<div class="order-footer">
|
||||
<div class="pay ml_20" @click="pay">提交订单</div>
|
||||
<div class="pay-address" v-if="addressList.length && selectedDeliverMethod === 'LOGISTICS'">
|
||||
<div class="pay-address" v-if="!isVirtualLikeCheckout && addressList.length && selectedDeliverMethod === 'LOGISTICS'">
|
||||
配送至:{{ $filters.unitAddress(selectedAddress.consigneeAddressPath) }}
|
||||
{{ selectedAddress.detail }} 收货人:{{
|
||||
selectedAddress.name
|
||||
}} {{ selectedAddress.mobile }}
|
||||
</div>
|
||||
<div class="pay-address" v-if="addressList.length && selectedDeliverMethod === 'SELF_PICK_UP'">
|
||||
<div class="pay-address" v-if="!isVirtualLikeCheckout && addressList.length && selectedDeliverMethod === 'SELF_PICK_UP'">
|
||||
自提地点:{{selectedStoreAddress.address}} 联系方式:{{ selectedStoreAddress.mobile }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -328,6 +329,7 @@ import {
|
||||
} from "@/api/cart";
|
||||
import { getStoreAddress } from "@/api/shopentry.js"
|
||||
import { canUseCouponList } from "@/api/member.js";
|
||||
import { isECoupon, shouldSkipPaymentPage } from "@/constants/goodsType";
|
||||
|
||||
export default {
|
||||
name: "Pay",
|
||||
@@ -377,6 +379,14 @@ export default {
|
||||
);
|
||||
return Number.isFinite(n) ? n : 0;
|
||||
},
|
||||
/** 电子卡券结算:免地址、隐藏发票;优惠券/礼品卡/促销明细可用(M-02) */
|
||||
isECouponCheckout() {
|
||||
return isECoupon(this.goodsType);
|
||||
},
|
||||
/** 虚拟型结算(核销虚拟 + 电子卡券):均不需要收货地址 */
|
||||
isVirtualLikeCheckout() {
|
||||
return this.goodsType === "VIRTUAL_GOODS" || this.isECouponCheckout;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -845,19 +855,24 @@ export default {
|
||||
.then((res) => {
|
||||
Spin.hide();
|
||||
if (res.success) {
|
||||
if (params.way === "POINTS") {
|
||||
// 积分支付不需要跳转支付页面
|
||||
const way = params.way;
|
||||
if (shouldSkipPaymentPage(res.result, way)) {
|
||||
this.$router.push("/payDone");
|
||||
} else {
|
||||
this.$router.push({
|
||||
path: "/payment",
|
||||
query: { orderType: "TRADE", sn: res.result.sn },
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.$router.push({
|
||||
path: "/payment",
|
||||
query: { orderType: "TRADE", sn: res.result.sn },
|
||||
});
|
||||
} else if (res.message) {
|
||||
Message.warning(res.message);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((err) => {
|
||||
Spin.hide();
|
||||
if (err?.message && !err?.data?.message) {
|
||||
Message.error(err.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
// 优惠券可用范围
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
</template>
|
||||
<script>
|
||||
|
||||
import {tradeDetail, pay} from '@/api/pay.js';
|
||||
import { tradeDetail, pay } from '@/api/pay.js';
|
||||
import { Message, Modal } from "@/utils/message";
|
||||
|
||||
export default {
|
||||
@@ -78,6 +78,10 @@ export default {
|
||||
this.isStart = true
|
||||
this.support = this.payDetail.support
|
||||
this.walletValue = this.payDetail.walletValue
|
||||
const price = Number(this.payDetail.price);
|
||||
if (!Number.isNaN(price) && price <= 0) {
|
||||
this.$router.replace('/payDone');
|
||||
}
|
||||
}
|
||||
}).catch((err) => {
|
||||
this.$router.push({name: 'MyOrder'});
|
||||
@@ -102,14 +106,21 @@ export default {
|
||||
title: '支付确认',
|
||||
content: '确认使用余额支付吗?',
|
||||
onOk: () => {
|
||||
pay(params).then(res => {
|
||||
if (res.success) {
|
||||
Message.success(res.message)
|
||||
this.$router.push('/payDone');
|
||||
} else {
|
||||
Message.warning(res.message)
|
||||
}
|
||||
})
|
||||
return pay(params)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
Message.success(res.message || '支付成功');
|
||||
this.$router.push('/payDone');
|
||||
} else {
|
||||
Message.warning(res.message || '支付失败');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
// 支付失败兜底:业务错误(如 CARD_KEY_STORE_SELL_FORBIDDEN)通常已由 axios 拦截器提示
|
||||
if (err?.message && !err?.data?.message) {
|
||||
Message.error(err.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
||||
@@ -11,19 +11,31 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="pay-way">{{params.paymentMethod === 'ALIPAY' ? '支付宝支付' : '微信支付'}}</div>
|
||||
<div class="pay-way">{{ payWayName }}支付</div>
|
||||
<div class="qrcode">
|
||||
<div style="width:200px;height:200px;border:1px solid #eee;">
|
||||
<vue-qr :text="qrcode" :margin="0" colorDark="#000" colorLight="#fff" :size="200"></vue-qr>
|
||||
<div class="qrcode-box">
|
||||
<div v-if="payLoading" class="qrcode-status">正在生成支付二维码...</div>
|
||||
<div v-else-if="payError" class="qrcode-status qrcode-status--error">
|
||||
<p>{{ payError }}</p>
|
||||
<p class="qrcode-status-tip">您可点击「重新支付」重试,或返回选择其他支付方式</p>
|
||||
</div>
|
||||
<vue-qr
|
||||
v-else
|
||||
:text="qrcode"
|
||||
:margin="0"
|
||||
colorDark="#000"
|
||||
colorLight="#fff"
|
||||
:size="200"
|
||||
/>
|
||||
</div>
|
||||
<div class="intro">
|
||||
<el-icon><Iphone /></el-icon> 请使用{{params.paymentMethod === 'ALIPAY' ? '支付宝' : '微信'}}扫码付款
|
||||
<div v-if="!payError" class="intro">
|
||||
<el-icon><Iphone /></el-icon> 请使用{{ payWayName }}扫码付款
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-div">
|
||||
<p class="mb_10">支付成功后自动跳转,如未跳转请点击按钮手动跳转。。。</p>
|
||||
<div>
|
||||
<el-button @click="handlePay">重新支付</el-button>
|
||||
<el-button :loading="payLoading" @click="handlePay">重新支付</el-button>
|
||||
<el-button type="success" @click="$router.push('/payDone')">支付成功</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -41,47 +53,79 @@ export default {
|
||||
components: { vueQr, Iphone },
|
||||
data () {
|
||||
return {
|
||||
qrcode: '', // 二维码
|
||||
params: this.$route.query, // 参数
|
||||
interval: null, // 定时器
|
||||
num: 0 // 商品数
|
||||
qrcode: '',
|
||||
params: this.$route.query,
|
||||
interval: null,
|
||||
num: 0,
|
||||
payLoading: false,
|
||||
payError: '',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 获取支付二维码
|
||||
handlePay () {
|
||||
const params = this.$route.query;
|
||||
pay(params).then(res => {
|
||||
if (res.success) {
|
||||
this.qrcode = res.result;
|
||||
this.num = 0;
|
||||
this.interval = setInterval(this.callback, 5000);
|
||||
} else {
|
||||
Message.error(res.message)
|
||||
}
|
||||
});
|
||||
computed: {
|
||||
payWayName () {
|
||||
return this.params.paymentMethod === 'ALIPAY' ? '支付宝' : '微信';
|
||||
},
|
||||
callback () { // 支付回调接口
|
||||
this.num++;
|
||||
if (this.num >= 7) {
|
||||
},
|
||||
methods: {
|
||||
formatPayError (rawMessage) {
|
||||
const message = (rawMessage || '').trim();
|
||||
if (!message || message === '支付业务异常,请稍后重试') {
|
||||
return `${this.payWayName}支付暂不可用,请稍后重试或选择其他支付方式`;
|
||||
}
|
||||
return message;
|
||||
},
|
||||
clearPayPoll () {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
}
|
||||
let params = JSON.parse(JSON.stringify(this.$route.query));
|
||||
},
|
||||
handlePay () {
|
||||
this.clearPayPoll();
|
||||
const params = this.$route.query;
|
||||
this.payLoading = true;
|
||||
this.payError = '';
|
||||
this.qrcode = '';
|
||||
pay(params, { skipMessage: true })
|
||||
.then((res) => {
|
||||
this.payLoading = false;
|
||||
if (res.success && res.result) {
|
||||
this.qrcode = res.result;
|
||||
this.num = 0;
|
||||
this.interval = setInterval(this.callback, 5000);
|
||||
return;
|
||||
}
|
||||
this.payError = this.formatPayError(res.message);
|
||||
Message.error(this.payError);
|
||||
})
|
||||
.catch((err) => {
|
||||
this.payLoading = false;
|
||||
this.payError = this.formatPayError(err?.message || err?.data?.message);
|
||||
Message.error(this.payError);
|
||||
});
|
||||
},
|
||||
callback () {
|
||||
this.num++;
|
||||
if (this.num >= 7) {
|
||||
this.clearPayPoll();
|
||||
}
|
||||
const params = JSON.parse(JSON.stringify(this.$route.query));
|
||||
delete params.paymentMethod;
|
||||
delete params.paymentClient;
|
||||
payCallback(params).then(res => {
|
||||
payCallback(params).then((res) => {
|
||||
if (res.result) {
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
this.$router.push({path: '/payDone', query: {orderType: this.$route.query.orderType}});
|
||||
this.clearPayPoll();
|
||||
this.$router.push({ path: '/payDone', query: { orderType: this.$route.query.orderType } });
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.handlePay();
|
||||
}
|
||||
},
|
||||
beforeUnmount () {
|
||||
this.clearPayPoll();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@@ -125,6 +169,33 @@ export default {
|
||||
margin: 30px 0 0 70px;
|
||||
}
|
||||
|
||||
.qrcode-box {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border: 1px solid #eee;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.qrcode-status {
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.qrcode-status--error {
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
.qrcode-status-tip {
|
||||
margin-top: 8px;
|
||||
color: #909399;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.intro {
|
||||
background-color: #ff7674;
|
||||
height: 40px;
|
||||
@@ -143,6 +214,9 @@ export default {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 20px;
|
||||
cursor: pointer;
|
||||
color: #409eff;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
.price {
|
||||
@@ -153,4 +227,7 @@ export default {
|
||||
.head-right {
|
||||
font-weight: bold;
|
||||
}
|
||||
.mb_10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,18 +2,14 @@
|
||||
<div style="background:#fff;">
|
||||
<BaseHeader></BaseHeader>
|
||||
<Search style="border-bottom:2px solid red;"></Search>
|
||||
<!-- <drawer></drawer> -->
|
||||
<div class="base-width cate-container">
|
||||
<el-breadcrumb>
|
||||
<el-breadcrumb-item to="/">首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>{{goodsMsg.pointsGoodsCategoryName}}</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>{{ goodsMsg.pointsGoodsCategoryName }}</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<!-- 商品信息展示 -->
|
||||
<div class="item-detail-show">
|
||||
<!-- 详情左侧展示数据、图片,收藏、举报 -->
|
||||
<div class="item-detail-left">
|
||||
<!-- 大图、放大镜 -->
|
||||
<div class="item-detail-big-img">
|
||||
<el-image
|
||||
v-if="goodsSku.thumbnail"
|
||||
@@ -29,22 +25,22 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧商品信息、活动信息、操作展示 -->
|
||||
<div class="item-detail-right">
|
||||
<div class="item-detail-title">
|
||||
<p>{{ goodsSku.goodsName }}</p>
|
||||
<div class="item-detail-title-row">
|
||||
<p>{{ goodsSku.goodsName }}</p>
|
||||
<el-tag v-if="isECouponSku" class="goods-type-tag" size="small">电子卡券</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sell-point">
|
||||
{{goodsSku.sellingPoint}}
|
||||
{{ goodsSku.sellingPoint }}
|
||||
</div>
|
||||
<!-- 商品详细 -->
|
||||
<div class="item-detail-price-row">
|
||||
<div class="item-price-left">
|
||||
<!-- 商品原价 -->
|
||||
<div class="item-price-row">
|
||||
<p>
|
||||
<span class="item-price-title">积 分</span>
|
||||
<span class="item-price">{{goodsMsg.points}}</span>
|
||||
<span class="item-price">{{ goodsMsg.points }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,25 +51,37 @@
|
||||
<p>数量</p>
|
||||
</div>
|
||||
<div class="item-select-row">
|
||||
<el-input-number :min="1" :disabled="goodsSku.quantity === 0" v-model="count"></el-input-number>
|
||||
<span class="inventory"> 库存{{goodsSku.quantity}}</span>
|
||||
<el-input-number
|
||||
:min="1"
|
||||
:max="quantityMax"
|
||||
:disabled="isOutOfStock"
|
||||
v-model="count"
|
||||
/>
|
||||
<span class="inventory"> 库存{{ displayStock }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-select" v-if="goodsSku.goodsType !== 'VIRTUAL_GOODS' && goodsSku.weight !== 0">
|
||||
<div
|
||||
class="item-select"
|
||||
v-if="!isECouponSku && goodsSku.goodsType !== 'VIRTUAL_GOODS' && goodsSku.weight !== 0"
|
||||
>
|
||||
<div class="item-select-title">
|
||||
<p>重量</p>
|
||||
</div>
|
||||
<div class="item-select-row">
|
||||
<span class="inventory"> {{goodsSku.weight}}kg</span>
|
||||
<span class="inventory"> {{ goodsSku.weight }}kg</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-buy-car">
|
||||
<el-button type="danger" :loading="loading" :disabled="goodsSku.quantity === 0" @click="pointBuy">积分购买</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
:loading="loading"
|
||||
:disabled="isOutOfStock"
|
||||
@click="pointBuy"
|
||||
>积分购买</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 商品详情 -->
|
||||
<div class="base-width item-intro" ref="itemIntroGoods">
|
||||
<div>商品介绍</div>
|
||||
<div v-html="goodsSku.intro" class="mt_10 ml_10" v-if="goodsSku.intro"></div>
|
||||
@@ -86,101 +94,140 @@
|
||||
|
||||
<script>
|
||||
import { Message } from "@/utils/message";
|
||||
import Search from '@/components/Search';
|
||||
import { addCartGoods } from '@/api/cart.js';
|
||||
import { pointGoodsDetail } from '@/api/promotion';
|
||||
import Search from "@/components/Search";
|
||||
import { addCartGoods } from "@/api/cart.js";
|
||||
import { pointGoodsDetail } from "@/api/promotion";
|
||||
import {
|
||||
isECoupon,
|
||||
getECouponStock,
|
||||
getECouponMaxBuyNum,
|
||||
E_COUPON_CART_POINTS,
|
||||
} from "@/constants/goodsType";
|
||||
|
||||
export default {
|
||||
name: 'PointGoodsDetail',
|
||||
beforeRouteEnter (to, from, next) {
|
||||
name: "PointGoodsDetail",
|
||||
components: { Search },
|
||||
beforeRouteEnter(to, from, next) {
|
||||
window.scrollTo(0, 0);
|
||||
next();
|
||||
},
|
||||
created () {
|
||||
created() {
|
||||
this.getGoodsDetail();
|
||||
},
|
||||
mounted () {
|
||||
window.addEventListener('scroll', this.handleScroll)
|
||||
mounted() {
|
||||
window.addEventListener("scroll", this.handleScroll);
|
||||
},
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
goodsMsg: {}, // 商品信息
|
||||
goodsSku: {}, // 商品sku
|
||||
isLoading: false, // 加载状态
|
||||
categoryBar: [], // 分类
|
||||
onceFlag: true, // 只调用一次
|
||||
count: 1, // 购买商品数量
|
||||
loading: false // 提交加载状态
|
||||
goodsMsg: {},
|
||||
goodsSku: {},
|
||||
isLoading: false,
|
||||
onceFlag: true,
|
||||
count: 1,
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 获取积分商品详情
|
||||
getGoodsDetail () {
|
||||
this.isLoading = true;
|
||||
pointGoodsDetail(this.$route.query.id).then((res) => {
|
||||
this.isLoading = false;
|
||||
if (res.success) {
|
||||
this.goodsMsg = res.result;
|
||||
this.goodsSku = res.result.goodsSku
|
||||
} else {
|
||||
Message.error(res.message)
|
||||
this.$router.push('/')
|
||||
}
|
||||
}).catch(() => {
|
||||
this.$router.push('/')
|
||||
});
|
||||
computed: {
|
||||
isECouponSku() {
|
||||
return isECoupon(this.goodsSku.goodsType);
|
||||
},
|
||||
pointBuy () {
|
||||
displayStock() {
|
||||
if (this.isECouponSku) {
|
||||
return getECouponStock(this.goodsSku);
|
||||
}
|
||||
return Number(this.goodsSku.quantity) || 0;
|
||||
},
|
||||
quantityMax() {
|
||||
if (this.isECouponSku) {
|
||||
return getECouponMaxBuyNum(this.goodsSku);
|
||||
}
|
||||
const qty = Number(this.goodsSku.quantity) || 0;
|
||||
return qty > 0 ? qty : 1;
|
||||
},
|
||||
isOutOfStock() {
|
||||
return this.displayStock <= 0;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getGoodsDetail() {
|
||||
this.isLoading = true;
|
||||
pointGoodsDetail(this.$route.query.id)
|
||||
.then((res) => {
|
||||
this.isLoading = false;
|
||||
if (res.success) {
|
||||
this.goodsMsg = res.result;
|
||||
this.goodsSku = res.result.goodsSku || {};
|
||||
this.syncCountWithQuantity();
|
||||
} else {
|
||||
Message.error(res.message);
|
||||
this.$router.push("/");
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.$router.push("/");
|
||||
});
|
||||
},
|
||||
syncCountWithQuantity() {
|
||||
const max = this.quantityMax;
|
||||
if (max <= 0) {
|
||||
this.count = 1;
|
||||
return;
|
||||
}
|
||||
if (this.count > max) this.count = max;
|
||||
if (this.count < 1) this.count = 1;
|
||||
},
|
||||
pointBuy() {
|
||||
const params = {
|
||||
num: this.count,
|
||||
skuId: this.goodsMsg.skuId,
|
||||
cartType: 'POINTS'
|
||||
cartType: E_COUPON_CART_POINTS,
|
||||
};
|
||||
this.loading = true;
|
||||
addCartGoods(params).then(res => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.$router.push({path: '/pay', query: {way: params.cartType}});
|
||||
} else {
|
||||
Message.warning(res.message);
|
||||
}
|
||||
}).catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
addCartGoods(params)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.$router.push({ path: "/pay", query: { way: params.cartType } });
|
||||
} else {
|
||||
Message.warning(res.message);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handleScroll () { // 监听页面滚动
|
||||
handleScroll() {
|
||||
if (this.onceFlag) {
|
||||
this.$nextTick(() => {
|
||||
this.changeHeight()
|
||||
this.changeHeight();
|
||||
});
|
||||
this.onceFlag = false
|
||||
this.onceFlag = false;
|
||||
}
|
||||
},
|
||||
changeHeight () { // 设置商品详情高度
|
||||
let goodsDetailCon = document.querySelector('.item-intro')
|
||||
changeHeight() {
|
||||
const goodsDetailCon = document.querySelector(".item-intro");
|
||||
if (!goodsDetailCon || !this.$refs.itemIntroGoods) return;
|
||||
let heightCss = window.getComputedStyle(goodsDetailCon).height;
|
||||
heightCss = parseInt(heightCss.substr(0, heightCss.length - 2)) + 89;
|
||||
this.$refs.itemIntroGoods.style.height = heightCss + 'px';
|
||||
}
|
||||
heightCss = parseInt(heightCss.substr(0, heightCss.length - 2), 10) + 89;
|
||||
this.$refs.itemIntroGoods.style.height = heightCss + "px";
|
||||
},
|
||||
},
|
||||
components: {
|
||||
Search,
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.base-width{
|
||||
.base-width {
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
}
|
||||
.cate-container{
|
||||
.cate-container {
|
||||
background-color: #eee;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding-left: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
// 商品图片,价格等
|
||||
.item-detail-show {
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
@@ -192,7 +239,6 @@ export default {
|
||||
width: 350px;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.item-detail-big-img {
|
||||
width: 350px;
|
||||
height: 350px;
|
||||
@@ -202,12 +248,10 @@ export default {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.item-detail-img-row {
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.item-detail-img-small {
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
@@ -219,20 +263,27 @@ export default {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
/*商品选购详情*/
|
||||
.item-detail-right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.item-detail-title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
.item-detail-title p {
|
||||
@include content_color($light_content_color);
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
padding: 8px 0;
|
||||
margin: 0;
|
||||
}
|
||||
.goods-type-tag {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.item-detail-express {
|
||||
font-size: 14px;
|
||||
padding: 2px 3px;
|
||||
@@ -240,15 +291,6 @@ export default {
|
||||
background-color: $theme_color;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/*商品标签*/
|
||||
.item-detail-tag {
|
||||
padding: 8px 0;
|
||||
font-size: 12px;
|
||||
color: $theme_color;
|
||||
}
|
||||
|
||||
/*价格详情等*/
|
||||
.item-detail-price-row {
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
@@ -256,42 +298,31 @@ export default {
|
||||
justify-content: space-between;
|
||||
background: url("../../assets/images/goodsDetail/price-bg.png");
|
||||
}
|
||||
|
||||
.item-price-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.item-price-title {
|
||||
color: #999999;
|
||||
font-size: 14px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.item-price-row {
|
||||
margin: 5px 0px;
|
||||
}
|
||||
|
||||
.item-price {
|
||||
color: $theme_color;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.item-price-old {
|
||||
color: gray;
|
||||
text-decoration: line-through;
|
||||
font-size: 14px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.add-buy-car-box {
|
||||
width: 100%;
|
||||
margin-top: 15px;
|
||||
border-top: 1px dotted $border_color;
|
||||
}
|
||||
|
||||
.add-buy-car {
|
||||
margin-top: 15px;
|
||||
>*{
|
||||
> * {
|
||||
margin: 0 4px;
|
||||
}
|
||||
}
|
||||
@@ -300,57 +331,23 @@ export default {
|
||||
flex-direction: row;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.item-select-title {
|
||||
@include content_color($light_content_color);
|
||||
font-size: 14px;
|
||||
margin-right: 15px;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.item-select-column {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.item-select-row {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.item-select-box {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 5px;
|
||||
margin-right: 8px;
|
||||
@include background_color($light_background_color);
|
||||
border: 0.5px solid $border_color;
|
||||
cursor: pointer;
|
||||
@include content_color($light_content_color);
|
||||
}
|
||||
|
||||
.item-select-box:hover {
|
||||
border: 0.5px solid $theme_color;
|
||||
}
|
||||
|
||||
.item-select-box-active {
|
||||
border: 0.5px solid $theme_color;
|
||||
}
|
||||
|
||||
.item-select-intro p {
|
||||
margin: 0px;
|
||||
padding: 5px;
|
||||
}
|
||||
.sell-point {
|
||||
font-size: 12px;
|
||||
color: red;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
// 商品详情
|
||||
.item-intro {
|
||||
margin-top: 10px;
|
||||
>div:nth-child(1) {
|
||||
> div:nth-child(1) {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
background-color: #eee;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
@click="goGoodsDetail(item.id)"
|
||||
>
|
||||
<div class="goods-show-img">
|
||||
<img :src="item.goodsSku.thumbnail" />
|
||||
<img :src="itemThumbnail(item)" />
|
||||
</div>
|
||||
<div class="goods-show-price">
|
||||
<span>
|
||||
@@ -26,7 +26,7 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="goods-show-detail">
|
||||
<span>{{ item.goodsSku.goodsName }}</span>
|
||||
<span>{{ itemGoodsName(item) }}</span>
|
||||
</div>
|
||||
<div class="goods-show-num">
|
||||
已有<span>{{ item.commentNum || 0 }}</span>人评价
|
||||
@@ -70,6 +70,13 @@ export default {
|
||||
this.getCate()
|
||||
},
|
||||
methods: {
|
||||
/** 列表 API 返回 PointsGoods(thumbnail/goodsName 在顶层);详情 API 才有 goodsSku */
|
||||
itemThumbnail (item) {
|
||||
return item?.goodsSku?.thumbnail || item?.thumbnail || ''
|
||||
},
|
||||
itemGoodsName (item) {
|
||||
return item?.goodsSku?.goodsName || item?.goodsName || ''
|
||||
},
|
||||
getList () { // 获取列表
|
||||
pointGoods(this.params).then(res => {
|
||||
if (res.success) {
|
||||
|
||||
Reference in New Issue
Block a user