@qxs-bns/components 0.0.77 → 0.0.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/package.json.mjs +1 -1
- package/es/src/file-upload/src/file-upload.vue.mjs +1 -1
- package/es/src/file-upload/src/file-upload.vue.mjs.map +1 -1
- package/es/src/icon/src/icon.vue.mjs +1 -1
- package/es/src/icon/src/icon.vue.mjs.map +1 -1
- package/es/src/image-upload/src/image-upload.vue.mjs +1 -1
- package/es/src/image-upload/src/image-upload.vue.mjs.map +1 -1
- package/lib/package.json.cjs +1 -1
- package/lib/src/file-upload/src/file-upload.vue.cjs +1 -1
- package/lib/src/file-upload/src/file-upload.vue.cjs.map +1 -1
- package/lib/src/icon/src/icon.vue.cjs +1 -1
- package/lib/src/icon/src/icon.vue.cjs.map +1 -1
- package/lib/src/image-upload/src/image-upload.vue.cjs +1 -1
- package/lib/src/image-upload/src/image-upload.vue.cjs.map +1 -1
- package/package.json +1 -1
- package/theme-chalk/index.css +1 -1
- package/theme-chalk/src/image-upload.css +1 -1
- package/theme-chalk/src/image-upload.scss +33 -0
- package/types/src/file-upload/src/file-upload.vue.d.ts.map +1 -1
- package/types/src/icon/src/icon.vue.d.ts.map +1 -1
- package/types/src/image-upload/src/image-upload.vue.d.ts.map +1 -1
- package/types/tsconfig.tsbuildinfo +1 -1
- package/theme-chalk/index-with-element-plus.css +0 -1
- package/theme-chalk/index-with-element-plus.scss +0 -68
package/es/package.json.mjs
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
var r="0.0.
|
1
|
+
var r="0.0.79";export{r as version};
|
2
2
|
//# sourceMappingURL=package.json.mjs.map
|
@@ -1,2 +1,2 @@
|
|
1
|
-
import{defineComponent as e,computed as a,
|
1
|
+
import{defineComponent as e,computed as a,createBlock as l,openBlock as t,unref as i,normalizeClass as s,withCtx as r,createElementVNode as o,createVNode as u,createTextVNode as n,createElementBlock as d,createCommentVNode as p}from"vue";import{UploadFilled as c}from"@element-plus/icons-vue";import{useNamespace as m}from"@qxs-bns/hooks";import{useNamespace as f,ElUpload as y,ElIcon as v,ElAlert as q,ElMessage as x}from"element-plus";const $={class:"slot"},_={style:{display:"inline-block"}};var b=e({name:"QxsFileUpload",__name:"file-upload",props:{action:{type:String,required:!0},headers:{type:null,required:!1},data:{type:null,required:!1},name:{type:String,required:!1,default:"file"},size:{type:Number,required:!1,default:20},max:{type:Number,required:!1,default:3},accept:{type:String,required:!1,default:"zip,rar"},files:{type:Array,required:!1,default:()=>[]},notip:{type:Boolean,required:!1,default:!1},ext:{type:Array,required:!1}},emits:["onSuccess"],setup(e,{emit:b}){const h=b,z=m("file-upload"),g=f("file-upload"),S=a(()=>e.accept.split(",")),k=a=>{const l=a.name.split(".").at(-1)??"",t=S.value.includes(l),i=a.size/1024/1024<e.size;return t||x.error(`上传文件只支持 ${S.value.join(" / ")} 格式!`),i||x.error(`上传文件大小不能超过 ${e.size}MB!`),t&&i},B=()=>{x.warning("文件上传超过限制")},N=(e,a,l)=>{h("onSuccess",e,a,l)};return(e,a)=>(t(),l(i(y),{headers:e.headers,action:e.action,data:e.data,name:e.name,"before-upload":k,"on-exceed":B,"on-success":N,"file-list":e.files,limit:e.max,drag:"",class:s(i(z).e("control"))},{tip:r(()=>[e.notip?p("v-if",!0):(t(),d("div",{key:0,class:s(`${i(g).namespace.value}-upload__tip`)},[o("div",_,[u(i(q),{title:`上传文件支持 ${S.value.join(" / ")} 格式,单个文件大小不超过 ${e.size}MB,且文件数量不超过 ${e.max} 个`,type:"info","show-icon":"",closable:!1},null,8,["title"])])],2))]),default:r(()=>[o("div",$,[u(i(v),{class:s(`${i(g).namespace.value}-icon--upload`)},{default:r(()=>[u(i(c))]),_:1},8,["class"]),o("div",{class:s(`${i(g).namespace.value}-upload__text`)},a[0]||(a[0]=[n(" 将文件拖到此处,或",-1),o("em",null,"点击上传",-1)]),2)])]),_:1},8,["headers","action","data","name","file-list","limit","class"]))}});export{b as default};
|
2
2
|
//# sourceMappingURL=file-upload.vue.mjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"file-upload.vue.mjs","sources":["../../../../../../packages/components/src/file-upload/src/file-upload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { UploadProps, UploadUserFile } from 'element-plus'\nimport { UploadFilled } from '@element-plus/icons-vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { ElMessage, useNamespace as useElNamespace } from 'element-plus'\nimport { computed } from 'vue'\n\ndefineOptions({\n name: 'QxsFileUpload',\n})\n\nconst {\n name = 'file',\n size = 20,\n max = 3,\n files = [],\n notip = false,\n accept = 'zip,rar',\n} = defineProps<{\n action: UploadProps['action']\n headers?: UploadProps['headers']\n data?: UploadProps['data']\n name?: UploadProps['name']\n size?: number\n max?: number\n accept?: string\n files?: UploadUserFile[]\n notip?: boolean\n ext?: string[]\n}>()\n\nconst emit = defineEmits(['onSuccess'])\n\nconst ns = useNamespace('file-upload')\nconst nsEl = useElNamespace('file-upload')\n\nconst exts = computed(() => {\n return accept.split(',')\n})\nconst beforeUpload: UploadProps['beforeUpload'] = (file) => {\n const fileName = file.name.split('.')\n const fileExt = fileName.at(-1) ?? ''\n const isTypeOk = exts.value.includes(fileExt)\n const isSizeOk = file.size / 1024 / 1024 < size\n if (!isTypeOk) {\n ElMessage.error(`上传文件只支持 ${exts.value.join(' / ')} 格式!`)\n }\n if (!isSizeOk) {\n ElMessage.error(`上传文件大小不能超过 ${size}MB!`)\n }\n return isTypeOk && isSizeOk\n}\n\nconst onExceed: UploadProps['onExceed'] = () => {\n ElMessage.warning('文件上传超过限制')\n}\n\nconst onSuccess: UploadProps['onSuccess'] = (res, file, fileList) => {\n emit('onSuccess', res, file, fileList)\n}\n</script>\n\n<template>\n <
|
1
|
+
{"version":3,"file":"file-upload.vue.mjs","sources":["../../../../../../packages/components/src/file-upload/src/file-upload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { UploadProps, UploadUserFile } from 'element-plus'\nimport { UploadFilled } from '@element-plus/icons-vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { ElAlert, ElIcon, ElMessage, ElUpload, useNamespace as useElNamespace } from 'element-plus'\nimport { computed } from 'vue'\n\ndefineOptions({\n name: 'QxsFileUpload',\n})\n\nconst {\n name = 'file',\n size = 20,\n max = 3,\n files = [],\n notip = false,\n accept = 'zip,rar',\n} = defineProps<{\n action: UploadProps['action']\n headers?: UploadProps['headers']\n data?: UploadProps['data']\n name?: UploadProps['name']\n size?: number\n max?: number\n accept?: string\n files?: UploadUserFile[]\n notip?: boolean\n ext?: string[]\n}>()\n\nconst emit = defineEmits(['onSuccess'])\n\nconst ns = useNamespace('file-upload')\nconst nsEl = useElNamespace('file-upload')\n\nconst exts = computed(() => {\n return accept.split(',')\n})\nconst beforeUpload: UploadProps['beforeUpload'] = (file) => {\n const fileName = file.name.split('.')\n const fileExt = fileName.at(-1) ?? ''\n const isTypeOk = exts.value.includes(fileExt)\n const isSizeOk = file.size / 1024 / 1024 < size\n if (!isTypeOk) {\n ElMessage.error(`上传文件只支持 ${exts.value.join(' / ')} 格式!`)\n }\n if (!isSizeOk) {\n ElMessage.error(`上传文件大小不能超过 ${size}MB!`)\n }\n return isTypeOk && isSizeOk\n}\n\nconst onExceed: UploadProps['onExceed'] = () => {\n ElMessage.warning('文件上传超过限制')\n}\n\nconst onSuccess: UploadProps['onSuccess'] = (res, file, fileList) => {\n emit('onSuccess', res, file, fileList)\n}\n</script>\n\n<template>\n <ElUpload\n :headers=\"headers\"\n :action=\"action\"\n :data=\"data\"\n :name=\"name\"\n :before-upload=\"beforeUpload\"\n :on-exceed=\"onExceed\"\n :on-success=\"onSuccess\"\n :file-list=\"files\"\n :limit=\"max\"\n drag\n :class=\"ns.e('control')\"\n >\n <div class=\"slot\">\n <ElIcon :class=\"`${nsEl.namespace.value}-icon--upload`\">\n <UploadFilled />\n </ElIcon>\n <div :class=\"`${nsEl.namespace.value}-upload__text`\">\n 将文件拖到此处,或<em>点击上传</em>\n </div>\n </div>\n <template #tip>\n <div\n v-if=\"!notip\"\n :class=\"`${nsEl.namespace.value}-upload__tip`\"\n >\n <div style=\"display: inline-block;\">\n <ElAlert\n :title=\"`上传文件支持 ${exts.join(\n ' / ',\n )} 格式,单个文件大小不超过 ${size}MB,且文件数量不超过 ${max} 个`\"\n type=\"info\"\n show-icon\n :closable=\"false\"\n />\n </div>\n </div>\n </template>\n </ElUpload>\n</template>\n"],"names":["emit","__emit","ns","useNamespace","nsEl","useElNamespace","exts","computed","__props","accept","split","beforeUpload","file","fileExt","name","at","isTypeOk","value","includes","isSizeOk","size","ElMessage","error","join","onExceed","warning","onSuccess","res","fileList","_createBlock","_unref","ElUpload","headers","action","data","files","limit","max","drag","class","_normalizeClass","e","tip","notip","_createElementBlock","namespace","_createElementVNode","_hoisted_2","_createVNode","ElAlert","title","type","closable","_hoisted_1","ElIcon","UploadFilled"],"mappings":"w9BA+BA,MAAMA,EAAOC,EAEPC,EAAKC,EAAa,eAClBC,EAAOC,EAAe,eAEtBC,EAAOC,EAAS,IACbC,EAAAC,OAAOC,MAAM,MAEhBC,EAA6CC,IACjD,MACMC,EADWD,EAAKE,KAAKJ,MAAM,KACRK,IAAG,IAAO,GAC7BC,EAAWV,EAAKW,MAAMC,SAASL,GAC/BM,EAAWP,EAAKQ,KAAO,KAAO,KAAOZ,EAAAY,KAO3C,OANKJ,GACHK,EAAUC,MAAM,WAAWhB,EAAKW,MAAMM,KAAK,cAExCJ,GACHE,EAAUC,MAAM,cAAcd,EAAAY,WAEzBJ,GAAYG,GAGfK,EAAoC,KACxCH,EAAUI,QAAQ,aAGdC,EAAsC,CAACC,EAAKf,EAAMgB,KACtD5B,EAAK,YAAa2B,EAAKf,EAAMgB,sBAK7BC,EAsCWC,EAAAC,GAAA,CArCRC,QAASA,EAAAA,QACTC,OAAQA,EAAAA,OACRC,KAAMA,EAAAA,KACNpB,KAAMA,EAAAA,KACN,gBAAeH,EACf,YAAWa,EACX,aAAYE,EACZ,YAAWS,EAAAA,MACXC,MAAOC,EAAAA,IACRC,KAAA,GACCC,MAAKC,EAAEV,EAAA5B,GAAGuC,EAAC,cAUDC,MACT,IAcM,CAbGC,EAAAA,wBADTC,EAcM,MAAA,OAZHL,MAAKC,EAAA,GAAKV,EAAA1B,GAAKyC,UAAU5B,uBAE1B6B,EASM,MATNC,EASM,CARJC,EAOElB,EAAAmB,GAAA,CANCC,MAAK,UAAY5C,EAAAW,MAAKM,4BAAyDH,EAAAA,mBAAmBiB,EAAAA,QAGnGc,KAAK,OACL,YAAA,GACCC,UAAU,wCApBnB,IAOM,CAPNN,EAOM,MAPNO,EAOM,CANJL,EAESlB,EAAAwB,GAAA,CAFAf,MAAKC,EAAA,GAAKV,EAAA1B,GAAKyC,UAAU5B,kCAChC,IAAgB,CAAhB+B,EAAgBlB,EAAAyB,wBAElBT,EAEM,MAAA,CAFAP,MAAKC,EAAA,GAAKV,EAAA1B,GAAKyC,UAAU5B,sCAAsB,cAC1C,GAAA6B,EAAa,UAAT,QAAI"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
import{defineComponent as e,useAttrs as
|
1
|
+
import{defineComponent as e,useAttrs as t,computed as i,ref as s,createElementBlock as l,openBlock as n,Fragment as r,createCommentVNode as o,createBlock as u,resolveDynamicComponent as a,normalizeStyle as c,normalizeClass as f,unref as v,createElementVNode as p,createVNode as y}from"vue";import{Icon as d}from"../../../node_modules/.pnpm/@iconify_vue@5.0.0_vue@3.5.18_typescript@5.9.2_/node_modules/@iconify/vue/dist/iconify.mjs";import{useNamespace as h}from"@qxs-bns/hooks";const m=["src"],g=["xlink:href"];var k=e({name:"QxsIcon",__name:"icon",props:{icon:{type:null,required:!0},flip:{type:null,required:!1,default:""},rotate:{type:Number,required:!1,default:0},color:{type:String,required:!1},size:{type:[String,Number],required:!1},localIconPrefix:{type:String,required:!1,default:"icon-"},fallback:{type:String,required:!1},loading:{type:String,required:!1}},setup(e){const k=t(),b=h("icon"),$=i(()=>"object"==typeof e.icon||"function"==typeof e.icon),z=i(()=>{if($.value)return"component";const t=e.icon;return/^https?:\/\//.test(t)||(/^\.{1,2}\//.test(i=t)||i.startsWith("/")||i.includes("/"))?"img":/^i-[^:]+:[^:]+/.test(t)?"unocss":t.startsWith("i-")&&!t.includes(":")?"css":t.includes(":")&&!t.startsWith("i-")?"iconify":/^[\w-]+$/.test(t)&&!t.startsWith("i-")?"svg":"css";var i}),S=i(()=>{if($.value)return"";const t=e.icon;return"img"===z.value||"unocss"===z.value||z.value,t}),q=i(()=>"css"===z.value?S.value.split(" ").filter(e=>e.trim()):[]);function x(e){return e?"number"==typeof e||/^\d+(?:\.\d+)?$/.test(e)?`${e}px`:e:""}const _=i(()=>{const t=[];switch(e.flip){case"horizontal":t.push("rotateY(180deg)");break;case"vertical":t.push("rotateX(180deg)");break;case"both":t.push("rotateX(180deg)"),t.push("rotateY(180deg)")}e.rotate&&t.push(`rotate(${e.rotate%360}deg)`);let i=`${e.color?`color: ${e.color};`:""}${e.size?`font-size: ${x(e.size)};`:""}${t.length?`transform: ${t.join(" ")};`:""}`;const s=k.style;if(s)if("string"==typeof s)i+=s;else if("object"==typeof s){i+=Object.entries(s).map(([e,t])=>`${e.replace(/([A-Z])/g,"-$1").toLowerCase()}: ${t};`).join("")}return i}),j=s(!0),w=s(!1);function I(){j.value=!1,w.value=!1}function W(){j.value=!1,w.value=!0}return(e,t)=>(n(),l(r,null,[o(" Vue组件 "),"component"===z.value?(n(),u(a(e.icon),{key:0,class:f([[v(b).b()],"size-inherit shrink-0"]),style:c([_.value])},null,8,["class","style"])):"unocss"===z.value?(n(),l(r,{key:1},[o(" UnoCSS图标 "),p("i",{class:f([v(b).b(),S.value]),style:c([_.value])},null,6)],2112)):"css"===z.value?(n(),l(r,{key:2},[o(" CSS类图标 "),p("i",{class:f(["size-inherit shrink-0",[v(b).b(),...q.value]]),style:c([_.value])},null,6)],2112)):"iconify"===z.value?(n(),l(r,{key:3},[o(" Iconify图标 "),y(v(d),{class:f(["size-inherit shrink-0",[v(b).b()]]),icon:S.value,style:c([_.value])},null,8,["icon","class","style"])],2112)):"img"===z.value?(n(),l(r,{key:4},[o(" 图片 "),o(" 加载中状态 "),j.value&&e.loading?(n(),l("i",{key:0,class:f(e.loading)},null,2)):w.value&&e.fallback?(n(),l(r,{key:1},[o(" 错误状态 "),p("i",{class:f(e.fallback)},null,2)],2112)):o("v-if",!0),o(" 图片本体 "),p("img",{src:S.value,class:f(["size-inherit shrink-0",[v(b).b()]]),style:c([_.value,{width:e.size?x(e.size):"auto",height:"auto"}]),onLoad:I,onError:W},null,46,m)],64)):S.value?(n(),l(r,{key:5},[o(" SVG Sprite "),(n(),l("svg",{"aria-hidden":"true",class:f([[v(b).b()],"size-inherit shrink-0"]),style:c([_.value])},[p("use",{"xlink:href":`#${e.localIconPrefix}${S.value}`},null,8,g)],6))],2112)):o("v-if",!0)],2112))}});export{k as default};
|
2
2
|
//# sourceMappingURL=icon.vue.mjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"icon.vue.mjs","sources":["../../../../../../packages/components/src/icon/src/icon.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { Component, CSSProperties } from 'vue'\nimport { Icon } from '@iconify/vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { computed, ref, useAttrs } from 'vue'\n\ndefineOptions({\n name: 'QxsIcon',\n})\n\nconst {\n icon,\n flip = '',\n rotate = 0,\n color,\n size,\n localIconPrefix = 'icon-',\n fallback,\n loading,\n} = defineProps<PropsType>()\n\nconst attrs = useAttrs()\n\nconst ns = useNamespace('icon')\n\nexport interface PropsType {\n icon: string | Component\n flip?: 'horizontal' | 'vertical' | 'both' | '' | undefined\n rotate?: number\n color?: string\n size?: string | number\n localIconPrefix?: string\n // 新增功能:支持图片URL\n fallback?: string // 加载失败时的备用图标\n loading?: string // 加载中显示的图标\n}\n\nconst isComponentName = computed(() => typeof icon === 'object' || typeof icon === 'function')\n\nconst outputType = computed(() => {\n if (isComponentName.value) {\n return 'component'\n }\n\n const iconStr = icon as string\n\n // 检测是否为图片URL或路径\n const hasPathFeatures = (str: string) => {\n return /^\\.{1,2}\\//.test(str) || str.startsWith('/') || str.includes('/')\n }\n if (/^https?:\\/\\//.test(iconStr) || hasPathFeatures(iconStr)) {\n return 'img'\n }\n\n // 检测UnoCSS图标格式 (i-[provider]:[name])\n if (/^i-[^:]+:[^:]+/.test(iconStr)) {\n return 'unocss'\n }\n\n //
|
1
|
+
{"version":3,"file":"icon.vue.mjs","sources":["../../../../../../packages/components/src/icon/src/icon.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { Component, CSSProperties } from 'vue'\nimport { Icon } from '@iconify/vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { computed, ref, useAttrs } from 'vue'\n\ndefineOptions({\n name: 'QxsIcon',\n})\n\nconst {\n icon,\n flip = '',\n rotate = 0,\n color,\n size,\n localIconPrefix = 'icon-',\n fallback,\n loading,\n} = defineProps<PropsType>()\n\nconst attrs = useAttrs()\n\nconst ns = useNamespace('icon')\n\nexport interface PropsType {\n icon: string | Component\n flip?: 'horizontal' | 'vertical' | 'both' | '' | undefined\n rotate?: number\n color?: string\n size?: string | number\n localIconPrefix?: string\n // 新增功能:支持图片URL\n fallback?: string // 加载失败时的备用图标\n loading?: string // 加载中显示的图标\n}\n\nconst isComponentName = computed(() => typeof icon === 'object' || typeof icon === 'function')\n\nconst outputType = computed(() => {\n if (isComponentName.value) {\n return 'component'\n }\n\n const iconStr = icon as string\n\n // 检测是否为图片URL或路径\n const hasPathFeatures = (str: string) => {\n return /^\\.{1,2}\\//.test(str) || str.startsWith('/') || str.includes('/')\n }\n if (/^https?:\\/\\//.test(iconStr) || hasPathFeatures(iconStr)) {\n return 'img'\n }\n\n // 检测UnoCSS图标格式 (i-[provider]:[name])\n if (/^i-[^:]+:[^:]+/.test(iconStr)) {\n return 'unocss'\n }\n\n // 检测以i-开头的自定义CSS类图标(不包含冒号)\n if (iconStr.startsWith('i-') && !iconStr.includes(':')) {\n return 'css'\n }\n\n // 检测Iconify格式 (provider:name,但不以i-开头)\n if (iconStr.includes(':') && !iconStr.startsWith('i-')) {\n return 'iconify'\n }\n\n // 检测SVG sprite(单个单词,不包含空格和特殊字符,且不以i-开头)\n if (/^[\\w-]+$/.test(iconStr) && !iconStr.startsWith('i-')) {\n return 'svg'\n }\n\n // 其他情况都视为CSS类图标(包括多个类名等)\n return 'css'\n})\n\nconst outputName = computed(() => {\n if (isComponentName.value) {\n return ''\n }\n\n const iconStr = icon as string\n\n // 对于图片类型,直接返回URL\n if (outputType.value === 'img') {\n return iconStr\n }\n\n // 对于UnoCSS图标,直接返回类名\n if (outputType.value === 'unocss') {\n return iconStr\n }\n\n // 对于传统CSS图标,处理多个类名的情况\n if (outputType.value === 'css') {\n return iconStr\n }\n\n // 其他情况直接返回\n return iconStr\n})\n\n// 对于CSS类图标,将字符串拆分为类名数组\nconst cssClasses = computed(() => {\n if (outputType.value === 'css') {\n return outputName.value.split(' ').filter(cls => cls.trim())\n }\n return []\n})\n\n// 用正则匹配 size 是不是 number 值,再判断是否有 px 结尾的单位,没有则拼接\nfunction formatSize(size: string | number | undefined): string {\n if (!size) {\n return ''\n }\n\n // 如果是数字,直接添加 px\n if (typeof size === 'number') {\n return `${size}px`\n }\n\n // 如果是纯数字字符串,添加 px\n if (/^\\d+(?:\\.\\d+)?$/.test(size)) {\n return `${size}px`\n }\n\n // 如果已经有单位(px、em、rem等)或者不是纯数字,直接返回\n return size\n}\n\n// 统一的样式计算属性,适用于所有图标类型\n// 包含颜色、尺寸和变换(旋转、翻转)\n// Iconify 图标通过外层 i 标签应用这些样式\nconst style = computed(() => {\n const transform = [] as string[]\n switch (flip) {\n case 'horizontal':\n transform.push('rotateY(180deg)')\n break\n case 'vertical':\n transform.push('rotateX(180deg)')\n break\n case 'both':\n transform.push('rotateX(180deg)')\n transform.push('rotateY(180deg)')\n break\n // 对于 '' 和 undefined,不做任何处理\n }\n if (rotate) {\n transform.push(`rotate(${rotate % 360}deg)`)\n }\n\n // 构建基础样式\n let baseStyle = `${color ? `color: ${color};` : ''}${size ? `font-size: ${formatSize(size)};` : ''}${transform.length ? `transform: ${transform.join(' ')};` : ''}`\n\n // 拼接 attrs.style\n const attrsStyle = attrs.style\n if (attrsStyle) {\n if (typeof attrsStyle === 'string') {\n baseStyle += attrsStyle\n }\n else if (typeof attrsStyle === 'object') {\n // 处理对象形式的样式\n const styleEntries = Object.entries(attrsStyle as CSSProperties)\n const styleString = styleEntries\n .map(([key, value]) => `${key.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value};`)\n .join('')\n baseStyle += styleString\n }\n }\n\n return baseStyle\n})\n\n// 图片加载状态管理\nconst imageLoading = ref(true)\nconst imageError = ref(false)\n\nfunction handleImageLoad() {\n imageLoading.value = false\n imageError.value = false\n}\n\nfunction handleImageError() {\n imageLoading.value = false\n imageError.value = true\n}\n</script>\n\n<template>\n <!-- Vue组件 -->\n <component\n :is=\"icon\"\n v-if=\"outputType === 'component'\"\n :class=\"[ns.b()]\"\n :style=\"[style]\"\n class=\"size-inherit shrink-0\"\n />\n\n <!-- UnoCSS图标 -->\n <i\n v-else-if=\"outputType === 'unocss'\"\n :class=\"[ns.b(), outputName]\"\n :style=\"[style]\"\n />\n\n <!-- CSS类图标 -->\n <i\n v-else-if=\"outputType === 'css'\"\n class=\"size-inherit shrink-0\"\n :class=\"[ns.b(), ...cssClasses]\"\n :style=\"[style]\"\n />\n\n <!-- Iconify图标 -->\n <Icon\n v-else-if=\"outputType === 'iconify'\"\n class=\"size-inherit shrink-0\"\n :icon=\"outputName\"\n :class=\"[ns.b()]\"\n :style=\"[style]\"\n />\n\n <!-- 图片 -->\n <template v-else-if=\"outputType === 'img'\">\n <!-- 加载中状态 -->\n <i\n v-if=\"imageLoading && loading\"\n :class=\"loading\"\n />\n <!-- 错误状态 -->\n <i\n v-else-if=\"imageError && fallback\"\n :class=\"fallback\"\n />\n <!-- 图片本体 -->\n <img\n :src=\"outputName\"\n class=\"size-inherit shrink-0\"\n :class=\"[ns.b()]\"\n :style=\"[style, { width: size ? formatSize(size) : 'auto', height: 'auto' }]\"\n @load=\"handleImageLoad\"\n @error=\"handleImageError\"\n >\n </template>\n\n <!-- SVG Sprite -->\n <svg\n v-else-if=\"outputName\"\n aria-hidden=\"true\"\n :class=\"[ns.b()]\"\n :style=\"[style]\"\n class=\"size-inherit shrink-0\"\n >\n <use :xlink:href=\"`#${localIconPrefix}${outputName}`\" />\n </svg>\n</template>\n"],"names":["attrs","useAttrs","ns","useNamespace","isComponentName","computed","__props","icon","outputType","value","iconStr","test","str","startsWith","includes","outputName","cssClasses","split","filter","cls","trim","formatSize","size","style","transform","flip","push","rotate","baseStyle","color","length","join","attrsStyle","Object","entries","map","key","replace","toLowerCase","imageLoading","ref","imageError","handleImageLoad","handleImageError","_createCommentVNode","_openBlock","_createBlock","_resolveDynamicComponent","class","_normalizeClass","_unref","b","_createElementBlock","_Fragment","_createElementVNode","_createVNode","Icon","loading","fallback","src","width","height","onLoad","onError","localIconPrefix"],"mappings":"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"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
import{defineComponent as e,mergeModels as a,useAttrs as
|
1
|
+
import{defineComponent as e,mergeModels as a,useAttrs as l,useModel as t,ref as i,computed as u,onUnmounted as s,resolveComponent as r,createElementBlock as o,openBlock as n,normalizeStyle as p,normalizeClass as d,unref as c,createVNode as v,createBlock as m,createCommentVNode as f,mergeProps as g,withCtx as h,renderSlot as b,createElementVNode as y,toDisplayString as _}from"vue";import{UploadImage as $,ZoomIn as L,Delete as k}from"@qxs-bns/icons";import{useNamespace as x,ElUpload as U,ElImageViewer as w,ElMessage as q}from"element-plus";const R={class:"image-slot"},j={style:{position:"relative",width:"100%",height:"100%"}},z=["src","alt"],O={key:2,class:"upload-progress"},C={key:3,class:"upload-debug"},B=["onClick"],M=["onClick"],S={class:"tip-content"};var N=e({name:"QxsImageUpload",__name:"image-upload",props:a({action:{type:String,required:!0},headers:{type:null,required:!1},data:{type:null,required:!1},name:{type:String,required:!1,default:"file"},size:{type:Number,required:!1,default:20},width:{type:Number,required:!1,default:160},height:{type:Number,required:!1,default:90},accept:{type:String,required:!1,default:"image/jpeg,image/jpg,image/png,image/gif"},placeholder:{type:String,required:!1,default:"上传图片"},notip:{type:Boolean,required:!1,default:!1},tipText:{type:String,required:!1,default:""},beforeUpload:{type:null,required:!1},disabled:{type:Boolean,required:!1,default:!1},limit:{type:Number,required:!1,default:1}},{fileList:{type:Array,default:()=>[]},fileListModifiers:{}}),emits:a(["success","remove"],["update:fileList"]),setup(e,{emit:a}){const N=a,I=l(),T=t(e,"fileList"),Q=x("image-upload"),W=i(!1),A=i(0),E=i(""),V=i(0),D=i(!1),F=u(()=>Q.cssVarBlock({ns:Q.namespace.value,width:`${e.width}px`,height:`${e.height}px`})),G=u(()=>e.accept.split(",").map(e=>e.split("/").pop())),H=u(()=>{if(e.tipText)return e.tipText;return`支持 ${G.value.join(" / ")} 格式,大小不超过 ${e.size}MB`+(e.width&&e.height?`,建议尺寸 ${e.width}×${e.height}`:"")});function J(e){if(!e.url)return void console.warn("文件缺少 URL,无法预览:",e);let a=T.value.indexOf(e);-1===a&&(a=T.value.findIndex(a=>a.url===e.url)),A.value=Math.max(0,a),W.value=!0}function K(a){if(e.disabled)return;"uploading"===a.status&&D.value&&(D.value=!1,V.value=0,E.value&&(URL.revokeObjectURL(E.value),E.value="")),a.url?.startsWith("blob:")&&URL.revokeObjectURL(a.url);const l=T.value.indexOf(a);l>-1&&T.value.splice(l,1),N("remove",a)}function P(){W.value=!1}const X=a=>{if(!a?.name)return q.error("文件信息无效,请重新选择文件"),!1;const l=a.name.split(".").pop()?.toLowerCase()??"";if(!G.value.some(e=>e?.toLowerCase()===l))return q.error(`仅支持上传 ${G.value.join(" / ")} 格式的图片`),!1;if(a.size/1024/1024>e.size)return q.error(`图片大小不能超过 ${e.size}MB`),!1;try{E.value=URL.createObjectURL(a)}catch(e){console.warn("创建预览失败:",e)}return D.value=!0,V.value=0,!e.beforeUpload||e.beforeUpload(a)},Y=e=>{V.value=Math.floor(e.percent)},Z=(e,a,l)=>{const t=T.value.some(e=>e.uid===a.uid||e.name===a.name&&e.size===a.size);E.value&&(URL.revokeObjectURL(E.value),E.value=""),D.value=!1,V.value=0,t&&N("success",e,a,l)},ee=(e,a,l)=>{const t=T.value.some(e=>e.uid===a.uid||e.name===a.name&&e.size===a.size);E.value&&(URL.revokeObjectURL(E.value),E.value=""),D.value=!1,V.value=0,t&&q.error(`图片上传失败:${e.message||"网络异常,请重试"}`)};return s(()=>{E.value&&URL.revokeObjectURL(E.value),T.value.forEach(e=>{e.url?.startsWith("blob:")&&URL.revokeObjectURL(e.url)})}),(e,a)=>{const l=r("QxsIcon");return n(),o("div",{class:d(c(Q).e("container")),style:p(F.value)},[v(c(U),g(c(I),{"file-list":T.value,"onUpdate:fileList":a[0]||(a[0]=e=>T.value=e),drag:"",limit:e.limit,"list-type":"picture-card",headers:e.headers,action:e.action,data:e.data,name:e.name,accept:e.accept,"before-upload":X,"on-progress":Y,"on-preview":J,"on-success":Z,"on-error":ee,class:[c(Q).e("control"),e.limit<=T.value.length?c(Q).e("more-than-limit"):""],"on-remove":K}),{file:h(({file:a})=>{return[y("div",j,[a.url?(n(),o("img",{key:0,class:d(`${c(Q).namespace.value}-upload-list__item-thumbnail`),src:a.url,alt:a.name||"图片"},null,10,z)):(n(),o("div",{key:1,class:d(`${c(Q).namespace.value}-upload-list__item-thumbnail`),style:{display:"flex","align-items":"center","justify-content":"center",color:"#909399",background:"#f5f7fa"}}," 无图片 ",2)),f(" 上传进度条 "),D.value?(n(),o("div",O,[y("div",{class:"upload-progress-bar",style:p({width:`${V.value}%`})},null,4)])):f("v-if",!0),f(" 调试信息 "),D.value?(n(),o("div",C,_(V.value)+"% - "+_((l=a.status,{ready:"准备中",uploading:"上传中",success:"上传成功",fail:"上传失败",error:"上传错误"}[l||""]||l||"未知状态")),1)):f("v-if",!0)]),y("span",{class:d(`${c(Q).namespace.value}-upload-list__item-actions`)},[a.url?(n(),o("span",{key:0,class:d([`${c(Q).namespace.value}-upload-list__item-preview`,`${c(Q).namespace.value}-image-upload__action-btn`,`${c(Q).namespace.value}-image-upload__action-btn--preview`]),onClick:e=>J(a)},[v(c(L),{size:"14px"})],10,B)):f("v-if",!0),a.url?(n(),o("span",{key:1,class:d(`${c(Q).namespace.value}-upload-list__item-divider`)},null,2)):f("v-if",!0),y("span",{class:d([`${c(Q).namespace.value}-upload-list__item-delete`,`${c(Q).namespace.value}-image-upload__action-btn`,`${c(Q).namespace.value}-image-upload__action-btn--delete`,e.disabled?"is-disabled":""]),onClick:e=>K(a)},[v(c(k),{size:"14px"})],10,M)],2)];var l}),tip:h(()=>[b(e.$slots,"tip",{},()=>[e.notip?f("v-if",!0):(n(),o("div",{key:0,class:d(`${c(Q).namespace.value}-upload__tip-text`)},[y("div",S,_(H.value),1)],2))])]),default:h(()=>[b(e.$slots,"default",{},()=>[y("div",R,[v(l,{size:"32px",icon:c($)},null,8,["icon"]),y("p",null,_(e.placeholder),1)])])]),_:3},16,["file-list","limit","headers","action","data","name","accept","class"]),W.value?(n(),m(c(w),{key:0,"url-list":T.value.map(e=>e.url).filter(Boolean),"initial-index":A.value,"show-progress":T.value.length>1,teleported:"",onClose:P},null,8,["url-list","initial-index","show-progress"])):f("v-if",!0)],6)}}});export{N as default};
|
2
2
|
//# sourceMappingURL=image-upload.vue.mjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"image-upload.vue.mjs","sources":["../../../../../../packages/components/src/image-upload/src/image-upload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { UploadFile, UploadFiles, UploadProps } from 'element-plus'\nimport { Delete, UploadImage, ZoomIn } from '@qxs-bns/icons'\nimport { ElImageViewer, ElMessage, ElUpload, useNamespace } from 'element-plus'\nimport { computed, onUnmounted, ref, useAttrs } from 'vue'\n\n// 类型定义\nexport interface ImageUploadProps {\n /** 上传地址(必需) */\n action: UploadProps['action']\n /** 请求头 */\n headers?: UploadProps['headers']\n /** 上传时附带的额外参数 */\n data?: UploadProps['data']\n /** 上传的文件字段名 */\n name?: UploadProps['name']\n /** 文件大小限制(MB) */\n size?: number\n /** 图片显示宽度(px) */\n width?: number\n /** 图片显示高度(px) */\n height?: number\n /** 接受的文件类型 */\n accept?: string\n /** 上传区域提示文字 */\n placeholder?: string\n /** 是否隐藏提示文字 */\n notip?: boolean\n /** 自定义提示文字 */\n tipText?: string\n /** 上传前的钩子函数 */\n beforeUpload?: UploadProps['beforeUpload']\n /** 是否禁用 */\n disabled?: boolean\n /** 最大上传数量 */\n limit?: number\n}\n\ninterface UploadProgress {\n preview: string\n percent: number\n}\n\n// 组件名称\ndefineOptions({\n name: 'QxsImageUpload',\n})\n\n// Props 定义\nconst {\n action,\n headers,\n data,\n name = 'file',\n size = 20,\n width = 160,\n height = 90,\n limit = 1,\n placeholder = '上传图片',\n notip = false,\n accept = 'image/jpeg,image/jpg,image/png,image/gif',\n beforeUpload,\n tipText = '',\n disabled = false,\n} = defineProps<ImageUploadProps>()\n\n// Emits 定义 - 统一事件命名\nconst emits = defineEmits<{\n success: [res: any, uploadFile: UploadFile, uploadFiles: UploadFiles]\n remove: [file: UploadFile]\n}>()\n\nconst attrs = useAttrs()\n\nconst fileList = defineModel('fileList', {\n type: Array as () => UploadFile[],\n default: () => [],\n})\n\n// 命名空间\nconst nsEl = useNamespace('image-upload')\n\nconst initialIndex = ref(0)\n// 响应式数据\nconst uploadData = ref<{\n imageViewerVisible: boolean\n progress: UploadProgress\n}>({\n imageViewerVisible: false,\n progress: {\n preview: '',\n percent: 0,\n },\n})\n\nconst cssVar = computed(() => {\n return nsEl.cssVarBlock({\n ns: nsEl.namespace.value,\n width: `${width}px`,\n height: `${height}px`,\n })\n})\n\n// 计算属性\nconst exts = computed(() =>\n accept.split(',').map(ext => ext.split('/').pop()),\n)\n\nconst tipMessage = computed(() => {\n if (tipText) {\n return tipText\n }\n\n const formatText = `上传图片支持 ${exts.value.join(' / ')} 格式,且图片大小不超过 ${size}MB`\n const sizeText = width && height ? `,建议图片尺寸为 ${width}×${height}` : ''\n\n return formatText + sizeText\n})\n\n// 方法\nfunction onPreview(file: UploadFile) {\n // 确保文件有有效的 URL 才能预览\n if (!file.url) {\n console.warn('文件缺少 URL,无法预览:', file)\n return\n }\n\n // 直接使用文件在列表中的索引\n initialIndex.value = fileList.value.indexOf(file)\n uploadData.value.imageViewerVisible = true\n}\n\nfunction onRemove(file: UploadFile) {\n // 如果组件被禁用,阻止删除\n if (disabled) {\n return\n }\n\n // 清理可能的 Object URL\n if (file.url && file.url.startsWith('blob:')) {\n URL.revokeObjectURL(file.url)\n }\n\n // 直接使用文件在列表中的索引来删除\n const index = fileList.value.indexOf(file)\n if (index > -1) {\n fileList.value.splice(index, 1)\n }\n\n // 触发删除事件\n emits('remove', file)\n}\n\nfunction previewClose() {\n uploadData.value.imageViewerVisible = false\n}\n\nconst handleBeforeUpload: UploadProps['beforeUpload'] = (file) => {\n // 参数校验\n if (!file || !file.name) {\n ElMessage.error('文件信息无效!')\n return false\n }\n\n // 文件类型校验\n const fileExt = file.name.split('.').pop()?.toLowerCase() ?? ''\n const isTypeOk = exts.value.some(ext => ext?.toLowerCase() === fileExt)\n\n if (!isTypeOk) {\n ElMessage.error(`上传图片只支持 ${exts.value.join(' / ')} 格式!`)\n return false\n }\n\n // 文件大小校验\n const fileSizeMB = file.size / 1024 / 1024\n if (fileSizeMB > size) {\n ElMessage.error(`上传图片大小不能超过 ${size}MB!`)\n return false\n }\n\n // 设置预览\n try {\n uploadData.value.progress.preview = URL.createObjectURL(file)\n }\n catch (error) {\n console.warn('创建预览失败:', error)\n }\n\n // 执行自定义校验\n return beforeUpload ? beforeUpload(file) : true\n}\n\nconst onProgress: UploadProps['onProgress'] = (evt) => {\n uploadData.value.progress.percent = Math.floor(evt.percent)\n}\n\nconst onError: UploadProps['onError'] = (error, _file, _fileList) => {\n // 上传失败时也要清理预览 URL\n if (uploadData.value.progress.preview) {\n URL.revokeObjectURL(uploadData.value.progress.preview)\n uploadData.value.progress.preview = ''\n }\n uploadData.value.progress.percent = 0\n\n ElMessage.error(`上传失败: ${error.message || '未知错误'}`)\n}\n\nconst onSuccess: UploadProps['onSuccess'] = (...args) => {\n // 清理预览 URL,防止内存泄漏\n if (uploadData.value.progress.preview) {\n URL.revokeObjectURL(uploadData.value.progress.preview)\n }\n\n uploadData.value.progress = {\n preview: '',\n percent: 0,\n }\n emits('success', ...args)\n}\n\n// 清理所有可能的 Object URL\nfunction cleanupObjectURLs() {\n // 清理进度预览 URL\n if (uploadData.value.progress.preview) {\n URL.revokeObjectURL(uploadData.value.progress.preview)\n uploadData.value.progress.preview = ''\n }\n\n // 清理文件列表中可能的 Object URL\n fileList.value.forEach((file) => {\n if (file.url && file.url.startsWith('blob:')) {\n URL.revokeObjectURL(file.url)\n }\n })\n}\n\n// 组件卸载时清理资源\nonUnmounted(() => {\n cleanupObjectURLs()\n})\n</script>\n\n<template>\n <div\n :class=\"nsEl.e('container')\"\n :style=\"cssVar\"\n >\n <ElUpload\n v-bind=\"attrs\"\n v-model:file-list=\"fileList\"\n drag\n :limit=\"limit\"\n list-type=\"picture-card\"\n :headers=\"headers\"\n :action=\"action\"\n :data=\"data\"\n :name=\"name\"\n :accept=\"accept\"\n :before-upload=\"handleBeforeUpload\"\n :on-progress=\"onProgress\"\n :on-preview=\"onPreview\"\n :on-success=\"onSuccess\"\n :on-error=\"onError\"\n :class=\"[nsEl.e('control'), limit <= fileList.length ? nsEl.e('more-than-limit') : '']\"\n :on-remove=\"onRemove\"\n >\n <slot>\n <div class=\"image-slot\">\n <QxsIcon\n size=\"32px\"\n :icon=\"UploadImage\"\n />\n <p>{{ placeholder }}</p>\n </div>\n </slot>\n <template #file=\"{ file }\">\n <img\n v-if=\"file.url\"\n :class=\"`${nsEl.namespace.value}-upload-list__item-thumbnail`\"\n :src=\"file.url\"\n :alt=\"file.name || '图片'\"\n >\n <div\n v-else\n :class=\"`${nsEl.namespace.value}-upload-list__item-thumbnail`\"\n style=\"display: flex; align-items: center; justify-content: center; color: #909399; background: #f5f7fa;\"\n >\n 无图片\n </div>\n <span :class=\"`${nsEl.namespace.value}-upload-list__item-actions`\">\n <span\n v-if=\"file.url\"\n :class=\"[\n `${nsEl.namespace.value}-upload-list__item-preview`,\n `${nsEl.namespace.value}-image-upload__action-btn`,\n `${nsEl.namespace.value}-image-upload__action-btn--preview`,\n ]\"\n @click=\"onPreview(file)\"\n >\n <ZoomIn size=\"14px\" />\n </span>\n <span\n v-if=\"file.url\"\n :class=\"`${nsEl.namespace.value}-upload-list__item-divider`\"\n />\n <span\n :class=\"[\n `${nsEl.namespace.value}-upload-list__item-delete`,\n `${nsEl.namespace.value}-image-upload__action-btn`,\n `${nsEl.namespace.value}-image-upload__action-btn--delete`,\n disabled ? 'is-disabled' : '',\n ]\"\n @click=\"onRemove(file)\"\n >\n <Delete size=\"14px\" />\n </span>\n </span>\n </template>\n <template #tip>\n <slot name=\"tip\">\n <div\n v-if=\"!notip\"\n :class=\"`${nsEl.namespace.value}-upload__tip-text`\"\n >\n <div class=\"tip-content\">\n {{ tipMessage }}\n </div>\n </div>\n </slot>\n </template>\n </ElUpload>\n\n <ElImageViewer\n v-if=\"uploadData.imageViewerVisible\"\n :url-list=\"fileList.map((item: UploadFile) => item.url!).filter(Boolean)\"\n :initial-index=\"initialIndex\"\n :show-progress=\"fileList.length > 1\"\n teleported\n @close=\"previewClose\"\n />\n </div>\n</template>\n"],"names":["emits","__emit","attrs","useAttrs","fileList","_useModel","__props","nsEl","useNamespace","initialIndex","ref","uploadData","imageViewerVisible","progress","preview","percent","cssVar","computed","cssVarBlock","ns","namespace","value","width","height","exts","split","map","ext","pop","tipMessage","tipText","join","size","onPreview","file","url","indexOf","console","warn","onRemove","disabled","startsWith","URL","revokeObjectURL","index","splice","previewClose","handleBeforeUpload","name","ElMessage","error","fileExt","toLowerCase","some","createObjectURL","beforeUpload","onProgress","evt","Math","floor","onError","_file","_fileList","message","onSuccess","args","onUnmounted","forEach","_createElementBlock","class","_normalizeClass","_unref","e","style","_createVNode","ElUpload","_mergeProps","$event","drag","limit","headers","action","data","accept","length","_withCtx","src","alt","display","color","background","_createElementVNode","onClick","ZoomIn","Delete","tip","_renderSlot","_ctx","notip","_hoisted_5","_toDisplayString","_hoisted_1","_component_QxsIcon","icon","UploadImage","placeholder","_createBlock","ElImageViewer","item","filter","Boolean","teleported","onClose"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"image-upload.vue.mjs","sources":["../../../../../../packages/components/src/image-upload/src/image-upload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { UploadFile, UploadFiles, UploadProps } from 'element-plus'\nimport { Delete, UploadImage, ZoomIn } from '@qxs-bns/icons'\nimport { ElImageViewer, ElMessage, ElUpload, useNamespace } from 'element-plus'\nimport { computed, onUnmounted, ref, useAttrs } from 'vue'\n\n// 类型定义\nexport interface ImageUploadProps {\n /** 上传地址(必需) */\n action: UploadProps['action']\n /** 请求头 */\n headers?: UploadProps['headers']\n /** 上传时附带的额外参数 */\n data?: UploadProps['data']\n /** 上传的文件字段名 */\n name?: UploadProps['name']\n /** 文件大小限制(MB) */\n size?: number\n /** 图片显示宽度(px) */\n width?: number\n /** 图片显示高度(px) */\n height?: number\n /** 接受的文件类型 */\n accept?: string\n /** 上传区域提示文字 */\n placeholder?: string\n /** 是否隐藏提示文字 */\n notip?: boolean\n /** 自定义提示文字 */\n tipText?: string\n /** 上传前的钩子函数 */\n beforeUpload?: UploadProps['beforeUpload']\n /** 是否禁用 */\n disabled?: boolean\n /** 最大上传数量 */\n limit?: number\n}\n\n// 组件名称\ndefineOptions({\n name: 'QxsImageUpload',\n})\n\n// Props 定义\nconst {\n action,\n headers,\n data,\n name = 'file',\n size = 20,\n width = 160,\n height = 90,\n limit = 1,\n placeholder = '上传图片',\n notip = false,\n accept = 'image/jpeg,image/jpg,image/png,image/gif',\n beforeUpload,\n tipText = '',\n disabled = false,\n} = defineProps<ImageUploadProps>()\n\n// Emits 定义\nconst emits = defineEmits<{\n success: [res: any, uploadFile: UploadFile, uploadFiles: UploadFiles]\n remove: [file: UploadFile]\n}>()\n\nconst attrs = useAttrs()\n\nconst fileList = defineModel('fileList', {\n type: Array as () => UploadFile[],\n default: () => [],\n})\n\n// 命名空间\nconst nsEl = useNamespace('image-upload')\n\n// 响应式数据\nconst imageViewerVisible = ref(false)\nconst initialIndex = ref(0)\nconst previewUrl = ref('')\nconst uploadProgress = ref(0)\nconst isUploading = ref(false)\n\nconst cssVar = computed(() => {\n return nsEl.cssVarBlock({\n ns: nsEl.namespace.value,\n width: `${width}px`,\n height: `${height}px`,\n })\n})\n\n// 计算属性\nconst exts = computed(() =>\n accept.split(',').map(ext => ext.split('/').pop()),\n)\n\nconst tipMessage = computed(() => {\n if (tipText) {\n return tipText\n }\n\n const formatText = `支持 ${exts.value.join(' / ')} 格式,大小不超过 ${size}MB`\n const sizeText = width && height ? `,建议尺寸 ${width}×${height}` : ''\n\n return formatText + sizeText\n})\n\n// 状态文本转换\nfunction getStatusText(status: string | undefined): string {\n const statusMap: Record<string, string> = {\n ready: '准备中',\n uploading: '上传中',\n success: '上传成功',\n fail: '上传失败',\n error: '上传错误',\n }\n return statusMap[status || ''] || status || '未知状态'\n}\n\n// 方法\nfunction onPreview(file: UploadFile) {\n if (!file.url) {\n console.warn('文件缺少 URL,无法预览:', file)\n return\n }\n\n // 简化索引查找:优先对象引用,备用 URL 匹配\n let index = fileList.value.indexOf(file)\n if (index === -1) {\n index = fileList.value.findIndex(item => item.url === file.url)\n }\n\n initialIndex.value = Math.max(0, index)\n imageViewerVisible.value = true\n}\n\nfunction onRemove(file: UploadFile) {\n if (disabled) {\n return\n }\n\n // 如果正在上传,重置上传状态\n if (file.status === 'uploading' && isUploading.value) {\n isUploading.value = false\n uploadProgress.value = 0\n\n // 清理预览 URL\n if (previewUrl.value) {\n URL.revokeObjectURL(previewUrl.value)\n previewUrl.value = ''\n }\n }\n\n // 清理可能的 Object URL\n if (file.url?.startsWith('blob:')) {\n URL.revokeObjectURL(file.url)\n }\n\n // 从数组中移除文件\n const index = fileList.value.indexOf(file)\n if (index > -1) {\n fileList.value.splice(index, 1)\n }\n\n emits('remove', file)\n}\n\nfunction previewClose() {\n imageViewerVisible.value = false\n}\n\nconst handleBeforeUpload: UploadProps['beforeUpload'] = (file) => {\n if (!file?.name) {\n ElMessage.error('文件信息无效,请重新选择文件')\n return false\n }\n\n // 文件类型校验\n const fileExt = file.name.split('.').pop()?.toLowerCase() ?? ''\n const isTypeOk = exts.value.some(ext => ext?.toLowerCase() === fileExt)\n if (!isTypeOk) {\n ElMessage.error(`仅支持上传 ${exts.value.join(' / ')} 格式的图片`)\n return false\n }\n\n // 文件大小校验\n const fileSizeMB = file.size / 1024 / 1024\n if (fileSizeMB > size) {\n ElMessage.error(`图片大小不能超过 ${size}MB`)\n return false\n }\n\n // 设置预览和上传状态\n try {\n previewUrl.value = URL.createObjectURL(file)\n }\n catch (error) {\n console.warn('创建预览失败:', error)\n }\n\n // 开始上传\n isUploading.value = true\n uploadProgress.value = 0\n\n return beforeUpload ? beforeUpload(file) : true\n}\n\nconst onProgress: UploadProps['onProgress'] = (evt) => {\n uploadProgress.value = Math.floor(evt.percent)\n}\n\nconst onSuccess: UploadProps['onSuccess'] = (response, uploadFile, uploadFiles) => {\n // 检查文件是否还在列表中(可能已被删除)\n const fileExists = fileList.value.some(file =>\n file.uid === uploadFile.uid\n || (file.name === uploadFile.name && file.size === uploadFile.size),\n )\n\n // 清理预览 URL 和重置状态\n if (previewUrl.value) {\n URL.revokeObjectURL(previewUrl.value)\n previewUrl.value = ''\n }\n isUploading.value = false\n uploadProgress.value = 0\n\n // 只有文件还存在时才触发成功回调\n if (fileExists) {\n emits('success', response, uploadFile, uploadFiles)\n }\n}\n\nconst onError: UploadProps['onError'] = (error, uploadFile, _uploadFiles) => {\n // 检查文件是否还在列表中(可能已被删除)\n const fileExists = fileList.value.some(file =>\n file.uid === uploadFile.uid\n || (file.name === uploadFile.name && file.size === uploadFile.size),\n )\n\n // 清理预览 URL 和重置状态\n if (previewUrl.value) {\n URL.revokeObjectURL(previewUrl.value)\n previewUrl.value = ''\n }\n isUploading.value = false\n uploadProgress.value = 0\n\n // 只有文件还存在时才显示错误信息\n if (fileExists) {\n ElMessage.error(`图片上传失败:${error.message || '网络异常,请重试'}`)\n }\n}\n\n// 组件卸载时清理资源\nonUnmounted(() => {\n if (previewUrl.value) {\n URL.revokeObjectURL(previewUrl.value)\n }\n // 清理文件列表中的 blob URL\n fileList.value.forEach((file) => {\n if (file.url?.startsWith('blob:')) {\n URL.revokeObjectURL(file.url)\n }\n })\n})\n</script>\n\n<template>\n <div\n :class=\"nsEl.e('container')\"\n :style=\"cssVar\"\n >\n <ElUpload\n v-bind=\"attrs\"\n v-model:file-list=\"fileList\"\n drag\n :limit=\"limit\"\n list-type=\"picture-card\"\n :headers=\"headers\"\n :action=\"action\"\n :data=\"data\"\n :name=\"name\"\n :accept=\"accept\"\n :before-upload=\"handleBeforeUpload\"\n :on-progress=\"onProgress\"\n :on-preview=\"onPreview\"\n :on-success=\"onSuccess\"\n :on-error=\"onError\"\n :class=\"[nsEl.e('control'), limit <= fileList.length ? nsEl.e('more-than-limit') : '']\"\n :on-remove=\"onRemove\"\n >\n <slot>\n <div class=\"image-slot\">\n <QxsIcon\n size=\"32px\"\n :icon=\"UploadImage\"\n />\n <p>{{ placeholder }}</p>\n </div>\n </slot>\n <template #file=\"{ file }\">\n <div style=\"position: relative; width: 100%; height: 100%;\">\n <img\n v-if=\"file.url\"\n :class=\"`${nsEl.namespace.value}-upload-list__item-thumbnail`\"\n :src=\"file.url\"\n :alt=\"file.name || '图片'\"\n >\n <div\n v-else\n :class=\"`${nsEl.namespace.value}-upload-list__item-thumbnail`\"\n style=\"display: flex; align-items: center; justify-content: center; color: #909399; background: #f5f7fa;\"\n >\n 无图片\n </div>\n\n <!-- 上传进度条 -->\n <div\n v-if=\"isUploading\"\n class=\"upload-progress\"\n >\n <div\n class=\"upload-progress-bar\"\n :style=\"{ width: `${uploadProgress}%` }\"\n />\n </div>\n\n <!-- 调试信息 -->\n <div\n v-if=\"isUploading\"\n class=\"upload-debug\"\n >\n {{ uploadProgress }}% - {{ getStatusText(file.status) }}\n </div>\n </div>\n\n <span :class=\"`${nsEl.namespace.value}-upload-list__item-actions`\">\n <span\n v-if=\"file.url\"\n :class=\"[\n `${nsEl.namespace.value}-upload-list__item-preview`,\n `${nsEl.namespace.value}-image-upload__action-btn`,\n `${nsEl.namespace.value}-image-upload__action-btn--preview`,\n ]\"\n @click=\"onPreview(file)\"\n >\n <ZoomIn size=\"14px\" />\n </span>\n <span\n v-if=\"file.url\"\n :class=\"`${nsEl.namespace.value}-upload-list__item-divider`\"\n />\n <span\n :class=\"[\n `${nsEl.namespace.value}-upload-list__item-delete`,\n `${nsEl.namespace.value}-image-upload__action-btn`,\n `${nsEl.namespace.value}-image-upload__action-btn--delete`,\n disabled ? 'is-disabled' : '',\n ]\"\n @click=\"onRemove(file)\"\n >\n <Delete size=\"14px\" />\n </span>\n </span>\n </template>\n <template #tip>\n <slot name=\"tip\">\n <div\n v-if=\"!notip\"\n :class=\"`${nsEl.namespace.value}-upload__tip-text`\"\n >\n <div class=\"tip-content\">\n {{ tipMessage }}\n </div>\n </div>\n </slot>\n </template>\n </ElUpload>\n\n <ElImageViewer\n v-if=\"imageViewerVisible\"\n :url-list=\"fileList.map((item: UploadFile) => item.url!).filter(Boolean)\"\n :initial-index=\"initialIndex\"\n :show-progress=\"fileList.length > 1\"\n teleported\n @close=\"previewClose\"\n />\n </div>\n</template>\n"],"names":["emits","__emit","attrs","useAttrs","fileList","_useModel","__props","nsEl","useNamespace","imageViewerVisible","ref","initialIndex","previewUrl","uploadProgress","isUploading","cssVar","computed","cssVarBlock","ns","namespace","value","width","height","exts","split","map","ext","pop","tipMessage","tipText","join","size","onPreview","file","url","console","warn","index","indexOf","findIndex","item","Math","max","onRemove","disabled","status","URL","revokeObjectURL","startsWith","splice","previewClose","handleBeforeUpload","name","ElMessage","error","fileExt","toLowerCase","some","createObjectURL","beforeUpload","onProgress","evt","floor","percent","onSuccess","response","uploadFile","uploadFiles","fileExists","uid","onError","_uploadFiles","message","onUnmounted","forEach","_createElementBlock","class","_normalizeClass","_unref","e","style","_createVNode","ElUpload","_mergeProps","$event","drag","limit","headers","action","data","accept","length","_withCtx","_createElementVNode","_hoisted_2","src","alt","display","color","background","_createCommentVNode","_openBlock","_hoisted_4","_hoisted_5","_toDisplayString","ready","uploading","success","fail","onClick","ZoomIn","Delete","tip","_renderSlot","_ctx","notip","_hoisted_8","_hoisted_1","_component_QxsIcon","icon","UploadImage","placeholder","_createBlock","ElImageViewer","filter","Boolean","teleported","onClose"],"mappings":"2iDA8DA,MAAMA,EAAQC,EAKRC,EAAQC,IAERC,EAAWC,EAAWC,EAAC,YAMvBC,EAAOC,EAAa,gBAGpBC,EAAqBC,GAAI,GACzBC,EAAeD,EAAI,GACnBE,EAAaF,EAAI,IACjBG,EAAiBH,EAAI,GACrBI,EAAcJ,GAAI,GAElBK,EAASC,EAAS,IACfT,EAAKU,YAAY,CACtBC,GAAIX,EAAKY,UAAUC,MACnBC,MAAO,GAAGf,YACVgB,OAAQ,GAAGhB,gBAKTiB,EAAOP,EAAS,IACpBV,SAAOkB,MAAM,KAAKC,IAAIC,GAAOA,EAAIF,MAAM,KAAKG,QAGxCC,EAAaZ,EAAS,KAC1B,GAAIV,EAAAuB,QACF,OAAOvB,EAAAuB,QAMT,MAHmB,MAAMN,EAAKH,MAAMU,KAAK,mBAAmBxB,EAAAyB,UAC3CzB,EAAAe,OAASf,SAAS,SAASA,WAASA,EAAAgB,SAAW,MAkBlE,SAASU,EAAUC,GACjB,IAAKA,EAAKC,IAER,YADAC,QAAQC,KAAK,iBAAkBH,GAKjC,IAAII,EAAQjC,EAASgB,MAAMkB,QAAQL,IACrB,IAAVI,IACFA,EAAQjC,EAASgB,MAAMmB,aAAkBC,EAAKN,MAAQD,EAAKC,MAG7DvB,EAAaS,MAAQqB,KAAKC,IAAI,EAAGL,GACjC5B,EAAmBW,OAAQ,CAC7B,CAEA,SAASuB,EAASV,GAChB,GAAI3B,EAAAsC,SACF,OAIkB,cAAhBX,EAAKY,QAA0B/B,EAAYM,QAC7CN,EAAYM,OAAQ,EACpBP,EAAeO,MAAQ,EAGnBR,EAAWQ,QACb0B,IAAIC,gBAAgBnC,EAAWQ,OAC/BR,EAAWQ,MAAQ,KAKnBa,EAAKC,KAAKc,WAAW,UACvBF,IAAIC,gBAAgBd,EAAKC,KAI3B,MAAMG,EAAQjC,EAASgB,MAAMkB,QAAQL,GACjCI,GAAQ,GACVjC,EAASgB,MAAM6B,OAAOZ,EAAO,GAG/BrC,EAAM,SAAUiC,EAClB,CAEA,SAASiB,IACPzC,EAAmBW,OAAQ,CAC7B,CAEA,MAAM+B,EAAmDlB,IACvD,IAAKA,GAAMmB,KAET,OADAC,EAAUC,MAAM,mBACT,EAIT,MAAMC,EAAUtB,EAAKmB,KAAK5B,MAAM,KAAKG,OAAO6B,eAAiB,GAE7D,IADiBjC,EAAKH,MAAMqC,QAAY/B,GAAK8B,gBAAkBD,GAG7D,OADAF,EAAUC,MAAM,SAAS/B,EAAKH,MAAMU,KAAK,iBAClC,EAKT,GADmBG,EAAKF,KAAO,KAAO,KACrBzB,EAAAyB,KAEf,OADAsB,EAAUC,MAAM,YAAYhD,EAAAyB,WACrB,EAIT,IACEnB,EAAWQ,MAAQ0B,IAAIY,gBAAgBzB,EACzC,OACOqB,GACLnB,QAAQC,KAAK,UAAWkB,EAC1B,CAMA,OAHAxC,EAAYM,OAAQ,EACpBP,EAAeO,MAAQ,GAEhBd,EAAAqD,cAAerD,eAAa2B,IAG/B2B,EAAyCC,IAC7ChD,EAAeO,MAAQqB,KAAKqB,MAAMD,EAAIE,UAGlCC,EAAsC,CAACC,EAAUC,EAAYC,KAEjE,MAAMC,EAAahE,EAASgB,MAAMqC,KAAKxB,GACrCA,EAAKoC,MAAQH,EAAWG,KACpBpC,EAAKmB,OAASc,EAAWd,MAAQnB,EAAKF,OAASmC,EAAWnC,MAI5DnB,EAAWQ,QACb0B,IAAIC,gBAAgBnC,EAAWQ,OAC/BR,EAAWQ,MAAQ,IAErBN,EAAYM,OAAQ,EACpBP,EAAeO,MAAQ,EAGnBgD,GACFpE,EAAM,UAAWiE,EAAUC,EAAYC,IAIrCG,GAAkC,CAAChB,EAAOY,EAAYK,KAE1D,MAAMH,EAAahE,EAASgB,MAAMqC,KAAKxB,GACrCA,EAAKoC,MAAQH,EAAWG,KACpBpC,EAAKmB,OAASc,EAAWd,MAAQnB,EAAKF,OAASmC,EAAWnC,MAI5DnB,EAAWQ,QACb0B,IAAIC,gBAAgBnC,EAAWQ,OAC/BR,EAAWQ,MAAQ,IAErBN,EAAYM,OAAQ,EACpBP,EAAeO,MAAQ,EAGnBgD,GACFf,EAAUC,MAAM,UAAUA,EAAMkB,SAAW,sBAK/CC,EAAY,KACN7D,EAAWQ,OACb0B,IAAIC,gBAAgBnC,EAAWQ,OAGjChB,EAASgB,MAAMsD,QAASzC,IAClBA,EAAKC,KAAKc,WAAW,UACvBF,IAAIC,gBAAgBd,EAAKC,iDAO7ByC,EAuHM,MAAA,CAtHHC,MAAKC,EAAEC,EAAAvE,GAAKwE,EAAC,cACbC,QAAOjE,EAAAK,SAER6D,EAyGWH,EAAAI,GAzGXC,EAyGWL,EAAA5E,GAxGI,CACL,YAAWE,EAAAgB,yCAAAhB,EAAQgB,MAAAgE,GAC3BC,KAAA,GACCC,MAAOA,EAAAA,MACR,YAAU,eACTC,QAASA,EAAAA,QACTC,OAAQA,EAAAA,OACRC,KAAMA,EAAAA,KACNrC,KAAMA,EAAAA,KACNsC,OAAQA,EAAAA,OACR,gBAAevC,EACf,cAAaS,EACb,aAAY5B,EACZ,aAAYgC,EACZ,WAAUM,GACVM,MAAK,CAAGE,EAAAvE,GAAKwE,EAAC,WAAaO,EAAAA,OAASlF,EAAAgB,MAASuE,OAASb,EAAAvE,GAAKwE,EAAC,mBAAA,IAC5D,YAAWpC,KAWDV,KAAI2D,EACb,EADiB3D,WAAI,OACrB4D,EAiCM,MAjCNC,EAiCM,CA/BI7D,EAAKC,SADbyC,EAKC,MAAA,OAHEC,MAAKC,EAAA,GAAKC,EAAAvE,GAAKY,UAAUC,qCACzB2E,IAAK9D,EAAKC,IACV8D,IAAK/D,EAAKmB,MAAI,uBAEjBuB,EAMM,MAAA,OAJHC,MAAKC,EAAA,GAAKC,EAAAvE,GAAKY,UAAUC,qCAC1B4D,MAAA,CAAAiB,QAAA,OAAA,cAAA,SAAA,kBAAA,SAAAC,MAAA,UAAAC,WAAA,YACD,QAED,IAEAC,EAAA,WAEQtF,EAAAM,OADRiF,IAAA1B,EAQM,MARN2B,EAQM,CAJJT,EAGE,MAAA,CAFAjB,MAAM,sBACLI,kBAAmBnE,EAAAO,oCAIxBgF,EAAA,UAEQtF,EAAAM,WADRuD,EAKM,MALN4B,EAKMC,EADD3F,EAAAO,OAAiB,OAAIoF,GAhOb3D,EAgO8BZ,EAAKY,OA/Nd,CACxC4D,MAAO,MACPC,UAAW,MACXC,QAAS,OACTC,KAAM,OACNtD,MAAO,QAEQT,GAAU,KAAOA,GAAU,SAwNkB,mBAIxDgD,EA2BO,OAAA,CA3BAjB,MAAKC,EAAA,GAAKC,EAAAvE,GAAKY,UAAUC,qCAEtBa,EAAKC,SADbyC,EAUO,OAAA,OARJC,MAAKC,EAAA,IAAqBC,EAAAvE,GAAKY,UAAUC,qCAAoD0D,EAAAvE,GAAKY,UAAUC,oCAAmD0D,EAAAvE,GAAKY,UAAUC,4CAK9KyF,QAAKzB,GAAEpD,EAAUC,KAElBgD,EAAsBH,EAAAgC,GAAA,CAAd/E,KAAK,8BAGPE,EAAKC,SADbyC,EAGE,OAAA,OADCC,MAAKC,EAAA,GAAKC,EAAAvE,GAAKY,UAAUC,0DAE5ByE,EAUO,OAAA,CATJjB,MAAKC,EAAA,IAAqBC,EAAAvE,GAAKY,UAAUC,oCAAmD0D,EAAAvE,GAAKY,UAAUC,oCAAmD0D,EAAAvE,GAAKY,UAAUC,yCAAwDwB,EAAAA,SAAQ,cAAA,KAM7OiE,QAAKzB,GAAEzC,EAASV,KAEjBgD,EAAsBH,EAAAiC,GAAA,CAAdhF,KAAK,qBA7PzB,IAAuBc,IAiQNmE,MACT,IASO,CATPC,EASOC,kBATP,IASO,CAPIC,EAAAA,wBADTxC,EAOM,MAAA,OALHC,MAAKC,EAAA,GAAKC,EAAAvE,GAAKY,UAAUC,4BAE1ByE,EAEM,MAFNuB,EAEMZ,EADD5E,EAAAR,OAAU,sBAjFrB,IAQO,CARP6F,EAQOC,sBARP,IAQO,CAPLrB,EAMM,MANNwB,EAMM,CALJpC,EAGEqC,EAAA,CAFAvF,KAAK,OACJwF,KAAMzC,EAAA0C,qBAET3B,EAAwB,WAAlB4B,EAAAA,aAAW,0FAmFfhH,EAAAW,WADRsG,EAOE5C,EAAA6C,GAAA,OALC,WAAUvH,EAAAgB,MAASK,IAAKe,GAAqBA,EAAKN,KAAM0F,OAAOC,SAC/D,gBAAelH,EAAAS,MACf,gBAAehB,EAAAgB,MAASuE,OAAM,EAC/BmC,WAAA,GACCC,QAAO7E"}
|
package/lib/package.json.cjs
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";exports.version="0.0.
|
1
|
+
"use strict";exports.version="0.0.79";
|
2
2
|
//# sourceMappingURL=package.json.cjs.map
|
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),a=require("@element-plus/icons-vue"),l=require("@qxs-bns/hooks"),t=require("element-plus");const r={class:"slot"},s={style:{display:"inline-block"}};var
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),a=require("@element-plus/icons-vue"),l=require("@qxs-bns/hooks"),t=require("element-plus");const r={class:"slot"},s={style:{display:"inline-block"}};var i=e.defineComponent({name:"QxsFileUpload",__name:"file-upload",props:{action:{type:String,required:!0},headers:{type:null,required:!1},data:{type:null,required:!1},name:{type:String,required:!1,default:"file"},size:{type:Number,required:!1,default:20},max:{type:Number,required:!1,default:3},accept:{type:String,required:!1,default:"zip,rar"},files:{type:Array,required:!1,default:()=>[]},notip:{type:Boolean,required:!1,default:!1},ext:{type:Array,required:!1}},emits:["onSuccess"],setup(i,{emit:n}){const o=n,u=l.useNamespace("file-upload"),d=t.useNamespace("file-upload"),c=e.computed(()=>i.accept.split(",")),p=e=>{const a=e.name.split(".").at(-1)??"",l=c.value.includes(a),r=e.size/1024/1024<i.size;return l||t.ElMessage.error(`上传文件只支持 ${c.value.join(" / ")} 格式!`),r||t.ElMessage.error(`上传文件大小不能超过 ${i.size}MB!`),l&&r},m=()=>{t.ElMessage.warning("文件上传超过限制")},f=(e,a,l)=>{o("onSuccess",e,a,l)};return(l,i)=>(e.openBlock(),e.createBlock(e.unref(t.ElUpload),{headers:l.headers,action:l.action,data:l.data,name:l.name,"before-upload":p,"on-exceed":m,"on-success":f,"file-list":l.files,limit:l.max,drag:"",class:e.normalizeClass(e.unref(u).e("control"))},{tip:e.withCtx(()=>[l.notip?e.createCommentVNode("v-if",!0):(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(`${e.unref(d).namespace.value}-upload__tip`)},[e.createElementVNode("div",s,[e.createVNode(e.unref(t.ElAlert),{title:`上传文件支持 ${c.value.join(" / ")} 格式,单个文件大小不超过 ${l.size}MB,且文件数量不超过 ${l.max} 个`,type:"info","show-icon":"",closable:!1},null,8,["title"])])],2))]),default:e.withCtx(()=>[e.createElementVNode("div",r,[e.createVNode(e.unref(t.ElIcon),{class:e.normalizeClass(`${e.unref(d).namespace.value}-icon--upload`)},{default:e.withCtx(()=>[e.createVNode(e.unref(a.UploadFilled))]),_:1},8,["class"]),e.createElementVNode("div",{class:e.normalizeClass(`${e.unref(d).namespace.value}-upload__text`)},i[0]||(i[0]=[e.createTextVNode(" 将文件拖到此处,或",-1),e.createElementVNode("em",null,"点击上传",-1)]),2)])]),_:1},8,["headers","action","data","name","file-list","limit","class"]))}});exports.default=i;
|
2
2
|
//# sourceMappingURL=file-upload.vue.cjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"file-upload.vue.cjs","sources":["../../../../../../packages/components/src/file-upload/src/file-upload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { UploadProps, UploadUserFile } from 'element-plus'\nimport { UploadFilled } from '@element-plus/icons-vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { ElMessage, useNamespace as useElNamespace } from 'element-plus'\nimport { computed } from 'vue'\n\ndefineOptions({\n name: 'QxsFileUpload',\n})\n\nconst {\n name = 'file',\n size = 20,\n max = 3,\n files = [],\n notip = false,\n accept = 'zip,rar',\n} = defineProps<{\n action: UploadProps['action']\n headers?: UploadProps['headers']\n data?: UploadProps['data']\n name?: UploadProps['name']\n size?: number\n max?: number\n accept?: string\n files?: UploadUserFile[]\n notip?: boolean\n ext?: string[]\n}>()\n\nconst emit = defineEmits(['onSuccess'])\n\nconst ns = useNamespace('file-upload')\nconst nsEl = useElNamespace('file-upload')\n\nconst exts = computed(() => {\n return accept.split(',')\n})\nconst beforeUpload: UploadProps['beforeUpload'] = (file) => {\n const fileName = file.name.split('.')\n const fileExt = fileName.at(-1) ?? ''\n const isTypeOk = exts.value.includes(fileExt)\n const isSizeOk = file.size / 1024 / 1024 < size\n if (!isTypeOk) {\n ElMessage.error(`上传文件只支持 ${exts.value.join(' / ')} 格式!`)\n }\n if (!isSizeOk) {\n ElMessage.error(`上传文件大小不能超过 ${size}MB!`)\n }\n return isTypeOk && isSizeOk\n}\n\nconst onExceed: UploadProps['onExceed'] = () => {\n ElMessage.warning('文件上传超过限制')\n}\n\nconst onSuccess: UploadProps['onSuccess'] = (res, file, fileList) => {\n emit('onSuccess', res, file, fileList)\n}\n</script>\n\n<template>\n <
|
1
|
+
{"version":3,"file":"file-upload.vue.cjs","sources":["../../../../../../packages/components/src/file-upload/src/file-upload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { UploadProps, UploadUserFile } from 'element-plus'\nimport { UploadFilled } from '@element-plus/icons-vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { ElAlert, ElIcon, ElMessage, ElUpload, useNamespace as useElNamespace } from 'element-plus'\nimport { computed } from 'vue'\n\ndefineOptions({\n name: 'QxsFileUpload',\n})\n\nconst {\n name = 'file',\n size = 20,\n max = 3,\n files = [],\n notip = false,\n accept = 'zip,rar',\n} = defineProps<{\n action: UploadProps['action']\n headers?: UploadProps['headers']\n data?: UploadProps['data']\n name?: UploadProps['name']\n size?: number\n max?: number\n accept?: string\n files?: UploadUserFile[]\n notip?: boolean\n ext?: string[]\n}>()\n\nconst emit = defineEmits(['onSuccess'])\n\nconst ns = useNamespace('file-upload')\nconst nsEl = useElNamespace('file-upload')\n\nconst exts = computed(() => {\n return accept.split(',')\n})\nconst beforeUpload: UploadProps['beforeUpload'] = (file) => {\n const fileName = file.name.split('.')\n const fileExt = fileName.at(-1) ?? ''\n const isTypeOk = exts.value.includes(fileExt)\n const isSizeOk = file.size / 1024 / 1024 < size\n if (!isTypeOk) {\n ElMessage.error(`上传文件只支持 ${exts.value.join(' / ')} 格式!`)\n }\n if (!isSizeOk) {\n ElMessage.error(`上传文件大小不能超过 ${size}MB!`)\n }\n return isTypeOk && isSizeOk\n}\n\nconst onExceed: UploadProps['onExceed'] = () => {\n ElMessage.warning('文件上传超过限制')\n}\n\nconst onSuccess: UploadProps['onSuccess'] = (res, file, fileList) => {\n emit('onSuccess', res, file, fileList)\n}\n</script>\n\n<template>\n <ElUpload\n :headers=\"headers\"\n :action=\"action\"\n :data=\"data\"\n :name=\"name\"\n :before-upload=\"beforeUpload\"\n :on-exceed=\"onExceed\"\n :on-success=\"onSuccess\"\n :file-list=\"files\"\n :limit=\"max\"\n drag\n :class=\"ns.e('control')\"\n >\n <div class=\"slot\">\n <ElIcon :class=\"`${nsEl.namespace.value}-icon--upload`\">\n <UploadFilled />\n </ElIcon>\n <div :class=\"`${nsEl.namespace.value}-upload__text`\">\n 将文件拖到此处,或<em>点击上传</em>\n </div>\n </div>\n <template #tip>\n <div\n v-if=\"!notip\"\n :class=\"`${nsEl.namespace.value}-upload__tip`\"\n >\n <div style=\"display: inline-block;\">\n <ElAlert\n :title=\"`上传文件支持 ${exts.join(\n ' / ',\n )} 格式,单个文件大小不超过 ${size}MB,且文件数量不超过 ${max} 个`\"\n type=\"info\"\n show-icon\n :closable=\"false\"\n />\n </div>\n </div>\n </template>\n </ElUpload>\n</template>\n"],"names":["emit","__emit","ns","useNamespace","nsEl","useElNamespace","exts","computed","__props","accept","split","beforeUpload","file","fileExt","name","at","isTypeOk","value","includes","isSizeOk","size","ElMessage","error","join","onExceed","warning","onSuccess","res","fileList","_createBlock","_unref","ElUpload","headers","action","data","files","limit","max","drag","class","_normalizeClass","e","tip","notip","_createElementBlock","namespace","_createElementVNode","_hoisted_2","_createVNode","ElAlert","title","type","closable","_hoisted_1","ElIcon","UploadFilled"],"mappings":"uuBA+BA,MAAMA,EAAOC,EAEPC,EAAKC,EAAAA,aAAa,eAClBC,EAAOC,EAAAA,aAAe,eAEtBC,EAAOC,EAAAA,SAAS,IACbC,EAAAC,OAAOC,MAAM,MAEhBC,EAA6CC,IACjD,MACMC,EADWD,EAAKE,KAAKJ,MAAM,KACRK,IAAG,IAAO,GAC7BC,EAAWV,EAAKW,MAAMC,SAASL,GAC/BM,EAAWP,EAAKQ,KAAO,KAAO,KAAOZ,EAAAY,KAO3C,OANKJ,GACHK,YAAUC,MAAM,WAAWhB,EAAKW,MAAMM,KAAK,cAExCJ,GACHE,EAAAA,UAAUC,MAAM,cAAcd,EAAAY,WAEzBJ,GAAYG,GAGfK,EAAoC,KACxCH,EAAAA,UAAUI,QAAQ,aAGdC,EAAsC,CAACC,EAAKf,EAAMgB,KACtD5B,EAAK,YAAa2B,EAAKf,EAAMgB,gCAK7BC,EAAAA,YAsCWC,EAAAA,MAAAC,EAAAA,UAAA,CArCRC,QAASA,EAAAA,QACTC,OAAQA,EAAAA,OACRC,KAAMA,EAAAA,KACNpB,KAAMA,EAAAA,KACN,gBAAeH,EACf,YAAWa,EACX,aAAYE,EACZ,YAAWS,EAAAA,MACXC,MAAOC,EAAAA,IACRC,KAAA,GACCC,MAAKC,EAAAA,eAAEV,EAAAA,MAAA5B,GAAGuC,EAAC,cAUDC,cACT,IAcM,CAbGC,EAAAA,qDADTC,EAAAA,mBAcM,MAAA,OAZHL,MAAKC,EAAAA,eAAA,GAAKV,EAAAA,MAAA1B,GAAKyC,UAAU5B,uBAE1B6B,EAAAA,mBASM,MATNC,EASM,CARJC,cAOElB,EAAAA,MAAAmB,EAAAA,SAAA,CANCC,MAAK,UAAY5C,EAAAW,MAAKM,4BAAyDH,EAAAA,mBAAmBiB,EAAAA,QAGnGc,KAAK,OACL,YAAA,GACCC,UAAU,gDApBnB,IAOM,CAPNN,EAAAA,mBAOM,MAPNO,EAOM,CANJL,cAESlB,EAAAA,MAAAwB,EAAAA,QAAA,CAFAf,MAAKC,EAAAA,eAAA,GAAKV,EAAAA,MAAA1B,GAAKyC,UAAU5B,0CAChC,IAAgB,CAAhB+B,EAAAA,YAAgBlB,EAAAA,MAAAyB,qCAElBT,EAAAA,mBAEM,MAAA,CAFAP,MAAKC,EAAAA,eAAA,GAAKV,EAAAA,MAAA1B,GAAKyC,UAAU5B,sDAAsB,cAC1C,GAAA6B,EAAAA,mBAAa,UAAT,QAAI"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),t=require("../../../node_modules/.pnpm/@iconify_vue@5.0.0_vue@3.5.18_typescript@5.9.2_/node_modules/@iconify/vue/dist/iconify.cjs"),
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),t=require("../../../node_modules/.pnpm/@iconify_vue@5.0.0_vue@3.5.18_typescript@5.9.2_/node_modules/@iconify/vue/dist/iconify.cjs"),o=require("@qxs-bns/hooks");const l=["src"],n=["xlink:href"];var r=e.defineComponent({name:"QxsIcon",__name:"icon",props:{icon:{type:null,required:!0},flip:{type:null,required:!1,default:""},rotate:{type:Number,required:!1,default:0},color:{type:String,required:!1},size:{type:[String,Number],required:!1},localIconPrefix:{type:String,required:!1,default:"icon-"},fallback:{type:String,required:!1},loading:{type:String,required:!1}},setup(r){const a=e.useAttrs(),s=o.useNamespace("icon"),i=e.computed(()=>"object"==typeof r.icon||"function"==typeof r.icon),c=e.computed(()=>{if(i.value)return"component";const e=r.icon;return/^https?:\/\//.test(e)||(/^\.{1,2}\//.test(t=e)||t.startsWith("/")||t.includes("/"))?"img":/^i-[^:]+:[^:]+/.test(e)?"unocss":e.startsWith("i-")&&!e.includes(":")?"css":e.includes(":")&&!e.startsWith("i-")?"iconify":/^[\w-]+$/.test(e)&&!e.startsWith("i-")?"svg":"css";var t}),u=e.computed(()=>{if(i.value)return"";const e=r.icon;return"img"===c.value||"unocss"===c.value||c.value,e}),m=e.computed(()=>"css"===c.value?u.value.split(" ").filter(e=>e.trim()):[]);function d(e){return e?"number"==typeof e||/^\d+(?:\.\d+)?$/.test(e)?`${e}px`:e:""}const p=e.computed(()=>{const e=[];switch(r.flip){case"horizontal":e.push("rotateY(180deg)");break;case"vertical":e.push("rotateX(180deg)");break;case"both":e.push("rotateX(180deg)"),e.push("rotateY(180deg)")}r.rotate&&e.push(`rotate(${r.rotate%360}deg)`);let t=`${r.color?`color: ${r.color};`:""}${r.size?`font-size: ${d(r.size)};`:""}${e.length?`transform: ${e.join(" ")};`:""}`;const o=a.style;if(o)if("string"==typeof o)t+=o;else if("object"==typeof o){t+=Object.entries(o).map(([e,t])=>`${e.replace(/([A-Z])/g,"-$1").toLowerCase()}: ${t};`).join("")}return t}),f=e.ref(!0),y=e.ref(!1);function v(){f.value=!1,y.value=!1}function k(){f.value=!1,y.value=!0}return(o,r)=>(e.openBlock(),e.createElementBlock(e.Fragment,null,[e.createCommentVNode(" Vue组件 "),"component"===c.value?(e.openBlock(),e.createBlock(e.resolveDynamicComponent(o.icon),{key:0,class:e.normalizeClass([[e.unref(s).b()],"size-inherit shrink-0"]),style:e.normalizeStyle([p.value])},null,8,["class","style"])):"unocss"===c.value?(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createCommentVNode(" UnoCSS图标 "),e.createElementVNode("i",{class:e.normalizeClass([e.unref(s).b(),u.value]),style:e.normalizeStyle([p.value])},null,6)],2112)):"css"===c.value?(e.openBlock(),e.createElementBlock(e.Fragment,{key:2},[e.createCommentVNode(" CSS类图标 "),e.createElementVNode("i",{class:e.normalizeClass(["size-inherit shrink-0",[e.unref(s).b(),...m.value]]),style:e.normalizeStyle([p.value])},null,6)],2112)):"iconify"===c.value?(e.openBlock(),e.createElementBlock(e.Fragment,{key:3},[e.createCommentVNode(" Iconify图标 "),e.createVNode(e.unref(t.Icon),{class:e.normalizeClass(["size-inherit shrink-0",[e.unref(s).b()]]),icon:u.value,style:e.normalizeStyle([p.value])},null,8,["icon","class","style"])],2112)):"img"===c.value?(e.openBlock(),e.createElementBlock(e.Fragment,{key:4},[e.createCommentVNode(" 图片 "),e.createCommentVNode(" 加载中状态 "),f.value&&o.loading?(e.openBlock(),e.createElementBlock("i",{key:0,class:e.normalizeClass(o.loading)},null,2)):y.value&&o.fallback?(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createCommentVNode(" 错误状态 "),e.createElementVNode("i",{class:e.normalizeClass(o.fallback)},null,2)],2112)):e.createCommentVNode("v-if",!0),e.createCommentVNode(" 图片本体 "),e.createElementVNode("img",{src:u.value,class:e.normalizeClass(["size-inherit shrink-0",[e.unref(s).b()]]),style:e.normalizeStyle([p.value,{width:o.size?d(o.size):"auto",height:"auto"}]),onLoad:v,onError:k},null,46,l)],64)):u.value?(e.openBlock(),e.createElementBlock(e.Fragment,{key:5},[e.createCommentVNode(" SVG Sprite "),(e.openBlock(),e.createElementBlock("svg",{"aria-hidden":"true",class:e.normalizeClass([[e.unref(s).b()],"size-inherit shrink-0"]),style:e.normalizeStyle([p.value])},[e.createElementVNode("use",{"xlink:href":`#${o.localIconPrefix}${u.value}`},null,8,n)],6))],2112)):e.createCommentVNode("v-if",!0)],2112))}});exports.default=r;
|
2
2
|
//# sourceMappingURL=icon.vue.cjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"icon.vue.cjs","sources":["../../../../../../packages/components/src/icon/src/icon.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { Component, CSSProperties } from 'vue'\nimport { Icon } from '@iconify/vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { computed, ref, useAttrs } from 'vue'\n\ndefineOptions({\n name: 'QxsIcon',\n})\n\nconst {\n icon,\n flip = '',\n rotate = 0,\n color,\n size,\n localIconPrefix = 'icon-',\n fallback,\n loading,\n} = defineProps<PropsType>()\n\nconst attrs = useAttrs()\n\nconst ns = useNamespace('icon')\n\nexport interface PropsType {\n icon: string | Component\n flip?: 'horizontal' | 'vertical' | 'both' | '' | undefined\n rotate?: number\n color?: string\n size?: string | number\n localIconPrefix?: string\n // 新增功能:支持图片URL\n fallback?: string // 加载失败时的备用图标\n loading?: string // 加载中显示的图标\n}\n\nconst isComponentName = computed(() => typeof icon === 'object' || typeof icon === 'function')\n\nconst outputType = computed(() => {\n if (isComponentName.value) {\n return 'component'\n }\n\n const iconStr = icon as string\n\n // 检测是否为图片URL或路径\n const hasPathFeatures = (str: string) => {\n return /^\\.{1,2}\\//.test(str) || str.startsWith('/') || str.includes('/')\n }\n if (/^https?:\\/\\//.test(iconStr) || hasPathFeatures(iconStr)) {\n return 'img'\n }\n\n // 检测UnoCSS图标格式 (i-[provider]:[name])\n if (/^i-[^:]+:[^:]+/.test(iconStr)) {\n return 'unocss'\n }\n\n //
|
1
|
+
{"version":3,"file":"icon.vue.cjs","sources":["../../../../../../packages/components/src/icon/src/icon.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { Component, CSSProperties } from 'vue'\nimport { Icon } from '@iconify/vue'\nimport { useNamespace } from '@qxs-bns/hooks'\nimport { computed, ref, useAttrs } from 'vue'\n\ndefineOptions({\n name: 'QxsIcon',\n})\n\nconst {\n icon,\n flip = '',\n rotate = 0,\n color,\n size,\n localIconPrefix = 'icon-',\n fallback,\n loading,\n} = defineProps<PropsType>()\n\nconst attrs = useAttrs()\n\nconst ns = useNamespace('icon')\n\nexport interface PropsType {\n icon: string | Component\n flip?: 'horizontal' | 'vertical' | 'both' | '' | undefined\n rotate?: number\n color?: string\n size?: string | number\n localIconPrefix?: string\n // 新增功能:支持图片URL\n fallback?: string // 加载失败时的备用图标\n loading?: string // 加载中显示的图标\n}\n\nconst isComponentName = computed(() => typeof icon === 'object' || typeof icon === 'function')\n\nconst outputType = computed(() => {\n if (isComponentName.value) {\n return 'component'\n }\n\n const iconStr = icon as string\n\n // 检测是否为图片URL或路径\n const hasPathFeatures = (str: string) => {\n return /^\\.{1,2}\\//.test(str) || str.startsWith('/') || str.includes('/')\n }\n if (/^https?:\\/\\//.test(iconStr) || hasPathFeatures(iconStr)) {\n return 'img'\n }\n\n // 检测UnoCSS图标格式 (i-[provider]:[name])\n if (/^i-[^:]+:[^:]+/.test(iconStr)) {\n return 'unocss'\n }\n\n // 检测以i-开头的自定义CSS类图标(不包含冒号)\n if (iconStr.startsWith('i-') && !iconStr.includes(':')) {\n return 'css'\n }\n\n // 检测Iconify格式 (provider:name,但不以i-开头)\n if (iconStr.includes(':') && !iconStr.startsWith('i-')) {\n return 'iconify'\n }\n\n // 检测SVG sprite(单个单词,不包含空格和特殊字符,且不以i-开头)\n if (/^[\\w-]+$/.test(iconStr) && !iconStr.startsWith('i-')) {\n return 'svg'\n }\n\n // 其他情况都视为CSS类图标(包括多个类名等)\n return 'css'\n})\n\nconst outputName = computed(() => {\n if (isComponentName.value) {\n return ''\n }\n\n const iconStr = icon as string\n\n // 对于图片类型,直接返回URL\n if (outputType.value === 'img') {\n return iconStr\n }\n\n // 对于UnoCSS图标,直接返回类名\n if (outputType.value === 'unocss') {\n return iconStr\n }\n\n // 对于传统CSS图标,处理多个类名的情况\n if (outputType.value === 'css') {\n return iconStr\n }\n\n // 其他情况直接返回\n return iconStr\n})\n\n// 对于CSS类图标,将字符串拆分为类名数组\nconst cssClasses = computed(() => {\n if (outputType.value === 'css') {\n return outputName.value.split(' ').filter(cls => cls.trim())\n }\n return []\n})\n\n// 用正则匹配 size 是不是 number 值,再判断是否有 px 结尾的单位,没有则拼接\nfunction formatSize(size: string | number | undefined): string {\n if (!size) {\n return ''\n }\n\n // 如果是数字,直接添加 px\n if (typeof size === 'number') {\n return `${size}px`\n }\n\n // 如果是纯数字字符串,添加 px\n if (/^\\d+(?:\\.\\d+)?$/.test(size)) {\n return `${size}px`\n }\n\n // 如果已经有单位(px、em、rem等)或者不是纯数字,直接返回\n return size\n}\n\n// 统一的样式计算属性,适用于所有图标类型\n// 包含颜色、尺寸和变换(旋转、翻转)\n// Iconify 图标通过外层 i 标签应用这些样式\nconst style = computed(() => {\n const transform = [] as string[]\n switch (flip) {\n case 'horizontal':\n transform.push('rotateY(180deg)')\n break\n case 'vertical':\n transform.push('rotateX(180deg)')\n break\n case 'both':\n transform.push('rotateX(180deg)')\n transform.push('rotateY(180deg)')\n break\n // 对于 '' 和 undefined,不做任何处理\n }\n if (rotate) {\n transform.push(`rotate(${rotate % 360}deg)`)\n }\n\n // 构建基础样式\n let baseStyle = `${color ? `color: ${color};` : ''}${size ? `font-size: ${formatSize(size)};` : ''}${transform.length ? `transform: ${transform.join(' ')};` : ''}`\n\n // 拼接 attrs.style\n const attrsStyle = attrs.style\n if (attrsStyle) {\n if (typeof attrsStyle === 'string') {\n baseStyle += attrsStyle\n }\n else if (typeof attrsStyle === 'object') {\n // 处理对象形式的样式\n const styleEntries = Object.entries(attrsStyle as CSSProperties)\n const styleString = styleEntries\n .map(([key, value]) => `${key.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value};`)\n .join('')\n baseStyle += styleString\n }\n }\n\n return baseStyle\n})\n\n// 图片加载状态管理\nconst imageLoading = ref(true)\nconst imageError = ref(false)\n\nfunction handleImageLoad() {\n imageLoading.value = false\n imageError.value = false\n}\n\nfunction handleImageError() {\n imageLoading.value = false\n imageError.value = true\n}\n</script>\n\n<template>\n <!-- Vue组件 -->\n <component\n :is=\"icon\"\n v-if=\"outputType === 'component'\"\n :class=\"[ns.b()]\"\n :style=\"[style]\"\n class=\"size-inherit shrink-0\"\n />\n\n <!-- UnoCSS图标 -->\n <i\n v-else-if=\"outputType === 'unocss'\"\n :class=\"[ns.b(), outputName]\"\n :style=\"[style]\"\n />\n\n <!-- CSS类图标 -->\n <i\n v-else-if=\"outputType === 'css'\"\n class=\"size-inherit shrink-0\"\n :class=\"[ns.b(), ...cssClasses]\"\n :style=\"[style]\"\n />\n\n <!-- Iconify图标 -->\n <Icon\n v-else-if=\"outputType === 'iconify'\"\n class=\"size-inherit shrink-0\"\n :icon=\"outputName\"\n :class=\"[ns.b()]\"\n :style=\"[style]\"\n />\n\n <!-- 图片 -->\n <template v-else-if=\"outputType === 'img'\">\n <!-- 加载中状态 -->\n <i\n v-if=\"imageLoading && loading\"\n :class=\"loading\"\n />\n <!-- 错误状态 -->\n <i\n v-else-if=\"imageError && fallback\"\n :class=\"fallback\"\n />\n <!-- 图片本体 -->\n <img\n :src=\"outputName\"\n class=\"size-inherit shrink-0\"\n :class=\"[ns.b()]\"\n :style=\"[style, { width: size ? formatSize(size) : 'auto', height: 'auto' }]\"\n @load=\"handleImageLoad\"\n @error=\"handleImageError\"\n >\n </template>\n\n <!-- SVG Sprite -->\n <svg\n v-else-if=\"outputName\"\n aria-hidden=\"true\"\n :class=\"[ns.b()]\"\n :style=\"[style]\"\n class=\"size-inherit shrink-0\"\n >\n <use :xlink:href=\"`#${localIconPrefix}${outputName}`\" />\n </svg>\n</template>\n"],"names":["attrs","useAttrs","ns","useNamespace","isComponentName","computed","__props","icon","outputType","value","iconStr","test","str","startsWith","includes","outputName","cssClasses","split","filter","cls","trim","formatSize","size","style","transform","flip","push","rotate","baseStyle","color","length","join","attrsStyle","Object","entries","map","key","replace","toLowerCase","imageLoading","ref","imageError","handleImageLoad","handleImageError","_createCommentVNode","_openBlock","_createBlock","_resolveDynamicComponent","class","_normalizeClass","_unref","b","_createElementBlock","_Fragment","_createElementVNode","_createVNode","Icon","loading","fallback","src","width","height","onLoad","onError","localIconPrefix"],"mappings":"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"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("vue"),a=require("@qxs-bns/icons"),l=require("element-plus");const t={class:"image-slot"},r={style:{position:"relative",width:"100%",height:"100%"}},i=["src","alt"],o={key:2,class:"upload-progress"},n={key:3,class:"upload-debug"},s=["onClick"],u=["onClick"],c={class:"tip-content"};var d=e.defineComponent({name:"QxsImageUpload",__name:"image-upload",props:e.mergeModels({action:{type:String,required:!0},headers:{type:null,required:!1},data:{type:null,required:!1},name:{type:String,required:!1,default:"file"},size:{type:Number,required:!1,default:20},width:{type:Number,required:!1,default:160},height:{type:Number,required:!1,default:90},accept:{type:String,required:!1,default:"image/jpeg,image/jpg,image/png,image/gif"},placeholder:{type:String,required:!1,default:"上传图片"},notip:{type:Boolean,required:!1,default:!1},tipText:{type:String,required:!1,default:""},beforeUpload:{type:null,required:!1},disabled:{type:Boolean,required:!1,default:!1},limit:{type:Number,required:!1,default:1}},{fileList:{type:Array,default:()=>[]},fileListModifiers:{}}),emits:e.mergeModels(["success","remove"],["update:fileList"]),setup(d,{emit:p}){const m=p,v=e.useAttrs(),f=e.useModel(d,"fileList"),g=l.useNamespace("image-upload"),h=e.ref(!1),y=e.ref(0),k=e.ref(""),b=e.ref(0),C=e.ref(!1),_=e.computed(()=>g.cssVarBlock({ns:g.namespace.value,width:`${d.width}px`,height:`${d.height}px`})),x=e.computed(()=>d.accept.split(",").map(e=>e.split("/").pop())),B=e.computed(()=>{if(d.tipText)return d.tipText;return`支持 ${x.value.join(" / ")} 格式,大小不超过 ${d.size}MB`+(d.width&&d.height?`,建议尺寸 ${d.width}×${d.height}`:"")});function N(e){if(!e.url)return void console.warn("文件缺少 URL,无法预览:",e);let a=f.value.indexOf(e);-1===a&&(a=f.value.findIndex(a=>a.url===e.url)),y.value=Math.max(0,a),h.value=!0}function U(e){if(d.disabled)return;"uploading"===e.status&&C.value&&(C.value=!1,b.value=0,k.value&&(URL.revokeObjectURL(k.value),k.value="")),e.url?.startsWith("blob:")&&URL.revokeObjectURL(e.url);const a=f.value.indexOf(e);a>-1&&f.value.splice(a,1),m("remove",e)}function $(){h.value=!1}const z=e=>{if(!e?.name)return l.ElMessage.error("文件信息无效,请重新选择文件"),!1;const a=e.name.split(".").pop()?.toLowerCase()??"";if(!x.value.some(e=>e?.toLowerCase()===a))return l.ElMessage.error(`仅支持上传 ${x.value.join(" / ")} 格式的图片`),!1;if(e.size/1024/1024>d.size)return l.ElMessage.error(`图片大小不能超过 ${d.size}MB`),!1;try{k.value=URL.createObjectURL(e)}catch(e){console.warn("创建预览失败:",e)}return C.value=!0,b.value=0,!d.beforeUpload||d.beforeUpload(e)},E=e=>{b.value=Math.floor(e.percent)},L=(e,a,l)=>{const t=f.value.some(e=>e.uid===a.uid||e.name===a.name&&e.size===a.size);k.value&&(URL.revokeObjectURL(k.value),k.value=""),C.value=!1,b.value=0,t&&m("success",e,a,l)},V=(e,a,t)=>{const r=f.value.some(e=>e.uid===a.uid||e.name===a.name&&e.size===a.size);k.value&&(URL.revokeObjectURL(k.value),k.value=""),C.value=!1,b.value=0,r&&l.ElMessage.error(`图片上传失败:${e.message||"网络异常,请重试"}`)};return e.onUnmounted(()=>{k.value&&URL.revokeObjectURL(k.value),f.value.forEach(e=>{e.url?.startsWith("blob:")&&URL.revokeObjectURL(e.url)})}),(d,p)=>{const m=e.resolveComponent("QxsIcon");return e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(e.unref(g).e("container")),style:e.normalizeStyle(_.value)},[e.createVNode(e.unref(l.ElUpload),e.mergeProps(e.unref(v),{"file-list":f.value,"onUpdate:fileList":p[0]||(p[0]=e=>f.value=e),drag:"",limit:d.limit,"list-type":"picture-card",headers:d.headers,action:d.action,data:d.data,name:d.name,accept:d.accept,"before-upload":z,"on-progress":E,"on-preview":N,"on-success":L,"on-error":V,class:[e.unref(g).e("control"),d.limit<=f.value.length?e.unref(g).e("more-than-limit"):""],"on-remove":U}),{file:e.withCtx(({file:l})=>{return[e.createElementVNode("div",r,[l.url?(e.openBlock(),e.createElementBlock("img",{key:0,class:e.normalizeClass(`${e.unref(g).namespace.value}-upload-list__item-thumbnail`),src:l.url,alt:l.name||"图片"},null,10,i)):(e.openBlock(),e.createElementBlock("div",{key:1,class:e.normalizeClass(`${e.unref(g).namespace.value}-upload-list__item-thumbnail`),style:{display:"flex","align-items":"center","justify-content":"center",color:"#909399",background:"#f5f7fa"}}," 无图片 ",2)),e.createCommentVNode(" 上传进度条 "),C.value?(e.openBlock(),e.createElementBlock("div",o,[e.createElementVNode("div",{class:"upload-progress-bar",style:e.normalizeStyle({width:`${b.value}%`})},null,4)])):e.createCommentVNode("v-if",!0),e.createCommentVNode(" 调试信息 "),C.value?(e.openBlock(),e.createElementBlock("div",n,e.toDisplayString(b.value)+"% - "+e.toDisplayString((t=l.status,{ready:"准备中",uploading:"上传中",success:"上传成功",fail:"上传失败",error:"上传错误"}[t||""]||t||"未知状态")),1)):e.createCommentVNode("v-if",!0)]),e.createElementVNode("span",{class:e.normalizeClass(`${e.unref(g).namespace.value}-upload-list__item-actions`)},[l.url?(e.openBlock(),e.createElementBlock("span",{key:0,class:e.normalizeClass([`${e.unref(g).namespace.value}-upload-list__item-preview`,`${e.unref(g).namespace.value}-image-upload__action-btn`,`${e.unref(g).namespace.value}-image-upload__action-btn--preview`]),onClick:e=>N(l)},[e.createVNode(e.unref(a.ZoomIn),{size:"14px"})],10,s)):e.createCommentVNode("v-if",!0),l.url?(e.openBlock(),e.createElementBlock("span",{key:1,class:e.normalizeClass(`${e.unref(g).namespace.value}-upload-list__item-divider`)},null,2)):e.createCommentVNode("v-if",!0),e.createElementVNode("span",{class:e.normalizeClass([`${e.unref(g).namespace.value}-upload-list__item-delete`,`${e.unref(g).namespace.value}-image-upload__action-btn`,`${e.unref(g).namespace.value}-image-upload__action-btn--delete`,d.disabled?"is-disabled":""]),onClick:e=>U(l)},[e.createVNode(e.unref(a.Delete),{size:"14px"})],10,u)],2)];var t}),tip:e.withCtx(()=>[e.renderSlot(d.$slots,"tip",{},()=>[d.notip?e.createCommentVNode("v-if",!0):(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(`${e.unref(g).namespace.value}-upload__tip-text`)},[e.createElementVNode("div",c,e.toDisplayString(B.value),1)],2))])]),default:e.withCtx(()=>[e.renderSlot(d.$slots,"default",{},()=>[e.createElementVNode("div",t,[e.createVNode(m,{size:"32px",icon:e.unref(a.UploadImage)},null,8,["icon"]),e.createElementVNode("p",null,e.toDisplayString(d.placeholder),1)])])]),_:3},16,["file-list","limit","headers","action","data","name","accept","class"]),h.value?(e.openBlock(),e.createBlock(e.unref(l.ElImageViewer),{key:0,"url-list":f.value.map(e=>e.url).filter(Boolean),"initial-index":y.value,"show-progress":f.value.length>1,teleported:"",onClose:$},null,8,["url-list","initial-index","show-progress"])):e.createCommentVNode("v-if",!0)],6)}}});exports.default=d;
|
2
2
|
//# sourceMappingURL=image-upload.vue.cjs.map
|