658 lines
22 KiB
Vue
658 lines
22 KiB
Vue
<script>
|
|
import "~/assets/styles/PromoCodeField.qFEkB6Hm.css";
|
|
import { toDisplayString } from "vue";
|
|
import { renderList } from "vue";
|
|
import { onMounted } from "vue";
|
|
import { useId } from "vue";
|
|
import { onBeforeUnmount } from "vue";
|
|
import { renderSlot } from "vue";
|
|
import { watch } from "vue";
|
|
import { createBlock } from "vue";
|
|
import { withCtx } from "vue";
|
|
import { createCommentVNode } from "vue";
|
|
import { computed } from "vue";
|
|
import { createElementBlock } from "vue";
|
|
import { Fragment } from "vue";
|
|
import { createElementVNode } from "vue";
|
|
import { createTextVNode } from "vue";
|
|
import { unref } from "vue";
|
|
import { defineComponent } from "vue";
|
|
import { createVNode } from "vue";
|
|
import { openBlock } from "vue";
|
|
import { useRoute } from "#app";
|
|
import { navigateTo } from "#app";
|
|
import { NuxtLink } from "#components";
|
|
import { useApi } from "~/lib/auth.js";
|
|
import { useAuth } from "~/lib/auth.js";
|
|
import button from "primevue/button";
|
|
import message from "primevue/message";
|
|
import PromoCodeField from "~/components/config/PromoCodeField.vue";
|
|
import { t as purchase_limit_state_t } from "~/lib/purchase-limit-state.js";
|
|
var O = {
|
|
class: `config-summary-wrap`,
|
|
},
|
|
k = {
|
|
class: `config-summary`,
|
|
},
|
|
ee = {
|
|
class: `buy-bar`,
|
|
},
|
|
te = [`aria-busy`],
|
|
ne = {
|
|
key: 0,
|
|
class: `price-value`,
|
|
},
|
|
A = {
|
|
key: 1,
|
|
class: `price-pending`,
|
|
},
|
|
j = {
|
|
key: 0,
|
|
class: `pi pi-spin pi-spinner`,
|
|
"aria-hidden": `true`,
|
|
},
|
|
M = {
|
|
key: 2,
|
|
class: `level-hint`,
|
|
},
|
|
N = {
|
|
key: 1,
|
|
class: `cart-confirmation`,
|
|
role: `status`,
|
|
},
|
|
P = {
|
|
class: `cart-confirmation-message`,
|
|
},
|
|
F = {
|
|
key: 2,
|
|
class: `quote-status`,
|
|
},
|
|
I = {
|
|
key: 3,
|
|
class: `quote-status`,
|
|
role: `status`,
|
|
},
|
|
L = {
|
|
class: `buy-actions`,
|
|
},
|
|
R = {
|
|
key: 6,
|
|
class: `quote-status`,
|
|
role: `status`,
|
|
},
|
|
z = [`href`],
|
|
B = {
|
|
class: `config-mobile-label`,
|
|
},
|
|
V = Object.assign(
|
|
defineComponent({
|
|
__name: `ConfigCheckout`,
|
|
props: {
|
|
productId: {},
|
|
quantity: {},
|
|
editPosition: {},
|
|
summary: {},
|
|
price: {},
|
|
quoteReady: {
|
|
type: Boolean,
|
|
},
|
|
priceLoading: {
|
|
type: Boolean,
|
|
},
|
|
canSubmit: {
|
|
type: Boolean,
|
|
},
|
|
activeAction: {
|
|
default: null,
|
|
},
|
|
disabled: {
|
|
type: Boolean,
|
|
default: !1,
|
|
},
|
|
promoCode: {
|
|
default: ``,
|
|
},
|
|
promoDiscount: {
|
|
default: 0,
|
|
},
|
|
levelDiscount: {
|
|
default: 0,
|
|
},
|
|
error: {
|
|
default: ``,
|
|
},
|
|
actionError: {
|
|
default: ``,
|
|
},
|
|
cartTip: {
|
|
default: ``,
|
|
},
|
|
showCart: {
|
|
type: Boolean,
|
|
default: !0,
|
|
},
|
|
showPromo: {
|
|
type: Boolean,
|
|
default: !0,
|
|
},
|
|
editing: {
|
|
type: Boolean,
|
|
default: !1,
|
|
},
|
|
loginRedirect: {},
|
|
},
|
|
emits: [`update:promoCode`, `recalc`, `retry`, `cart`, `buy`],
|
|
setup(g, { emit: V }) {
|
|
let H = g,
|
|
U = V,
|
|
W = `configuration-${useId()}`,
|
|
G = useAuth(),
|
|
K = useRoute(),
|
|
q = computed(() => H.disabled || H.activeAction !== null),
|
|
J = purchase_limit_state_t((e) =>
|
|
useApi().post(`/purchase_limit/check`, e, !1, {
|
|
timeoutMs: 15e3,
|
|
}),
|
|
),
|
|
Y = computed(() => H.productId !== void 0 && G.isLoggedIn),
|
|
X = computed(() => Y.value && (!J.checked.value || !J.allowed.value)),
|
|
Z;
|
|
function Q() {
|
|
if (!Y.value) {
|
|
J.reset();
|
|
return;
|
|
}
|
|
let e = {
|
|
product_id: Number(H.productId),
|
|
qty: H.quantity ?? 1,
|
|
};
|
|
return J.check(
|
|
H.editPosition === void 0
|
|
? {
|
|
mode: `single`,
|
|
...e,
|
|
}
|
|
: {
|
|
mode: `cart_update`,
|
|
...e,
|
|
position: H.editPosition,
|
|
},
|
|
);
|
|
}
|
|
(onMounted(() => {
|
|
Z = watch(
|
|
() => [
|
|
G.token,
|
|
G.isLoggedIn,
|
|
H.productId,
|
|
H.quantity,
|
|
H.editPosition,
|
|
],
|
|
Q,
|
|
{
|
|
immediate: !0,
|
|
flush: `sync`,
|
|
},
|
|
);
|
|
}),
|
|
onBeforeUnmount(() => {
|
|
(Z?.(), J.reset());
|
|
}));
|
|
function $(e) {
|
|
if (H.canSubmit && H.quoteReady && !H.priceLoading && !q.value) {
|
|
if (!G.isLoggedIn)
|
|
return navigateTo({
|
|
path: `/login`,
|
|
query: {
|
|
redirect: H.loginRedirect || K.fullPath,
|
|
},
|
|
});
|
|
X.value ||
|
|
(e === `cart` ? H.showCart && U(`cart`) : H.editing || U(`buy`));
|
|
}
|
|
}
|
|
return (n, r) => {
|
|
let i = PromoCodeField,
|
|
o = NuxtLink,
|
|
u = message,
|
|
y = button;
|
|
return (
|
|
openBlock(),
|
|
createElementBlock(`div`, O, [
|
|
(r[13] ||= createElementVNode(
|
|
`h2`,
|
|
{
|
|
class: `config-column-title`,
|
|
},
|
|
`所选配置`,
|
|
-1,
|
|
)),
|
|
createElementVNode(
|
|
`aside`,
|
|
{
|
|
id: W,
|
|
class: `panel config-checkout`,
|
|
"aria-label": `订单确认`,
|
|
},
|
|
[
|
|
(r[10] ||= createElementVNode(
|
|
`h3`,
|
|
{
|
|
class: `section-title`,
|
|
},
|
|
`配置详情`,
|
|
-1,
|
|
)),
|
|
createElementVNode(`dl`, k, [
|
|
(openBlock(!0),
|
|
createElementBlock(
|
|
Fragment,
|
|
null,
|
|
renderList(
|
|
g.summary,
|
|
(t, n) => (
|
|
openBlock(),
|
|
createElementBlock(
|
|
`div`,
|
|
{
|
|
key: `${t.label}-${n}`,
|
|
class: `config-summary-row`,
|
|
},
|
|
[
|
|
createElementVNode(
|
|
`dt`,
|
|
null,
|
|
toDisplayString(t.label),
|
|
1,
|
|
),
|
|
createElementVNode(
|
|
`dd`,
|
|
null,
|
|
toDisplayString(t.value),
|
|
1,
|
|
),
|
|
],
|
|
)
|
|
),
|
|
),
|
|
128,
|
|
)),
|
|
renderSlot(n.$slots, `summary`),
|
|
]),
|
|
n.$slots.default
|
|
? (openBlock(),
|
|
createElementBlock(
|
|
Fragment,
|
|
{
|
|
key: 0,
|
|
},
|
|
[
|
|
(r[5] ||= createElementVNode(
|
|
`div`,
|
|
{
|
|
class: `checkout-divider`,
|
|
},
|
|
null,
|
|
-1,
|
|
)),
|
|
renderSlot(n.$slots, `default`),
|
|
],
|
|
64,
|
|
))
|
|
: createCommentVNode(``, !0),
|
|
createElementVNode(`div`, ee, [
|
|
createElementVNode(
|
|
`div`,
|
|
{
|
|
class: `price-area`,
|
|
"aria-live": `polite`,
|
|
"aria-busy": g.priceLoading,
|
|
},
|
|
[
|
|
(r[6] ||= createElementVNode(
|
|
`span`,
|
|
{
|
|
class: `price-label`,
|
|
},
|
|
`配置费用`,
|
|
-1,
|
|
)),
|
|
g.quoteReady
|
|
? (openBlock(),
|
|
createElementBlock(
|
|
`span`,
|
|
ne,
|
|
`¥ ` + toDisplayString(g.price),
|
|
1,
|
|
))
|
|
: (openBlock(),
|
|
createElementBlock(`span`, A, [
|
|
g.priceLoading
|
|
? (openBlock(), createElementBlock(`i`, j))
|
|
: createCommentVNode(``, !0),
|
|
createTextVNode(
|
|
` ` +
|
|
toDisplayString(
|
|
g.priceLoading ? `正在计算…` : `待确认`,
|
|
),
|
|
1,
|
|
),
|
|
])),
|
|
g.quoteReady && g.levelDiscount > 0
|
|
? (openBlock(),
|
|
createElementBlock(
|
|
`span`,
|
|
M,
|
|
`已享会员折扣 -¥` +
|
|
toDisplayString(g.levelDiscount.toFixed(2)),
|
|
1,
|
|
))
|
|
: createCommentVNode(``, !0),
|
|
],
|
|
8,
|
|
te,
|
|
),
|
|
g.showPromo
|
|
? (openBlock(),
|
|
createBlock(
|
|
i,
|
|
{
|
|
key: 0,
|
|
"model-value": g.promoCode,
|
|
discount: g.quoteReady ? g.promoDiscount : 0,
|
|
loading: g.priceLoading,
|
|
disabled: unref(q),
|
|
"onUpdate:modelValue": (r[0] ||= (e) =>
|
|
U(`update:promoCode`, e)),
|
|
onRecalc: (r[1] ||= (e) => U(`recalc`)),
|
|
},
|
|
null,
|
|
8,
|
|
[`model-value`, `discount`, `loading`, `disabled`],
|
|
))
|
|
: createCommentVNode(``, !0),
|
|
g.cartTip
|
|
? (openBlock(),
|
|
createElementBlock(`div`, N, [
|
|
createElementVNode(`span`, P, [
|
|
(r[7] ||= createElementVNode(
|
|
`i`,
|
|
{
|
|
class: `pi pi-check-circle`,
|
|
"aria-hidden": `true`,
|
|
},
|
|
null,
|
|
-1,
|
|
)),
|
|
createTextVNode(toDisplayString(g.cartTip), 1),
|
|
]),
|
|
createVNode(
|
|
o,
|
|
{
|
|
to: `/cart`,
|
|
class: `cart-confirmation-link`,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
...(r[8] ||= [
|
|
createTextVNode(`查看购物车`, -1),
|
|
createElementVNode(
|
|
`i`,
|
|
{
|
|
class: `pi pi-arrow-right`,
|
|
"aria-hidden": `true`,
|
|
},
|
|
null,
|
|
-1,
|
|
),
|
|
]),
|
|
]),
|
|
_: 1,
|
|
},
|
|
),
|
|
]))
|
|
: createCommentVNode(``, !0),
|
|
renderSlot(n.$slots, `agreement`),
|
|
unref(G).isLoggedIn
|
|
? createCommentVNode(``, !0)
|
|
: (openBlock(),
|
|
createElementBlock(
|
|
`p`,
|
|
F,
|
|
`登录后可加入购物车或购买,登录完成后返回当前产品页面。`,
|
|
)),
|
|
unref(J).pending.value
|
|
? (openBlock(),
|
|
createElementBlock(`p`, I, `正在检查购买限制…`))
|
|
: createCommentVNode(``, !0),
|
|
unref(J).message.value
|
|
? (openBlock(),
|
|
createBlock(
|
|
u,
|
|
{
|
|
key: 4,
|
|
severity: `warn`,
|
|
closable: !1,
|
|
role: `alert`,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
createTextVNode(
|
|
toDisplayString(unref(J).message.value),
|
|
1,
|
|
),
|
|
]),
|
|
_: 1,
|
|
},
|
|
))
|
|
: createCommentVNode(``, !0),
|
|
unref(J).message.value
|
|
? (openBlock(),
|
|
createBlock(
|
|
y,
|
|
{
|
|
key: 5,
|
|
label: `重新检查购买限制`,
|
|
icon: `pi pi-refresh`,
|
|
severity: `secondary`,
|
|
size: `small`,
|
|
outlined: ``,
|
|
disabled: unref(q) || unref(J).pending.value,
|
|
onClick: Q,
|
|
},
|
|
null,
|
|
8,
|
|
[`disabled`],
|
|
))
|
|
: createCommentVNode(``, !0),
|
|
createElementVNode(`div`, L, [
|
|
g.showCart
|
|
? (openBlock(),
|
|
createBlock(
|
|
y,
|
|
{
|
|
key: 0,
|
|
label: g.editing ? `保存配置` : `加入购物车`,
|
|
icon: g.editing
|
|
? `pi pi-check`
|
|
: `pi pi-shopping-cart`,
|
|
severity: `secondary`,
|
|
outlined: ``,
|
|
loading: g.activeAction === `cart`,
|
|
disabled:
|
|
!g.canSubmit ||
|
|
!g.quoteReady ||
|
|
g.priceLoading ||
|
|
unref(q) ||
|
|
unref(X),
|
|
onClick: (r[2] ||= (e) => $(`cart`)),
|
|
},
|
|
null,
|
|
8,
|
|
[`label`, `icon`, `loading`, `disabled`],
|
|
))
|
|
: createCommentVNode(``, !0),
|
|
g.editing && !unref(q)
|
|
? (openBlock(),
|
|
createBlock(
|
|
o,
|
|
{
|
|
key: 1,
|
|
to: `/cart`,
|
|
class: `cart-confirmation-link`,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
...(r[9] ||= [createTextVNode(`取消`, -1)]),
|
|
]),
|
|
_: 1,
|
|
},
|
|
))
|
|
: g.editing
|
|
? createCommentVNode(``, !0)
|
|
: (openBlock(),
|
|
createBlock(
|
|
y,
|
|
{
|
|
key: 2,
|
|
label: `立即购买`,
|
|
loading: g.activeAction === `buy`,
|
|
disabled:
|
|
!g.canSubmit ||
|
|
!g.quoteReady ||
|
|
g.priceLoading ||
|
|
unref(q) ||
|
|
unref(X),
|
|
onClick: (r[3] ||= (e) => $(`buy`)),
|
|
},
|
|
null,
|
|
8,
|
|
[`loading`, `disabled`],
|
|
)),
|
|
]),
|
|
!g.quoteReady && !g.priceLoading
|
|
? (openBlock(),
|
|
createElementBlock(`div`, R, [
|
|
createElementVNode(
|
|
`p`,
|
|
null,
|
|
toDisplayString(
|
|
g.error
|
|
? `报价未能完成,请重试后再提交。`
|
|
: `请选择完整配置并计算报价后继续。`,
|
|
),
|
|
1,
|
|
),
|
|
createVNode(
|
|
y,
|
|
{
|
|
label: g.error ? `重新获取报价` : `计算报价`,
|
|
icon: `pi pi-refresh`,
|
|
severity: `secondary`,
|
|
size: `small`,
|
|
outlined: ``,
|
|
disabled: unref(q),
|
|
onClick: (r[4] ||= (e) => U(`retry`)),
|
|
},
|
|
null,
|
|
8,
|
|
[`label`, `disabled`],
|
|
),
|
|
]))
|
|
: createCommentVNode(``, !0),
|
|
g.error
|
|
? (openBlock(),
|
|
createBlock(
|
|
u,
|
|
{
|
|
key: 7,
|
|
severity: `error`,
|
|
closable: !1,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
createTextVNode(toDisplayString(g.error), 1),
|
|
]),
|
|
_: 1,
|
|
},
|
|
))
|
|
: createCommentVNode(``, !0),
|
|
g.actionError
|
|
? (openBlock(),
|
|
createBlock(
|
|
u,
|
|
{
|
|
key: 8,
|
|
severity: `error`,
|
|
closable: !1,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
createTextVNode(
|
|
toDisplayString(g.actionError),
|
|
1,
|
|
),
|
|
]),
|
|
_: 1,
|
|
},
|
|
))
|
|
: createCommentVNode(``, !0),
|
|
]),
|
|
],
|
|
),
|
|
createElementVNode(
|
|
`a`,
|
|
{
|
|
href: `#${W}`,
|
|
class: `config-mobile-total`,
|
|
},
|
|
[
|
|
createElementVNode(`span`, null, [
|
|
(r[11] ||= createTextVNode(`配置费用`, -1)),
|
|
createElementVNode(
|
|
`strong`,
|
|
null,
|
|
toDisplayString(
|
|
g.quoteReady
|
|
? `¥ ${g.price}`
|
|
: g.priceLoading
|
|
? `正在计算…`
|
|
: `待确认`,
|
|
),
|
|
1,
|
|
),
|
|
]),
|
|
createElementVNode(`span`, B, [
|
|
createTextVNode(
|
|
toDisplayString(
|
|
g.editing ? `查看配置与保存` : `查看配置与购买`,
|
|
),
|
|
1,
|
|
),
|
|
(r[12] ||= createElementVNode(
|
|
`i`,
|
|
{
|
|
class: `pi pi-angle-up`,
|
|
"aria-hidden": `true`,
|
|
},
|
|
null,
|
|
-1,
|
|
)),
|
|
]),
|
|
],
|
|
8,
|
|
z,
|
|
),
|
|
])
|
|
);
|
|
};
|
|
},
|
|
}),
|
|
{
|
|
__name: `ConfigCheckout`,
|
|
},
|
|
);
|
|
export {};
|
|
export default V;
|
|
</script>
|