vue3-smart-table 1.0.4 → 1.0.5

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/README.md CHANGED
@@ -175,7 +175,6 @@ onMounted(() => {
175
175
  ```txt
176
176
  src/
177
177
  ├─ components/SmartTable/ # 主组件(完全自包含)
178
- │ ├─ column/ # TableColumn 子组件
179
178
  │ ├─ hooks/ # 组件内部 Hooks(不对外暴露)
180
179
  │ ├─ renderers/ # 内置渲染器
181
180
  │ ├─ renderer.ts # 渲染器管理器
@@ -492,6 +491,7 @@ const columns = [
492
491
  previewSrcList?: string[] // 预览图片列表(可选)
493
492
  placeholder?: string // 无图片时的占位文本
494
493
  style?: string // 自定义样式
494
+ ... // el-Image属性都支持
495
495
  }
496
496
  }
497
497
  ```
@@ -1,2 +1,2 @@
1
- "use strict";var j=Object.defineProperty;var J=(n,e,r)=>e in n?j(n,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):n[e]=r;var A=(n,e,r)=>J(n,typeof e!="symbol"?e+"":e,r);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("vue"),w=require("element-plus"),D=require("@element-plus/icons-vue");class U{constructor(){A(this,"renderers",new Map)}register(e,r){this.renderers.has(e)&&process.env.NODE_ENV==="development"&&console.debug(`[SmartTable] Renderer "${e}" already registered, skipping.`),this.renderers.set(e,r)}registerMultiple(e){Object.entries(e).forEach(([r,o])=>{this.renderers.has(r)||this.renderers.set(r,o)})}get(e){return this.renderers.get(e)}has(e){return this.renderers.has(e)}unregister(e){return this.renderers.delete(e)}clear(){this.renderers.clear()}names(){return Array.from(this.renderers.keys())}}let R=null;function E(){return R||(R=new U),R}function T(n){return t.defineComponent({props:["row","col","onCellChange","onCellBlur","onCellEnter","onClick"],setup(e){return()=>t.h(n,e)}})}function B(n){return t.defineComponent({props:["row","col","onCellChange","onCellBlur","onCellEnter","onClick"],setup(e){return()=>n(e)}})}function H(n,e){if(process.env.NODE_ENV!=="production"&&e)switch(n){case"dict":(!e.options||!Array.isArray(e.options))&&console.warn("[SmartTable] 'dict' renderer requires 'options' array, received:",e.options);break;case"select":!e.options||!Array.isArray(e.options)?console.warn("[SmartTable] 'select' renderer requires 'options' array, received:",e.options):e.options.length===0&&console.warn("[SmartTable] 'select' renderer 'options' array is empty");break;case"map":(!e.options||typeof e.options!="object")&&console.warn("[SmartTable] 'map' renderer requires 'options' object, received:",e.options);break;case"link":(!e.href||typeof e.href!="string")&&console.warn("[SmartTable] 'link' renderer requires 'href' string, received:",e.href);break;case"input-number":e.min!==void 0&&e.max!==void 0&&e.min>e.max&&console.warn(`[SmartTable] 'input-number' renderer: min (${e.min}) should not be greater than max (${e.max})`);break}}function C(n,e){if(!(!n||!e))return e.split(".").reduce((r,o)=>r==null?void 0:r[o],n)}function P(n,e,r){if(!n||!e)return;const o=e.split("."),i=o.pop(),l=o.reduce((s,c)=>(s[c]||(s[c]={}),s[c]),n);l[i]=r}const Y=t.defineComponent({__name:"input",props:{row:{},col:{},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,r=t.ref(C(e.row,e.col.key));t.watch(r,l=>{P(e.row,e.col.key,l)});const o=()=>{var l;return(l=e.onCellBlur)==null?void 0:l.call(e,e.row,e.col)},i=()=>{var l;return(l=e.onCellEnter)==null?void 0:l.call(e,e.row,e.col)};return(l,s)=>{const c=t.resolveComponent("el-input");return t.openBlock(),t.createBlock(c,t.mergeProps({modelValue:r.value,"onUpdate:modelValue":s[0]||(s[0]=d=>r.value=d)},{placeholder:"",size:"small",clearable:!0,...n.col.renderProps},{onBlur:o,onKeyup:t.withKeys(i,["enter"])}),null,16,["modelValue"])}}}),G=t.defineComponent({__name:"inputNumber",props:{row:{},col:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,r=t.ref(C(e.row,e.col.key));t.watch(r,l=>{var s;P(e.row,e.col.key,l),(s=e.onCellChange)==null||s.call(e,e.row,e.col)});const o=()=>{var l;return(l=e.onCellBlur)==null?void 0:l.call(e,e.row,e.col)},i=()=>{var l;return(l=e.onCellEnter)==null?void 0:l.call(e,e.row,e.col)};return(l,s)=>{const c=t.resolveComponent("el-input-number");return t.openBlock(),t.createBlock(c,t.mergeProps({modelValue:r.value,"onUpdate:modelValue":s[0]||(s[0]=d=>r.value=d)},{min:0,max:99999,controls:!1,size:"small",...n.col.renderProps},{onBlur:o,onKeyup:t.withKeys(i,["enter"])}),null,16,["modelValue"])}}}),Q=t.defineComponent({__name:"select",props:{row:{},col:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,r=t.ref(C(e.row,e.col.key));t.watch(r,s=>{P(e.row,e.col.key,s)});const o=()=>{var s;return(s=e.onCellChange)==null?void 0:s.call(e,e.row,e.col)},i=()=>{var s;return(s=e.onCellBlur)==null?void 0:s.call(e,e.row,e.col)},l=()=>{var s;return(s=e.onCellEnter)==null?void 0:s.call(e,e.row,e.col)};return(s,c)=>{const d=t.resolveComponent("el-option"),g=t.resolveComponent("el-select");return t.openBlock(),t.createBlock(g,t.mergeProps({modelValue:r.value,"onUpdate:modelValue":c[0]||(c[0]=h=>r.value=h)},{placeholder:"请选择",size:"small",clearable:!0,...n.col.renderProps},{onChange:o,onBlur:i,onKeyup:t.withKeys(l,["enter"])}),{default:t.withCtx(()=>{var h;return[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(((h=n.col.renderProps)==null?void 0:h.options)||[],f=>(t.openBlock(),t.createBlock(d,{key:f.value,label:f.label,value:f.value},null,8,["label","value"]))),128))]}),_:1},16,["modelValue"])}}}),X=T(Y),Z=T(G),ee=T(Q),te=B(n=>{const e=n.col.renderProps||{},r=C(n.row,n.col.key);return t.h(w.ElButton,{type:e.type||"primary",...e,onClick:()=>{var o;return(o=n.onClick)==null?void 0:o.call(n,n.row,n.col)}},()=>e.label||r)}),ne=B(n=>{const e=n.col.renderProps||{},r=C(n.row,n.col.key);return t.h("a",{href:e.href||"#",target:e.blank?"_blank":"_self",style:e.style||"color:#409EFF;cursor:pointer;"},e.label||r)}),re=B(n=>{var r;const e=C(n.row,n.col.key);return t.h("div",{class:"line-clamp-2",innerHTML:e??"",...((r=n.col)==null?void 0:r.renderProps)||{}})}),le=B(n=>{const e=C(n.row,n.col.key)??"",r=n.col.renderProps??{},o={position:"absolute",right:"-5px",top:"50%",transform:"translateY(-50%)",cursor:"pointer",display:"none","font-size":"12px",color:r.iconColor||"#409EFF","user-select":"none"},i={"padding-right":"10px",display:"-webkit-box","-webkit-box-orient":"vertical","-webkit-line-clamp":r.lineClamp??2,overflow:"hidden",...r.textStyles};return t.h("div",{class:"st_copy_wrapper",style:"width: 100%; position: relative; display: inline-block;"},[t.h("span",{class:`st_copy_text ${r.textClass??""}`,style:i,title:e},e),e&&t.h("span",{class:"st_copy_btn",style:o,title:r.copyTitle||"复制",onClick:()=>{if(e)try{if(navigator.clipboard&&navigator.clipboard.writeText)navigator.clipboard.writeText(e).then(()=>{w.ElMessage.success(r.successText??"复制成功")}).catch(()=>{w.ElMessage.error(r.errorText??"复制失败")});else{const l=document.createElement("textarea");l.value=e,l.style.position="fixed",l.style.opacity="0",document.body.appendChild(l),l.select();const s=document.execCommand("copy");document.body.removeChild(l),s?w.ElMessage.success(r.successText??"复制成功"):w.ElMessage.error(r.errorText??"复制失败")}}catch{w.ElMessage.error(r.errorText??"复制失败")}}},[t.h(D.DocumentCopy,{style:"width: 1em; height: 1em;"})])].filter(Boolean))}),oe=B(n=>{var s;const e=C(n.row,n.col.key)??"",r=((s=n.col)==null?void 0:s.renderProps)||{},i=e?Array.isArray(e)?e.filter(c=>c&&typeof c=="string"):[e]:[];if(i.length===0)return r.placeholder||"";const l={width:r.width||"80px",height:r.height||"80px",marginRight:i.length>1?"4px":"0",...r.style||{}};return i.length===1?t.h(w.ElImage,{src:i[0],previewSrcList:r.previewSrcList||i,fit:r.fit||"contain",style:l,...r}):t.h("div",{class:"st_img_wrapper",style:"display: flex; align-items: center; position: relative"},[t.h(w.ElImage,{src:i[0],previewSrcList:r.previewSrcList||i,fit:r.fit||"contain",style:l,...r}),i.length>1&&t.h("span",{class:"st_img_total",style:"position: absolute; top: 0; right: 0; ",title:`${i.length}`},[t.h(D.CopyDocument,{style:"width: 1em; height: 1em; "})])])}),ie=B(n=>{const e=C(n.row,n.col.key)??"",r=n.col.renderProps||{},o=r.options??[],i=r.showValue??!1;if(e==null||e==="")return"";const l=Array.isArray(e)?e.map(String):[String(e)],s=o.filter(g=>l.includes(String(g.value))),c=l.filter(g=>!o.some(h=>String(h.value)===g)),d=s.map((g,h)=>t.h(w.ElTag,{key:g.value,type:g.listClass,class:g.cssClass,disableTransitions:!0},{default:()=>g.label+" "}));return i&&c.length>0&&d.push(t.h("span",{},c.join(" "))),t.h("div",{},d)}),se=B(n=>{var o;const e=C(n.row,n.col.key)??"",r=((o=n.col.renderProps)==null?void 0:o.options)??{};return e!=null?r[e]??"":""});function ae(n){return typeof n.formatter=="function"}const ce=B(n=>{var i;const{col:e,row:r}=n,o=C(n.row,n.col.key)??"";return ae(e)?(i=e.formatter)==null?void 0:i.call(e,o,r):o??""}),ue=B(n=>{const e=C(n.row,n.col.key)??"",r=n.col.renderProps||{};return e?/^https?:\/\//.test(e)?t.h(w.ElImage,{src:e,previewSrcList:[e],fit:"contain",style:"width:40px;height:40px",...r}):/^\s*<svg[\s\S]*<\/svg>\s*$/.test(e)?t.h("div",{innerHTML:e,style:`width:40px;height:40px;display:inline-block;${r.style||""}`,...r}):t.h("i",{class:e,style:`font-size:20px;${r.style||""}`,...r}):""}),F={input:X,"input-number":Z,select:ee,button:te,link:ne,html:re,copy:le,img:oe,dict:ie,map:se,formatter:ce,icon:ue};function N(n){n.registerMultiple(F)}function de(){return F}function fe(n,e=10,r=[]){const i="*:*:*",l=a=>{if(!a)return!0;const m=Array.isArray(a)?a:[a];return r.some(p=>p===i||m.includes(p))},s=t.computed(()=>n.some(a=>l(a.permission))),c=t.computed(()=>n.filter(m=>l(m.permission)).slice(0,e).reduce((m,p)=>m+(p.width??60),0)),d=(a,m)=>l(a.permission)&&(a.visible?a.visible(m):!0),g=a=>n.filter(p=>d(p,a)).slice(0,e).reduce((p,_)=>p+(_.width??60),0);return{hasAnyButton:s,optWidth:c,hasAnyVisibleButton:a=>a!=null&&a.length?a.some(m=>n.some(p=>d(p,m))):!1,getMaxOptWidth:a=>a!=null&&a.length?a.reduce((m,p)=>Math.max(m,g(p)),0):c.value,getVisibleButtons:a=>n.filter(m=>d(m,a)).slice(0,e)}}const me=["title"],pe=t.defineComponent({__name:"index",props:{col:{type:Object,required:!0},permissions:{type:Array,default:()=>[]},pagination:{type:Object,default:()=>({})}},emits:["cellBlur","cellEnter","cellChange","cellClick"],setup(n,{emit:e}){const r=n,o=e,i=u=>{var x,v;const y=(x=r.pagination)==null?void 0:x.page,b=(v=r.pagination)==null?void 0:v.size;return y&&b?(y-1)*b+u+1:u+1},{col:l}=t.toRefs(r),s=(u,y)=>o("cellChange",u,y),c=(u,y)=>o("cellBlur",u,y),d=(u,y)=>o("cellEnter",u,y),g=(u,y)=>o("cellClick",u,y);N(E());const h=t.computed(()=>{const u=E(),y={};return u.names().forEach(b=>{const x=u.get(b);x&&(y[b]=x)}),y}),{hasAnyButton:f,hasAnyVisibleButton:k,optWidth:a,getMaxOptWidth:m,getVisibleButtons:p}=fe(l.value.buttons||[],l.value.maxbtn??10,r.permissions||[]),_=t.computed(()=>(l.value.buttons||[]).length?(l.value.__rows||[]).length?k(l.value.__rows||[]):f.value:!1),M=t.computed(()=>l.value.__rows?m(l.value.__rows):a.value);function q(u){return!(u.type==="selection"||u.type==="index"||u.type==="operation"&&!_.value||u.visible===!1)}return(u,y)=>{const b=t.resolveComponent("el-table-column"),x=t.resolveComponent("el-button");return t.unref(l).type==="selection"?(t.openBlock(),t.createBlock(b,t.mergeProps({key:0,type:"selection"},t.unref(l).columnProps),null,16)):t.unref(l).type==="index"?(t.openBlock(),t.createBlock(b,t.mergeProps({key:1,type:"index",label:t.unref(l).label||"#",align:"center"},t.unref(l).columnProps),{default:t.withCtx(({$index:v})=>[t.createTextVNode(t.toDisplayString(i(v)),1)]),_:1},16,["label"])):t.unref(l).type==="operation"&&_.value?(t.openBlock(),t.createBlock(b,t.mergeProps({key:2,label:t.unref(l).label||"操作",align:"center"},{...t.unref(l).columnProps,width:M.value}),{default:t.withCtx(({row:v})=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(t.unref(p)(v),S=>(t.openBlock(),t.createBlock(x,{key:S.label,type:S.type||"primary",link:"",onClick:V=>S.action(v)},{default:t.withCtx(()=>[t.createTextVNode(t.toDisplayString(S.label),1)]),_:2},1032,["type","onClick"]))),128))]),_:1},16,["label"])):q(t.unref(l))?(t.openBlock(),t.createBlock(b,t.mergeProps({key:3,label:t.unref(l).label,align:"center"},t.unref(l).columnProps||{}),{default:t.withCtx(v=>{var S,V,$,I;return[t.unref(l).render==="slot"&&u.$slots[((S=t.unref(l))==null?void 0:S.slot)||t.unref(l).key]?t.renderSlot(u.$slots,((V=t.unref(l))==null?void 0:V.slot)||t.unref(l).key,t.normalizeProps(t.mergeProps({key:0},v))):t.unref(l).render&&h.value[t.unref(l).render]?(t.openBlock(),t.createBlock(t.resolveDynamicComponent(h.value[t.unref(l).render]),{key:1,row:v.row,col:t.unref(l),onCellChange:s,onCellBlur:c,onCellEnter:d,onClick:g},null,40,["row","col"])):(t.openBlock(),t.createElementBlock("span",{key:2,style:t.normalizeStyle((($=t.unref(l).renderProps)==null?void 0:$.style)||""),class:t.normalizeClass(((I=t.unref(l).renderProps)==null?void 0:I.class)||""),title:t.unref(C)(v.row,t.unref(l).key)},t.toDisplayString(t.unref(C)(v.row,t.unref(l).key)),15,me))]}),_:3},16,["label"])):t.createCommentVNode("",!0)}}});function L(n,e){if(!(e!=null&&e.length))return n;const r=new Map(e.map(o=>[o.key,o]));return n.map(o=>{const i=r.get(o.key);return i?{...o,visible:typeof i.visible=="boolean"?i.visible:o.visible}:o})}function ge(n,e){const{cacheKey:r,storage:o=localStorage}=e||{},i=r?o.getItem(r):null,l=t.ref(L(n,i?JSON.parse(i):[]));return t.watch(l,s=>{if(!r)return;const c=s.map(d=>({key:d.key,visible:d.visible,columnOpts:d.columnOpts}));o.setItem(r,JSON.stringify(c))},{deep:!0}),{columns:l,setColumns(s){l.value=L(n,s),r&&o.setItem(r,JSON.stringify(s))},resetColumns(){l.value=n,r&&o.removeItem(r)}}}const z=t.defineComponent({__name:"index",props:{data:{type:Array,default:()=>[]},columns:{type:Array,default:()=>[]},rowKey:{type:String,default:"id"},loading:{type:Boolean,default:!1},permissions:{type:Array,default:()=>[]},cacheKey:String,pagination:{type:Object,default:()=>({})}},emits:["update:columns","cellChange","cellBlur","cellEnter","cell-click"],setup(n,{expose:e,emit:r}){const o=n,i=r,{columns:l}=ge(o.columns,{cacheKey:o.cacheKey??""});t.watch(l,f=>i("update:columns",f),{deep:!0,immediate:!0});const s=(f,k)=>i("cellChange",f,k),c=(f,k)=>{i("cellBlur",f,k)},d=(f,k)=>{console.log("enter"),i("cellEnter",f,k)},g=(f,k)=>{k&&i("cell-click",f,k)},h=t.ref();return e({tableRef:h}),(f,k)=>{const a=t.resolveComponent("el-table"),m=t.resolveDirective("loading");return t.withDirectives((t.openBlock(),t.createBlock(a,t.mergeProps({ref_key:"tableRef",ref:h},f.$attrs,{data:n.data,"row-key":n.rowKey,class:"smart_table"}),{default:t.withCtx(()=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(t.unref(l),p=>(t.openBlock(),t.createBlock(pe,{key:p.key,col:p,permissions:n.permissions,pagination:n.pagination,onCellChange:s,onCellBlur:c,onCellEnter:d,onCellClick:g},t.createSlots({_:2},[t.renderList(t.unref(l),_=>({name:_.key,fn:t.withCtx(M=>[t.renderSlot(f.$slots,_.key,t.mergeProps({ref_for:!0},M))])}))]),1032,["col","permissions","pagination"]))),128))]),_:3},16,["data","row-key"])),[[m,n.loading]])}}}),K={defaultPagination:{page:1,size:10,total:0},defaultTableProps:{},defaultColumnProps:{}};class ye{constructor(){A(this,"config",{...K})}getConfig(){return{...this.config}}setConfig(e){this.config=this.mergeConfig(this.config,e),e.renderers&&E().registerMultiple(e.renderers)}get(e){return this.config[e]}reset(){this.config={...K}}mergeConfig(e,r){const o={...e};for(const i in r)r[i]&&typeof r[i]=="object"&&!Array.isArray(r[i])?o[i]=this.mergeConfig(e[i]||{},r[i]):o[i]=r[i];return o}}let O=null;function W(){return O||(O=new ye),O}function he(n){W().setConfig(n)}function Ce(){return W().getConfig()}function ke(n,e){return{key:n,...e}}exports.SmartTable=z;exports.builtInRenderers=F;exports.createFunctionalRenderer=B;exports.createRenderer=de;exports.default=z;exports.defineColumn=ke;exports.getRendererManager=E;exports.getSmartTableConfig=Ce;exports.registerBuiltInRenderers=N;exports.setSmartTableConfig=he;exports.validateRendererProps=H;exports.wrapSFCComponent=T;
1
+ "use strict";var Y=Object.defineProperty;var G=(n,e,r)=>e in n?Y(n,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):n[e]=r;var A=(n,e,r)=>G(n,typeof e!="symbol"?e+"":e,r);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("vue"),b=require("element-plus"),z=require("@element-plus/icons-vue");function I(n,e){if(!(e!=null&&e.length))return n;const r=new Map(e.map(o=>[o.key,o]));return n.map(o=>{const s=r.get(o.key);return s?{...o,visible:typeof s.visible=="boolean"?s.visible:o.visible}:o})}function Q(n,e){const{cacheKey:r,storage:o=localStorage}=e||{},s=r?o.getItem(r):null,l=t.ref(I(n,s?JSON.parse(s):[]));return t.watch(l,a=>{if(!r)return;const m=a.map(p=>({key:p.key,visible:p.visible,columnOpts:p.columnOpts}));o.setItem(r,JSON.stringify(m))},{deep:!0}),{columns:l,setColumns(a){l.value=I(n,a),r&&o.setItem(r,JSON.stringify(a))},resetColumns(){l.value=n,r&&o.removeItem(r)}}}function X(n,e=10,r=[]){const s="*:*:*",l=d=>{if(!d)return!0;const g=Array.isArray(d)?d:[d];return r.some(h=>h===s||g.includes(h))},a=t.computed(()=>n.some(d=>l(d.permission))),m=t.computed(()=>n.filter(g=>l(g.permission)).slice(0,e).reduce((g,h)=>g+(h.width??55),0)),p=(d,g)=>l(d.permission)&&(d.visible?d.visible(g):!0),y=d=>n.filter(h=>p(h,d)).slice(0,e).reduce((h,M)=>h+(M.width??55),0);return{hasAnyButton:a,optWidth:m,hasAnyVisibleButton:d=>d!=null&&d.length?d.some(g=>n.some(h=>p(h,g))):!1,getMaxOptWidth:d=>d!=null&&d.length?d.reduce((g,h)=>Math.max(g,y(h)),0):m.value,getVisibleButtons:d=>n.filter(g=>p(g,d)).slice(0,e)}}class Z{constructor(){A(this,"renderers",new Map)}register(e,r){this.renderers.has(e)&&process.env.NODE_ENV==="development"&&console.debug(`[SmartTable] Renderer "${e}" already registered, skipping.`),this.renderers.set(e,r)}registerMultiple(e){Object.entries(e).forEach(([r,o])=>{this.renderers.has(r)||this.renderers.set(r,o)})}get(e){return this.renderers.get(e)}has(e){return this.renderers.has(e)}unregister(e){return this.renderers.delete(e)}clear(){this.renderers.clear()}names(){return Array.from(this.renderers.keys())}}let F=null;function S(){return F||(F=new Z),F}function T(n){return t.defineComponent({props:["row","col","onCellChange","onCellBlur","onCellEnter","onClick"],setup(e){return()=>t.h(n,e)}})}function w(n){return t.defineComponent({props:["row","col","onCellChange","onCellBlur","onCellEnter","onClick"],setup(e){return()=>n(e)}})}function ee(n,e){if(process.env.NODE_ENV!=="production"&&e)switch(n){case"dict":(!e.options||!Array.isArray(e.options))&&console.warn("[SmartTable] 'dict' renderer requires 'options' array, received:",e.options);break;case"select":!e.options||!Array.isArray(e.options)?console.warn("[SmartTable] 'select' renderer requires 'options' array, received:",e.options):e.options.length===0&&console.warn("[SmartTable] 'select' renderer 'options' array is empty");break;case"map":(!e.options||typeof e.options!="object")&&console.warn("[SmartTable] 'map' renderer requires 'options' object, received:",e.options);break;case"link":(!e.href||typeof e.href!="string")&&console.warn("[SmartTable] 'link' renderer requires 'href' string, received:",e.href);break;case"input-number":e.min!==void 0&&e.max!==void 0&&e.min>e.max&&console.warn(`[SmartTable] 'input-number' renderer: min (${e.min}) should not be greater than max (${e.max})`);break}}function k(n,e){if(!(!n||!e))return e.split(".").reduce((r,o)=>r==null?void 0:r[o],n)}function P(n,e,r){if(!n||!e)return;const o=e.split("."),s=o.pop(),l=o.reduce((a,m)=>(a[m]||(a[m]={}),a[m]),n);l[s]=r}const te=t.defineComponent({__name:"input",props:{row:{},col:{},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,r=t.ref(k(e.row,e.col.key));t.watch(r,l=>{P(e.row,e.col.key,l)});const o=()=>{var l;return(l=e.onCellBlur)==null?void 0:l.call(e,e.row,e.col)},s=()=>{var l;return(l=e.onCellEnter)==null?void 0:l.call(e,e.row,e.col)};return(l,a)=>{const m=t.resolveComponent("el-input");return t.openBlock(),t.createBlock(m,t.mergeProps({modelValue:r.value,"onUpdate:modelValue":a[0]||(a[0]=p=>r.value=p)},{placeholder:"",size:"small",clearable:!0,...n.col.renderProps},{onBlur:o,onKeyup:t.withKeys(s,["enter"])}),null,16,["modelValue"])}}}),ne=t.defineComponent({__name:"inputNumber",props:{row:{},col:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,r=t.ref(k(e.row,e.col.key));t.watch(r,l=>{var a;P(e.row,e.col.key,l),(a=e.onCellChange)==null||a.call(e,e.row,e.col)});const o=()=>{var l;return(l=e.onCellBlur)==null?void 0:l.call(e,e.row,e.col)},s=()=>{var l;return(l=e.onCellEnter)==null?void 0:l.call(e,e.row,e.col)};return(l,a)=>{const m=t.resolveComponent("el-input-number");return t.openBlock(),t.createBlock(m,t.mergeProps({modelValue:r.value,"onUpdate:modelValue":a[0]||(a[0]=p=>r.value=p)},{min:0,max:99999,controls:!1,size:"small",...n.col.renderProps},{onBlur:o,onKeyup:t.withKeys(s,["enter"])}),null,16,["modelValue"])}}}),re=t.defineComponent({__name:"select",props:{row:{},col:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,r=t.ref(k(e.row,e.col.key));t.watch(r,a=>{P(e.row,e.col.key,a)});const o=()=>{var a;return(a=e.onCellChange)==null?void 0:a.call(e,e.row,e.col)},s=()=>{var a;return(a=e.onCellBlur)==null?void 0:a.call(e,e.row,e.col)},l=()=>{var a;return(a=e.onCellEnter)==null?void 0:a.call(e,e.row,e.col)};return(a,m)=>{const p=t.resolveComponent("el-option"),y=t.resolveComponent("el-select");return t.openBlock(),t.createBlock(y,t.mergeProps({modelValue:r.value,"onUpdate:modelValue":m[0]||(m[0]=C=>r.value=C)},{placeholder:"请选择",size:"small",clearable:!0,...n.col.renderProps},{onChange:o,onBlur:s,onKeyup:t.withKeys(l,["enter"])}),{default:t.withCtx(()=>{var C;return[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(((C=n.col.renderProps)==null?void 0:C.options)||[],_=>(t.openBlock(),t.createBlock(p,{key:_.value,label:_.label,value:_.value},null,8,["label","value"]))),128))]}),_:1},16,["modelValue"])}}}),oe=T(te),le=T(ne),ie=T(re),se=w(n=>{const e=n.col.renderProps||{},r=k(n.row,n.col.key);return t.h(b.ElButton,{type:e.type||"primary",...e,onClick:()=>{var o;return(o=n.onClick)==null?void 0:o.call(n,n.row,n.col)}},()=>e.label||r)}),ae=w(n=>{const e=n.col.renderProps||{},r=k(n.row,n.col.key);return t.h("a",{href:e.href||"#",target:e.blank?"_blank":"_self",style:e.style||"color:#409EFF;cursor:pointer;"},e.label||r)}),ce=w(n=>{var r;const e=k(n.row,n.col.key);return t.h("div",{class:"line-clamp-2",innerHTML:e??"",...((r=n.col)==null?void 0:r.renderProps)||{}})}),ue=w(n=>{const e=k(n.row,n.col.key)??"",r=n.col.renderProps??{},o={position:"absolute",right:"-5px",top:"50%",transform:"translateY(-50%)",cursor:"pointer",display:"none","font-size":"12px",color:r.iconColor||"#409EFF","user-select":"none"},s={"padding-right":"10px",display:"-webkit-box","-webkit-box-orient":"vertical","-webkit-line-clamp":r.lineClamp??2,overflow:"hidden",...r.textStyles};return t.h("div",{class:"st_copy_wrapper",style:"width: 100%; position: relative; display: inline-block;"},[t.h("span",{class:`st_copy_text ${r.textClass??""}`,style:s,title:e},e),e&&t.h("span",{class:"st_copy_btn",style:o,title:r.copyTitle||"复制",onClick:()=>{if(e)try{if(navigator.clipboard&&navigator.clipboard.writeText)navigator.clipboard.writeText(e).then(()=>{b.ElMessage.success(r.successText??"复制成功")}).catch(()=>{b.ElMessage.error(r.errorText??"复制失败")});else{const l=document.createElement("textarea");l.value=e,l.style.position="fixed",l.style.opacity="0",document.body.appendChild(l),l.select();const a=document.execCommand("copy");document.body.removeChild(l),a?b.ElMessage.success(r.successText??"复制成功"):b.ElMessage.error(r.errorText??"复制失败")}}catch{b.ElMessage.error(r.errorText??"复制失败")}}},[t.h(z.DocumentCopy,{style:"width: 1em; height: 1em;"})])].filter(Boolean))}),de=w(n=>{var a;const e=k(n.row,n.col.key)??"",r=((a=n.col)==null?void 0:a.renderProps)||{},s=e?Array.isArray(e)?e.filter(m=>m&&typeof m=="string"):[e]:[];if(s.length===0)return r.placeholder||"";const l={width:r.width||"80px",height:r.height||"80px",marginRight:s.length>1?"4px":"0",...r.style||{}};return s.length===1?t.h(b.ElImage,{src:s[0],previewSrcList:r.previewSrcList||s,previewTeleported:!0,fit:r.fit||"contain",style:l,...r}):t.h("div",{class:"st_img_wrapper",style:"display: flex; align-items: center; position: relative"},[t.h(b.ElImage,{src:s[0],previewSrcList:r.previewSrcList||s,previewTeleported:!0,fit:r.fit||"contain",style:l,...r}),s.length>1&&t.h("span",{class:"st_img_total",style:"position: absolute; top: 0; right: 0; ",title:`${s.length}`},[t.h(z.CopyDocument,{style:"width: 1em; height: 1em; "})])])}),me=w(n=>{const e=k(n.row,n.col.key)??"",r=n.col.renderProps||{},o=r.options??[],s=r.showValue??!1;if(e==null||e==="")return"";const l=Array.isArray(e)?e.map(String):[String(e)],a=o.filter(y=>l.includes(String(y.value))),m=l.filter(y=>!o.some(C=>String(C.value)===y)),p=a.map((y,C)=>t.h(b.ElTag,{key:y.value,type:y.listClass,class:y.cssClass,disableTransitions:!0},{default:()=>y.label+" "}));return s&&m.length>0&&p.push(t.h("span",{},m.join(" "))),t.h("div",{},p)}),pe=w(n=>{var o;const e=k(n.row,n.col.key)??"",r=((o=n.col.renderProps)==null?void 0:o.options)??{};return e!=null?r[e]??"":""});function fe(n){return typeof n.formatter=="function"}const ge=w(n=>{var s;const{col:e,row:r}=n,o=k(n.row,n.col.key)??"";return fe(e)?(s=e.formatter)==null?void 0:s.call(e,o,r):o??""}),ye=w(n=>{const e=k(n.row,n.col.key)??"",r=n.col.renderProps||{};return e?/^https?:\/\//.test(e)?t.h(b.ElImage,{src:e,previewSrcList:[e],previewTeleported:!0,fit:"contain",style:"width:40px;height:40px",...r}):/^\s*<svg[\s\S]*<\/svg>\s*$/.test(e)?t.h("div",{innerHTML:e,style:`width:40px;height:40px;display:inline-block;${r.style||""}`,...r}):t.h("i",{class:e,style:`font-size:20px;${r.style||""}`,...r}):""}),O={input:oe,"input-number":le,select:ie,button:se,link:ae,html:ce,copy:ue,img:de,dict:me,map:pe,formatter:ge,icon:ye};function N(n){n.registerMultiple(O)}function he(){return O}const ke=["title"],D=t.defineComponent({__name:"index",props:{data:{type:Array,default:()=>[]},columns:{type:Array,default:()=>[]},rowKey:{type:String,default:"id"},loading:{type:Boolean,default:!1},permissions:{type:Array,default:()=>[]},cacheKey:String,pagination:{type:Object,default:()=>({})}},emits:["update:columns","cellChange","cellBlur","cellEnter","cell-click"],setup(n,{expose:e,emit:r}){const o=n,s=r,{columns:l}=Q(o.columns,{cacheKey:o.cacheKey??""});t.watch(l,i=>s("update:columns",i),{deep:!0,immediate:!0}),t.watch(()=>o.data,i=>{i&&l.value.forEach(c=>{c.type==="operation"&&(c.__rows=i)})},{deep:!0,immediate:!0});const a=t.computed(()=>l.value.filter(i=>i.type==="selection")),m=t.computed(()=>l.value.filter(i=>i.type==="index")),p=t.computed(()=>l.value.filter(i=>i.type==="operation")),y=t.computed(()=>l.value.filter(i=>!(i.type==="selection"||i.type==="index"||i.type==="operation"||i.visible===!1))),C=i=>{var B,E;const c=(B=o.pagination)==null?void 0:B.page,f=(E=o.pagination)==null?void 0:E.size;return c&&f?(c-1)*f+i+1:i+1};N(S());const _=t.computed(()=>{const i=S(),c={};return i.names().forEach(f=>{const B=i.get(f);B&&(c[f]=B)}),c}),L=t.computed(()=>{const i=new Map;return p.value.forEach(c=>{const f=X(c.buttons||[],c.maxbtn??10,o.permissions||[]);i.set(c.key,f)}),i}),d=i=>L.value.get(i.key),g=i=>{const c=d(i);return c?i.__rows?c.getMaxOptWidth(i.__rows):c.optWidth.value:0},h=(i,c)=>{const f=d(i);return f?(i.buttons||[]).length?((i.__rows||[]).length,f.getVisibleButtons(c)):[]:[]},M=()=>p.value.filter(i=>{const c=d(i);return!c||!(i.buttons||[]).length?!1:(i.__rows||[]).length?c.hasAnyVisibleButton(i.__rows||[]):c.hasAnyButton.value}),q=(i,c)=>{s("cellChange",i,c)},j=(i,c)=>{s("cellBlur",i,c)},H=(i,c)=>{s("cellEnter",i,c)},J=(i,c)=>{c&&s("cell-click",i,c)},$=t.ref();return e({tableRef:$}),(i,c)=>{const f=t.resolveComponent("el-table-column"),B=t.resolveComponent("el-button"),E=t.resolveComponent("el-table"),U=t.resolveDirective("loading");return t.withDirectives((t.openBlock(),t.createBlock(E,t.mergeProps({ref_key:"tableRef",ref:$},i.$attrs,{data:n.data,"row-key":n.rowKey,class:"smart_table"}),t.createSlots({default:t.withCtx(()=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(a.value,u=>(t.openBlock(),t.createBlock(f,t.mergeProps({key:"selection",type:"selection"},{ref_for:!0},u.columnProps),null,16))),128)),(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(m.value,u=>(t.openBlock(),t.createBlock(f,t.mergeProps({key:"index",type:"index",label:u.label||"#",align:"center"},{ref_for:!0},u.columnProps),{default:t.withCtx(({$index:v})=>[t.createTextVNode(t.toDisplayString(C(v)),1)]),_:1},16,["label"]))),128)),(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(M(),u=>(t.openBlock(),t.createBlock(f,t.mergeProps({key:u.key,label:u.label||"操作",align:"center"},{ref_for:!0},{...u.columnProps,width:g(u)}),{default:t.withCtx(({row:v})=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(h(u,v),x=>(t.openBlock(),t.createBlock(B,{key:x.label,type:x.type||"primary",link:"",onClick:V=>x.action(v)},{default:t.withCtx(()=>[t.createTextVNode(t.toDisplayString(x.label),1)]),_:2},1032,["type","onClick"]))),128))]),_:2},1040,["label"]))),128)),(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(y.value,u=>(t.openBlock(),t.createBlock(f,t.mergeProps({key:u.key,label:u.label,align:"center"},{ref_for:!0},u.columnProps||{}),{default:t.withCtx(v=>{var x,V;return[u.render==="slot"?t.renderSlot(i.$slots,(u==null?void 0:u.slot)||u.key,t.mergeProps({key:0,ref_for:!0},v)):u.render&&_.value[u.render]?(t.openBlock(),t.createBlock(t.resolveDynamicComponent(_.value[u.render]),{key:1,row:v.row,col:u,onCellChange:q,onCellBlur:j,onCellEnter:H,onClick:J},null,40,["row","col"])):(t.openBlock(),t.createElementBlock("span",{key:2,style:t.normalizeStyle(((x=u.renderProps)==null?void 0:x.style)||""),class:t.normalizeClass(((V=u.renderProps)==null?void 0:V.class)||""),title:t.unref(k)(v.row,u.key)},t.toDisplayString(t.unref(k)(v.row,u.key)),15,ke))]}),_:2},1040,["label"]))),128))]),_:2},[t.renderList(y.value,u=>({name:u.key,fn:t.withCtx(v=>[t.renderSlot(i.$slots,u.key,t.normalizeProps(t.guardReactiveProps(v)))])}))]),1040,["data","row-key"])),[[U,n.loading]])}}}),K={defaultPagination:{page:1,size:10,total:0},defaultTableProps:{},defaultColumnProps:{}};class ve{constructor(){A(this,"config",{...K})}getConfig(){return{...this.config}}setConfig(e){this.config=this.mergeConfig(this.config,e),e.renderers&&S().registerMultiple(e.renderers)}get(e){return this.config[e]}reset(){this.config={...K}}mergeConfig(e,r){const o={...e};for(const s in r)r[s]&&typeof r[s]=="object"&&!Array.isArray(r[s])?o[s]=this.mergeConfig(e[s]||{},r[s]):o[s]=r[s];return o}}let R=null;function W(){return R||(R=new ve),R}function Ce(n){W().setConfig(n)}function be(){return W().getConfig()}function we(n,e){return{key:n,...e}}exports.SmartTable=D;exports.builtInRenderers=O;exports.createFunctionalRenderer=w;exports.createRenderer=he;exports.default=D;exports.defineColumn=we;exports.getRendererManager=S;exports.getSmartTableConfig=be;exports.registerBuiltInRenderers=N;exports.setSmartTableConfig=Ce;exports.validateRendererProps=ee;exports.wrapSFCComponent=T;
2
2
  //# sourceMappingURL=vue3-smart-table.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vue3-smart-table.cjs.js","sources":["../src/components/SmartTable/renderer.ts","../src/components/SmartTable/utils/path.ts","../src/components/SmartTable/renderers/input.vue","../src/components/SmartTable/renderers/inputNumber.vue","../src/components/SmartTable/renderers/select.vue","../src/components/SmartTable/renderers/index.ts","../src/components/SmartTable/hooks/useOperationColumn.ts","../src/components/SmartTable/column/index.vue","../src/components/SmartTable/hooks/useTableColumns.ts","../src/components/SmartTable/index.vue","../src/components/SmartTable/config.ts","../src/types/enhanced.ts"],"sourcesContent":["/**\r\n * SmartTable 内部渲染器管理系统\r\n * 移动到组件内部,保证组件的自包含性\r\n */\r\nimport { defineComponent, h, Component } from 'vue'\r\nimport type { Renderer } from './types'\r\n\r\n/**\r\n * 渲染器注册表接口\r\n */\r\nexport interface RendererRegistry {\r\n register(name: string, renderer: Renderer): void\r\n registerMultiple(renderers: Record<string, Renderer>): void\r\n get(name: string): Renderer | undefined\r\n has(name: string): boolean\r\n unregister(name: string): boolean\r\n clear(): void\r\n names(): string[]\r\n}\r\n\r\n/**\r\n * 渲染器管理器类\r\n */\r\nclass RendererManager implements RendererRegistry {\r\n private renderers: Map<string, Renderer> = new Map()\r\n\r\n register(name: string, renderer: Renderer): void {\r\n if (this.renderers.has(name)) {\r\n // 批量注册时不警告,只在单独注册时警告\r\n if (process.env.NODE_ENV === 'development') {\r\n console.debug(`[SmartTable] Renderer \"${name}\" already registered, skipping.`)\r\n }\r\n }\r\n this.renderers.set(name, renderer)\r\n }\r\n\r\n registerMultiple(renderers: Record<string, Renderer>): void {\r\n Object.entries(renderers).forEach(([name, renderer]) => {\r\n if (!this.renderers.has(name)) {\r\n this.renderers.set(name, renderer)\r\n }\r\n })\r\n }\r\n\r\n get(name: string): Renderer | undefined {\r\n return this.renderers.get(name)\r\n }\r\n\r\n has(name: string): boolean {\r\n return this.renderers.has(name)\r\n }\r\n\r\n unregister(name: string): boolean {\r\n return this.renderers.delete(name)\r\n }\r\n\r\n clear(): void {\r\n this.renderers.clear()\r\n }\r\n\r\n names(): string[] {\r\n return Array.from(this.renderers.keys())\r\n }\r\n}\r\n\r\n/**\r\n * 全局渲染器管理器单例\r\n */\r\nlet globalRendererManager: RendererManager | null = null\r\n\r\n/**\r\n * 获取渲染器管理器\r\n */\r\nexport function getRendererManager(): RendererManager {\r\n if (!globalRendererManager) {\r\n globalRendererManager = new RendererManager()\r\n }\r\n return globalRendererManager\r\n}\r\n\r\n/**\r\n * 包装 SFC 组件为渲染器\r\n */\r\nexport function wrapSFCComponent(comp: Component): Renderer {\r\n return defineComponent({\r\n props: ['row', 'col', 'onCellChange', 'onCellBlur', 'onCellEnter', 'onClick'],\r\n setup(props) {\r\n return () => h(comp, props)\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * 创建函数式渲染器\r\n */\r\nexport function createFunctionalRenderer(\r\n render: (props: {\r\n row: any\r\n col: any\r\n onCellChange?: (row: any, col: any) => void\r\n onCellBlur?: (row: any, col: any) => void\r\n onCellEnter?: (row: any, col: any) => void\r\n onClick?: (row: any, col: any) => void\r\n }) => any\r\n): Renderer {\r\n return defineComponent({\r\n props: ['row', 'col', 'onCellChange', 'onCellBlur', 'onCellEnter', 'onClick'],\r\n setup(props) {\r\n return () => render(props)\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * 验证渲染器配置\r\n * 在开发环境下验证 renderProps 的正确性\r\n */\r\nexport function validateRendererProps(\r\n rendererName: string,\r\n renderProps: Record<string, any> | undefined\r\n): void {\r\n if (process.env.NODE_ENV !== 'production' && renderProps) {\r\n switch (rendererName) {\r\n case 'dict':\r\n if (!renderProps.options || !Array.isArray(renderProps.options)) {\r\n console.warn(\r\n `[SmartTable] 'dict' renderer requires 'options' array, received:`,\r\n renderProps.options\r\n )\r\n }\r\n break\r\n\r\n case 'select':\r\n if (!renderProps.options || !Array.isArray(renderProps.options)) {\r\n console.warn(\r\n `[SmartTable] 'select' renderer requires 'options' array, received:`,\r\n renderProps.options\r\n )\r\n } else if (renderProps.options.length === 0) {\r\n console.warn(`[SmartTable] 'select' renderer 'options' array is empty`)\r\n }\r\n break\r\n\r\n case 'map':\r\n if (!renderProps.options || typeof renderProps.options !== 'object') {\r\n console.warn(\r\n `[SmartTable] 'map' renderer requires 'options' object, received:`,\r\n renderProps.options\r\n )\r\n }\r\n break\r\n\r\n case 'link':\r\n if (!renderProps.href || typeof renderProps.href !== 'string') {\r\n console.warn(\r\n `[SmartTable] 'link' renderer requires 'href' string, received:`,\r\n renderProps.href\r\n )\r\n }\r\n break\r\n\r\n case 'input-number':\r\n if (renderProps.min !== undefined && renderProps.max !== undefined) {\r\n if (renderProps.min > renderProps.max) {\r\n console.warn(\r\n `[SmartTable] 'input-number' renderer: min (${renderProps.min}) should not be greater than max (${renderProps.max})`\r\n )\r\n }\r\n }\r\n break\r\n }\r\n }\r\n}\r\n","/**\r\n * 安全获取对象深层属性\r\n * 支持 a.b.c / a.0.b\r\n */\r\nexport function getValueByPath(obj: any, path?: string) {\r\n if (!obj || !path) return undefined\r\n return path.split('.').reduce((acc, key) => acc?.[key], obj)\r\n }\r\n \r\n /**\r\n * 安全设置对象深层属性(用于可编辑表格)\r\n */\r\n export function setValueByPath(\r\n obj: any,\r\n path: string,\r\n value: any\r\n ) {\r\n if (!obj || !path) return\r\n const keys = path.split('.')\r\n const lastKey = keys.pop()!\r\n \r\n const target = keys.reduce((acc, key) => {\r\n if (!acc[key]) acc[key] = {}\r\n return acc[key]\r\n }, obj)\r\n \r\n target[lastKey] = value\r\n }\r\n ","<template>\n <el-input\n v-model=\"value\"\n v-bind=\"{ placeholder: '', size: 'small', clearable: true, ...col.renderProps }\"\n @blur=\"onBlur\"\n @keyup.enter=\"onEnter\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport type { ColumnConfig } from '../types'\nimport { getValueByPath, setValueByPath } from '../utils/path'\n\ninterface Props {\n readonly row: any\n readonly col: ColumnConfig\n onCellBlur?: (row: any, col: ColumnConfig) => void\n onCellEnter?: (row: any, col: ColumnConfig) => void\n}\n\nconst props = defineProps<Props>()\nconst value = ref(getValueByPath(props.row, props.col.key))\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n})\n\nconst onBlur = () => props.onCellBlur?.(props.row, props.col)\nconst onEnter = () => props.onCellEnter?.(props.row, props.col)\n</script>\n","<template>\n <el-input-number\n v-model=\"value\"\n v-bind=\"{ min: 0, max: 99999, controls: false, size: 'small', ...col.renderProps }\"\n @blur=\"onBlur\"\n @keyup.enter=\"onEnter\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport type { ColumnConfig } from '../types'\nimport { getValueByPath, setValueByPath } from '../utils/path'\n\ninterface Props {\n readonly row: any\n readonly col: ColumnConfig\n onCellChange?: (row: any, col: ColumnConfig) => void\n onCellBlur?: (row: any, col: ColumnConfig) => void\n onCellEnter?: (row: any, col: ColumnConfig) => void\n}\n\nconst props = defineProps<Props>()\nconst value = ref(getValueByPath(props.row, props.col.key))\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n props.onCellChange?.(props.row, props.col)\n})\n\nconst onBlur = () => props.onCellBlur?.(props.row, props.col)\nconst onEnter = () => props.onCellEnter?.(props.row, props.col)\n</script>\n","<template>\n <el-select\n v-model=\"value\"\n v-bind=\"{ placeholder: '请选择', size: 'small', clearable: true, ...col.renderProps }\"\n @change=\"onChange\"\n @blur=\"onBlur\"\n @keyup.enter=\"onEnter\"\n >\n <el-option\n v-for=\"opt in col.renderProps?.options || []\"\n :key=\"opt.value\"\n :label=\"opt.label\"\n :value=\"opt.value\"\n />\n </el-select>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport type { ColumnConfig } from '../types'\nimport { getValueByPath, setValueByPath } from '../utils/path'\n\ninterface Props {\n readonly row: any\n readonly col: ColumnConfig\n onCellChange?: (row: any, col: ColumnConfig) => void\n onCellBlur?: (row: any, col: ColumnConfig) => void\n onCellEnter?: (row: any, col: ColumnConfig) => void\n}\n\nconst props = defineProps<Props>()\nconst value = ref(getValueByPath(props.row, props.col.key))\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n})\n\nconst onChange = () => props.onCellChange?.(props.row, props.col)\nconst onBlur = () => props.onCellBlur?.(props.row, props.col)\nconst onEnter = () => props.onCellEnter?.(props.row, props.col)\n</script>\n","/**\r\n * 内置渲染器集合\r\n * 可以按需引入或批量注册\r\n */\r\nimport { h } from 'vue'\r\nimport { ElButton, ElTag, ElImage, ElMessage } from 'element-plus'\r\nimport { DocumentCopy, CopyDocument } from '@element-plus/icons-vue'\r\nimport type { ColumnConfig } from '../types'\r\nimport { getValueByPath } from '../utils/path'\r\nimport { wrapSFCComponent, createFunctionalRenderer } from '../renderer'\r\nimport EditableInput from './input.vue'\r\nimport EditableNumber from './inputNumber.vue'\r\nimport EditableSelect from './select.vue'\r\n\r\n/**\r\n * 包装 SFC 组件\r\n */\r\nconst input = wrapSFCComponent(EditableInput)\r\nconst inputNumber = wrapSFCComponent(EditableNumber)\r\nconst select = wrapSFCComponent(EditableSelect)\r\n\r\n/**\r\n * button 渲染器\r\n */\r\nconst button = createFunctionalRenderer((props) => {\r\n const rp = props.col.renderProps || {}\r\n const val = getValueByPath(props.row, props.col.key)\r\n return h(ElButton as any, {\r\n type: rp.type || 'primary',\r\n ...rp,\r\n onClick: () => props.onClick?.(props.row, props.col)\r\n }, () => rp.label || val)\r\n})\r\n\r\n/**\r\n * link 渲染器\r\n */\r\nconst link = createFunctionalRenderer((props) => {\r\n const rp = props.col.renderProps || {}\r\n const val = getValueByPath(props.row, props.col.key)\r\n return h('a', {\r\n href: rp.href || '#',\r\n target: rp.blank ? '_blank' : '_self',\r\n style: rp.style || 'color:#409EFF;cursor:pointer;',\r\n }, rp.label || val)\r\n})\r\n\r\n/**\r\n * html 渲染器\r\n */\r\nconst html = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key)\r\n return h('div', {\r\n class: 'line-clamp-2',\r\n innerHTML: val ?? '',\r\n ...(props.col?.renderProps || {})\r\n })\r\n})\r\n\r\n/**\r\n * copy 渲染器\r\n */\r\nconst copy = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.renderProps ?? {}\r\n const butStyle = {\r\n 'position': 'absolute',\r\n 'right': '-5px',\r\n 'top': '50%',\r\n 'transform': 'translateY(-50%)',\r\n 'cursor': 'pointer',\r\n 'display': 'none',\r\n 'font-size': '12px',\r\n 'color': rp.iconColor || '#409EFF',\r\n 'user-select': 'none'\r\n }\r\n const testStyle = {\r\n 'padding-right': '10px',\r\n 'display': '-webkit-box',\r\n '-webkit-box-orient': 'vertical',\r\n '-webkit-line-clamp': rp.lineClamp ?? 2,\r\n 'overflow': 'hidden',\r\n ...rp.textStyles\r\n }\r\n return h('div', {\r\n class: 'st_copy_wrapper',\r\n style: 'width: 100%; position: relative; display: inline-block;'\r\n },\r\n [\r\n h('span', {\r\n class: `st_copy_text ${rp.textClass ?? ''}`,\r\n style: testStyle,\r\n title: val\r\n }, val),\r\n val && h('span', {\r\n class: 'st_copy_btn',\r\n style: butStyle,\r\n title: rp.copyTitle || '复制',\r\n onClick: () => {\r\n if (!val) return\r\n try {\r\n if (navigator.clipboard && navigator.clipboard.writeText) {\r\n navigator.clipboard.writeText(val).then(() => {\r\n ElMessage.success(rp.successText ?? '复制成功')\r\n }).catch(() => {\r\n ElMessage.error(rp.errorText ?? '复制失败')\r\n })\r\n } else {\r\n const textarea = document.createElement('textarea')\r\n textarea.value = val\r\n textarea.style.position = 'fixed'\r\n textarea.style.opacity = '0'\r\n document.body.appendChild(textarea)\r\n textarea.select()\r\n const successful = document.execCommand('copy')\r\n document.body.removeChild(textarea)\r\n\r\n if (successful) {\r\n ElMessage.success(rp.successText ?? '复制成功')\r\n } else {\r\n ElMessage.error(rp.errorText ?? '复制失败')\r\n }\r\n }\r\n } catch (err) {\r\n ElMessage.error(rp.errorText ?? '复制失败')\r\n }\r\n }\r\n }, [h(DocumentCopy, {\r\n style: 'width: 1em; height: 1em;'\r\n })])\r\n ].filter(Boolean)\r\n )\r\n})\r\n\r\n/**\r\n * img 渲染器\r\n */\r\nconst img = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col?.renderProps || {}\r\n\r\n const getImageList = () => {\r\n if (!val) return []\r\n if (Array.isArray(val)) {\r\n return val.filter(item => item && typeof item === 'string')\r\n }\r\n return [val]\r\n }\r\n\r\n const imageList = getImageList()\r\n\r\n if (imageList.length === 0) {\r\n return rp.placeholder || ''\r\n }\r\n\r\n const defaultStyle = {\r\n width: rp.width || '80px',\r\n height: rp.height || '80px',\r\n marginRight: imageList.length > 1 ? '4px' : '0',\r\n ...(rp.style || {})\r\n }\r\n\r\n if (imageList.length === 1) {\r\n return h(ElImage, {\r\n src: imageList[0],\r\n previewSrcList: rp.previewSrcList || imageList,\r\n fit: rp.fit || 'contain',\r\n style: defaultStyle,\r\n ...rp\r\n })\r\n }\r\n\r\n return h('div',\r\n {\r\n class: 'st_img_wrapper',\r\n style: 'display: flex; align-items: center; position: relative'\r\n },\r\n [\r\n h(ElImage, {\r\n src: imageList[0],\r\n previewSrcList: rp.previewSrcList || imageList,\r\n fit: rp.fit || 'contain',\r\n style: defaultStyle,\r\n ...rp\r\n }),\r\n imageList.length > 1 && h('span', {\r\n class: 'st_img_total',\r\n style: `position: absolute; top: 0; right: 0; `,\r\n title: `${imageList.length}`\r\n }, [h(CopyDocument, { style: `width: 1em; height: 1em; ` })])\r\n ]\r\n )\r\n})\r\n\r\n/**\r\n * dict 渲染器\r\n */\r\nconst dict = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.renderProps || {}\r\n const options = rp.options ?? []\r\n const showValue = rp.showValue ?? false\r\n\r\n if (val === null || val === undefined || val === '') return ''\r\n\r\n const values = Array.isArray(val) ? val.map(String) : [String(val)]\r\n const matchedOptions = options.filter((opt: any) => values.includes(String(opt.value)))\r\n const unmatched = values.filter(v => !options.some((opt: any) => String(opt.value) === v))\r\n\r\n const children = matchedOptions.map((item: any, _index: number) => {\r\n return h(\r\n ElTag,\r\n { key: item.value, type: item.listClass, class: item.cssClass, disableTransitions: true },\r\n { default: () => item.label + ' ' }\r\n )\r\n })\r\n\r\n if (showValue && unmatched.length > 0) {\r\n children.push(h('span', {}, unmatched.join(' ')))\r\n }\r\n\r\n return h('div', {}, children)\r\n})\r\n\r\n/**\r\n * map 渲染器\r\n */\r\nconst map = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const options = (props.col.renderProps?.options ?? {}) as Record<string, any>\r\n return val != null ? options[val] ?? '' : ''\r\n})\r\n\r\n/**\r\n * formatter 渲染器\r\n */\r\nexport function isDataColumn(\r\n col: ColumnConfig\r\n): col is any {\r\n return typeof (col as any).formatter === 'function'\r\n}\r\n\r\nconst formatter = createFunctionalRenderer((props) => {\r\n const { col, row } = props\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n if (isDataColumn(col)) {\r\n return col.formatter?.(val, row)\r\n }\r\n return val ?? ''\r\n})\r\n\r\n/**\r\n * icon 渲染器\r\n */\r\nconst icon = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.renderProps || {}\r\n if (!val) return ''\r\n // 判断网络图片\r\n if (/^https?:\\/\\//.test(val)) {\r\n return h(ElImage, {\r\n src: val,\r\n previewSrcList: [val],\r\n fit: 'contain',\r\n style: 'width:40px;height:40px',\r\n ...rp\r\n })\r\n }\r\n // 判断 svg 源码\r\n if (/^\\s*<svg[\\s\\S]*<\\/svg>\\s*$/.test(val)) {\r\n return h('div', {\r\n innerHTML: val,\r\n style: `width:40px;height:40px;display:inline-block;${rp.style || ''}`,\r\n ...rp\r\n })\r\n }\r\n // 默认当作 iconfont\r\n return h('i', {\r\n class: val,\r\n style: `font-size:20px;${rp.style || ''}`,\r\n ...rp\r\n })\r\n})\r\n\r\n/**\r\n * 所有内置渲染器\r\n */\r\nexport const builtInRenderers = {\r\n input,\r\n 'input-number': inputNumber,\r\n select,\r\n button,\r\n link,\r\n html,\r\n copy,\r\n img,\r\n dict,\r\n map,\r\n formatter,\r\n icon,\r\n}\r\n\r\n/**\r\n * 安装所有内置渲染器\r\n */\r\nexport function registerBuiltInRenderers(registry: { registerMultiple: (renderers: Record<string, any>) => void }) {\r\n registry.registerMultiple(builtInRenderers)\r\n}\r\n\r\n/**\r\n * 创建默认渲染器集合(兼容旧 API)\r\n * @deprecated 建议使用插件化架构\r\n */\r\nexport function createRenderer() {\r\n return builtInRenderers\r\n}\r\n","import { computed } from 'vue'\r\n\r\nimport { ButtonConfig } from \"../types\"\r\n/**\r\n * useOperationColumn\r\n *\r\n * 操作列专用逻辑 Hook,负责:\r\n * 1. 根据权限判断操作列是否需要显示\r\n * 2. 计算操作列宽度(支持按钮自定义宽度)\r\n * 3. 支持行级 visible 配置\r\n * @param buttonConfigs 操作列按钮配置\r\n * @param maxbtn 操作列最多显示按钮数量(超过的不参与宽度计算)\r\n * @param userPermissions 当前用户权限列表\r\n */\r\nexport function useOperationColumn(\r\n buttonConfigs: ButtonConfig[],\r\n maxbtn = 10,\r\n userPermissions: string[] = []\r\n) {\r\n /** 默认按钮宽度 */\r\n const defaultWidth = 60\r\n\r\n /** 超级权限标识 */\r\n const all_permission = '*:*:*'\r\n\r\n /** --------------------------\r\n * 权限判断\r\n * -------------------------- */\r\n\r\n /**\r\n * 判断是否具备按钮权限\r\n *\r\n * 规则:\r\n * - permission 未配置 ⇒ 永远有权限\r\n * - permission 为 string | string[] ⇒ 与用户权限匹配\r\n */\r\n const hasPermi = (value?: string | string[]) => {\r\n if (!value) return true\r\n\r\n const permArray = Array.isArray(value) ? value : [value]\r\n return userPermissions.some(\r\n p => p === all_permission || permArray.includes(p)\r\n )\r\n }\r\n\r\n /** --------------------------\r\n * 仅基于权限(不考虑行级 visible)\r\n * 适用于:表格未加载数据时的判断\r\n * -------------------------- */\r\n\r\n /**\r\n * 是否至少存在一个有权限的按钮\r\n * 用于判断操作列是否需要渲染\r\n */\r\n const hasAnyButton = computed(() => {\r\n return buttonConfigs.some(btn => hasPermi(btn.permission))\r\n })\r\n\r\n /**\r\n * 操作列宽度(仅基于权限)\r\n * 用于无行数据时的兜底宽度计算\r\n */\r\n const optWidth = computed(() => {\r\n const permittedBtns = buttonConfigs\r\n .filter(btn => hasPermi(btn.permission))\r\n .slice(0, maxbtn)\r\n\r\n return permittedBtns.reduce(\r\n (sum, btn) => sum + (btn.width ?? defaultWidth),\r\n 0\r\n )\r\n })\r\n\r\n /** --------------------------\r\n * 权限 + 行级 visible\r\n * -------------------------- */\r\n\r\n /**\r\n * 判断某个按钮在某一行是否可见\r\n */\r\n const isButtonVisible = (btn: ButtonConfig, row: any) => {\r\n return (\r\n hasPermi(btn.permission) &&\r\n (btn.visible ? btn.visible(row) : true)\r\n )\r\n }\r\n\r\n /**\r\n * 单行操作列宽度\r\n */\r\n const optRowWidth = (row: any) => {\r\n const visibleBtns = buttonConfigs\r\n .filter(btn => isButtonVisible(btn, row))\r\n .slice(0, maxbtn)\r\n\r\n return visibleBtns.reduce(\r\n (sum, btn) => sum + (btn.width ?? defaultWidth),\r\n 0\r\n )\r\n }\r\n\r\n /**\r\n * 遍历所有行,获取最大操作列宽度\r\n */\r\n const getMaxOptWidth = (rows: any[]) => {\r\n if (!rows?.length) return optWidth.value\r\n return rows.reduce(\r\n (max, row) => Math.max(max, optRowWidth(row)),\r\n 0\r\n )\r\n }\r\n\r\n /**\r\n * 判断是否至少有一行存在可见按钮\r\n */\r\n const hasAnyVisibleButton = (rows: any[]) => {\r\n if (!rows?.length) return false\r\n return rows.some(row =>\r\n buttonConfigs.some(btn => isButtonVisible(btn, row))\r\n )\r\n }\r\n\r\n const getVisibleButtons = (row: any) => {\r\n return buttonConfigs\r\n .filter(btn => isButtonVisible(btn, row))\r\n .slice(0, maxbtn)\r\n }\r\n\r\n return {\r\n hasAnyButton,\r\n optWidth,\r\n hasAnyVisibleButton,\r\n getMaxOptWidth,\r\n getVisibleButtons\r\n }\r\n}\r\n","<template>\r\n <!-- ========== selection 列 ========== -->\r\n <el-table-column\r\n v-if=\"col.type === 'selection'\"\r\n type=\"selection\"\r\n v-bind=\"col.columnProps\"\r\n />\r\n\r\n <!-- ========== index 列 ========== -->\r\n <el-table-column\r\n v-else-if=\"col.type === 'index'\"\r\n type=\"index\"\r\n :label=\"col.label || '#'\"\r\n align=\"center\"\r\n v-bind=\"col.columnProps\"\r\n >\r\n <template #default=\"{ $index }\">\r\n {{ computeIndex($index) }}\r\n </template>\r\n </el-table-column>\r\n\r\n <!-- ========== operation 列 ========== -->\r\n <el-table-column\r\n v-else-if=\"col.type === 'operation' && showOperationColumn\"\r\n :label=\"col.label || '操作'\"\r\n align=\"center\"\r\n v-bind=\"{\r\n ...col.columnProps,\r\n width: operationWidth\r\n }\"\r\n >\r\n <template #default=\"{ row }\">\r\n <el-button\r\n v-for=\"btn in getVisibleButtons(row)\"\r\n :key=\"btn.label\"\r\n :type=\"btn.type || 'primary'\"\r\n link\r\n @click=\"btn.action(row)\"\r\n >\r\n {{ btn.label }}\r\n </el-button>\r\n </template>\r\n </el-table-column>\r\n\r\n <!-- ========== 普通列 / renderer / editable ========== -->\r\n <el-table-column\r\n v-else-if=\"isDataOrOperationColumn(col)\"\r\n :label=\"col.label\"\r\n align=\"center\"\r\n v-bind=\"col.columnProps || {}\"\r\n >\r\n \r\n <template #default=\"scope\">\r\n <!-- 父组件插槽优先 -->\r\n <template v-if=\"col.render === 'slot' && $slots[col?.slot || col.key]\">\r\n <slot :name=\"col?.slot || col.key\" v-bind=\"scope\" />\r\n </template>\r\n\r\n <!-- renderer -->\r\n <component\r\n v-else-if=\"col.render && renderer[col.render]\"\r\n :is=\"renderer[col.render]\"\r\n :row=\"scope.row\"\r\n :col=\"col\"\r\n :onCellChange=\"handleCellChange\"\r\n :onCellBlur=\"handleCellBlur\"\r\n :onCellEnter=\"handleCellEnter\"\r\n :onClick=\"handleCellClick\"\r\n />\r\n <!-- 默认文本 -->\r\n <span v-else\r\n :style=\"col.renderProps?.style || ''\"\r\n :class=\"col.renderProps?.class || ''\"\r\n :title=\"getValueByPath(scope.row, col.key)\">\r\n {{ getValueByPath(scope.row, col.key) }}\r\n </span>\r\n </template>\r\n </el-table-column>\r\n \r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, toRefs } from 'vue'\r\nimport type { PropType } from 'vue'\r\nimport type { ColumnConfig } from '../types'\r\nimport { getRendererManager } from '../renderer'\r\nimport { registerBuiltInRenderers } from '../renderers'\r\nimport { useOperationColumn } from '../hooks/useOperationColumn'\r\nimport { getValueByPath } from '../utils/path'\r\n\r\nconst props = defineProps({\r\n col: { type: Object as PropType<ColumnConfig>, required: true },\r\n permissions: { type: Array as PropType<string[]>, default: () => [] },\r\n pagination: { type: Object, default: () => ({}) },\r\n})\r\n\r\nconst emit = defineEmits(['cellBlur', 'cellEnter', 'cellChange', 'cellClick'])\r\n\r\nconst computeIndex = (index: number) => {\r\n const page = props.pagination?.page\r\n const size = props.pagination?.size\r\n return page && size ? (page - 1) * size + index + 1 : index + 1\r\n}\r\n\r\n/** 解构 col 响应式引用 */\r\nconst { col } = toRefs(props)\r\n\r\n/** ========== 事件统一上抛 ========== */\r\nconst handleCellChange = (row: any, key: string) => emit('cellChange', row, key)\r\nconst handleCellBlur = (row: any, key: string) => emit('cellBlur', row, key)\r\nconst handleCellEnter = (row: any, key: string) => emit('cellEnter', row, key)\r\nconst handleCellClick = (row: any, col: any) => emit('cellClick', row, col)\r\n\r\n/** ========== renderer 注册 ========== */\r\n// 注册内置渲染器(重复调用会自动跳过已存在的)\r\nregisterBuiltInRenderers(getRendererManager())\r\n\r\n// 获取所有渲染器(内置 + 自定义)\r\nconst renderer = computed(() => {\r\n const manager = getRendererManager()\r\n const allRenderers: Record<string, any> = {}\r\n\r\n // 合并内置渲染器和自定义渲染器\r\n manager.names().forEach((name: string) => {\r\n const r = manager.get(name)\r\n if (r) allRenderers[name] = r\r\n })\r\n\r\n return allRenderers\r\n})\r\n\r\n/** ========== operation 列逻辑 ========== */\r\nconst {\r\n hasAnyButton,\r\n hasAnyVisibleButton,\r\n optWidth,\r\n getMaxOptWidth,\r\n getVisibleButtons\r\n} = useOperationColumn(\r\n col.value.buttons || [],\r\n col.value.maxbtn ?? 10,\r\n props.permissions || []\r\n)\r\n\r\n/** 是否显示操作列 */\r\nconst showOperationColumn = computed(() => {\r\n const buttons = col.value.buttons || []\r\n if (!buttons.length) return false // 没有配置按钮直接隐藏\r\n const rows = col.value.__rows || []\r\n // 无行数据时,至少有一个按钮有权限就显示\r\n if (!rows.length) return hasAnyButton.value\r\n // 有行数据时,至少一行有可见按钮才显示\r\n return hasAnyVisibleButton(col.value.__rows || [])\r\n})\r\n\r\n/** 操作列宽度 */\r\nconst operationWidth = computed(() => {\r\n // 无行数据,用静态宽度\r\n if (!col.value.__rows) return optWidth.value\r\n // 有行数据,取最大宽度\r\n return getMaxOptWidth(col.value.__rows)\r\n})\r\n\r\nfunction isDataOrOperationColumn(c: ColumnConfig) {\r\n if (c.type === 'selection' || c.type === 'index') return false\r\n if (c.type === 'operation' && !showOperationColumn.value) return false\r\n if (c.visible === false) return false\r\n return true\r\n}\r\n</script>","import { ref, watch } from 'vue'\r\n\r\n\r\n/**\r\n * 合并默认列配置和缓存配置\r\n *\r\n * 设计原则:\r\n * 1️⃣ 列顺序:以 defaultColumns 为准\r\n * 2️⃣ 列增减:以 defaultColumns 为准\r\n * 3️⃣ 缓存只覆盖用户可配置字段(如 visible)\r\n */\r\nfunction mergeColumns(\r\n defaultColumns: any[],\r\n cacheColumns: Array<{ key: string; visible?: boolean }>\r\n) {\r\n if (!cacheColumns?.length) return defaultColumns\r\n\r\n // 建立 key => cache 映射表,提升查找效率\r\n const cacheMap = new Map(\r\n cacheColumns.map(c => [c.key, c])\r\n )\r\n\r\n return defaultColumns.map(col => {\r\n const cacheCol = cacheMap.get(col.key)\r\n\r\n // 只允许缓存覆盖「可配置字段」\r\n if (!cacheCol) return col\r\n\r\n return {\r\n ...col,\r\n visible:\r\n typeof cacheCol.visible === 'boolean'\r\n ? cacheCol.visible\r\n : col.visible\r\n }\r\n })\r\n}\r\n\r\n\r\n/**\r\n * useTableColumns\r\n *\r\n * 表格列管理 Hook\r\n *\r\n * 职责:\r\n * - 管理表格列顺序\r\n * - 管理列显示 / 隐藏\r\n * - 持久化用户配置\r\n */\r\nexport function useTableColumns(\r\n defaultColumns: any[],\r\n options?: {\r\n /** 缓存唯一标识 */\r\n cacheKey?: string\r\n /** 存储介质,默认 localStorage */\r\n storage?: Storage\r\n }\r\n) {\r\n\r\n /** 解构参数并设置默认值 */\r\n const { cacheKey, storage = localStorage } = options || {}\r\n\r\n /**\r\n * 如果没有 cacheKey,则不启用缓存\r\n * (例如公共页面、未登录页面)\r\n * 从缓存中读取列配置\r\n */\r\n const cache = cacheKey ? storage.getItem(cacheKey) : null\r\n\r\n /**\r\n * 响应式列配置\r\n * 初始化时合并默认列和缓存列\r\n */\r\n const columns = ref(\r\n mergeColumns(\r\n defaultColumns,\r\n cache ? JSON.parse(cache) : []\r\n )\r\n )\r\n\r\n /**\r\n * 监听列变化,自动写入缓存\r\n */\r\n watch(\r\n columns,\r\n (newVal: any) => {\r\n if (!cacheKey) return\r\n\r\n /**\r\n * ⚠️ 只保存“轻量配置”\r\n * 避免把 render / action / 函数序列化进 localStorage\r\n */\r\n const lightColumns = newVal.map((col: any) => ({\r\n key: col.key,\r\n visible: col.visible,\r\n columnOpts: col.columnOpts\r\n }))\r\n\r\n storage.setItem(\r\n cacheKey,\r\n JSON.stringify(lightColumns)\r\n )\r\n },\r\n { deep: true }\r\n )\r\n\r\n /**\r\n * 对外暴露的 API\r\n */\r\n return {\r\n /** 当前列配置(响应式) */\r\n columns,\r\n\r\n /**\r\n * 主动设置列配置\r\n * 常用于:列设置弹窗 / 拖拽排序完成\r\n */\r\n setColumns(newColumns: any[]) {\r\n columns.value = mergeColumns(\r\n defaultColumns,\r\n newColumns\r\n )\r\n\r\n if (cacheKey) {\r\n storage.setItem(\r\n cacheKey,\r\n JSON.stringify(newColumns)\r\n )\r\n }\r\n },\r\n\r\n /**\r\n * 重置为默认列配置\r\n */\r\n resetColumns() {\r\n columns.value = defaultColumns\r\n\r\n if (cacheKey) {\r\n storage.removeItem(cacheKey)\r\n }\r\n }\r\n }\r\n}\r\n","<template>\r\n <el-table ref=\"tableRef\"\r\n v-bind=\"$attrs\"\r\n :data=\"data\"\r\n :row-key=\"rowKey\"\r\n class=\"smart_table\"\r\n v-loading=\"loading\">\r\n <TableColumn \r\n v-for=\"col in cachedColumns\" \r\n :key=\"col.key\" \r\n :col=\"col\" \r\n :permissions=\"permissions\"\r\n :pagination=\"pagination\"\r\n @cell-change=\"handleCellChange\"\r\n @cell-blur=\"handleCellBlur\"\r\n @cell-enter=\"handleCellEnter\"\r\n @cell-click=\"handleCellClick\">\r\n <template v-for=\"col in cachedColumns\" #[col.key]=\"slotProps\">\r\n <slot :name=\"col.key\" v-bind=\"slotProps\" />\r\n </template>\r\n </TableColumn>\r\n </el-table>\r\n</template>\r\n\r\n<script setup lang=\"ts\" name=\"SmartTable\">\r\n import { PropType, ref, watch } from 'vue'\r\n import TableColumn from './column/index.vue'\r\n import type { BaseColumn, ColumnConfig } from './types'\r\n import { useTableColumns } from \"./hooks/useTableColumns\"\r\n\r\n const props = defineProps({\r\n data: { type: Array, default: () => [] },\r\n columns: { type: Array, default: () => [] },\r\n rowKey: { type: String, default: 'id' },\r\n loading: { type: Boolean, default: false },\r\n permissions: {\r\n type: Array as PropType<string[]>,\r\n default: () => []\r\n },\r\n cacheKey: String,\r\n pagination: { type: Object, default: () => ({}) },\r\n\r\n })\r\n \r\n const emit = defineEmits([\r\n 'update:columns',\r\n 'cellChange',\r\n 'cellBlur',\r\n 'cellEnter',\r\n 'cell-click',\r\n ])\r\n\r\n // ------------------ columns 处理 ------------------\r\n const { columns: cachedColumns } = useTableColumns(props.columns, {\r\n cacheKey: props.cacheKey ?? '',\r\n })\r\n watch(\r\n cachedColumns,\r\n (val: ColumnConfig[]) => emit(\"update:columns\", val),\r\n { deep: true, immediate: true },\r\n )\r\n\r\n // ----------------事件封装 ------------------\r\n const handleCellChange = (row: any, key: string) => emit('cellChange', row, key)\r\n const handleCellBlur = (row: any, key: string) => {\r\n emit('cellBlur', row, key)\r\n }\r\n const handleCellEnter = (row: any, key: string) => {\r\n console.log('enter')\r\n emit('cellEnter', row, key)\r\n }\r\n \r\n // SmartTable\r\n const handleCellClick = (row: any, col: any) => {\r\n if(!col) return\r\n emit('cell-click', row, col)\r\n }\r\n\r\n // el-table\r\n const tableRef = ref();\r\n defineExpose({\r\n tableRef,\r\n });\r\n\r\n</script>\r\n\r\n<style>\r\n .smart_table {\r\n width: 100%;\r\n }\r\n \r\n .st_copy_wrapper:hover .st_copy_btn {\r\n display: inline-block !important;\r\n }\r\n\r\n .st_copy_btn:hover {\r\n transform: translateY(-50%) scale(1.1);\r\n }\r\n</style>\r\n","/**\r\n * 全局配置管理\r\n */\r\nimport type { SmartTableConfig } from './types'\r\nimport { getRendererManager } from './renderer'\r\n\r\n/**\r\n * 默认配置\r\n */\r\nconst defaultConfig: SmartTableConfig = {\r\n defaultPagination: {\r\n page: 1,\r\n size: 10,\r\n total: 0\r\n },\r\n defaultTableProps: {},\r\n defaultColumnProps: {}\r\n}\r\n\r\n/**\r\n * 全局配置类\r\n */\r\nclass ConfigManager {\r\n private config: SmartTableConfig = { ...defaultConfig }\r\n\r\n /**\r\n * 获取所有配置\r\n */\r\n getConfig(): SmartTableConfig {\r\n return { ...this.config }\r\n }\r\n\r\n /**\r\n * 设置配置\r\n */\r\n setConfig(config: Partial<SmartTableConfig>): void {\r\n this.config = this.mergeConfig(this.config, config)\r\n\r\n // 如果有自定义渲染器,自动注册\r\n if (config.renderers) {\r\n const manager = getRendererManager()\r\n manager.registerMultiple(config.renderers)\r\n }\r\n }\r\n\r\n /**\r\n * 获取特定配置项\r\n */\r\n get<K extends keyof SmartTableConfig>(key: K): SmartTableConfig[K] {\r\n return this.config[key]\r\n }\r\n\r\n /**\r\n * 重置为默认配置\r\n */\r\n reset(): void {\r\n this.config = { ...defaultConfig }\r\n }\r\n\r\n /**\r\n * 深度合并配置\r\n */\r\n private mergeConfig(target: any, source: any): any {\r\n const result = { ...target }\r\n\r\n for (const key in source) {\r\n if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {\r\n result[key] = this.mergeConfig(target[key] || {}, source[key])\r\n } else {\r\n result[key] = source[key]\r\n }\r\n }\r\n\r\n return result\r\n }\r\n}\r\n\r\n/**\r\n * 全局配置管理器单例\r\n */\r\nlet globalConfigManager: ConfigManager | null = null\r\n\r\n/**\r\n * 获取全局配置管理器\r\n */\r\nexport function getConfigManager(): ConfigManager {\r\n if (!globalConfigManager) {\r\n globalConfigManager = new ConfigManager()\r\n }\r\n return globalConfigManager\r\n}\r\n\r\n/**\r\n * 安装插件(用于 Vue.use())\r\n */\r\nexport interface SmartTablePlugin {\r\n install: (options?: SmartTableConfig) => void\r\n}\r\n\r\n/**\r\n * 创建插件实例\r\n */\r\nexport function createSmartTablePlugin(defaultOptions?: SmartTableConfig): SmartTablePlugin {\r\n return {\r\n install(options?: SmartTableConfig) {\r\n const manager = getConfigManager()\r\n const config = { ...defaultOptions, ...options }\r\n if (config) {\r\n manager.setConfig(config)\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 全局配置快捷方法\r\n */\r\nexport function setSmartTableConfig(config: Partial<SmartTableConfig>): void {\r\n getConfigManager().setConfig(config)\r\n}\r\n\r\nexport function getSmartTableConfig(): SmartTableConfig {\r\n return getConfigManager().getConfig()\r\n}\r\n","/**\r\n * 增强类型系统 - 提供更好的类型推断\r\n */\r\nimport type { ColumnConfig, RendererName } from '../components/SmartTable/types'\r\n\r\n/**\r\n * 提取行数据的类型\r\n */\r\nexport type ExtractRowType<T> = T extends ColumnConfig<infer R> ? R : never\r\n\r\n/**\r\n * 根据列配置提取表格数据类型\r\n */\r\nexport type TableDataFromColumns<T extends ColumnConfig[]> = T extends (infer C)[]\r\n ? C extends ColumnConfig<infer R>\r\n ? R\r\n : any\r\n : any\r\n\r\n/**\r\n * 渲染器 Props 类型推断\r\n */\r\nexport type InferRendererProps<T extends RendererName> =\r\n T extends 'html'\r\n ? { style?: string; class?: string; [key: string]: any }\r\n : T extends 'copy'\r\n ? { successText?: string; errorText?: string; iconColor?: string; [key: string]: any }\r\n : T extends 'img'\r\n ? { width?: string | number; height?: string | number; fit?: string; previewSrcList?: string[]; [key: string]: any }\r\n : T extends 'dict'\r\n ? { options: Array<{ label: string; value: string | number; listClass?: string; cssClass?: string }>; showValue?: boolean }\r\n : T extends 'map'\r\n ? { options: Record<string | number, any> }\r\n : T extends 'input'\r\n ? { placeholder?: string; size?: 'small' | 'default' | 'large'; clearable?: boolean }\r\n : T extends 'select'\r\n ? { options: Array<{ label: string; value: string | number }>; placeholder?: string; clearable?: boolean }\r\n : { [key: string]: any }\r\n\r\n/**\r\n * 快捷创建列的辅助函数(类型安全简化版)\r\n */\r\nexport function defineColumn(\r\n key: string,\r\n config?: Partial<Omit<ColumnConfig, 'key'>>\r\n): ColumnConfig {\r\n return {\r\n key,\r\n ...config\r\n } as ColumnConfig\r\n}\r\n"],"names":["RendererManager","__publicField","name","renderer","renderers","globalRendererManager","getRendererManager","wrapSFCComponent","comp","defineComponent","props","h","createFunctionalRenderer","render","validateRendererProps","rendererName","renderProps","getValueByPath","obj","path","acc","key","setValueByPath","value","keys","lastKey","target","__props","ref","watch","v","onBlur","_a","onEnter","_openBlock","_createBlock","_component_el_input","_mergeProps","$event","_component_el_input_number","onChange","_component_el_select","_createElementBlock","_Fragment","opt","_component_el_option","input","EditableInput","inputNumber","EditableNumber","select","EditableSelect","button","rp","val","ElButton","link","html","copy","butStyle","testStyle","ElMessage","textarea","successful","DocumentCopy","img","imageList","item","defaultStyle","ElImage","CopyDocument","dict","options","showValue","values","matchedOptions","unmatched","children","_index","ElTag","map","isDataColumn","col","formatter","row","icon","builtInRenderers","registerBuiltInRenderers","registry","createRenderer","useOperationColumn","buttonConfigs","maxbtn","userPermissions","all_permission","hasPermi","permArray","hasAnyButton","computed","btn","optWidth","sum","isButtonVisible","optRowWidth","rows","max","emit","__emit","computeIndex","index","page","size","_b","toRefs","handleCellChange","handleCellBlur","handleCellEnter","handleCellClick","manager","allRenderers","r","hasAnyVisibleButton","getMaxOptWidth","getVisibleButtons","showOperationColumn","operationWidth","isDataOrOperationColumn","c","_unref","_component_el_table_column","_withCtx","$index","_createTextVNode","_toDisplayString","_renderList","_component_el_button","scope","$slots","_renderSlot","_ctx","_normalizeProps","_resolveDynamicComponent","_normalizeStyle","_normalizeClass","_hoisted_1","mergeColumns","defaultColumns","cacheColumns","cacheMap","cacheCol","useTableColumns","cacheKey","storage","cache","columns","newVal","lightColumns","newColumns","cachedColumns","tableRef","__expose","_withDirectives","_component_el_table","$attrs","TableColumn","slotProps","defaultConfig","ConfigManager","config","source","result","globalConfigManager","getConfigManager","setSmartTableConfig","getSmartTableConfig","defineColumn"],"mappings":"sWAuBA,MAAMA,CAA4C,CAAlD,cACUC,EAAA,qBAAuC,KAE/C,SAASC,EAAcC,EAA0B,CAC3C,KAAK,UAAU,IAAID,CAAI,GAErB,QAAQ,IAAI,WAAa,eAC3B,QAAQ,MAAM,0BAA0BA,CAAI,iCAAiC,EAGjF,KAAK,UAAU,IAAIA,EAAMC,CAAQ,CACnC,CAEA,iBAAiBC,EAA2C,CAC1D,OAAO,QAAQA,CAAS,EAAE,QAAQ,CAAC,CAACF,EAAMC,CAAQ,IAAM,CACjD,KAAK,UAAU,IAAID,CAAI,GAC1B,KAAK,UAAU,IAAIA,EAAMC,CAAQ,CAErC,CAAC,CACH,CAEA,IAAID,EAAoC,CACtC,OAAO,KAAK,UAAU,IAAIA,CAAI,CAChC,CAEA,IAAIA,EAAuB,CACzB,OAAO,KAAK,UAAU,IAAIA,CAAI,CAChC,CAEA,WAAWA,EAAuB,CAChC,OAAO,KAAK,UAAU,OAAOA,CAAI,CACnC,CAEA,OAAc,CACZ,KAAK,UAAU,MAAA,CACjB,CAEA,OAAkB,CAChB,OAAO,MAAM,KAAK,KAAK,UAAU,MAAM,CACzC,CACF,CAKA,IAAIG,EAAgD,KAK7C,SAASC,GAAsC,CACpD,OAAKD,IACHA,EAAwB,IAAIL,GAEvBK,CACT,CAKO,SAASE,EAAiBC,EAA2B,CAC1D,OAAOC,kBAAgB,CACrB,MAAO,CAAC,MAAO,MAAO,eAAgB,aAAc,cAAe,SAAS,EAC5E,MAAMC,EAAO,CACX,MAAO,IAAMC,EAAAA,EAAEH,EAAME,CAAK,CAC5B,CAAA,CACD,CACH,CAKO,SAASE,EACdC,EAQU,CACV,OAAOJ,kBAAgB,CACrB,MAAO,CAAC,MAAO,MAAO,eAAgB,aAAc,cAAe,SAAS,EAC5E,MAAMC,EAAO,CACX,MAAO,IAAMG,EAAOH,CAAK,CAC3B,CAAA,CACD,CACH,CAMO,SAASI,EACdC,EACAC,EACM,CACN,GAAI,QAAQ,IAAI,WAAa,cAAgBA,EAC3C,OAAQD,EAAA,CACN,IAAK,QACC,CAACC,EAAY,SAAW,CAAC,MAAM,QAAQA,EAAY,OAAO,IAC5D,QAAQ,KACN,mEACAA,EAAY,OAAA,EAGhB,MAEF,IAAK,SACC,CAACA,EAAY,SAAW,CAAC,MAAM,QAAQA,EAAY,OAAO,EAC5D,QAAQ,KACN,qEACAA,EAAY,OAAA,EAELA,EAAY,QAAQ,SAAW,GACxC,QAAQ,KAAK,yDAAyD,EAExE,MAEF,IAAK,OACC,CAACA,EAAY,SAAW,OAAOA,EAAY,SAAY,WACzD,QAAQ,KACN,mEACAA,EAAY,OAAA,EAGhB,MAEF,IAAK,QACC,CAACA,EAAY,MAAQ,OAAOA,EAAY,MAAS,WACnD,QAAQ,KACN,iEACAA,EAAY,IAAA,EAGhB,MAEF,IAAK,eACCA,EAAY,MAAQ,QAAaA,EAAY,MAAQ,QACnDA,EAAY,IAAMA,EAAY,KAChC,QAAQ,KACN,8CAA8CA,EAAY,GAAG,qCAAqCA,EAAY,GAAG,GAAA,EAIvH,KAAA,CAGR,CCxKO,SAASC,EAAeC,EAAUC,EAAe,CACpD,GAAI,GAACD,GAAO,CAACC,GACb,OAAOA,EAAK,MAAM,GAAG,EAAE,OAAO,CAACC,EAAKC,IAAQD,GAAA,YAAAA,EAAMC,GAAMH,CAAG,CAC7D,CAKO,SAASI,EACdJ,EACAC,EACAI,EACA,CACA,GAAI,CAACL,GAAO,CAACC,EAAM,OACnB,MAAMK,EAAOL,EAAK,MAAM,GAAG,EACrBM,EAAUD,EAAK,IAAA,EAEfE,EAASF,EAAK,OAAO,CAACJ,EAAKC,KAC1BD,EAAIC,CAAG,IAAGD,EAAIC,CAAG,EAAI,CAAA,GACnBD,EAAIC,CAAG,GACbH,CAAG,EAENQ,EAAOD,CAAO,EAAIF,CACpB,iICNF,MAAMb,EAAQiB,EACRJ,EAAQK,EAAAA,IAAIX,EAAeP,EAAM,IAAKA,EAAM,IAAI,GAAG,CAAC,EAE1DmB,QAAMN,EAAQO,GAAM,CAClBR,EAAeZ,EAAM,IAAKA,EAAM,IAAI,IAAKoB,CAAC,CAC5C,CAAC,EAED,MAAMC,EAAS,IAAA,OAAM,OAAAC,EAAAtB,EAAM,aAAN,YAAAsB,EAAA,KAAAtB,EAAmBA,EAAM,IAAKA,EAAM,MACnDuB,EAAU,IAAA,OAAM,OAAAD,EAAAtB,EAAM,cAAN,YAAAsB,EAAA,KAAAtB,EAAoBA,EAAM,IAAKA,EAAM,2DA5BzD,OAAAwB,YAAA,EAAAC,cAKEC,EALFC,EAAAA,WAKE,YAJSd,EAAA,2CAAAA,EAAK,MAAAe,EAAA,EACgD,CAAA,YAAA,GAAA,KAAA,QAAA,UAAA,GAAA,GAAAX,EAAA,IAAI,WAAA,EAAW,CAC5E,OAAAI,EACA,mBAAaE,EAAO,CAAA,OAAA,CAAA,CAAA,4LCiBzB,MAAMvB,EAAQiB,EACRJ,EAAQK,EAAAA,IAAIX,EAAeP,EAAM,IAAKA,EAAM,IAAI,GAAG,CAAC,EAE1DmB,QAAMN,EAAQO,GAAM,OAClBR,EAAeZ,EAAM,IAAKA,EAAM,IAAI,IAAKoB,CAAC,GAC1CE,EAAAtB,EAAM,eAAN,MAAAsB,EAAA,KAAAtB,EAAqBA,EAAM,IAAKA,EAAM,IACxC,CAAC,EAED,MAAMqB,EAAS,IAAA,OAAM,OAAAC,EAAAtB,EAAM,aAAN,YAAAsB,EAAA,KAAAtB,EAAmBA,EAAM,IAAKA,EAAM,MACnDuB,EAAU,IAAA,OAAM,OAAAD,EAAAtB,EAAM,cAAN,YAAAsB,EAAA,KAAAtB,EAAoBA,EAAM,IAAKA,EAAM,kEA9BzD,OAAAwB,YAAA,EAAAC,cAKEI,EALFF,EAAAA,WAKE,YAJSd,EAAA,2CAAAA,EAAK,MAAAe,EAAA,EACmD,CAAA,IAAA,EAAA,IAAA,MAAA,SAAA,GAAA,KAAA,QAAA,GAAAX,EAAA,IAAI,aAAW,CAC/E,OAAAI,EACA,mBAAaE,EAAO,CAAA,OAAA,CAAA,CAAA,uLCyBzB,MAAMvB,EAAQiB,EACRJ,EAAQK,EAAAA,IAAIX,EAAeP,EAAM,IAAKA,EAAM,IAAI,GAAG,CAAC,EAE1DmB,QAAMN,EAAQO,GAAM,CAClBR,EAAeZ,EAAM,IAAKA,EAAM,IAAI,IAAKoB,CAAC,CAC5C,CAAC,EAED,MAAMU,EAAW,IAAA,OAAM,OAAAR,EAAAtB,EAAM,eAAN,YAAAsB,EAAA,KAAAtB,EAAqBA,EAAM,IAAKA,EAAM,MACvDqB,EAAS,IAAA,OAAM,OAAAC,EAAAtB,EAAM,aAAN,YAAAsB,EAAA,KAAAtB,EAAmBA,EAAM,IAAKA,EAAM,MACnDuB,EAAU,IAAA,OAAM,OAAAD,EAAAtB,EAAM,cAAN,YAAAsB,EAAA,KAAAtB,EAAoBA,EAAM,IAAKA,EAAM,8FAtCzD,OAAAwB,YAAA,EAAAC,cAaYM,EAbZJ,EAAAA,WAaY,YAZDd,EAAA,2CAAAA,EAAK,MAAAe,EAAA,EACmD,CAAA,YAAA,MAAA,KAAA,QAAA,UAAA,GAAA,GAAAX,EAAA,IAAI,WAAA,EAAW,CAC/E,SAAAa,EACA,OAAAT,EACA,mBAAaE,EAAO,CAAA,OAAA,CAAA,CAAA,sBAGnB,IAAA,OAA6C,QAD/CC,EAAAA,UAAA,EAAA,EAAAQ,qBAKEC,EAAAA,6BAJcX,EAAAL,EAAA,IAAI,cAAJ,YAAAK,EAAiB,aAAxBY,kBADTT,EAAAA,YAKEU,EAAA,CAHC,IAAKD,EAAI,MACT,MAAOA,EAAI,MACX,MAAOA,EAAI,KAAA,mECKZE,EAAQvC,EAAiBwC,CAAa,EACtCC,EAAczC,EAAiB0C,CAAc,EAC7CC,GAAS3C,EAAiB4C,CAAc,EAKxCC,GAASxC,EAA0BF,GAAU,CACjD,MAAM2C,EAAK3C,EAAM,IAAI,aAAe,CAAA,EAC9B4C,EAAMrC,EAAeP,EAAM,IAAKA,EAAM,IAAI,GAAG,EACnD,OAAOC,EAAAA,EAAE4C,EAAAA,SAAiB,CACxB,KAAMF,EAAG,MAAQ,UACjB,GAAGA,EACH,QAAS,IAAA,OAAM,OAAArB,EAAAtB,EAAM,UAAN,YAAAsB,EAAA,KAAAtB,EAAgBA,EAAM,IAAKA,EAAM,KAAG,EAClD,IAAM2C,EAAG,OAASC,CAAG,CAC1B,CAAC,EAKKE,GAAO5C,EAA0BF,GAAU,CAC/C,MAAM2C,EAAK3C,EAAM,IAAI,aAAe,CAAA,EAC9B4C,EAAMrC,EAAeP,EAAM,IAAKA,EAAM,IAAI,GAAG,EACnD,OAAOC,EAAAA,EAAE,IAAK,CACZ,KAAM0C,EAAG,MAAQ,IACjB,OAAQA,EAAG,MAAQ,SAAW,QAC9B,MAAOA,EAAG,OAAS,+BAAA,EAClBA,EAAG,OAASC,CAAG,CACpB,CAAC,EAKKG,GAAO7C,EAA0BF,GAAU,OAC/C,MAAM4C,EAAMrC,EAAeP,EAAM,IAAKA,EAAM,IAAI,GAAG,EACnD,OAAOC,EAAAA,EAAE,MAAO,CACd,MAAO,eACP,UAAW2C,GAAO,GAClB,KAAItB,EAAAtB,EAAM,MAAN,YAAAsB,EAAW,cAAe,CAAA,CAAC,CAChC,CACH,CAAC,EAKK0B,GAAO9C,EAA0BF,GAAU,CAC/C,MAAM4C,EAAMrC,EAAeP,EAAM,IAAKA,EAAM,IAAI,GAAG,GAAK,GAClD2C,EAAK3C,EAAM,IAAI,aAAe,CAAA,EAC9BiD,EAAW,CACf,SAAY,WACZ,MAAS,OACT,IAAO,MACP,UAAa,mBACb,OAAU,UACV,QAAW,OACX,YAAa,OACb,MAASN,EAAG,WAAa,UACzB,cAAe,MAAA,EAEXO,EAAY,CAChB,gBAAiB,OACjB,QAAW,cACX,qBAAsB,WACtB,qBAAsBP,EAAG,WAAa,EACtC,SAAY,SACZ,GAAGA,EAAG,UAAA,EAER,OAAO1C,EAAAA,EAAE,MAAO,CACZ,MAAO,kBACP,MAAO,yDAAA,EAET,CACEA,EAAAA,EAAE,OAAQ,CACR,MAAO,gBAAgB0C,EAAG,WAAa,EAAE,GACzC,MAAOO,EACP,MAAON,CAAA,EACNA,CAAG,EACNA,GAAO3C,EAAAA,EAAE,OAAQ,CACf,MAAO,cACP,MAAOgD,EACP,MAAON,EAAG,WAAa,KACvB,QAAS,IAAM,CACb,GAAKC,EACL,GAAI,CACF,GAAI,UAAU,WAAa,UAAU,UAAU,UAC7C,UAAU,UAAU,UAAUA,CAAG,EAAE,KAAK,IAAM,CAC5CO,EAAAA,UAAU,QAAQR,EAAG,aAAe,MAAM,CAC5C,CAAC,EAAE,MAAM,IAAM,CACbQ,EAAAA,UAAU,MAAMR,EAAG,WAAa,MAAM,CACxC,CAAC,MACI,CACL,MAAMS,EAAW,SAAS,cAAc,UAAU,EAClDA,EAAS,MAAQR,EACjBQ,EAAS,MAAM,SAAW,QAC1BA,EAAS,MAAM,QAAU,IACzB,SAAS,KAAK,YAAYA,CAAQ,EAClCA,EAAS,OAAA,EACT,MAAMC,EAAa,SAAS,YAAY,MAAM,EAC9C,SAAS,KAAK,YAAYD,CAAQ,EAE9BC,EACFF,EAAAA,UAAU,QAAQR,EAAG,aAAe,MAAM,EAE1CQ,EAAAA,UAAU,MAAMR,EAAG,WAAa,MAAM,CAE1C,CACF,MAAc,CACZQ,EAAAA,UAAU,MAAMR,EAAG,WAAa,MAAM,CACxC,CACF,CAAA,EACC,CAAC1C,EAAAA,EAAEqD,eAAc,CAClB,MAAO,0BAAA,CACR,CAAC,CAAC,CAAA,EACH,OAAO,OAAO,CAAA,CAEpB,CAAC,EAKKC,GAAMrD,EAA0BF,GAAU,OAC9C,MAAM4C,EAAMrC,EAAeP,EAAM,IAAKA,EAAM,IAAI,GAAG,GAAK,GAClD2C,IAAKrB,EAAAtB,EAAM,MAAN,YAAAsB,EAAW,cAAe,CAAA,EAU/BkC,EAPCZ,EACD,MAAM,QAAQA,CAAG,EACZA,EAAI,OAAOa,GAAQA,GAAQ,OAAOA,GAAS,QAAQ,EAErD,CAACb,CAAG,EAJM,CAAA,EASnB,GAAIY,EAAU,SAAW,EACvB,OAAOb,EAAG,aAAe,GAG3B,MAAMe,EAAe,CACnB,MAAOf,EAAG,OAAS,OACnB,OAAQA,EAAG,QAAU,OACrB,YAAaa,EAAU,OAAS,EAAI,MAAQ,IAC5C,GAAIb,EAAG,OAAS,CAAA,CAAC,EAGnB,OAAIa,EAAU,SAAW,EAChBvD,EAAAA,EAAE0D,EAAAA,QAAS,CAChB,IAAKH,EAAU,CAAC,EAChB,eAAgBb,EAAG,gBAAkBa,EACrC,IAAKb,EAAG,KAAO,UACf,MAAOe,EACP,GAAGf,CAAA,CACJ,EAGI1C,EAAAA,EAAE,MACP,CACE,MAAO,iBACP,MAAO,wDAAA,EAET,CACEA,EAAAA,EAAE0D,EAAAA,QAAS,CACT,IAAKH,EAAU,CAAC,EAChB,eAAgBb,EAAG,gBAAkBa,EACrC,IAAKb,EAAG,KAAO,UACf,MAAOe,EACP,GAAGf,CAAA,CACJ,EACDa,EAAU,OAAS,GAAKvD,EAAAA,EAAE,OAAQ,CAChC,MAAO,eACP,MAAO,yCACP,MAAO,GAAGuD,EAAU,MAAM,EAAA,EACzB,CAACvD,EAAAA,EAAE2D,eAAc,CAAE,MAAO,2BAAA,CAA6B,CAAC,CAAC,CAAA,CAC9D,CAEJ,CAAC,EAKKC,GAAO3D,EAA0BF,GAAU,CAC/C,MAAM4C,EAAMrC,EAAeP,EAAM,IAAKA,EAAM,IAAI,GAAG,GAAK,GAClD2C,EAAK3C,EAAM,IAAI,aAAe,CAAA,EAC9B8D,EAAUnB,EAAG,SAAW,CAAA,EACxBoB,EAAYpB,EAAG,WAAa,GAElC,GAAIC,GAAQ,MAA6BA,IAAQ,GAAI,MAAO,GAE5D,MAAMoB,EAAS,MAAM,QAAQpB,CAAG,EAAIA,EAAI,IAAI,MAAM,EAAI,CAAC,OAAOA,CAAG,CAAC,EAC5DqB,EAAiBH,EAAQ,OAAQ5B,GAAa8B,EAAO,SAAS,OAAO9B,EAAI,KAAK,CAAC,CAAC,EAChFgC,EAAYF,EAAO,OAAO5C,GAAK,CAAC0C,EAAQ,KAAM5B,GAAa,OAAOA,EAAI,KAAK,IAAMd,CAAC,CAAC,EAEnF+C,EAAWF,EAAe,IAAI,CAACR,EAAWW,IACvCnE,EAAAA,EACLoE,EAAAA,MACA,CAAE,IAAKZ,EAAK,MAAO,KAAMA,EAAK,UAAW,MAAOA,EAAK,SAAU,mBAAoB,EAAA,EACnF,CAAE,QAAS,IAAMA,EAAK,MAAQ,GAAA,CAAI,CAErC,EAED,OAAIM,GAAaG,EAAU,OAAS,GAClCC,EAAS,KAAKlE,EAAAA,EAAE,OAAQ,CAAA,EAAIiE,EAAU,KAAK,GAAG,CAAC,CAAC,EAG3CjE,IAAE,MAAO,CAAA,EAAIkE,CAAQ,CAC9B,CAAC,EAKKG,GAAMpE,EAA0BF,GAAU,OAC9C,MAAM4C,EAAMrC,EAAeP,EAAM,IAAKA,EAAM,IAAI,GAAG,GAAK,GAClD8D,IAAWxC,EAAAtB,EAAM,IAAI,cAAV,YAAAsB,EAAuB,UAAW,CAAA,EACnD,OAAOsB,GAAO,KAAOkB,EAAQlB,CAAG,GAAK,GAAK,EAC5C,CAAC,EAKM,SAAS2B,GACdC,EACY,CACZ,OAAO,OAAQA,EAAY,WAAc,UAC3C,CAEA,MAAMC,GAAYvE,EAA0BF,GAAU,OACpD,KAAM,CAAE,IAAAwE,EAAK,IAAAE,CAAA,EAAQ1E,EACf4C,EAAMrC,EAAeP,EAAM,IAAKA,EAAM,IAAI,GAAG,GAAK,GACxD,OAAIuE,GAAaC,CAAG,GACXlD,EAAAkD,EAAI,YAAJ,YAAAlD,EAAA,KAAAkD,EAAgB5B,EAAK8B,GAEvB9B,GAAO,EAChB,CAAC,EAKK+B,GAAOzE,EAA0BF,GAAU,CAC/C,MAAM4C,EAAMrC,EAAeP,EAAM,IAAKA,EAAM,IAAI,GAAG,GAAK,GAClD2C,EAAK3C,EAAM,IAAI,aAAe,CAAA,EACpC,OAAK4C,EAED,eAAe,KAAKA,CAAG,EAClB3C,EAAAA,EAAE0D,EAAAA,QAAS,CAChB,IAAKf,EACL,eAAgB,CAACA,CAAG,EACpB,IAAK,UACL,MAAO,yBACP,GAAGD,CAAA,CACJ,EAGC,6BAA6B,KAAKC,CAAG,EAChC3C,EAAAA,EAAE,MAAO,CACd,UAAW2C,EACX,MAAO,+CAA+CD,EAAG,OAAS,EAAE,GACpE,GAAGA,CAAA,CACJ,EAGI1C,EAAAA,EAAE,IAAK,CACZ,MAAO2C,EACP,MAAO,kBAAkBD,EAAG,OAAS,EAAE,GACvC,GAAGA,CAAA,CACJ,EAxBgB,EAyBnB,CAAC,EAKYiC,EAAmB,CAC9B,MAAAxC,EACA,eAAgBE,EAChB,OAAAE,GACA,OAAAE,GACA,KAAAI,GACA,KAAAC,GACA,KAAAC,GACA,IAAAO,GACA,KAAAM,GACA,IAAAS,GACA,UAAAG,GACA,KAAAE,EACF,EAKO,SAASE,EAAyBC,EAA0E,CACjHA,EAAS,iBAAiBF,CAAgB,CAC5C,CAMO,SAASG,IAAiB,CAC/B,OAAOH,CACT,CC7SO,SAASI,GACdC,EACAC,EAAS,GACTC,EAA4B,CAAA,EAC5B,CAKA,MAAMC,EAAiB,QAajBC,EAAYxE,GAA8B,CAC9C,GAAI,CAACA,EAAO,MAAO,GAEnB,MAAMyE,EAAY,MAAM,QAAQzE,CAAK,EAAIA,EAAQ,CAACA,CAAK,EACvD,OAAOsE,EAAgB,KACrB,GAAK,IAAMC,GAAkBE,EAAU,SAAS,CAAC,CAAA,CAErD,EAWMC,EAAeC,EAAAA,SAAS,IACrBP,EAAc,KAAKQ,GAAOJ,EAASI,EAAI,UAAU,CAAC,CAC1D,EAMKC,EAAWF,EAAAA,SAAS,IACFP,EACnB,OAAOQ,GAAOJ,EAASI,EAAI,UAAU,CAAC,EACtC,MAAM,EAAGP,CAAM,EAEG,OACnB,CAACS,EAAKF,IAAQE,GAAOF,EAAI,OAAS,IAClC,CAAA,CAEH,EASKG,EAAkB,CAACH,EAAmBf,IAExCW,EAASI,EAAI,UAAU,IACtBA,EAAI,QAAUA,EAAI,QAAQf,CAAG,EAAI,IAOhCmB,EAAenB,GACCO,EACjB,OAAOQ,GAAOG,EAAgBH,EAAKf,CAAG,CAAC,EACvC,MAAM,EAAGQ,CAAM,EAEC,OACjB,CAACS,EAAKF,IAAQE,GAAOF,EAAI,OAAS,IAClC,CAAA,EA+BJ,MAAO,CACL,aAAAF,EACA,SAAAG,EACA,oBAhB2BI,GACtBA,GAAA,MAAAA,EAAM,OACJA,EAAK,QACVb,EAAc,QAAYW,EAAgBH,EAAKf,CAAG,CAAC,CAAA,EAF3B,GAgB1B,eA5BsBoB,GACjBA,GAAA,MAAAA,EAAM,OACJA,EAAK,OACV,CAACC,EAAKrB,IAAQ,KAAK,IAAIqB,EAAKF,EAAYnB,CAAG,CAAC,EAC5C,CAAA,EAHwBgB,EAAS,MA4BnC,kBAXyBhB,GAClBO,EACJ,OAAOQ,GAAOG,EAAgBH,EAAKf,CAAG,CAAC,EACvC,MAAM,EAAGQ,CAAM,CAQlB,CAEJ,2PC7CA,MAAMlF,EAAQiB,EAMR+E,EAAOC,EAEPC,EAAgBC,GAAkB,SACtC,MAAMC,GAAO9E,EAAAtB,EAAM,aAAN,YAAAsB,EAAkB,KACzB+E,GAAOC,EAAAtG,EAAM,aAAN,YAAAsG,EAAkB,KAC/B,OAAOF,GAAQC,GAAQD,EAAO,GAAKC,EAAOF,EAAQ,EAAIA,EAAQ,CAChE,EAGM,CAAE,IAAA3B,CAAA,EAAQ+B,EAAAA,OAAOvG,CAAK,EAGtBwG,EAAmB,CAAC9B,EAAU/D,IAAgBqF,EAAK,aAActB,EAAK/D,CAAG,EACzE8F,EAAiB,CAAC/B,EAAU/D,IAAiBqF,EAAK,WAAYtB,EAAK/D,CAAG,EACtE+F,EAAkB,CAAChC,EAAU/D,IAAgBqF,EAAK,YAAatB,EAAK/D,CAAG,EACvEgG,EAAkB,CAACjC,EAAUF,IAAawB,EAAK,YAAatB,EAAKF,CAAG,EAI1EK,EAAyBjF,GAAoB,EAG7C,MAAMH,EAAW+F,EAAAA,SAAS,IAAM,CAC9B,MAAMoB,EAAUhH,EAAA,EACViH,EAAoC,CAAA,EAG1C,OAAAD,EAAQ,MAAA,EAAQ,QAASpH,GAAiB,CACxC,MAAMsH,EAAIF,EAAQ,IAAIpH,CAAI,EACtBsH,IAAGD,EAAarH,CAAI,EAAIsH,EAC9B,CAAC,EAEMD,CACT,CAAC,EAGK,CACJ,aAAAtB,EACA,oBAAAwB,EACA,SAAArB,EACA,eAAAsB,EACA,kBAAAC,CAAA,EACEjC,GACFR,EAAI,MAAM,SAAW,CAAA,EACrBA,EAAI,MAAM,QAAU,GACpBxE,EAAM,aAAe,CAAA,CAAC,EAIlBkH,EAAsB1B,EAAAA,SAAS,KACnBhB,EAAI,MAAM,SAAW,CAAA,GACxB,QACAA,EAAI,MAAM,QAAU,CAAA,GAEvB,OAEHuC,EAAoBvC,EAAI,MAAM,QAAU,CAAA,CAAE,EAFxBe,EAAa,MAHV,EAM7B,EAGK4B,EAAiB3B,EAAAA,SAAS,IAEzBhB,EAAI,MAAM,OAERwC,EAAexC,EAAI,MAAM,MAAM,EAFRkB,EAAS,KAGxC,EAED,SAAS0B,EAAwBC,EAAiB,CAGhD,MAFI,EAAAA,EAAE,OAAS,aAAeA,EAAE,OAAS,SACrCA,EAAE,OAAS,aAAe,CAACH,EAAoB,OAC/CG,EAAE,UAAY,GAEpB,+FArKU,OAAAC,EAAAA,MAAA9C,CAAA,EAAI,OAAI,aADhBhD,EAAAA,YAAAC,EAAAA,YAIE8F,EAJF5F,aAIE,OAFA,KAAK,WAAA,EACG2F,EAAAA,MAAA9C,CAAA,EAAI,WAAW,EAAA,KAAA,EAAA,GAKZ8C,EAAAA,MAAA9C,CAAA,EAAI,OAAI,SADrBhD,EAAAA,YAAAC,EAAAA,YAUkB8F,EAVlB5F,aAUkB,OARhB,KAAK,QACJ,MAAO2F,EAAAA,MAAA9C,CAAA,EAAI,OAAK,IACjB,MAAM,QAAA,EACE8C,QAAA9C,CAAA,EAAI,WAAW,EAAA,CAEZ,QAAOgD,EAAAA,QAChB,CAA0B,CADN,OAAAC,KAAM,CACvBC,EAAAA,gBAAAC,EAAAA,gBAAAzB,EAAauB,CAAM,CAAA,EAAA,CAAA,CAAA,uBAMbH,EAAAA,MAAA9C,CAAA,EAAI,OAAI,aAAoB0C,EAAA,OADzC1F,EAAAA,YAAAC,EAAAA,YAoBkB8F,EApBlB5F,aAoBkB,OAlBf,MAAO2F,EAAAA,MAAA9C,CAAA,EAAI,OAAK,KACjB,MAAM,QAAA,GACc,GAAA8C,EAAAA,MAAA9C,CAAA,EAAI,kBAA2B2C,EAAA,KAAA,IAKxC,QAAOK,EAAAA,QAEd,CAAqC,CAFnB,IAAA9C,KAAG,EACvBlD,EAAAA,UAAA,EAAA,EAAAQ,EAAAA,mBAQYC,EAAAA,SAAA,KAAA2F,aAPIN,EAAAA,MAAAL,CAAA,EAAkBvC,CAAG,EAA5Be,kBADThE,EAAAA,YAQYoG,EAAA,CANT,IAAKpC,EAAI,MACT,KAAMA,EAAI,MAAI,UACf,KAAA,GACC,QAAK7D,GAAE6D,EAAI,OAAOf,CAAG,CAAA,qBAEtB,IAAe,CAAZgD,EAAAA,gBAAAC,EAAAA,gBAAAlC,EAAI,KAAK,EAAA,CAAA,CAAA,+DAOL2B,EAAwBE,EAAAA,MAAA9C,CAAA,CAAG,GADxChD,EAAAA,UAAA,EAAAC,cAgCkB8F,EAhClB5F,EAAAA,WAgCkB,OA9Bf,MAAO2F,EAAAA,MAAA9C,CAAA,EAAI,MACZ,MAAM,QAAA,EACE8C,EAAAA,MAAA9C,CAAA,EAAI,aAAW,CAAA,CAAA,EAAA,CAGZ,QAAOgD,EAAAA,QAILM,GAAA,aAJY,OAEPR,EAAAA,MAAA9C,CAAA,EAAI,SAAM,QAAeuD,EAAAA,SAAOT,EAAAA,EAAAA,MAAA9C,CAAA,IAAA8C,YAAAA,EAAK,OAAQA,EAAAA,MAAA9C,CAAA,EAAI,GAAG,EAClEwD,EAAAA,WAAoDC,EAAA,SAAvCX,EAAAA,EAAAA,WAAAA,YAAAA,EAAK,OAAQA,EAAAA,MAAA9C,CAAA,EAAI,IAAG0D,EAAAA,eAAAvG,aAAA,CAAA,IAAA,GAAUmG,CAAK,CAAA,CAAA,EAKrCR,QAAA9C,CAAA,EAAI,QAAU/E,QAAS6H,EAAAA,MAAA9C,CAAA,EAAI,MAAM,GAD9ChD,YAAA,EAAAC,EAAAA,YASE0G,EAAAA,wBAPK1I,EAAA,MAAS6H,EAAAA,MAAA9C,CAAA,EAAI,MAAM,CAAA,EAAA,OACvB,IAAKsD,EAAM,IACX,IAAKR,EAAAA,MAAA9C,CAAA,EACL,aAAcgC,EACd,WAAYC,EACZ,YAAaC,EACb,QAASC,CAAA,yCAGZ3E,EAAAA,mBAKO,OAAA,OAJJ,MAAKoG,EAAAA,iBAAEd,EAAAA,QAAA9C,CAAA,EAAI,cAAJ8C,YAAAA,EAAiB,QAAK,EAAA,EAC7B,MAAKe,EAAAA,iBAAEf,EAAAA,QAAA9C,CAAA,EAAI,cAAJ8C,YAAAA,EAAiB,QAAK,EAAA,EAC7B,MAAOA,EAAAA,SAAeQ,EAAM,IAAKR,EAAAA,MAAA9C,CAAA,EAAI,GAAG,CAAA,EACtCmD,EAAAA,gBAAAL,EAAAA,MAAA/G,CAAA,EAAeuH,EAAM,IAAKR,QAAA9C,CAAA,EAAI,GAAG,CAAA,EAAA,GAAA8D,EAAA,EAAA,wDC/D5C,SAASC,EACPC,EACAC,EACA,CACA,GAAI,EAACA,GAAA,MAAAA,EAAc,QAAQ,OAAOD,EAGlC,MAAME,EAAW,IAAI,IACnBD,EAAa,IAAIpB,GAAK,CAACA,EAAE,IAAKA,CAAC,CAAC,CAAA,EAGlC,OAAOmB,EAAe,IAAIhE,GAAO,CAC/B,MAAMmE,EAAWD,EAAS,IAAIlE,EAAI,GAAG,EAGrC,OAAKmE,EAEE,CACL,GAAGnE,EACH,QACE,OAAOmE,EAAS,SAAY,UACxBA,EAAS,QACTnE,EAAI,OAAA,EAPUA,CASxB,CAAC,CACH,CAaO,SAASoE,GACdJ,EACA1E,EAMA,CAGA,KAAM,CAAE,SAAA+E,EAAU,QAAAC,EAAU,YAAA,EAAiBhF,GAAW,CAAA,EAOlDiF,EAAQF,EAAWC,EAAQ,QAAQD,CAAQ,EAAI,KAM/CG,EAAU9H,EAAAA,IACdqH,EACEC,EACAO,EAAQ,KAAK,MAAMA,CAAK,EAAI,CAAA,CAAC,CAC/B,EAMF5H,OAAAA,EAAAA,MACE6H,EACCC,GAAgB,CACf,GAAI,CAACJ,EAAU,OAMf,MAAMK,EAAeD,EAAO,IAAKzE,IAAc,CAC7C,IAAKA,EAAI,IACT,QAASA,EAAI,QACb,WAAYA,EAAI,UAAA,EAChB,EAEFsE,EAAQ,QACND,EACA,KAAK,UAAUK,CAAY,CAAA,CAE/B,EACA,CAAE,KAAM,EAAA,CAAK,EAMR,CAEL,QAAAF,EAMA,WAAWG,EAAmB,CAC5BH,EAAQ,MAAQT,EACdC,EACAW,CAAA,EAGEN,GACFC,EAAQ,QACND,EACA,KAAK,UAAUM,CAAU,CAAA,CAG/B,EAKA,cAAe,CACbH,EAAQ,MAAQR,EAEZK,GACFC,EAAQ,WAAWD,CAAQ,CAE/B,CAAA,CAEJ,mYChHE,MAAM7I,EAAQiB,EAcR+E,EAAOC,EASP,CAAE,QAASmD,CAAA,EAAkBR,GAAgB5I,EAAM,QAAS,CAChE,SAAUA,EAAM,UAAY,EAAA,CAC7B,EACDmB,EAAAA,MACEiI,EACCxG,GAAwBoD,EAAK,iBAAkBpD,CAAG,EACnD,CAAE,KAAM,GAAM,UAAW,EAAA,CAAK,EAIhC,MAAM4D,EAAmB,CAAC9B,EAAU/D,IAAgBqF,EAAK,aAActB,EAAK/D,CAAG,EACzE8F,EAAiB,CAAC/B,EAAU/D,IAAgB,CAChDqF,EAAK,WAAYtB,EAAK/D,CAAG,CAC3B,EACM+F,EAAkB,CAAChC,EAAU/D,IAAgB,CACjD,QAAQ,IAAI,OAAO,EACnBqF,EAAK,YAAatB,EAAK/D,CAAG,CAC5B,EAGMgG,EAAkB,CAACjC,EAAUF,IAAa,CAC1CA,GACJwB,EAAK,aAActB,EAAKF,CAAG,CAC7B,EAGM6E,EAAWnI,EAAAA,IAAA,EACjB,OAAAoI,EAAa,CACX,SAAAD,CAAA,CACD,iFAjFD,OAAAE,EAAAA,gBAAA/H,EAAAA,UAAA,EAAAC,EAAAA,YAoBW+H,EApBX7H,EAAAA,WAoBW,SApBG,WAAJ,IAAI0H,CAAA,EACJI,EAAAA,OAAM,CACb,KAAMxI,EAAA,KACN,UAASA,EAAA,OACV,MAAM,aAAA,sBAGJ,IAA4B,kBAD9Be,EAAAA,mBAacC,WAAA,KAAA2F,EAAAA,WAZEN,QAAA8B,CAAA,EAAP5E,kBADT/C,EAAAA,YAaciI,GAAA,CAXX,IAAKlF,EAAI,IACT,IAAAA,EACA,YAAavD,EAAA,YACb,WAAYA,EAAA,WACZ,aAAauF,EACb,WAAWC,EACX,YAAYC,EACZ,YAAYC,CAAA,uBACWiB,EAAAA,WAAAN,EAAAA,MAAA8B,CAAA,EAAP5E,KAAuB,KAAAA,EAAI,IAC1C,GAAAgD,EAAAA,QADiDmC,GAAS,CAC1D3B,aAA2CC,SAA9BzD,EAAI,IAAjB7C,EAAAA,WAA2C,aAAbgI,CAAS,CAAA,CAAA,4FAZhC1I,EAAA,OAAO,CAAA,OCGhB2I,EAAkC,CACtC,kBAAmB,CACjB,KAAM,EACN,KAAM,GACN,MAAO,CAAA,EAET,kBAAmB,CAAA,EACnB,mBAAoB,CAAA,CACtB,EAKA,MAAMC,EAAc,CAApB,cACUtK,EAAA,cAA2B,CAAE,GAAGqK,CAAA,GAKxC,WAA8B,CAC5B,MAAO,CAAE,GAAG,KAAK,MAAA,CACnB,CAKA,UAAUE,EAAyC,CACjD,KAAK,OAAS,KAAK,YAAY,KAAK,OAAQA,CAAM,EAG9CA,EAAO,WACOlK,EAAA,EACR,iBAAiBkK,EAAO,SAAS,CAE7C,CAKA,IAAsCnJ,EAA6B,CACjE,OAAO,KAAK,OAAOA,CAAG,CACxB,CAKA,OAAc,CACZ,KAAK,OAAS,CAAE,GAAGiJ,CAAA,CACrB,CAKQ,YAAY5I,EAAa+I,EAAkB,CACjD,MAAMC,EAAS,CAAE,GAAGhJ,CAAA,EAEpB,UAAWL,KAAOoJ,EACZA,EAAOpJ,CAAG,GAAK,OAAOoJ,EAAOpJ,CAAG,GAAM,UAAY,CAAC,MAAM,QAAQoJ,EAAOpJ,CAAG,CAAC,EAC9EqJ,EAAOrJ,CAAG,EAAI,KAAK,YAAYK,EAAOL,CAAG,GAAK,CAAA,EAAIoJ,EAAOpJ,CAAG,CAAC,EAE7DqJ,EAAOrJ,CAAG,EAAIoJ,EAAOpJ,CAAG,EAI5B,OAAOqJ,CACT,CACF,CAKA,IAAIC,EAA4C,KAKzC,SAASC,GAAkC,CAChD,OAAKD,IACHA,EAAsB,IAAIJ,IAErBI,CACT,CA2BO,SAASE,GAAoBL,EAAyC,CAC3EI,EAAA,EAAmB,UAAUJ,CAAM,CACrC,CAEO,SAASM,IAAwC,CACtD,OAAOF,EAAA,EAAmB,UAAA,CAC5B,CCjFO,SAASG,GACd1J,EACAmJ,EACc,CACd,MAAO,CACL,IAAAnJ,EACA,GAAGmJ,CAAA,CAEP"}
1
+ {"version":3,"file":"vue3-smart-table.cjs.js","sources":["../src/components/SmartTable/hooks/useTableColumns.ts","../src/components/SmartTable/hooks/useOperationColumn.ts","../src/components/SmartTable/renderer.ts","../src/components/SmartTable/utils/path.ts","../src/components/SmartTable/renderers/input.vue","../src/components/SmartTable/renderers/inputNumber.vue","../src/components/SmartTable/renderers/select.vue","../src/components/SmartTable/renderers/index.ts","../src/components/SmartTable/index.vue","../src/components/SmartTable/config.ts","../src/types/enhanced.ts"],"sourcesContent":["import { ref, watch } from 'vue'\r\n\r\n\r\n/**\r\n * 合并默认列配置和缓存配置\r\n *\r\n * 设计原则:\r\n * 1️⃣ 列顺序:以 defaultColumns 为准\r\n * 2️⃣ 列增减:以 defaultColumns 为准\r\n * 3️⃣ 缓存只覆盖用户可配置字段(如 visible)\r\n */\r\nfunction mergeColumns(\r\n defaultColumns: any[],\r\n cacheColumns: Array<{ key: string; visible?: boolean }>\r\n) {\r\n if (!cacheColumns?.length) return defaultColumns\r\n\r\n // 建立 key => cache 映射表,提升查找效率\r\n const cacheMap = new Map(\r\n cacheColumns.map(c => [c.key, c])\r\n )\r\n\r\n return defaultColumns.map(col => {\r\n const cacheCol = cacheMap.get(col.key)\r\n\r\n // 只允许缓存覆盖「可配置字段」\r\n if (!cacheCol) return col\r\n\r\n return {\r\n ...col,\r\n visible:\r\n typeof cacheCol.visible === 'boolean'\r\n ? cacheCol.visible\r\n : col.visible\r\n }\r\n })\r\n}\r\n\r\n\r\n/**\r\n * useTableColumns\r\n *\r\n * 表格列管理 Hook\r\n *\r\n * 职责:\r\n * - 管理表格列顺序\r\n * - 管理列显示 / 隐藏\r\n * - 持久化用户配置\r\n */\r\nexport function useTableColumns(\r\n defaultColumns: any[],\r\n options?: {\r\n /** 缓存唯一标识 */\r\n cacheKey?: string\r\n /** 存储介质,默认 localStorage */\r\n storage?: Storage\r\n }\r\n) {\r\n\r\n /** 解构参数并设置默认值 */\r\n const { cacheKey, storage = localStorage } = options || {}\r\n\r\n /**\r\n * 如果没有 cacheKey,则不启用缓存\r\n * (例如公共页面、未登录页面)\r\n * 从缓存中读取列配置\r\n */\r\n const cache = cacheKey ? storage.getItem(cacheKey) : null\r\n\r\n /**\r\n * 响应式列配置\r\n * 初始化时合并默认列和缓存列\r\n */\r\n const columns = ref(\r\n mergeColumns(\r\n defaultColumns,\r\n cache ? JSON.parse(cache) : []\r\n )\r\n )\r\n\r\n /**\r\n * 监听列变化,自动写入缓存\r\n */\r\n watch(\r\n columns,\r\n (newVal: any) => {\r\n if (!cacheKey) return\r\n\r\n /**\r\n * ⚠️ 只保存“轻量配置”\r\n * 避免把 render / action / 函数序列化进 localStorage\r\n */\r\n const lightColumns = newVal.map((col: any) => ({\r\n key: col.key,\r\n visible: col.visible,\r\n columnOpts: col.columnOpts\r\n }))\r\n\r\n storage.setItem(\r\n cacheKey,\r\n JSON.stringify(lightColumns)\r\n )\r\n },\r\n { deep: true }\r\n )\r\n\r\n /**\r\n * 对外暴露的 API\r\n */\r\n return {\r\n /** 当前列配置(响应式) */\r\n columns,\r\n\r\n /**\r\n * 主动设置列配置\r\n * 常用于:列设置弹窗 / 拖拽排序完成\r\n */\r\n setColumns(newColumns: any[]) {\r\n columns.value = mergeColumns(\r\n defaultColumns,\r\n newColumns\r\n )\r\n\r\n if (cacheKey) {\r\n storage.setItem(\r\n cacheKey,\r\n JSON.stringify(newColumns)\r\n )\r\n }\r\n },\r\n\r\n /**\r\n * 重置为默认列配置\r\n */\r\n resetColumns() {\r\n columns.value = defaultColumns\r\n\r\n if (cacheKey) {\r\n storage.removeItem(cacheKey)\r\n }\r\n }\r\n }\r\n}\r\n","import { computed } from 'vue'\r\n\r\nimport { ButtonConfig } from \"../types\"\r\n\r\n/**\r\n * useOperationColumn\r\n *\r\n * 操作列专用逻辑 Hook,负责:\r\n * 1. 根据权限判断操作列是否需要显示\r\n * 2. 计算操作列宽度(支持按钮自定义宽度)\r\n * 3. 支持行级 visible 配置\r\n * @param buttonConfigs 操作列按钮配置\r\n * @param maxbtn 操作列最多显示按钮数量(超过的不参与宽度计算)\r\n * @param userPermissions 当前用户权限列表\r\n */\r\nexport function useOperationColumn(\r\n buttonConfigs: ButtonConfig[],\r\n maxbtn = 10,\r\n userPermissions: string[] = []\r\n) {\r\n /** 默认按钮宽度 */\r\n const defaultWidth = 55\r\n\r\n /** 超级权限标识 */\r\n const all_permission = '*:*:*'\r\n\r\n /** --------------------------\r\n * 权限判断\r\n * -------------------------- */\r\n\r\n /**\r\n * 判断是否具备按钮权限\r\n *\r\n * 规则:\r\n * - permission 未配置 ⇒ 永远有权限\r\n * - permission 为 string | string[] ⇒ 与用户权限匹配\r\n */\r\n const hasPermi = (value?: string | string[]) => {\r\n if (!value) return true\r\n\r\n const permArray = Array.isArray(value) ? value : [value]\r\n return userPermissions.some(\r\n p => p === all_permission || permArray.includes(p)\r\n )\r\n }\r\n\r\n /** --------------------------\r\n * 仅基于权限(不考虑行级 visible)\r\n * 适用于:表格未加载数据时的判断\r\n * -------------------------- */\r\n\r\n /**\r\n * 是否至少存在一个有权限的按钮\r\n * 用于判断操作列是否需要渲染\r\n */\r\n const hasAnyButton = computed(() => {\r\n return buttonConfigs.some(btn => hasPermi(btn.permission))\r\n })\r\n\r\n /**\r\n * 操作列宽度(仅基于权限)\r\n * 用于无行数据时的兜底宽度计算\r\n *\r\n * 注意:这里不考虑 visible,因为没有 row 数据无法执行 visible 函数\r\n * 实际使用时会根据行数据重新计算\r\n */\r\n const optWidth = computed(() => {\r\n const permittedBtns = buttonConfigs\r\n .filter(btn => hasPermi(btn.permission))\r\n .slice(0, maxbtn)\r\n\r\n return permittedBtns.reduce(\r\n (sum, btn) => sum + (btn.width ?? defaultWidth),\r\n 0\r\n )\r\n })\r\n\r\n /** --------------------------\r\n * 权限 + 行级 visible\r\n * -------------------------- */\r\n\r\n /**\r\n * 判断某个按钮在某一行是否可见\r\n */\r\n const isButtonVisible = (btn: ButtonConfig, row: any) => {\r\n return (\r\n hasPermi(btn.permission) &&\r\n (btn.visible ? btn.visible(row) : true)\r\n )\r\n }\r\n\r\n /**\r\n * 单行操作列宽度\r\n */\r\n const optRowWidth = (row: any) => {\r\n const visibleBtns = buttonConfigs\r\n .filter(btn => isButtonVisible(btn, row))\r\n .slice(0, maxbtn)\r\n\r\n return visibleBtns.reduce(\r\n (sum, btn) => sum + (btn.width ?? defaultWidth),\r\n 0\r\n )\r\n }\r\n\r\n /**\r\n * 遍历所有行,获取最大操作列宽度\r\n */\r\n const getMaxOptWidth = (rows: any[]) => {\r\n if (!rows?.length) return optWidth.value\r\n return rows.reduce(\r\n (max, row) => Math.max(max, optRowWidth(row)),\r\n 0\r\n )\r\n }\r\n\r\n /**\r\n * 判断是否至少有一行存在可见按钮\r\n */\r\n const hasAnyVisibleButton = (rows: any[]) => {\r\n if (!rows?.length) return false\r\n return rows.some(row =>\r\n buttonConfigs.some(btn => isButtonVisible(btn, row))\r\n )\r\n }\r\n\r\n const getVisibleButtons = (row: any) => {\r\n return buttonConfigs\r\n .filter(btn => isButtonVisible(btn, row))\r\n .slice(0, maxbtn)\r\n }\r\n\r\n return {\r\n hasAnyButton,\r\n optWidth,\r\n hasAnyVisibleButton,\r\n getMaxOptWidth,\r\n getVisibleButtons\r\n }\r\n}\r\n","/**\r\n * SmartTable 内部渲染器管理系统\r\n * 移动到组件内部,保证组件的自包含性\r\n */\r\nimport { defineComponent, h, Component } from 'vue'\r\nimport type { Renderer } from './types'\r\n\r\n/**\r\n * 渲染器注册表接口\r\n */\r\nexport interface RendererRegistry {\r\n register(name: string, renderer: Renderer): void\r\n registerMultiple(renderers: Record<string, Renderer>): void\r\n get(name: string): Renderer | undefined\r\n has(name: string): boolean\r\n unregister(name: string): boolean\r\n clear(): void\r\n names(): string[]\r\n}\r\n\r\n/**\r\n * 渲染器管理器类\r\n */\r\nclass RendererManager implements RendererRegistry {\r\n private renderers: Map<string, Renderer> = new Map()\r\n\r\n register(name: string, renderer: Renderer): void {\r\n if (this.renderers.has(name)) {\r\n // 批量注册时不警告,只在单独注册时警告\r\n if (process.env.NODE_ENV === 'development') {\r\n console.debug(`[SmartTable] Renderer \"${name}\" already registered, skipping.`)\r\n }\r\n }\r\n this.renderers.set(name, renderer)\r\n }\r\n\r\n registerMultiple(renderers: Record<string, Renderer>): void {\r\n Object.entries(renderers).forEach(([name, renderer]) => {\r\n if (!this.renderers.has(name)) {\r\n this.renderers.set(name, renderer)\r\n }\r\n })\r\n }\r\n\r\n get(name: string): Renderer | undefined {\r\n return this.renderers.get(name)\r\n }\r\n\r\n has(name: string): boolean {\r\n return this.renderers.has(name)\r\n }\r\n\r\n unregister(name: string): boolean {\r\n return this.renderers.delete(name)\r\n }\r\n\r\n clear(): void {\r\n this.renderers.clear()\r\n }\r\n\r\n names(): string[] {\r\n return Array.from(this.renderers.keys())\r\n }\r\n}\r\n\r\n/**\r\n * 全局渲染器管理器单例\r\n */\r\nlet globalRendererManager: RendererManager | null = null\r\n\r\n/**\r\n * 获取渲染器管理器\r\n */\r\nexport function getRendererManager(): RendererManager {\r\n if (!globalRendererManager) {\r\n globalRendererManager = new RendererManager()\r\n }\r\n return globalRendererManager\r\n}\r\n\r\n/**\r\n * 包装 SFC 组件为渲染器\r\n */\r\nexport function wrapSFCComponent(comp: Component): Renderer {\r\n return defineComponent({\r\n props: ['row', 'col', 'onCellChange', 'onCellBlur', 'onCellEnter', 'onClick'],\r\n setup(props) {\r\n return () => h(comp, props)\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * 创建函数式渲染器\r\n */\r\nexport function createFunctionalRenderer(\r\n render: (props: {\r\n row: any\r\n col: any\r\n onCellChange?: (row: any, col: any) => void\r\n onCellBlur?: (row: any, col: any) => void\r\n onCellEnter?: (row: any, col: any) => void\r\n onClick?: (row: any, col: any) => void\r\n }) => any\r\n): Renderer {\r\n return defineComponent({\r\n props: ['row', 'col', 'onCellChange', 'onCellBlur', 'onCellEnter', 'onClick'],\r\n setup(props) {\r\n return () => render(props)\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * 验证渲染器配置\r\n * 在开发环境下验证 renderProps 的正确性\r\n */\r\nexport function validateRendererProps(\r\n rendererName: string,\r\n renderProps: Record<string, any> | undefined\r\n): void {\r\n if (process.env.NODE_ENV !== 'production' && renderProps) {\r\n switch (rendererName) {\r\n case 'dict':\r\n if (!renderProps.options || !Array.isArray(renderProps.options)) {\r\n console.warn(\r\n `[SmartTable] 'dict' renderer requires 'options' array, received:`,\r\n renderProps.options\r\n )\r\n }\r\n break\r\n\r\n case 'select':\r\n if (!renderProps.options || !Array.isArray(renderProps.options)) {\r\n console.warn(\r\n `[SmartTable] 'select' renderer requires 'options' array, received:`,\r\n renderProps.options\r\n )\r\n } else if (renderProps.options.length === 0) {\r\n console.warn(`[SmartTable] 'select' renderer 'options' array is empty`)\r\n }\r\n break\r\n\r\n case 'map':\r\n if (!renderProps.options || typeof renderProps.options !== 'object') {\r\n console.warn(\r\n `[SmartTable] 'map' renderer requires 'options' object, received:`,\r\n renderProps.options\r\n )\r\n }\r\n break\r\n\r\n case 'link':\r\n if (!renderProps.href || typeof renderProps.href !== 'string') {\r\n console.warn(\r\n `[SmartTable] 'link' renderer requires 'href' string, received:`,\r\n renderProps.href\r\n )\r\n }\r\n break\r\n\r\n case 'input-number':\r\n if (renderProps.min !== undefined && renderProps.max !== undefined) {\r\n if (renderProps.min > renderProps.max) {\r\n console.warn(\r\n `[SmartTable] 'input-number' renderer: min (${renderProps.min}) should not be greater than max (${renderProps.max})`\r\n )\r\n }\r\n }\r\n break\r\n }\r\n }\r\n}\r\n","/**\r\n * 安全获取对象深层属性\r\n * 支持 a.b.c / a.0.b\r\n */\r\nexport function getValueByPath(obj: any, path?: string) {\r\n if (!obj || !path) return undefined\r\n return path.split('.').reduce((acc, key) => acc?.[key], obj)\r\n }\r\n \r\n /**\r\n * 安全设置对象深层属性(用于可编辑表格)\r\n */\r\n export function setValueByPath(\r\n obj: any,\r\n path: string,\r\n value: any\r\n ) {\r\n if (!obj || !path) return\r\n const keys = path.split('.')\r\n const lastKey = keys.pop()!\r\n \r\n const target = keys.reduce((acc, key) => {\r\n if (!acc[key]) acc[key] = {}\r\n return acc[key]\r\n }, obj)\r\n \r\n target[lastKey] = value\r\n }\r\n ","<template>\n <el-input\n v-model=\"value\"\n v-bind=\"{ placeholder: '', size: 'small', clearable: true, ...col.renderProps }\"\n @blur=\"onBlur\"\n @keyup.enter=\"onEnter\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport type { ColumnConfig } from '../types'\nimport { getValueByPath, setValueByPath } from '../utils/path'\n\ninterface Props {\n readonly row: any\n readonly col: ColumnConfig\n onCellBlur?: (row: any, col: ColumnConfig) => void\n onCellEnter?: (row: any, col: ColumnConfig) => void\n}\n\nconst props = defineProps<Props>()\nconst value = ref(getValueByPath(props.row, props.col.key))\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n})\n\nconst onBlur = () => props.onCellBlur?.(props.row, props.col)\nconst onEnter = () => props.onCellEnter?.(props.row, props.col)\n</script>\n","<template>\n <el-input-number\n v-model=\"value\"\n v-bind=\"{ min: 0, max: 99999, controls: false, size: 'small', ...col.renderProps }\"\n @blur=\"onBlur\"\n @keyup.enter=\"onEnter\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport type { ColumnConfig } from '../types'\nimport { getValueByPath, setValueByPath } from '../utils/path'\n\ninterface Props {\n readonly row: any\n readonly col: ColumnConfig\n onCellChange?: (row: any, col: ColumnConfig) => void\n onCellBlur?: (row: any, col: ColumnConfig) => void\n onCellEnter?: (row: any, col: ColumnConfig) => void\n}\n\nconst props = defineProps<Props>()\nconst value = ref(getValueByPath(props.row, props.col.key))\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n props.onCellChange?.(props.row, props.col)\n})\n\nconst onBlur = () => props.onCellBlur?.(props.row, props.col)\nconst onEnter = () => props.onCellEnter?.(props.row, props.col)\n</script>\n","<template>\n <el-select\n v-model=\"value\"\n v-bind=\"{ placeholder: '请选择', size: 'small', clearable: true, ...col.renderProps }\"\n @change=\"onChange\"\n @blur=\"onBlur\"\n @keyup.enter=\"onEnter\"\n >\n <el-option\n v-for=\"opt in col.renderProps?.options || []\"\n :key=\"opt.value\"\n :label=\"opt.label\"\n :value=\"opt.value\"\n />\n </el-select>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport type { ColumnConfig } from '../types'\nimport { getValueByPath, setValueByPath } from '../utils/path'\n\ninterface Props {\n readonly row: any\n readonly col: ColumnConfig\n onCellChange?: (row: any, col: ColumnConfig) => void\n onCellBlur?: (row: any, col: ColumnConfig) => void\n onCellEnter?: (row: any, col: ColumnConfig) => void\n}\n\nconst props = defineProps<Props>()\nconst value = ref(getValueByPath(props.row, props.col.key))\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n})\n\nconst onChange = () => props.onCellChange?.(props.row, props.col)\nconst onBlur = () => props.onCellBlur?.(props.row, props.col)\nconst onEnter = () => props.onCellEnter?.(props.row, props.col)\n</script>\n","/**\r\n * 内置渲染器集合\r\n * 可以按需引入或批量注册\r\n */\r\nimport { h } from 'vue'\r\nimport { ElButton, ElTag, ElImage, ElMessage } from 'element-plus'\r\nimport { DocumentCopy, CopyDocument } from '@element-plus/icons-vue'\r\nimport type { ColumnConfig } from '../types'\r\nimport { getValueByPath } from '../utils/path'\r\nimport { wrapSFCComponent, createFunctionalRenderer } from '../renderer'\r\nimport EditableInput from './input.vue'\r\nimport EditableNumber from './inputNumber.vue'\r\nimport EditableSelect from './select.vue'\r\n\r\n/**\r\n * 包装 SFC 组件\r\n */\r\nconst input = wrapSFCComponent(EditableInput)\r\nconst inputNumber = wrapSFCComponent(EditableNumber)\r\nconst select = wrapSFCComponent(EditableSelect)\r\n\r\n/**\r\n * button 渲染器\r\n */\r\nconst button = createFunctionalRenderer((props) => {\r\n const rp = props.col.renderProps || {}\r\n const val = getValueByPath(props.row, props.col.key)\r\n return h(ElButton as any, {\r\n type: rp.type || 'primary',\r\n ...rp,\r\n onClick: () => props.onClick?.(props.row, props.col)\r\n }, () => rp.label || val)\r\n})\r\n\r\n/**\r\n * link 渲染器\r\n */\r\nconst link = createFunctionalRenderer((props) => {\r\n const rp = props.col.renderProps || {}\r\n const val = getValueByPath(props.row, props.col.key)\r\n return h('a', {\r\n href: rp.href || '#',\r\n target: rp.blank ? '_blank' : '_self',\r\n style: rp.style || 'color:#409EFF;cursor:pointer;',\r\n }, rp.label || val)\r\n})\r\n\r\n/**\r\n * html 渲染器\r\n */\r\nconst html = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key)\r\n return h('div', {\r\n class: 'line-clamp-2',\r\n innerHTML: val ?? '',\r\n ...(props.col?.renderProps || {})\r\n })\r\n})\r\n\r\n/**\r\n * copy 渲染器\r\n */\r\nconst copy = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.renderProps ?? {}\r\n const butStyle = {\r\n 'position': 'absolute',\r\n 'right': '-5px',\r\n 'top': '50%',\r\n 'transform': 'translateY(-50%)',\r\n 'cursor': 'pointer',\r\n 'display': 'none',\r\n 'font-size': '12px',\r\n 'color': rp.iconColor || '#409EFF',\r\n 'user-select': 'none'\r\n }\r\n const testStyle = {\r\n 'padding-right': '10px',\r\n 'display': '-webkit-box',\r\n '-webkit-box-orient': 'vertical',\r\n '-webkit-line-clamp': rp.lineClamp ?? 2,\r\n 'overflow': 'hidden',\r\n ...rp.textStyles\r\n }\r\n return h('div', {\r\n class: 'st_copy_wrapper',\r\n style: 'width: 100%; position: relative; display: inline-block;'\r\n },\r\n [\r\n h('span', {\r\n class: `st_copy_text ${rp.textClass ?? ''}`,\r\n style: testStyle,\r\n title: val\r\n }, val),\r\n val && h('span', {\r\n class: 'st_copy_btn',\r\n style: butStyle,\r\n title: rp.copyTitle || '复制',\r\n onClick: () => {\r\n if (!val) return\r\n try {\r\n if (navigator.clipboard && navigator.clipboard.writeText) {\r\n navigator.clipboard.writeText(val).then(() => {\r\n ElMessage.success(rp.successText ?? '复制成功')\r\n }).catch(() => {\r\n ElMessage.error(rp.errorText ?? '复制失败')\r\n })\r\n } else {\r\n const textarea = document.createElement('textarea')\r\n textarea.value = val\r\n textarea.style.position = 'fixed'\r\n textarea.style.opacity = '0'\r\n document.body.appendChild(textarea)\r\n textarea.select()\r\n const successful = document.execCommand('copy')\r\n document.body.removeChild(textarea)\r\n\r\n if (successful) {\r\n ElMessage.success(rp.successText ?? '复制成功')\r\n } else {\r\n ElMessage.error(rp.errorText ?? '复制失败')\r\n }\r\n }\r\n } catch (err) {\r\n ElMessage.error(rp.errorText ?? '复制失败')\r\n }\r\n }\r\n }, [h(DocumentCopy, {\r\n style: 'width: 1em; height: 1em;'\r\n })])\r\n ].filter(Boolean)\r\n )\r\n})\r\n\r\n/**\r\n * img 渲染器\r\n */\r\nconst img = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col?.renderProps || {}\r\n\r\n const getImageList = () => {\r\n if (!val) return []\r\n if (Array.isArray(val)) {\r\n return val.filter(item => item && typeof item === 'string')\r\n }\r\n return [val]\r\n }\r\n\r\n const imageList = getImageList()\r\n\r\n if (imageList.length === 0) {\r\n return rp.placeholder || ''\r\n }\r\n\r\n const defaultStyle = {\r\n width: rp.width || '80px',\r\n height: rp.height || '80px',\r\n marginRight: imageList.length > 1 ? '4px' : '0',\r\n ...(rp.style || {})\r\n }\r\n\r\n if (imageList.length === 1) {\r\n return h(ElImage, {\r\n src: imageList[0],\r\n previewSrcList: rp.previewSrcList || imageList,\r\n previewTeleported: true, \r\n fit: rp.fit || 'contain',\r\n style: defaultStyle,\r\n ...rp\r\n })\r\n }\r\n\r\n return h('div',\r\n {\r\n class: 'st_img_wrapper',\r\n style: 'display: flex; align-items: center; position: relative'\r\n },\r\n [\r\n h(ElImage, {\r\n src: imageList[0],\r\n previewSrcList: rp.previewSrcList || imageList,\r\n previewTeleported: true, \r\n fit: rp.fit || 'contain',\r\n style: defaultStyle,\r\n ...rp\r\n }),\r\n imageList.length > 1 && h('span', {\r\n class: 'st_img_total',\r\n style: `position: absolute; top: 0; right: 0; `,\r\n title: `${imageList.length}`\r\n }, [h(CopyDocument, { style: `width: 1em; height: 1em; ` })])\r\n ]\r\n )\r\n})\r\n\r\n/**\r\n * dict 渲染器\r\n */\r\nconst dict = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.renderProps || {}\r\n const options = rp.options ?? []\r\n const showValue = rp.showValue ?? false\r\n\r\n if (val === null || val === undefined || val === '') return ''\r\n\r\n const values = Array.isArray(val) ? val.map(String) : [String(val)]\r\n const matchedOptions = options.filter((opt: any) => values.includes(String(opt.value)))\r\n const unmatched = values.filter(v => !options.some((opt: any) => String(opt.value) === v))\r\n\r\n const children = matchedOptions.map((item: any, _index: number) => {\r\n return h(\r\n ElTag,\r\n { key: item.value, type: item.listClass, class: item.cssClass, disableTransitions: true },\r\n { default: () => item.label + ' ' }\r\n )\r\n })\r\n\r\n if (showValue && unmatched.length > 0) {\r\n children.push(h('span', {}, unmatched.join(' ')))\r\n }\r\n\r\n return h('div', {}, children)\r\n})\r\n\r\n/**\r\n * map 渲染器\r\n */\r\nconst map = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const options = (props.col.renderProps?.options ?? {}) as Record<string, any>\r\n return val != null ? options[val] ?? '' : ''\r\n})\r\n\r\n/**\r\n * formatter 渲染器\r\n */\r\nexport function isDataColumn(\r\n col: ColumnConfig\r\n): col is any {\r\n return typeof (col as any).formatter === 'function'\r\n}\r\n\r\nconst formatter = createFunctionalRenderer((props) => {\r\n const { col, row } = props\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n if (isDataColumn(col)) {\r\n return col.formatter?.(val, row)\r\n }\r\n return val ?? ''\r\n})\r\n\r\n/**\r\n * icon 渲染器\r\n */\r\nconst icon = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.renderProps || {}\r\n if (!val) return ''\r\n // 判断网络图片\r\n if (/^https?:\\/\\//.test(val)) {\r\n return h(ElImage, {\r\n src: val,\r\n previewSrcList: [val],\r\n previewTeleported: true, \r\n fit: 'contain',\r\n style: 'width:40px;height:40px',\r\n ...rp\r\n })\r\n }\r\n // 判断 svg 源码\r\n if (/^\\s*<svg[\\s\\S]*<\\/svg>\\s*$/.test(val)) {\r\n return h('div', {\r\n innerHTML: val,\r\n style: `width:40px;height:40px;display:inline-block;${rp.style || ''}`,\r\n ...rp\r\n })\r\n }\r\n // 默认当作 iconfont\r\n return h('i', {\r\n class: val,\r\n style: `font-size:20px;${rp.style || ''}`,\r\n ...rp\r\n })\r\n})\r\n\r\n/**\r\n * 所有内置渲染器\r\n */\r\nexport const builtInRenderers = {\r\n input,\r\n 'input-number': inputNumber,\r\n select,\r\n button,\r\n link,\r\n html,\r\n copy,\r\n img,\r\n dict,\r\n map,\r\n formatter,\r\n icon,\r\n}\r\n\r\n/**\r\n * 安装所有内置渲染器\r\n */\r\nexport function registerBuiltInRenderers(registry: { registerMultiple: (renderers: Record<string, any>) => void }) {\r\n registry.registerMultiple(builtInRenderers)\r\n}\r\n\r\n/**\r\n * 创建默认渲染器集合(兼容旧 API)\r\n * @deprecated 建议使用插件化架构\r\n */\r\nexport function createRenderer() {\r\n return builtInRenderers\r\n}\r\n","<template>\r\n <el-table ref=\"tableRef\"\r\n v-bind=\"$attrs\"\r\n :data=\"data\"\r\n :row-key=\"rowKey\"\r\n class=\"smart_table\"\r\n v-loading=\"loading\">\r\n\r\n <!-- ========== selection 列 ========== -->\r\n <el-table-column\r\n v-for=\"col in selectionColumns\"\r\n key=\"selection\"\r\n type=\"selection\"\r\n v-bind=\"col.columnProps\"\r\n />\r\n\r\n <!-- ========== index 列 ========== -->\r\n <el-table-column\r\n v-for=\"col in indexColumns\"\r\n key=\"index\"\r\n type=\"index\"\r\n :label=\"col.label || '#'\"\r\n align=\"center\"\r\n v-bind=\"col.columnProps\"\r\n >\r\n <template #default=\"{ $index }\">\r\n {{ computeIndex($index) }}\r\n </template>\r\n </el-table-column>\r\n\r\n <!-- ========== operation 列 ========== -->\r\n <el-table-column\r\n v-for=\"col in getOperationColumns()\"\r\n :key=\"col.key\"\r\n :label=\"col.label || '操作'\"\r\n align=\"center\"\r\n v-bind=\"{\r\n ...col.columnProps,\r\n width: getOperationWidth(col)\r\n }\"\r\n >\r\n <template #default=\"{ row }\">\r\n <el-button\r\n v-for=\"btn in getVisibleButtons(col, row)\"\r\n :key=\"btn.label\"\r\n :type=\"btn.type || 'primary'\"\r\n link\r\n @click=\"btn.action(row)\"\r\n >\r\n {{ btn.label }}\r\n </el-button>\r\n </template>\r\n </el-table-column>\r\n\r\n <!-- ========== 普通数据列 ========== -->\r\n <el-table-column\r\n v-for=\"col in dataColumns\"\r\n :key=\"col.key\"\r\n :label=\"col.label\"\r\n align=\"center\"\r\n v-bind=\"col.columnProps || {}\"\r\n >\r\n <template #default=\"scope\">\r\n <!-- 父组件插槽优先 -->\r\n <template v-if=\"col.render === 'slot'\">\r\n <slot :name=\"col?.slot || col.key\" v-bind=\"scope\" />\r\n </template>\r\n\r\n <!-- renderer -->\r\n <component\r\n v-else-if=\"col.render && renderer[col.render]\"\r\n :is=\"renderer[col.render]\"\r\n :row=\"scope.row\"\r\n :col=\"col\"\r\n :onCellChange=\"handleCellChange\"\r\n :onCellBlur=\"handleCellBlur\"\r\n :onCellEnter=\"handleCellEnter\"\r\n :onClick=\"handleCellClick\"\r\n />\r\n <!-- 默认文本 -->\r\n <span v-else\r\n :style=\"col.renderProps?.style || ''\"\r\n :class=\"col.renderProps?.class || ''\"\r\n :title=\"getValueByPath(scope.row, col.key)\">\r\n {{ getValueByPath(scope.row, col.key) }}\r\n </span>\r\n </template>\r\n </el-table-column>\r\n\r\n <!-- 动态插槽 -->\r\n <template v-for=\"col in dataColumns\" #[col.key]=\"slotProps\">\r\n <slot :name=\"col.key\" v-bind=\"slotProps\" />\r\n </template>\r\n </el-table>\r\n</template>\r\n\r\n<script setup lang=\"ts\" name=\"SmartTable\">\r\n import { PropType, ref, watch, computed } from 'vue'\r\n import type { BaseColumn, ColumnConfig } from './types'\r\n import { useTableColumns } from \"./hooks/useTableColumns\"\r\n import { useOperationColumn } from './hooks/useOperationColumn'\r\n import { getRendererManager } from './renderer'\r\n import { registerBuiltInRenderers } from './renderers'\r\n import { getValueByPath } from './utils/path'\r\n\r\n const props = defineProps({\r\n data: { type: Array, default: () => [] },\r\n columns: { type: Array, default: () => [] },\r\n rowKey: { type: String, default: 'id' },\r\n loading: { type: Boolean, default: false },\r\n permissions: {\r\n type: Array as PropType<string[]>,\r\n default: () => []\r\n },\r\n cacheKey: String,\r\n pagination: { type: Object, default: () => ({}) },\r\n })\r\n\r\n const emit = defineEmits([\r\n 'update:columns',\r\n 'cellChange',\r\n 'cellBlur',\r\n 'cellEnter',\r\n 'cell-click',\r\n ])\r\n\r\n // ------------------ columns 处理 ------------------\r\n const { columns: cachedColumns } = useTableColumns(props.columns, {\r\n cacheKey: props.cacheKey ?? '',\r\n })\r\n watch(\r\n cachedColumns,\r\n (val: ColumnConfig[]) => emit(\"update:columns\", val),\r\n { deep: true, immediate: true },\r\n )\r\n\r\n // ------------------ 将行数据传递给 operation 列 ------------------\r\n watch(\r\n () => props.data,\r\n (newData) => {\r\n if (!newData) return\r\n\r\n // 为 operation 列注入 __rows,用于计算宽度\r\n cachedColumns.value.forEach((col: ColumnConfig) => {\r\n if (col.type === 'operation') {\r\n col.__rows = newData\r\n }\r\n })\r\n },\r\n { deep: true, immediate: true }\r\n )\r\n\r\n // ------------------ 列分类 ------------------\r\n const selectionColumns = computed(() =>\r\n cachedColumns.value.filter(col => col.type === 'selection')\r\n )\r\n\r\n const indexColumns = computed(() =>\r\n cachedColumns.value.filter(col => col.type === 'index')\r\n )\r\n\r\n const operationColumns = computed(() =>\r\n cachedColumns.value.filter(col => col.type === 'operation')\r\n )\r\n\r\n const dataColumns = computed(() =>\r\n cachedColumns.value.filter(col => {\r\n if (col.type === 'selection' || col.type === 'index') return false\r\n if (col.type === 'operation') return false\r\n if (col.visible === false) return false\r\n return true\r\n })\r\n )\r\n\r\n // ------------------ index 列序号计算 ------------------\r\n const computeIndex = (index: number) => {\r\n const page = props.pagination?.page\r\n const size = props.pagination?.size\r\n return page && size ? (page - 1) * size + index + 1 : index + 1\r\n }\r\n\r\n // ------------------ renderer 注册 ------------------\r\n registerBuiltInRenderers(getRendererManager())\r\n\r\n const renderer = computed(() => {\r\n const manager = getRendererManager()\r\n const allRenderers: Record<string, any> = {}\r\n\r\n manager.names().forEach((name: string) => {\r\n const r = manager.get(name)\r\n if (r) allRenderers[name] = r\r\n })\r\n\r\n return allRenderers\r\n })\r\n\r\n // ------------------ operation 列逻辑 ------------------\r\n // 为每个 operation 列创建 useOperationColumn 实例\r\n const operationColumnMap = computed(() => {\r\n const map = new Map<string, ReturnType<typeof useOperationColumn>>()\r\n\r\n operationColumns.value.forEach(col => {\r\n const hook = useOperationColumn(\r\n col.buttons || [],\r\n col.maxbtn ?? 10,\r\n props.permissions || []\r\n )\r\n map.set(col.key, hook)\r\n })\r\n\r\n return map\r\n })\r\n\r\n const getOperationColumnHook = (col: ColumnConfig) => {\r\n return operationColumnMap.value.get(col.key)\r\n }\r\n\r\n const getOperationWidth = (col: ColumnConfig) => {\r\n const hook = getOperationColumnHook(col)\r\n if (!hook) return 0\r\n\r\n // 无行数据,用静态宽度\r\n if (!col.__rows) return hook.optWidth.value\r\n // 有行数据,取最大宽度\r\n return hook.getMaxOptWidth(col.__rows)\r\n }\r\n\r\n const getVisibleButtons = (col: ColumnConfig, row: any) => {\r\n const hook = getOperationColumnHook(col)\r\n if (!hook) return []\r\n\r\n // 检查 operation 列是否应该显示\r\n const buttons = col.buttons || []\r\n if (!buttons.length) return []\r\n\r\n const rows = col.__rows || []\r\n if (!rows.length) {\r\n // 无行数据,基于权限判断\r\n return hook.getVisibleButtons(row)\r\n }\r\n\r\n // 有行数据,基于权限 + visible 判断\r\n return hook.getVisibleButtons(row)\r\n }\r\n\r\n const getOperationColumns = () => {\r\n return operationColumns.value.filter(col => {\r\n const hook = getOperationColumnHook(col)\r\n if (!hook) return false\r\n\r\n const buttons = col.buttons || []\r\n if (!buttons.length) return false\r\n\r\n const rows = col.__rows || []\r\n if (!rows.length) return hook.hasAnyButton.value\r\n\r\n return hook.hasAnyVisibleButton(col.__rows || [])\r\n })\r\n }\r\n\r\n // ----------------事件封装 ------------------\r\n const handleCellChange = (row: any, key: string) => {\r\n emit('cellChange', row, key)\r\n }\r\n const handleCellBlur = (row: any, key: string) => {\r\n emit('cellBlur', row, key)\r\n }\r\n const handleCellEnter = (row: any, key: string) => {\r\n emit('cellEnter', row, key)\r\n }\r\n const handleCellClick = (row: any, col: any) => {\r\n if(!col) return\r\n emit('cell-click', row, col)\r\n }\r\n\r\n // el-table\r\n const tableRef = ref();\r\n defineExpose({\r\n tableRef,\r\n });\r\n\r\n</script>\r\n\r\n<style>\r\n .smart_table {\r\n width: 100%;\r\n }\r\n \r\n .st_copy_wrapper:hover .st_copy_btn {\r\n display: inline-block !important;\r\n }\r\n\r\n .st_copy_btn:hover {\r\n transform: translateY(-50%) scale(1.1);\r\n }\r\n</style>\r\n","/**\r\n * 全局配置管理\r\n */\r\nimport type { SmartTableConfig } from './types'\r\nimport { getRendererManager } from './renderer'\r\n\r\n/**\r\n * 默认配置\r\n */\r\nconst defaultConfig: SmartTableConfig = {\r\n defaultPagination: {\r\n page: 1,\r\n size: 10,\r\n total: 0\r\n },\r\n defaultTableProps: {},\r\n defaultColumnProps: {}\r\n}\r\n\r\n/**\r\n * 全局配置类\r\n */\r\nclass ConfigManager {\r\n private config: SmartTableConfig = { ...defaultConfig }\r\n\r\n /**\r\n * 获取所有配置\r\n */\r\n getConfig(): SmartTableConfig {\r\n return { ...this.config }\r\n }\r\n\r\n /**\r\n * 设置配置\r\n */\r\n setConfig(config: Partial<SmartTableConfig>): void {\r\n this.config = this.mergeConfig(this.config, config)\r\n\r\n // 如果有自定义渲染器,自动注册\r\n if (config.renderers) {\r\n const manager = getRendererManager()\r\n manager.registerMultiple(config.renderers)\r\n }\r\n }\r\n\r\n /**\r\n * 获取特定配置项\r\n */\r\n get<K extends keyof SmartTableConfig>(key: K): SmartTableConfig[K] {\r\n return this.config[key]\r\n }\r\n\r\n /**\r\n * 重置为默认配置\r\n */\r\n reset(): void {\r\n this.config = { ...defaultConfig }\r\n }\r\n\r\n /**\r\n * 深度合并配置\r\n */\r\n private mergeConfig(target: any, source: any): any {\r\n const result = { ...target }\r\n\r\n for (const key in source) {\r\n if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {\r\n result[key] = this.mergeConfig(target[key] || {}, source[key])\r\n } else {\r\n result[key] = source[key]\r\n }\r\n }\r\n\r\n return result\r\n }\r\n}\r\n\r\n/**\r\n * 全局配置管理器单例\r\n */\r\nlet globalConfigManager: ConfigManager | null = null\r\n\r\n/**\r\n * 获取全局配置管理器\r\n */\r\nexport function getConfigManager(): ConfigManager {\r\n if (!globalConfigManager) {\r\n globalConfigManager = new ConfigManager()\r\n }\r\n return globalConfigManager\r\n}\r\n\r\n/**\r\n * 安装插件(用于 Vue.use())\r\n */\r\nexport interface SmartTablePlugin {\r\n install: (options?: SmartTableConfig) => void\r\n}\r\n\r\n/**\r\n * 创建插件实例\r\n */\r\nexport function createSmartTablePlugin(defaultOptions?: SmartTableConfig): SmartTablePlugin {\r\n return {\r\n install(options?: SmartTableConfig) {\r\n const manager = getConfigManager()\r\n const config = { ...defaultOptions, ...options }\r\n if (config) {\r\n manager.setConfig(config)\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 全局配置快捷方法\r\n */\r\nexport function setSmartTableConfig(config: Partial<SmartTableConfig>): void {\r\n getConfigManager().setConfig(config)\r\n}\r\n\r\nexport function getSmartTableConfig(): SmartTableConfig {\r\n return getConfigManager().getConfig()\r\n}\r\n","/**\r\n * 增强类型系统 - 提供更好的类型推断\r\n */\r\nimport type { ColumnConfig, RendererName } from '../components/SmartTable/types'\r\n\r\n/**\r\n * 提取行数据的类型\r\n */\r\nexport type ExtractRowType<T> = T extends ColumnConfig<infer R> ? R : never\r\n\r\n/**\r\n * 根据列配置提取表格数据类型\r\n */\r\nexport type TableDataFromColumns<T extends ColumnConfig[]> = T extends (infer C)[]\r\n ? C extends ColumnConfig<infer R>\r\n ? R\r\n : any\r\n : any\r\n\r\n/**\r\n * 渲染器 Props 类型推断\r\n */\r\nexport type InferRendererProps<T extends RendererName> =\r\n T extends 'html'\r\n ? { style?: string; class?: string; [key: string]: any }\r\n : T extends 'copy'\r\n ? { successText?: string; errorText?: string; iconColor?: string; [key: string]: any }\r\n : T extends 'img'\r\n ? { width?: string | number; height?: string | number; fit?: string; previewSrcList?: string[]; [key: string]: any }\r\n : T extends 'dict'\r\n ? { options: Array<{ label: string; value: string | number; listClass?: string; cssClass?: string }>; showValue?: boolean }\r\n : T extends 'map'\r\n ? { options: Record<string | number, any> }\r\n : T extends 'input'\r\n ? { placeholder?: string; size?: 'small' | 'default' | 'large'; clearable?: boolean }\r\n : T extends 'select'\r\n ? { options: Array<{ label: string; value: string | number }>; placeholder?: string; clearable?: boolean }\r\n : { [key: string]: any }\r\n\r\n/**\r\n * 快捷创建列的辅助函数(类型安全简化版)\r\n */\r\nexport function defineColumn(\r\n key: string,\r\n config?: Partial<Omit<ColumnConfig, 'key'>>\r\n): ColumnConfig {\r\n return {\r\n key,\r\n ...config\r\n } as ColumnConfig\r\n}\r\n"],"names":["mergeColumns","defaultColumns","cacheColumns","cacheMap","c","col","cacheCol","useTableColumns","options","cacheKey","storage","cache","columns","ref","watch","newVal","lightColumns","newColumns","useOperationColumn","buttonConfigs","maxbtn","userPermissions","all_permission","hasPermi","value","permArray","p","hasAnyButton","computed","btn","optWidth","sum","isButtonVisible","row","optRowWidth","rows","max","RendererManager","__publicField","name","renderer","renderers","globalRendererManager","getRendererManager","wrapSFCComponent","comp","defineComponent","props","h","createFunctionalRenderer","render","validateRendererProps","rendererName","renderProps","getValueByPath","obj","path","acc","key","setValueByPath","keys","lastKey","target","__props","v","onBlur","_a","onEnter","_openBlock","_createBlock","_component_el_input","_mergeProps","$event","_component_el_input_number","onChange","_component_el_select","_createElementBlock","_Fragment","opt","_component_el_option","input","EditableInput","inputNumber","EditableNumber","select","EditableSelect","button","rp","val","ElButton","link","html","copy","butStyle","testStyle","ElMessage","textarea","successful","DocumentCopy","img","imageList","item","defaultStyle","ElImage","CopyDocument","dict","showValue","values","matchedOptions","unmatched","children","_index","ElTag","map","isDataColumn","formatter","icon","builtInRenderers","registerBuiltInRenderers","registry","createRenderer","emit","__emit","cachedColumns","newData","selectionColumns","indexColumns","operationColumns","dataColumns","computeIndex","index","page","size","_b","manager","allRenderers","r","operationColumnMap","hook","getOperationColumnHook","getOperationWidth","getVisibleButtons","getOperationColumns","handleCellChange","handleCellBlur","handleCellEnter","handleCellClick","tableRef","__expose","_withDirectives","_component_el_table","$attrs","_renderList","_component_el_table_column","_withCtx","$index","_createTextVNode","_toDisplayString","_component_el_button","scope","_renderSlot","_ctx","_resolveDynamicComponent","_normalizeStyle","_normalizeClass","_unref","_hoisted_1","slotProps","defaultConfig","ConfigManager","config","source","result","globalConfigManager","getConfigManager","setSmartTableConfig","getSmartTableConfig","defineColumn"],"mappings":"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"}