first commit

This commit is contained in:
cieanyau committed 2026-11-06 00:04:38 +08:00
commit db5762abd4
687 files changed
+171307

No files matched your search

@@ -0,0 +1,449 @@
<script>
import "~/assets/styles/ProductGroupLabel.B1kWpFA-.css";
import "~/assets/styles/CloudProductPicker.CAm9rmUl.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { useId } from "vue";
import { normalizeClass } from "vue";
import { createBlock } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } 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 { NuxtLink } from "#components";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import { n as product_name_n } from "~/lib/product-name.js";
import paginator from "primevue/paginator";
import skeleton from "primevue/skeleton";
import ProductGroupLabel from "~/components/ProductGroupLabel.vue";
var C = {
class: `cloud-product-picker`,
},
w = [`aria-labelledby`],
T = [`id`],
E = {
class: `zone-options`,
role: `group`,
"aria-label": `产品专区`,
},
D = [`aria-pressed`, `disabled`, `onClick`],
O = {
key: 2,
class: `catalog-empty`,
},
k = [`aria-labelledby`],
A = [`id`],
j = {
key: 2,
class: `catalog-empty`,
},
M = {
key: 3,
class: `product-options`,
role: `group`,
"aria-label": `选择云服务器产品`,
},
N = [`aria-pressed`, `disabled`, `onClick`],
P = {
key: 0,
},
F = {
key: 1,
},
I = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `CloudProductPicker`,
props: {
groups: {},
activeGroup: {},
products: {},
selectedId: {},
loading: {
type: Boolean,
},
productLoading: {
type: Boolean,
},
error: {},
errorSource: {},
total: {},
page: {},
disabled: {
type: Boolean,
},
soldOut: {
type: Function,
},
stockLabel: {
type: Function,
},
},
emits: [
`choose-group`,
`choose-product`,
`retry-groups`,
`retry-products`,
`paginate`,
],
setup(f, { emit: _ }) {
let I = _,
L = useId();
return (n, _) => {
let R = skeleton,
z = button,
B = message,
V = ProductGroupLabel,
H = NuxtLink,
U = paginator;
return (
openBlock(),
createElementBlock(`div`, C, [
createElementVNode(
`section`,
{
class: `selection-section`,
"aria-labelledby": `${unref(L)}-lines-title`,
},
[
createElementVNode(
`h3`,
{
id: `${unref(L)}-lines-title`,
},
`选择线路`,
8,
T,
),
f.loading
? (openBlock(),
createBlock(R, {
key: 0,
height: `110px`,
}))
: (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
f.error && f.errorSource === `groups`
? (openBlock(),
createBlock(
B,
{
key: 0,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(f.error),
1,
),
createVNode(
z,
{
label: `重新加载线路`,
severity: `secondary`,
text: ``,
disabled: f.disabled,
onClick: (_[0] ||= (e) =>
I(`retry-groups`)),
},
null,
8,
[`disabled`],
),
]),
_: 1,
},
))
: f.groups.length
? (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
(_[3] ||= createElementVNode(
`div`,
{
class: `selection-label`,
},
`产品专区`,
-1,
)),
createElementVNode(`div`, E, [
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
f.groups,
(e) => (
openBlock(),
createElementBlock(
`button`,
{
key: e.id,
type: `button`,
class: normalizeClass([
`zone-option`,
{
active:
f.activeGroup === e.id,
},
]),
"aria-pressed":
f.activeGroup === e.id,
disabled: f.disabled,
onClick: (t) =>
I(`choose-group`, e.id),
},
[
createVNode(
V,
{
name: e.name,
},
null,
8,
[`name`],
),
],
10,
D,
)
),
),
128,
)),
]),
],
64,
))
: (openBlock(),
createElementBlock(`div`, O, [
(_[5] ||= createElementVNode(
`i`,
{
class: `pi pi-box`,
"aria-hidden": `true`,
},
null,
-1,
)),
(_[6] ||= createElementVNode(
`p`,
null,
`暂未提供可选的云服务器线路`,
-1,
)),
createVNode(
H,
{
to: `/products`,
},
{
default: withCtx(() => [
...(_[4] ||= [
createTextVNode(`浏览产品`, -1),
]),
]),
_: 1,
},
),
])),
],
64,
)),
],
8,
w,
),
f.groups.length
? (openBlock(),
createElementBlock(
`section`,
{
key: 0,
class: `selection-section`,
"aria-labelledby": `${unref(L)}-products-title`,
},
[
createElementVNode(
`h3`,
{
id: `${unref(L)}-products-title`,
class: `products-title`,
},
`产品`,
8,
A,
),
f.productLoading && !f.products.length
? (openBlock(),
createBlock(R, {
key: 0,
height: `110px`,
}))
: f.error && f.errorSource === `products`
? (openBlock(),
createBlock(
B,
{
key: 1,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(f.error),
1,
),
createVNode(
z,
{
label: `重新加载商品`,
severity: `secondary`,
text: ``,
disabled: f.disabled,
onClick: (_[1] ||= (e) =>
I(`retry-products`)),
},
null,
8,
[`disabled`],
),
]),
_: 1,
},
))
: !f.products.length && !f.error
? (openBlock(),
createElementBlock(`div`, j, [
...(_[7] ||= [
createElementVNode(
`p`,
null,
`该专区暂无可售产品`,
-1,
),
]),
]))
: (openBlock(),
createElementBlock(`div`, M, [
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
f.products,
(t) => (
openBlock(),
createElementBlock(
`button`,
{
key: t.id,
type: `button`,
class: normalizeClass([
`product-option`,
{
active: f.selectedId === t.id,
},
]),
"aria-pressed":
f.selectedId === t.id,
disabled:
f.disabled || f.soldOut(t),
onClick: (e) =>
I(`choose-product`, t.id),
},
[
createElementVNode(
`strong`,
null,
toDisplayString(
unref(product_name_n)(t.name),
),
1,
),
f.soldOut(t)
? (openBlock(),
createElementBlock(
`span`,
P,
toDisplayString(
f.stockLabel(t),
),
1,
))
: (openBlock(),
createElementBlock(
`span`,
F,
toDisplayString(
f.selectedId === t.id
? `当前配置`
: `查看可选配置`,
),
1,
)),
],
10,
N,
)
),
),
128,
)),
])),
f.total > 24
? (openBlock(),
createBlock(
U,
{
key: 4,
first: (f.page - 1) * 24,
rows: 24,
totalRecords: f.total,
disabled: f.disabled,
onPage: (_[2] ||= (e) => I(`paginate`, e)),
},
null,
8,
[`first`, `totalRecords`, `disabled`],
))
: createCommentVNode(``, !0),
],
8,
k,
))
: createCommentVNode(``, !0),
])
);
};
},
}),
[[`__scopeId`, `data-v-a438862d`]],
),
{
__name: `CloudProductPicker`,
},
);
export {};
export default I;
</script>
File diff suppressed because it is too large. Load diff
+305
View File
@@ -0,0 +1,305 @@
<script>
import "~/assets/styles/ConfigBandwidth.CWSH1WJZ.css";
import { nextTick } from "vue";
import { normalizeClass } from "vue";
import { computed } from "vue";
import { createElementBlock } from "vue";
import { withDirectives } from "vue";
import { createElementVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import inputnumber from "primevue/inputnumber";
import tooltip from "primevue/tooltip";
var p = {
class: `bandwidth-field`,
},
m = {
class: `bandwidth-label`,
},
h = [`aria-label`],
g = [`aria-valuetext`, `disabled`, `value`, `min`, `max`],
_ = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `ConfigBandwidth`,
props: {
modelValue: {},
options: {},
disabled: {
type: Boolean,
},
},
emits: [`update:modelValue`, `change`],
setup(s, { emit: u }) {
let _ = s,
v = u,
y = computed(() =>
_.options
.map((e) => {
let t = e.type === `step` || e.type === `total`,
n = Number(t ? (e.min_value ?? e.value) : e.value),
r = Number(
t ? (e.max_value ?? e.min_value ?? e.value) : e.value,
),
i = Number(e.step),
a = Number.isFinite(i) && i > 0 ? i : 1;
return {
min: n,
max: Number(
(n + Math.floor((r - n) / a + 1e-7) * a).toFixed(8),
),
step: a,
};
})
.filter(
(e) =>
Number.isFinite(e.min) &&
Number.isFinite(e.max) &&
e.max >= e.min,
),
),
b = computed(() =>
y.value.length ? Math.min(...y.value.map((e) => e.min)) : 0,
),
x = computed(() =>
y.value.length ? Math.max(...y.value.map((e) => e.max)) : 0,
),
S = computed(() => b.value === x.value),
C = computed(() =>
_.modelValue == null ||
_.modelValue === `` ||
!Number.isFinite(Number(_.modelValue))
? null
: Number(_.modelValue),
),
w = computed(() =>
y.value.length
? S.value
? `当前线路带宽固定为 ${b.value} Mbps。`
: `设置服务器的带宽上限,可输入数值或拖动滑块。可选范围 ${b.value}–${x.value} Mbps,数值会自动匹配可用档位。`
: `当前线路暂无可用带宽。`,
);
function T(e) {
let t = b.value,
n = 1 / 0;
for (let r of y.value) {
let i = Number(
Math.min(
r.max,
Math.max(
r.min,
r.min + Math.round((e - r.min) / r.step) * r.step,
),
).toFixed(8),
),
a = Math.abs(i - e);
a < n && ((t = i), (n = a));
}
return t;
}
let E = !1;
function D(e, t = !0) {
if (
_.disabled ||
S.value ||
e === null ||
!Number.isFinite(e) ||
!y.value.length
)
return;
let n = T(e);
C.value !== n &&
(v(`update:modelValue`, n), t ? v(`change`) : (E = !0));
}
function O(e) {
let t = e.target;
_.disabled ||
S.value ||
(D(Number(t.value), !1), (t.value = String(T(Number(t.value)))));
}
function k() {
(E && !_.disabled && !S.value && v(`change`), (E = !1));
}
function A(e) {
if (_.disabled || S.value) return;
if (e.key === `Home` || e.key === `End`) {
(e.preventDefault(), D(e.key === `Home` ? b.value : x.value));
return;
}
let t = [`ArrowRight`, `ArrowUp`, `PageUp`].includes(e.key)
? 1
: [`ArrowLeft`, `ArrowDown`, `PageDown`].includes(e.key)
? -1
: 0;
if (!t) return;
e.preventDefault();
let n = C.value ?? b.value,
r = y.value.flatMap((e) => {
let r =
t > 0
? Math.max(
e.min,
e.min +
(Math.floor((n - e.min) / e.step + 1e-7) + 1) *
e.step,
)
: Math.min(
e.max,
e.min +
(Math.ceil((n - e.min) / e.step - 1e-7) - 1) * e.step,
);
return r >= e.min && r <= e.max ? [r] : [];
});
r.length && D(t > 0 ? Math.min(...r) : Math.max(...r));
}
async function j(t) {
(await Promise.resolve(), await nextTick());
let n = t.originalEvent.target;
((n.value = C.value === null ? `` : String(C.value)),
C.value === null
? n.removeAttribute(`aria-valuenow`)
: n.setAttribute(`aria-valuenow`, String(C.value)));
}
function M(e) {
if (e.key === `ArrowUp` || e.key === `ArrowDown`)
return (
e.stopPropagation(),
A(e),
j({
originalEvent: e,
})
);
if (e.key === `Enter`)
return new Promise((t) => {
setTimeout(() => {
j({
originalEvent: e,
}).then(t);
}, 0);
});
}
return (e, n) => {
let u = inputnumber,
_ = tooltip;
return (
openBlock(),
createElementBlock(`div`, p, [
createElementVNode(`div`, m, [
(n[1] ||= createElementVNode(`span`, null, `带宽上限`, -1)),
withDirectives(
(openBlock(),
createElementBlock(
`button`,
{
class: `bandwidth-help`,
type: `button`,
"aria-label": unref(w),
},
[
...(n[0] ||= [
createElementVNode(
`i`,
{
class: `pi pi-question-circle`,
"aria-hidden": `true`,
},
null,
-1,
),
]),
],
8,
h,
)),
[
[
_,
{
value: unref(w),
autoHide: !1,
},
void 0,
{
top: !0,
},
],
],
),
]),
createElementVNode(
`div`,
{
class: normalizeClass([
`bandwidth-capacity`,
{
"is-disabled": s.disabled,
},
]),
onKeydownCapture: M,
},
[
createVNode(
u,
{
"aria-label": `带宽上限`,
disabled: s.disabled || unref(S),
"model-value": unref(C),
min: unref(b),
max: unref(x),
"use-grouping": !1,
"onUpdate:modelValue": D,
onBlur: j,
},
null,
8,
[`disabled`, `model-value`, `min`, `max`],
),
(n[2] ||= createElementVNode(
`span`,
{
class: `bandwidth-unit`,
"aria-hidden": `true`,
},
`Mbps`,
-1,
)),
],
34,
),
createElementVNode(
`input`,
{
class: `bandwidth-slider`,
type: `range`,
"aria-label": `带宽上限滑块`,
"aria-valuetext": `${unref(C) ?? unref(b)} Mbps`,
disabled: s.disabled || unref(S),
value: unref(C) ?? unref(b),
min: unref(b),
max: unref(x),
step: `any`,
onInput: O,
onChange: k,
onKeydown: A,
},
null,
40,
g,
),
])
);
};
},
}),
[[`__scopeId`, `data-v-45a9c613`]],
),
{
__name: `ConfigBandwidth`,
},
);
export {};
export default _;
</script>
+657
View File
@@ -0,0 +1,657 @@
<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>
+140
View File
@@ -0,0 +1,140 @@
<script>
import "~/assets/styles/OsIcon.CAi4Iz2S.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { normalizeClass } from "vue";
import { createBlock } from "vue";
import { createCommentVNode } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { defineComponent } from "vue";
import { openBlock } from "vue";
import OsIcon from "~/components/OsIcon.vue";
var d = [`aria-label`],
f = [`aria-pressed`, `disabled`, `onClick`],
p = {
key: 1,
},
m = Object.assign(
defineComponent({
__name: `ConfigChoiceGrid`,
props: {
modelValue: {},
options: {},
disabled: {
type: Boolean,
},
compact: {
type: Boolean,
},
images: {
type: Boolean,
},
label: {},
},
emits: [`update:modelValue`, `change`],
setup(c, { emit: m }) {
let h = c,
g = m;
function _(e) {
h.disabled ||
h.modelValue === e ||
(g(`update:modelValue`, e), g(`change`));
}
return (m, h) => {
let g = OsIcon;
return (
openBlock(),
createElementBlock(
`div`,
{
class: normalizeClass([
`config-choices`,
{
compact: c.compact && !c.images,
"image-groups": c.images,
},
]),
role: `group`,
"aria-label": c.label,
},
[
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
c.options,
(t) => (
openBlock(),
createElementBlock(
`button`,
{
key: t.value,
type: `button`,
class: normalizeClass([
c.images ? `image-group` : `config-choice`,
{
active: c.modelValue === t.value,
},
]),
"aria-pressed": c.modelValue === t.value,
disabled: c.disabled,
onClick: (e) => _(t.value),
},
[
c.images
? (openBlock(),
createBlock(
g,
{
key: 0,
name: t.label,
url: t.iconUrl,
icon: t.icon,
size: 36,
},
null,
8,
[`name`, `url`, `icon`],
))
: createCommentVNode(``, !0),
createElementVNode(
`span`,
null,
toDisplayString(t.label),
1,
),
t.description
? (openBlock(),
createElementBlock(
`small`,
p,
toDisplayString(t.description),
1,
))
: createCommentVNode(``, !0),
],
10,
f,
)
),
),
128,
)),
],
10,
d,
)
);
};
},
}),
{
__name: `ConfigChoiceGrid`,
},
);
export {};
export default m;
</script>
+66
View File
@@ -0,0 +1,66 @@
<script>
import "~/assets/styles/ConfigDiskAdd.C92e9ZuF.css";
import { toDisplayString } from "vue";
import { createCommentVNode } from "vue";
import { createElementBlock } from "vue";
import { createElementVNode } from "vue";
import { defineComponent } from "vue";
import { openBlock } from "vue";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
var s = [`disabled`],
c = {
key: 0,
},
l = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `ConfigDiskAdd`,
props: {
disabled: {
type: Boolean,
},
hint: {},
},
emits: [`add`],
setup(i) {
return (o, l) => (
openBlock(),
createElementBlock(
`button`,
{
class: `storage-add`,
type: `button`,
disabled: i.disabled,
onClick: (l[0] ||= (e) => o.$emit(`add`)),
},
[
(l[1] ||= createElementVNode(
`i`,
{
class: `pi pi-plus`,
"aria-hidden": `true`,
},
null,
-1,
)),
(l[2] ||= createElementVNode(`span`, null, `添加数据盘`, -1)),
i.hint
? (openBlock(),
createElementBlock(`small`, c, toDisplayString(i.hint), 1))
: createCommentVNode(``, !0),
],
8,
s,
)
);
},
}),
[[`__scopeId`, `data-v-68361f8e`]],
),
{
__name: `ConfigDiskAdd`,
},
);
export {};
export default l;
</script>
+346
View File
@@ -0,0 +1,346 @@
<script>
import "~/assets/styles/ConfigDiskCard.Dx9IqqQ_.css";
import { nextTick } from "vue";
import { toDisplayString } from "vue";
import { renderSlot } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import inputnumber from "primevue/inputnumber";
var m = {
class: `storage-field`,
},
h = {
key: 0,
class: `storage-label`,
},
g = [`aria-label`],
_ = {
class: `storage-card-header`,
},
v = [`disabled`, `aria-label`],
y = {
class: `storage-unit`,
"aria-hidden": `true`,
},
b = [`aria-label`, `aria-valuetext`, `disabled`, `value`, `min`, `max`],
x = {
key: 0,
class: `storage-description`,
},
S = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `ConfigDiskCard`,
props: {
label: {},
hideLabel: {
type: Boolean,
},
title: {},
modelValue: {},
options: {
default: () => [],
},
unit: {
default: `GB`,
},
description: {},
disabled: {
type: Boolean,
},
removable: {
type: Boolean,
},
},
emits: [`update:modelValue`, `change`, `remove`],
setup(l, { emit: f }) {
let S = l,
C = f,
w = computed(() =>
S.options
.map((e) => {
let t = e.type === `step` || e.type === `total`,
n = Number(t ? (e.min_value ?? e.value) : e.value),
r = Number(
t ? (e.max_value ?? e.min_value ?? e.value) : e.value,
),
i = Number(e.step) > 0 ? Number(e.step) : 1;
return {
min: n,
max: n + Math.floor((r - n) / i + 1e-7) * i,
step: i,
};
})
.filter(
(e) =>
Number.isFinite(e.min) &&
Number.isFinite(e.max) &&
e.max >= e.min,
),
),
T = computed(() => Math.min(...w.value.map((e) => e.min))),
E = computed(() => Math.max(...w.value.map((e) => e.max))),
D = computed(() => T.value === E.value),
O = computed(() => Number(S.modelValue) || 0),
k = computed(() =>
D.value
? `容量 ${T.value} ${S.unit}`
: `容量 ${T.value}–${E.value} ${S.unit}`,
);
function A(e) {
let t = T.value,
n = 1 / 0;
for (let r of w.value) {
let i = Number(
Math.min(
r.max,
Math.max(
r.min,
r.min + Math.round((e - r.min) / r.step) * r.step,
),
).toFixed(8),
),
a = Math.abs(i - e);
a < n && ((t = i), (n = a));
}
return t;
}
function j(e, t = !0) {
if (
S.disabled ||
D.value ||
e === null ||
!Number.isFinite(e) ||
!w.value.length
)
return;
let n = A(e);
Number(S.modelValue) !== n &&
(C(`update:modelValue`, n), t && C(`change`));
}
function M(e) {
let t = e.target,
n = Number(t.value);
(j(n, !1), (t.value = String(A(n))));
}
function N() {
!S.disabled && !D.value && C(`change`);
}
function P(e) {
let t = [`ArrowRight`, `ArrowUp`].includes(e.key)
? 1
: [`ArrowLeft`, `ArrowDown`].includes(e.key)
? -1
: 0;
if (!t || S.disabled || D.value) return;
e.preventDefault();
let n = O.value,
r = w.value.flatMap((e) => {
let r =
t > 0
? Math.max(
e.min,
e.min +
(Math.floor((n - e.min) / e.step + 1e-7) + 1) *
e.step,
)
: Math.min(
e.max,
e.min +
(Math.ceil((n - e.min) / e.step - 1e-7) - 1) * e.step,
);
return r >= e.min && r <= e.max ? [r] : [];
});
r.length && j(t > 0 ? Math.min(...r) : Math.max(...r));
}
function F() {
!S.disabled && S.removable && C(`remove`);
}
async function I(t) {
(await Promise.resolve(), await nextTick());
let n = t.originalEvent.target;
((n.value = String(O.value)),
n.setAttribute(`aria-valuenow`, String(O.value)));
}
function L(e) {
e.key === `ArrowUp` || e.key === `ArrowDown`
? (e.stopPropagation(),
P(e),
I({
originalEvent: e,
}))
: e.key === `Enter` &&
I({
originalEvent: e,
});
}
return (e, i) => {
let f = inputnumber;
return (
openBlock(),
createElementBlock(`div`, m, [
l.hideLabel
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(`div`, h, toDisplayString(l.label), 1)),
createElementVNode(
`div`,
{
class: `storage-card`,
role: `group`,
"aria-label": l.label,
},
[
createElementVNode(`div`, _, [
createElementVNode(
`strong`,
null,
toDisplayString(l.title || `标准存储`),
1,
),
l.removable
? (openBlock(),
createElementBlock(
`button`,
{
key: 0,
class: `storage-remove`,
type: `button`,
disabled: l.disabled,
"aria-label": `删除${l.label}`,
onClick: F,
},
[
...(i[0] ||= [
createElementVNode(
`i`,
{
class: `pi pi-trash`,
"aria-hidden": `true`,
},
null,
-1,
),
]),
],
8,
v,
))
: createCommentVNode(``, !0),
]),
renderSlot(e.$slots, `type`, {}, void 0, !0),
renderSlot(
e.$slots,
`default`,
{},
() => [
unref(w).length
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createElementVNode(
`div`,
{
class: `storage-capacity`,
onKeydownCapture: L,
},
[
createVNode(
f,
{
"aria-label": l.label,
disabled: l.disabled || unref(D),
"model-value": unref(O),
min: unref(T),
max: unref(E),
"use-grouping": !1,
"onUpdate:modelValue": j,
onBlur: I,
},
null,
8,
[
`aria-label`,
`disabled`,
`model-value`,
`min`,
`max`,
],
),
createElementVNode(
`span`,
y,
toDisplayString(l.unit),
1,
),
],
32,
),
createElementVNode(
`input`,
{
class: `storage-slider`,
type: `range`,
"aria-label": `${l.label}容量滑块`,
"aria-valuetext": `${unref(O)} ${l.unit}`,
disabled: l.disabled || unref(D),
value: unref(O),
min: unref(T),
max: unref(E),
step: `any`,
onInput: M,
onChange: N,
onKeydown: P,
},
null,
40,
b,
),
],
64,
))
: createCommentVNode(``, !0),
],
!0,
),
l.description || unref(w).length
? (openBlock(),
createElementBlock(
`p`,
x,
toDisplayString(l.description || unref(k)),
1,
))
: createCommentVNode(``, !0),
renderSlot(e.$slots, `extra`, {}, void 0, !0),
],
8,
g,
),
renderSlot(e.$slots, `hint`, {}, void 0, !0),
])
);
};
},
}),
[[`__scopeId`, `data-v-83c644c5`]],
),
{
__name: `ConfigDiskCard`,
},
);
export {};
export default S;
</script>
@@ -0,0 +1,197 @@
<script>
import { renderList } from "vue";
import { renderSlot } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import skeleton from "primevue/skeleton";
var l = [`aria-busy`, `aria-label`],
u = {
class: `config-layout`,
},
d = {
class: `config-options`,
},
f = {
class: `section-title`,
},
p = {
class: `config-loading-fields`,
},
m = {
class: `config-choices`,
},
h = {
class: `config-summary-wrap`,
"aria-hidden": `true`,
},
g = {
class: `panel config-checkout config-loading-summary`,
},
_ = Object.assign(
defineComponent({
__name: `ConfigLoadingShell`,
props: {
busy: {
type: Boolean,
default: !0,
},
},
setup(a) {
return (_, v) => {
let y = skeleton;
return (
openBlock(),
createElementBlock(
`div`,
{
class: `config-page config-loading-shell`,
"aria-busy": a.busy,
"aria-label": a.busy ? `正在加载产品配置` : `产品配置`,
},
[
createElementVNode(`div`, u, [
createElementVNode(`div`, d, [
renderSlot(_.$slots, `catalog`),
(openBlock(),
createElementBlock(
Fragment,
null,
renderList(3, (t) =>
createElementVNode(
`section`,
{
key: t,
class: `panel`,
"aria-hidden": `true`,
},
[
createElementVNode(`h2`, f, [
createVNode(y, {
width: `6rem`,
height: `1.429rem`,
}),
]),
createElementVNode(`div`, p, [
createVNode(y, {
width: `4rem`,
height: `1.429rem`,
}),
createElementVNode(`div`, m, [
(openBlock(),
createElementBlock(
Fragment,
null,
renderList(4, (e) =>
createVNode(y, {
key: e,
height: `60px`,
}),
),
64,
)),
]),
createVNode(y, {
width: `4rem`,
height: `1.429rem`,
}),
createVNode(y, {
width: `70%`,
height: `36px`,
}),
]),
],
),
),
64,
)),
]),
createElementVNode(`div`, h, [
(v[3] ||= createElementVNode(
`h2`,
{
class: `config-column-title`,
},
`所选配置`,
-1,
)),
createElementVNode(`aside`, g, [
(v[0] ||= createElementVNode(
`h3`,
{
class: `section-title`,
},
`配置详情`,
-1,
)),
(openBlock(),
createElementBlock(
Fragment,
null,
renderList(6, (e) =>
createVNode(y, {
key: e,
height: `1.429rem`,
}),
),
64,
)),
(v[1] ||= createElementVNode(
`div`,
{
class: `checkout-divider`,
},
null,
-1,
)),
createVNode(y, {
height: `36px`,
}),
createVNode(y, {
height: `36px`,
}),
(v[2] ||= createElementVNode(
`div`,
{
class: `checkout-divider`,
},
null,
-1,
)),
createVNode(y, {
width: `5rem`,
height: `1.714rem`,
}),
createVNode(y, {
height: `2.275rem`,
}),
createVNode(y, {
height: `100px`,
}),
createVNode(y, {
height: `36px`,
}),
createVNode(y, {
height: `36px`,
}),
]),
]),
]),
],
8,
l,
)
);
};
},
}),
{
__name: `ConfigLoadingShell`,
},
);
export {};
export default _;
</script>
@@ -0,0 +1,233 @@
<script>
import "~/assets/styles/OsIcon.CAi4Iz2S.css";
import "~/assets/styles/ConfigResourceOption.Dj4VopnA.css";
import { toDisplayString } from "vue";
import { createBlock } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import select from "primevue/select";
import inputnumber from "primevue/inputnumber";
import ConfigChoiceGrid from "~/components/config/ConfigChoiceGrid.vue";
var h = {
key: 1,
class: `resource-range`,
},
g = {
key: 1,
class: `hint`,
},
_ = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `ConfigResourceOption`,
props: {
modelValue: {},
options: {},
label: {},
unit: {},
disabled: {
type: Boolean,
},
},
emits: [`update:modelValue`, `change`],
setup(c, { emit: d }) {
let _ = c,
v = d,
y = computed(() =>
_.options
.map((e, t) => {
let n = e.type === `step` || e.type === `total`,
r = Number(n ? (e.min_value ?? e.value) : e.value),
i = Number(
n ? (e.max_value ?? e.min_value ?? e.value) : e.value,
);
return {
value: t,
min: r,
max: i,
step: Number(e.step) > 0 ? Number(e.step) : 1,
label: e.desc || `${r}${i > r ? `–${i}` : ``} ${_.unit}`,
};
})
.filter(
(e) =>
Number.isFinite(e.min) &&
Number.isFinite(e.max) &&
e.max >= e.min,
),
),
b = computed(() => y.value.some((e) => e.max > e.min)),
x = computed(
() =>
y.value.find((e) => {
let t =
_.modelValue === null ||
_.modelValue === void 0 ||
_.modelValue === ``
? NaN
: Number(_.modelValue);
return (
t >= e.min &&
t <= e.max &&
Math.abs(
(t - e.min) / e.step - Math.round((t - e.min) / e.step),
) < 1e-7
);
}) ?? y.value[0],
),
S = computed(() =>
_.modelValue === null ||
_.modelValue === void 0 ||
_.modelValue === ``
? null
: Number(_.modelValue),
);
function C(e) {
if (_.disabled || e === null || !Number.isFinite(e) || !x.value)
return;
let { min: t, max: n, step: r } = x.value,
i = t + Math.floor((n - t) / r + 1e-7) * r,
a = Number(
Math.min(
i,
Math.max(t, t + Math.round((e - t) / r) * r),
).toFixed(8),
);
Number(_.modelValue) !== a &&
(v(`update:modelValue`, a), v(`change`));
}
function w(e) {
if (_.disabled) return;
let t = y.value.find((t) => t.value === e);
if (!t) return;
let n = S.value;
(x.value === t &&
n !== null &&
n >= t.min &&
n <= t.max &&
Math.abs(
(n - t.min) / t.step - Math.round((n - t.min) / t.step),
) < 1e-7) ||
(v(`update:modelValue`, t.min), v(`change`));
}
return (r, d) => {
let _ = ConfigChoiceGrid,
v = select,
T = inputnumber;
return unref(b)
? (openBlock(),
createElementBlock(`div`, h, [
unref(y).length > 1
? (openBlock(),
createBlock(
v,
{
key: 0,
"aria-label": `${c.label}范围`,
disabled: c.disabled,
"model-value": unref(x)?.value,
options: unref(y),
"option-label": `label`,
"option-value": `value`,
"onUpdate:modelValue": w,
},
null,
8,
[`aria-label`, `disabled`, `model-value`, `options`],
))
: createCommentVNode(``, !0),
createVNode(
T,
{
"aria-label": c.label,
disabled: c.disabled || unref(x)?.min === unref(x)?.max,
"model-value": unref(S),
min: unref(x)?.min,
max: unref(x)?.max,
step: unref(x)?.step,
suffix: ` ${c.unit}`,
"show-buttons": ``,
"button-layout": `horizontal`,
"onUpdate:modelValue": C,
},
null,
8,
[
`aria-label`,
`disabled`,
`model-value`,
`min`,
`max`,
`step`,
`suffix`,
],
),
unref(x)
? (openBlock(),
createElementBlock(`small`, g, [
createTextVNode(
toDisplayString(unref(x).min) +
`–` +
toDisplayString(unref(x).max) +
` ` +
toDisplayString(c.unit),
1,
),
unref(x).max > unref(x).min
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createTextVNode(
`,步长 ` +
toDisplayString(unref(x).step) +
` ` +
toDisplayString(c.unit),
1,
),
],
64,
))
: createCommentVNode(``, !0),
]))
: createCommentVNode(``, !0),
]))
: (openBlock(),
createBlock(
_,
{
key: 0,
label: c.label,
disabled: c.disabled,
"model-value": unref(x)?.value,
options: unref(y),
compact: ``,
"onUpdate:modelValue": w,
},
null,
8,
[`label`, `disabled`, `model-value`, `options`],
));
};
},
}),
[[`__scopeId`, `data-v-5a04c843`]],
),
{
__name: `ConfigResourceOption`,
},
);
export {};
export default _;
</script>
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,268 @@
<script>
import "~/assets/styles/ProductCustomFields.B2QMnPil.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { createBlock } 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 { openBlock } from "vue";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import inputtext from "primevue/inputtext";
import select from "primevue/select";
import checkbox from "primevue/checkbox";
import textarea from "primevue/textarea";
var _ = {
key: 0,
class: `panel product-custom-fields`,
},
v = [`for`],
y = {
key: 0,
},
b = {
key: 4,
class: `field-note`,
},
x = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `ProductCustomFields`,
props: {
fields: {},
modelValue: {},
disabled: {
type: Boolean,
},
},
emits: [`update:modelValue`],
setup(u, { emit: f }) {
let x = u,
S = f,
C = computed(() => x.fields.filter((e) => e.kind !== `explain`));
function w(e, t) {
S(`update:modelValue`, {
...x.modelValue,
[e]: t == null ? `` : String(t),
});
}
return (i, f) => {
let x = textarea,
S = select,
T = checkbox,
E = inputtext;
return u.fields.length
? (openBlock(),
createElementBlock(`section`, _, [
(f[0] ||= createElementVNode(
`h2`,
{
class: `section-title`,
},
`订购信息`,
-1,
)),
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
u.fields.filter((e) => e.kind === `explain`),
(t) => (
openBlock(),
createElementBlock(
`p`,
{
key: `explain-${t.id}`,
class: `field-note`,
},
toDisplayString(t.explain || t.description),
1,
)
),
),
128,
)),
(openBlock(!0),
createElementBlock(
Fragment,
null,
renderList(
unref(C),
(t) => (
openBlock(),
createElementBlock(
`div`,
{
key: t.id,
class: `form-row`,
},
[
createElementVNode(
`label`,
{
for: `product-field-${t.id}`,
},
[
createTextVNode(toDisplayString(t.label), 1),
t.required
? (openBlock(),
createElementBlock(`span`, y, ` *`))
: createCommentVNode(``, !0),
],
8,
v,
),
t.kind === `textarea`
? (openBlock(),
createBlock(
x,
{
key: 0,
id: `product-field-${t.id}`,
"model-value": u.modelValue[t.id],
"aria-label": t.label,
required: t.required,
disabled: u.disabled,
rows: `3`,
class: `grow`,
"onUpdate:modelValue": (e) => w(t.id, e),
},
null,
8,
[
`id`,
`model-value`,
`aria-label`,
`required`,
`disabled`,
`onUpdate:modelValue`,
],
))
: t.kind === `select`
? (openBlock(),
createBlock(
S,
{
key: 1,
"input-id": `product-field-${t.id}`,
"model-value": u.modelValue[t.id],
"aria-label": t.label,
required: t.required,
options: t.options,
"option-label": `label`,
"option-value": `value`,
disabled: u.disabled,
class: `grow`,
"onUpdate:modelValue": (e) => w(t.id, e),
},
null,
8,
[
`input-id`,
`model-value`,
`aria-label`,
`required`,
`options`,
`disabled`,
`onUpdate:modelValue`,
],
))
: t.kind === `boolean`
? (openBlock(),
createBlock(
T,
{
key: 2,
"input-id": `product-field-${t.id}`,
"model-value":
u.modelValue[t.id] === `1`,
"aria-label": t.label,
required: t.required,
binary: ``,
disabled: u.disabled,
"onUpdate:modelValue": (e) =>
w(t.id, e ? `1` : ``),
},
null,
8,
[
`input-id`,
`model-value`,
`aria-label`,
`required`,
`disabled`,
`onUpdate:modelValue`,
],
))
: (openBlock(),
createBlock(
E,
{
key: 3,
id: `product-field-${t.id}`,
"model-value": u.modelValue[t.id],
"aria-label": t.label,
required: t.required,
type:
t.kind === `password`
? `password`
: t.kind === `link`
? `url`
: `text`,
disabled: u.disabled,
autocomplete:
t.kind === `password`
? `new-password`
: `off`,
class: `grow`,
"onUpdate:modelValue": (e) =>
w(t.id, e),
},
null,
8,
[
`id`,
`model-value`,
`aria-label`,
`required`,
`type`,
`disabled`,
`autocomplete`,
`onUpdate:modelValue`,
],
)),
t.description
? (openBlock(),
createElementBlock(
`small`,
b,
toDisplayString(t.description),
1,
))
: createCommentVNode(``, !0),
],
)
),
),
128,
)),
]))
: createCommentVNode(``, !0);
};
},
}),
[[`__scopeId`, `data-v-9d2a6f70`]],
),
{
__name: `ProductCustomFields`,
},
);
export {};
export default x;
</script>
+193
View File
@@ -0,0 +1,193 @@
<script>
import "~/assets/styles/PromoCodeField.qFEkB6Hm.css";
import { toDisplayString } from "vue";
import { normalizeClass } from "vue";
import { mergeModels } from "vue";
import { useModel } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { createCommentVNode } from "vue";
import { isRef } from "vue";
import { createElementBlock } from "vue";
import { createElementVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { withKeys } from "vue";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import inputtext from "primevue/inputtext";
var y = [`open`],
b = {
class: `promo-body`,
},
x = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `PromoCodeField`,
props: mergeModels(
{
discount: {},
loading: {
type: Boolean,
},
disabled: {
type: Boolean,
},
},
{
modelValue: {
default: ``,
},
modelModifiers: {},
},
),
emits: mergeModels([`recalc`], [`update:modelValue`]),
setup(n, { emit: f }) {
let _ = useModel(n, `modelValue`),
x = n,
S = f,
C = ref(``),
w = ref(!1),
T = ref(`idle`);
function E() {
if (x.disabled || x.loading) return;
let e = C.value.trim();
e &&
((w.value = !0), (T.value = `idle`), (_.value = e), S(`recalc`));
}
function D() {
x.disabled ||
x.loading ||
((C.value = ``),
(_.value = ``),
(T.value = `idle`),
(w.value = !1),
S(`recalc`));
}
return (
watch(
() => x.loading,
(e, t) => {
t &&
!e &&
w.value &&
((w.value = !1),
(T.value = (x.discount ?? 0) > 0 ? `ok` : `fail`));
},
),
watch(_, (e) => {
!e && !w.value && ((C.value = ``), (T.value = `idle`));
}),
(r, i) => {
let o = inputtext,
f = button;
return (
openBlock(),
createElementBlock(
`details`,
{
class: `promo`,
open: !!_.value,
},
[
(i[1] ||= createElementVNode(
`summary`,
null,
`我有优惠码,立即使用`,
-1,
)),
createElementVNode(`div`, b, [
createVNode(
o,
{
modelValue: unref(C),
"onUpdate:modelValue": (i[0] ||= (e) =>
isRef(C) ? (C.value = e) : null),
"aria-label": `优惠码`,
placeholder: `选填,输入后点「使用」`,
disabled: n.disabled,
class: `promo-input`,
onKeyup: withKeys(E, [`enter`]),
},
null,
8,
[`modelValue`, `disabled`],
),
createVNode(
f,
{
label: `使用`,
size: `small`,
severity: `secondary`,
outlined: ``,
disabled: n.disabled || !unref(C).trim(),
loading: unref(w),
onClick: E,
},
null,
8,
[`disabled`, `loading`],
),
_.value
? (openBlock(),
createBlock(
f,
{
key: 0,
label: `取消`,
size: `small`,
severity: `secondary`,
text: ``,
disabled: n.disabled,
onClick: D,
},
null,
8,
[`disabled`],
))
: createCommentVNode(``, !0),
]),
unref(T) === `idle`
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(
`p`,
{
key: 0,
class: normalizeClass([
`promo-tip`,
{
ok: unref(T) === `ok`,
fail: unref(T) === `fail`,
},
]),
role: `status`,
},
toDisplayString(
unref(T) === `ok`
? `优惠码已生效,已优惠 ¥${(n.discount ?? 0).toFixed(2)}`
: `该优惠码不可用`,
),
3,
)),
],
8,
y,
)
);
}
);
},
}),
[[`__scopeId`, `data-v-a17e621a`]],
),
{
__name: `PromoCodeField`,
},
);
export {};
export default x;
</script>