165 lines
5.4 KiB
JavaScript
165 lines
5.4 KiB
JavaScript
"use strict";
|
|
const common_vendor = require("../common/vendor.js");
|
|
const common_http = require("../common/http.js");
|
|
const common_config = require("../common/config.js");
|
|
const common_assets = require("../common/assets.js");
|
|
const ITEM_SIZE = 210;
|
|
const GAP = 18;
|
|
const COLS = 3;
|
|
function px(rpx) {
|
|
return rpx;
|
|
}
|
|
const _sfc_main = {
|
|
name: "ImageUploader",
|
|
props: {
|
|
modelValue: { type: Array, default: () => [] },
|
|
max: { type: Number, default: 9 },
|
|
uploadPath: { type: String, default: "/api/attachments" },
|
|
uploadFieldName: { type: String, default: "file" },
|
|
formData: { type: Object, default: () => ({ ownerType: "product" }) }
|
|
},
|
|
data() {
|
|
return {
|
|
innerList: []
|
|
};
|
|
},
|
|
computed: {
|
|
areaHeight() {
|
|
const rows = Math.ceil((this.innerList.length + 1) / COLS) || 1;
|
|
return rows * ITEM_SIZE + (rows - 1) * GAP;
|
|
},
|
|
adderStyle() {
|
|
const index = this.innerList.length;
|
|
const row = Math.floor(index / COLS);
|
|
const col = index % COLS;
|
|
const x = px(col * (ITEM_SIZE + GAP));
|
|
const y = px(row * (ITEM_SIZE + GAP));
|
|
return { left: x + "rpx", top: y + "rpx" };
|
|
}
|
|
},
|
|
watch: {
|
|
modelValue: {
|
|
immediate: true,
|
|
handler(list) {
|
|
const mapped = (list || []).map((u, i) => ({
|
|
uid: String(i) + "_" + (u.id || u.url || Math.random().toString(36).slice(2)),
|
|
url: this.ensureAbsoluteUrl(typeof u === "string" ? u : u.url || ""),
|
|
x: this.posOf(i).x,
|
|
y: this.posOf(i).y
|
|
}));
|
|
this.innerList = mapped;
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
ensureAbsoluteUrl(u) {
|
|
if (!u)
|
|
return "";
|
|
const s = String(u);
|
|
if (s.startsWith("http://") || s.startsWith("https://"))
|
|
return s;
|
|
return common_config.API_BASE_URL + (s.startsWith("/") ? s : "/" + s);
|
|
},
|
|
posOf(index) {
|
|
const row = Math.floor(index / COLS);
|
|
const col = index % COLS;
|
|
return { x: px(col * (ITEM_SIZE + GAP)), y: px(row * (ITEM_SIZE + GAP)) };
|
|
},
|
|
cellStyle(index) {
|
|
return {
|
|
width: ITEM_SIZE + "rpx",
|
|
height: ITEM_SIZE + "rpx"
|
|
};
|
|
},
|
|
preview(index) {
|
|
common_vendor.index.previewImage({ urls: this.innerList.map((i) => i.url), current: index });
|
|
},
|
|
remove(index) {
|
|
this.innerList.splice(index, 1);
|
|
this.reflow();
|
|
this.emit();
|
|
},
|
|
choose() {
|
|
const remain = this.max - this.innerList.length;
|
|
if (remain <= 0)
|
|
return;
|
|
common_vendor.index.chooseImage({ count: remain, success: async (res) => {
|
|
for (const path of res.tempFilePaths) {
|
|
await this.doUpload(path);
|
|
}
|
|
} });
|
|
},
|
|
async doUpload(filePath) {
|
|
var _a;
|
|
try {
|
|
const resp = await common_http.upload(this.uploadPath, filePath, this.formData, this.uploadFieldName);
|
|
const url = this.ensureAbsoluteUrl((resp == null ? void 0 : resp.url) || ((_a = resp == null ? void 0 : resp.data) == null ? void 0 : _a.url) || (resp == null ? void 0 : resp.path) || "");
|
|
if (!url)
|
|
throw new Error("上传响应无 url");
|
|
this.innerList.push({ uid: Math.random().toString(36).slice(2), url, ...this.posOf(this.innerList.length) });
|
|
this.reflow();
|
|
this.emit();
|
|
} catch (e) {
|
|
common_vendor.index.showToast({ title: "上传失败", icon: "none" });
|
|
}
|
|
},
|
|
onMoving(index, e) {
|
|
const { x, y } = e.detail;
|
|
this.innerList[index].x = x;
|
|
this.innerList[index].y = y;
|
|
},
|
|
onMoveEnd(index) {
|
|
const mv = this.innerList[index];
|
|
const col = Math.round(mv.x / (ITEM_SIZE + GAP));
|
|
const row = Math.round(mv.y / (ITEM_SIZE + GAP));
|
|
let newIndex = row * COLS + col;
|
|
newIndex = Math.max(0, Math.min(newIndex, this.innerList.length - 1));
|
|
if (newIndex !== index) {
|
|
const moved = this.innerList.splice(index, 1)[0];
|
|
this.innerList.splice(newIndex, 0, moved);
|
|
}
|
|
this.reflow();
|
|
this.emit();
|
|
},
|
|
reflow() {
|
|
this.innerList.forEach((it, i) => {
|
|
const p = this.posOf(i);
|
|
it.x = p.x;
|
|
it.y = p.y;
|
|
});
|
|
},
|
|
emit() {
|
|
this.$emit("update:modelValue", this.innerList.map((i) => i.url));
|
|
this.$emit("change", this.innerList.map((i) => i.url));
|
|
}
|
|
}
|
|
};
|
|
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
return common_vendor.e({
|
|
a: common_vendor.f($data.innerList, (img, index, i0) => {
|
|
return {
|
|
a: img.url,
|
|
b: common_vendor.o(($event) => $options.preview(index), img.uid),
|
|
c: common_vendor.o(($event) => $options.remove(index), img.uid),
|
|
d: img.uid,
|
|
e: common_vendor.s($options.cellStyle(index)),
|
|
f: img.x,
|
|
g: img.y,
|
|
h: common_vendor.o(($event) => $options.onMoving(index, $event), img.uid),
|
|
i: common_vendor.o(($event) => $options.onMoveEnd(index), img.uid)
|
|
};
|
|
}),
|
|
b: common_assets._imports_0$4,
|
|
c: $data.innerList.length < $props.max
|
|
}, $data.innerList.length < $props.max ? {
|
|
d: common_vendor.s($options.adderStyle),
|
|
e: common_vendor.o((...args) => $options.choose && $options.choose(...args))
|
|
} : {}, {
|
|
f: $options.areaHeight + "rpx",
|
|
g: $options.areaHeight + "rpx"
|
|
});
|
|
}
|
|
const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
|
|
wx.createComponent(Component);
|
|
//# sourceMappingURL=../../.sourcemap/mp-weixin/components/ImageUploader.js.map
|