vue3-product-sku
Version:
302 lines (301 loc) • 12.6 kB
JavaScript
(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".sku-btn[data-v-654bfdce]{background-color:#1fabc4;color:#fff;border:0;padding:7px 20px;border-radius:5px;cursor:pointer}.sku[data-v-654bfdce]{padding-left:5px;border-left:4px solid #1FABC4;margin-bottom:20px}.attr-name[data-v-654bfdce]{background-color:#f8f8f8;padding:10px 20px 10px 5px;display:flex;justify-content:space-between}.attr-name-value[data-v-654bfdce]{outline:none;border:1px solid #e5e6e7;height:32px;line-height:32px;border-radius:4px;padding:0 15px}.attr-name-value[data-v-654bfdce]::placeholder{color:#a8a4a4}.add-attr[data-v-654bfdce]{display:flex;align-items:center;padding:0 5px;flex-wrap:wrap}.add-attr-value[data-v-654bfdce]{margin:10px 10px 0 0;border:1px solid #e5e6e7;height:32px;line-height:32px;padding:0 15px;border-radius:4px;color:#1fabc4;display:flex}.delv[data-v-654bfdce]{color:#067488;cursor:pointer;width:32px;text-align:center}.delN[data-v-654bfdce]{font-size:22px;color:#1fabc4;cursor:pointer}.attr-value[data-v-654bfdce]{width:280px;display:flex;align-items:center;justify-content:space-between;height:32px;line-height:32px;border-radius:4px;border:1px solid #e5e6e7;padding:0 10px;margin-top:10px}.attr-value-value[data-v-654bfdce]{outline:none;border:none;flex:1}.attr-value-value[data-v-654bfdce]::placeholder{color:#a8a4a4}.addIcon[data-v-654bfdce]{font-size:22px;color:#c0c4cc;cursor:pointer}table[data-v-654bfdce]{width:100%;border-collapse:collapse;margin:20px 0}table[data-v-654bfdce],th[data-v-654bfdce],td[data-v-654bfdce]{border:1px solid #e9e4e4}th[data-v-654bfdce],td[data-v-654bfdce]{padding:10px;text-align:center}th[data-v-654bfdce]{background-color:#f8f8f8}.modal-overlay[data-v-654bfdce]{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#000c;display:flex;justify-content:center;align-items:center;z-index:1000}.modal[data-v-654bfdce]{position:relative;background:#fff;padding:20px;border-radius:8px;max-width:90%;max-height:90%;overflow:auto}.close-button[data-v-654bfdce]{position:absolute;top:0;right:0;font-size:30px;cursor:pointer;background:none;border:none}.modal-image[data-v-654bfdce]{width:500px;height:auto}.productImg[data-v-654bfdce]{display:flex;align-items:center;justify-content:space-between;padding-right:10%}.productImg img[data-v-654bfdce]{border:1px solid #e5e6e7;border-radius:5px}.delete-button[data-v-654bfdce]{font-size:18px;cursor:pointer;background:none;border:none;margin-left:20px}")),document.head.appendChild(e)}}catch(d){console.error("vite-plugin-css-injected-by-js",d)}})();
import { ref as f, onMounted as J, watch as K, createElementBlock as o, openBlock as n, Fragment as k, createCommentVNode as p, createElementVNode as u, renderList as S, normalizeStyle as C, withDirectives as V, vModelText as P, toDisplayString as U } from "vue";
const Q = (r, A) => {
const d = r.__vccOpts || r;
for (const [v, b] of A)
d[v] = b;
return d;
}, X = { class: "attr-name" }, Y = ["onUpdate:modelValue"], Z = ["onClick"], x = { class: "add-attr" }, ee = ["onClick"], te = { class: "attr-value" }, ae = ["onUpdate:modelValue"], le = ["onClick"], oe = {
key: 1,
border: "1"
}, ne = { key: 0 }, ce = { key: 1 }, ue = { key: 2 }, se = { key: 3 }, re = ["rowspan"], de = { key: 0 }, ie = ["onUpdate:modelValue"], pe = { key: 1 }, me = ["onUpdate:modelValue"], ve = { key: 2 }, he = ["onUpdate:modelValue"], ye = {
key: 3,
style: { width: "20%" }
}, ke = { class: "productImg" }, ge = ["src", "onClick"], _e = ["onClick"], fe = ["onChange"], be = { class: "modal" }, Se = ["src"], Ce = {
__name: "ProductSku",
props: {
color: {
type: String,
default: "#1FABC4"
},
productStock: {
type: Boolean,
default: !0
},
productPrice: {
type: Boolean,
default: !0
},
memberPrice: {
type: Boolean,
default: !0
},
productImg: {
type: Boolean,
default: !0
},
deleteImg: {
type: Boolean,
default: !1
},
parentTableData: {
type: Array,
default: () => []
},
parentAttr: {
type: Array,
default: () => []
}
},
emits: ["data-quote", "upload-img", "delete-img"],
setup(r, { emit: A }) {
const d = f([]), v = f([]), b = f(!1), w = f(""), g = f([]), D = f([]), _ = r, I = A;
J(() => {
_.parentTableData.length > 0 && _.parentAttr.length > 0 && (D.value = _.parentAttr.map((e) => e.name), d.value = [..._.parentAttr], g.value = [..._.parentTableData]);
}), K(() => d.value, (e) => {
q(G(e));
}, { deep: !0 });
const M = () => {
d.value.push({
name: "",
value: []
});
}, T = (e) => {
d.value.splice(e, 1);
}, E = (e) => {
if (!v.value[e] || !v.value[e].trim()) {
v.value[e] = "";
return;
}
const c = v.value[e].trim().split(/\s+/);
d.value[e].value = [.../* @__PURE__ */ new Set([...d.value[e].value, ...c])], v.value[e] = "";
}, $ = (e, c) => {
d.value[e].value.splice(c, 1);
}, F = (e, c) => {
const a = e.target.files[0];
a && a.type.startsWith("image/") ? I("upload-img", a, c) : alert("Please select a valid image file.");
}, N = (e) => {
_.deleteImg ? I("delete-img", e) : g.value[e].productImg = "";
}, j = (e) => {
b.value = !0, w.value = g.value[e].productImg;
}, B = () => {
b.value = !1;
}, q = (e) => {
D.value = e.map((a) => a.name);
const c = R(e, g.value);
g.value = z(c, D.value), O();
}, O = () => {
const e = {
attr: d.value,
tableData: g.value
};
I("data-quote", e);
}, R = (e, c) => {
const a = e.map((s) => s.name), l = e.map((s) => s.value), t = L(...l), m = /* @__PURE__ */ new Map();
return c.forEach((s) => {
const i = a.map((h) => s.productSpec[h]).join("|");
m.set(i, s);
}), t.map((s) => {
const i = {};
a.forEach((y, H) => {
i[y] = s[H];
});
const h = a.map((y) => i[y]).join("|");
return m.get(h) || {
productSpec: i,
productPrice: "",
memberPrice: "",
productStock: "",
productImg: ""
};
});
}, z = (e, c) => {
const a = c.reduce((l, t) => (l[t] = W(e, t), l), {});
return e.map((l, t) => {
const m = c.map((s) => {
var i, h;
return {
value: l.productSpec[s],
show: ((i = a[s][t]) == null ? void 0 : i.show) ?? !0,
rowspan: ((h = a[s][t]) == null ? void 0 : h.rowspan) ?? 1
};
});
return {
...l,
specs: m
};
});
}, L = (...e) => e.reduce((c, a) => c.flatMap((l) => a.map((t) => [l, t].flat())), [[]]), W = (e, c) => {
const a = [];
let l = null, t = 0;
e.forEach((s, i) => {
if (s.productSpec[c] !== l) {
if (l !== null) {
const h = i - t;
for (let y = t; y < i; y++)
a[y] = { show: y === t, rowspan: h };
}
l = s.productSpec[c], t = i;
}
});
const m = e.length - t;
for (let s = t; s < e.length; s++)
a[s] = { show: s === t, rowspan: m };
return a;
}, G = (e) => e.filter((c) => c.name !== "" && Array.isArray(c.value) && c.value.length > 0);
return (e, c) => (n(), o(k, null, [
d.value.length > 0 ? (n(!0), o(k, { key: 0 }, S(d.value, (a, l) => (n(), o("div", {
class: "sku",
style: C({ "border-left": `4px solid ${r.color}` }),
key: l
}, [
u("div", X, [
V(u("input", {
class: "attr-name-value",
"onUpdate:modelValue": (t) => a.name = t,
type: "text",
placeholder: "输入规格名"
}, null, 8, Y), [
[
P,
a.name,
void 0,
{ trim: !0 }
]
]),
u("span", {
class: "delN",
style: C({ color: r.color }),
onClick: (t) => T(l)
}, "x", 12, Z)
]),
u("div", x, [
(n(!0), o(k, null, S(a.value, (t, m) => (n(), o("div", {
class: "add-attr-value",
style: C({ color: r.color }),
key: m
}, [
u("div", null, U(t), 1),
u("div", {
class: "delv",
style: C({ color: r.color }),
onClick: (s) => $(l, m)
}, "x", 12, ee)
], 4))), 128)),
u("div", te, [
V(u("input", {
class: "attr-value-value",
"onUpdate:modelValue": (t) => v.value[l] = t,
type: "text",
placeholder: "输入规格值,多个值可用空格隔开一次添加"
}, null, 8, ae), [
[P, v.value[l]]
]),
u("span", {
class: "addIcon",
onClick: (t) => E(l)
}, "+", 8, le)
])
])
], 4))), 128)) : p("", !0),
u("button", {
class: "sku-btn",
style: C({ "background-color": r.color }),
onClick: M
}, "添加规格", 4),
d.value.length > 0 ? (n(), o("table", oe, [
u("thead", null, [
u("tr", null, [
(n(!0), o(k, null, S(D.value, (a) => (n(), o("th", { key: a }, U(a), 1))), 128)),
r.productPrice ? (n(), o("th", ne, "价格")) : p("", !0),
r.memberPrice ? (n(), o("th", ce, "会员价格")) : p("", !0),
r.productStock ? (n(), o("th", ue, "库存")) : p("", !0),
r.productImg ? (n(), o("th", se, "产品图片")) : p("", !0)
])
]),
u("tbody", null, [
(n(!0), o(k, null, S(g.value, (a, l) => (n(), o("tr", { key: l }, [
(n(!0), o(k, null, S(a.specs, (t, m) => (n(), o(k, { key: m }, [
t.show ? (n(), o("td", {
key: 0,
rowspan: t.rowspan
}, U(t.value), 9, re)) : p("", !0)
], 64))), 128)),
r.productPrice ? (n(), o("td", de, [
V(u("input", {
class: "attr-name-value",
"onUpdate:modelValue": (t) => a.productPrice = t,
type: "number",
placeholder: "价格"
}, null, 8, ie), [
[P, a.productPrice]
])
])) : p("", !0),
r.memberPrice ? (n(), o("td", pe, [
V(u("input", {
class: "attr-name-value",
"onUpdate:modelValue": (t) => a.memberPrice = t,
type: "number",
placeholder: "会员价格"
}, null, 8, me), [
[P, a.memberPrice]
])
])) : p("", !0),
r.productStock ? (n(), o("td", ve, [
V(u("input", {
class: "attr-name-value",
"onUpdate:modelValue": (t) => a.productStock = t,
type: "number",
placeholder: "库存"
}, null, 8, he), [
[P, a.productStock]
])
])) : p("", !0),
r.productImg ? (n(), o("td", ye, [
u("div", ke, [
a.productImg ? (n(), o(k, { key: 0 }, [
u("img", {
src: a.productImg,
alt: "点击放大图片",
height: "50",
onClick: (t) => j(l)
}, null, 8, ge),
u("button", {
onClick: (t) => N(l),
class: "delete-button"
}, "❌", 8, _e)
], 64)) : (n(), o("input", {
key: 1,
type: "file",
accept: "image/*",
id: "upload",
onChange: (t) => F(t, l)
}, null, 40, fe))
])
])) : p("", !0)
]))), 128))
])
])) : p("", !0),
b.value ? (n(), o("div", {
key: 2,
onClick: B,
class: "modal-overlay"
}, [
u("div", be, [
u("button", {
onClick: B,
class: "close-button"
}, "×"),
u("img", {
src: w.value,
alt: "放大图片",
class: "modal-image"
}, null, 8, Se)
])
])) : p("", !0)
], 64));
}
}, Pe = /* @__PURE__ */ Q(Ce, [["__scopeId", "data-v-654bfdce"]]);
export {
Pe as default
};