import { defineComponent as G, ref as d, watch as J, getCurrentInstance as K, computed as M, reactive as X, resolveComponent as S, openBlock as n, createElementBlock as c, normalizeClass as z, createElementVNode as m, createBlock as h, resolveDynamicComponent as I, withCtx as E, Fragment as Y, renderList as Z, mergeProps as x, createVNode as f, createCommentVNode as w } from "vue"; import { useUi as ee } from "@fast-crud/fast-crud"; import { u as oe, _ as te } from "./index-50ffe046.mjs"; import "lodash-es"; const re = G({ name: "FsCropperUploader", props: { /** * 初始图片url,或者是数组 */ modelValue: { type: [String, Object, Array] }, img: {}, /** * 上传后端类型,[form, cos, qiniu , alioss] */ type: { type: String }, /** * 上传提示 */ uploadTip: { type: String }, /** * 对话框标题 */ title: String, /** * cropper的高度,默认为浏览器可视窗口高度的40%,最小270 */ cropperHeight: { type: [String, Number] }, /** * 对话框宽度,默认50% */ dialogWidth: { type: [String, Number], default: "50%" }, /** * 图片大小限制,单位MB */ maxSize: { type: Number, default: 5 }, /** * 图片数量限制,0为不限制 */ limit: { type: Number, default: 1 }, /** * 可接收的文件后缀 */ accept: { type: String, default: ".jpg, .jpeg, .png, .gif, .webp" }, /** * [cropperjs的参数](https://github.com/fengyuanchen/cropperjs) */ cropper: { type: Object }, /** * FsUploaderXXX的配置,会临时覆盖全局上传配置参数 */ uploader: { type: Object }, /** * 压缩质量 */ compressQuality: { type: Number, default: 0.8 }, /** * 构建下载url方法,不影响提交的value */ buildUrl: { type: Function, default: async function(e) { return typeof e == "object" ? e.url : e; } }, /** * 返回值类型 * 支持:`[url,key,object]` */ valueType: { type: String, // url ,key, object default: "url" }, /** * 是否禁用 */ disabled: {} }, emits: ["update:modelValue", "change", "ready"], setup(e, a) { const { ui: b } = ee(), g = d(), N = d(), U = d(), s = d([]), u = b.formItem.injectFormItemContext(); let y = e.modelValue; i(e.modelValue); async function i(o) { const t = []; if (o == null || o === "") { s.value = t; return; } if (typeof o == "string") t.push({ url: await e.buildUrl(o), value: o, status: "done" }); else if (Array.isArray(o)) for (const r of o) t.push({ url: await e.buildUrl(r), value: r, status: "done" }); else if (typeof o == "object") t.push({ url: await e.buildUrl(o), value: o, status: "done" }); else for (const r of o) t.push({ url: await e.buildUrl(r), value: r, status: "done" }); s.value = t; } function v() { e.disabled || (U.value = void 0, g.value.clear(), g.value.open()); } function C(o) { s.value.splice(o, 1), j(); } function B() { const o = s.value; if (o && o.length > 0) { for (const t of o) if (t.status === "uploading") return !0; } return !1; } async function _(o) { const t = o.blob, r = o.dataUrl, T = o.file.name, L = new File([t], T, { type: t.type }), p = X({ url: void 0, dataUrl: r, status: "uploading", progress: 0 }), Q = (l) => { p.progress = l.percent; }, $ = (l) => { p.status = "error", p.message = "文件上传出错:" + l.message, console.error(l); }, W = { file: L, onProgress: Q, onError: $, fileName: T }; s.value.push(p); try { const l = await R(W); let V = l; e.valueType !== "object" && (V = l[e.valueType]), p.url = await e.buildUrl(V), p.value = V, p.status = "done", j(); } catch (l) { $(l); } } async function R(o) { o.options = e.uploader || {}; const { getUploaderImpl: t } = oe(); let r = await t(o.options.type); if (r == null) throw new Error("Sorry,The component is not ready yet"); return await (r == null ? void 0 : r.upload(o)); } async function j() { const o = []; for (const r of s.value) typeof r == "string" ? o.push(r) : o.push(r.value); let t = o; e.limit === 1 && (t = o && o.length > 0 ? o[0] : void 0), y = t, a.emit("update:modelValue", t), await u.onChange(), await u.onBlur(); } function F(o) { return o.dataUrl ? o.dataUrl : o.url; } const P = d(!1), k = d(); function A(o) { P.value = !0, k.value = F(o); } function D() { P.value = !1, k.value = null; } J( () => e.modelValue, async (o) => { a.emit("change", o), o !== y && await i(o); } ); const O = K(); function q(o) { a.emit("ready", { uploaderRef: O, ...o }); } const H = M(() => ({ ...e })); return { ui: b, cropperRef: g, uploaderImplRef: N, indexRef: U, listRef: s, addNewImage: v, hasUploading: B, cropComplete: _, doUpload: R, removeImage: C, getImageSrc: F, previewUrl: k, previewVisible: P, preview: A, closePreview: D, doReady: q, computedProps: H }; } }); const ie = { class: "image-list" }, ne = { class: "image-slot" }, se = { class: "delete" }, le = { key: 0, class: "status-uploading" }, ae = { key: 1, class: "status-done" }, ue = { class: "fs-cropper-preview-content" }, pe = ["src"]; function ce(e, a, b, g, N, U) { const s = S("fs-loading"), u = S("fs-icon"), y = S("fs-cropper"); return n(), c("div", { class: z(["fs-cropper-uploader", { "is-disabled": e.computedProps.disabled }]) }, [ m("div", ie, [ (n(), h(I(e.ui.imageGroup.name), null, { default: E(() => [ (n(!0), c(Y, null, Z(e.listRef, (i, v) => (n(), c("div", { key: v, class: "image-item" }, [ (n(), h(I(e.ui.image.name), x({ class: "image", src: e.getImageSrc(i) }, { ref_for: !0 }, e.computedProps.img), { placeholder: E(() => [ m("div", ne, [ f(s, { loading: !0 }) ]) ]), _: 2 }, 1040, ["src"])), m("div", se, [ e.computedProps.disabled ? w("", !0) : (n(), h(u, { key: 0, icon: e.ui.icons.remove, onClick: (C) => e.removeImage(v) }, null, 8, ["icon", "onClick"])), f(u, { icon: e.ui.icons.search, onClick: (C) => e.preview(i) }, null, 8, ["icon", "onClick"]) ]), i.status === "uploading" ? (n(), c("div", le, [ (n(), h(I(e.ui.progress.name), { type: "circle", percentage: i.progress, width: 70 }, null, 8, ["percentage"])) ])) : i.status === "done" ? (n(), c("div", ae, [ f(u, { icon: e.ui.icons.check, class: "status-down-icon" }, null, 8, ["icon"]) ])) : w("", !0) ]))), 128)), e.computedProps.limit <= 0 || e.computedProps.limit > e.listRef.length ? (n(), c("div", { key: 0, class: "image-item image-plus", onClick: a[0] || (a[0] = (...i) => e.addNewImage && e.addNewImage(...i)) }, [ f(u, { icon: e.ui.icons.plus, class: "cropper-uploader-icon" }, null, 8, ["icon"]) ])) : w("", !0) ]), _: 1 })) ]), f(y, { ref: "cropperRef", title: e.computedProps.title, "cropper-height": e.computedProps.cropperHeight, "dialog-width": e.computedProps.dialogWidth, accept: e.computedProps.accept, "upload-tip": e.computedProps.uploadTip, "max-size": e.computedProps.maxSize, cropper: e.computedProps.cropper, "compress-quality": e.computedProps.compressQuality, output: "all", onDone: e.cropComplete, onReady: e.doReady }, null, 8, ["title", "cropper-height", "dialog-width", "accept", "upload-tip", "max-size", "cropper", "compress-quality", "onDone", "onReady"]), m("div", { class: z(["fs-cropper-preview", { open: e.previewVisible }]), onClick: a[1] || (a[1] = (...i) => e.closePreview && e.closePreview(...i)) }, [ m("div", ue, [ e.previewUrl ? (n(), c("img", { key: 0, src: e.previewUrl, class: "preview-image" }, null, 8, pe)) : w("", !0) ]) ], 2) ], 2); } const ve = /* @__PURE__ */ te(re, [["render", ce]]); export { ve as default }; //# sourceMappingURL=fs-cropper-uploader-c3fbe88c.mjs.map