vue3-smart-table 1.0.3 → 1.0.4
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 +3 -0
- package/dist/vue3-smart-table.cjs.js +1 -1
- package/dist/vue3-smart-table.cjs.js.map +1 -1
- package/dist/vue3-smart-table.es.js +101 -93
- package/dist/vue3-smart-table.es.js.map +1 -1
- package/dist/vue3-smart-table.umd.js +2 -2
- package/dist/vue3-smart-table.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/SmartTable/renderers/index.ts +11 -2
- package/src/components/SmartTable/types.ts +3 -0
package/README.md
CHANGED
|
@@ -444,6 +444,9 @@ const tableData = [
|
|
|
444
444
|
copyTitle?: string // 复制提示文本,默认 '复制'
|
|
445
445
|
successText?: string // 成功提示,默认 '复制成功'
|
|
446
446
|
errorText?: string // 失败提示,默认 '复制失败'
|
|
447
|
+
lineClamp?: 2 // 默认显示2行,超出省略
|
|
448
|
+
textStyles?: object // 文本样式 {fontSize: '12px'}
|
|
449
|
+
textClass?: string // 文本类名
|
|
447
450
|
}
|
|
448
451
|
}
|
|
449
452
|
```
|
|
@@ -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,i])=>{this.renderers.has(r)||this.renderers.set(r,i)})}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 S(){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,i)=>r==null?void 0:r[i],n)}function P(n,e,r){if(!n||!e)return;const i=e.split("."),o=i.pop(),l=i.reduce((s,c)=>(s[c]||(s[c]={}),s[c]),n);l[o]=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 i=()=>{var l;return(l=e.onCellBlur)==null?void 0:l.call(e,e.row,e.col)},o=()=>{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:i,onKeyup:t.withKeys(o,["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 i=()=>{var l;return(l=e.onCellBlur)==null?void 0:l.call(e,e.row,e.col)},o=()=>{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:i,onKeyup:t.withKeys(o,["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 i=()=>{var s;return(s=e.onCellChange)==null?void 0:s.call(e,e.row,e.col)},o=()=>{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:i,onBlur:o,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 i;return(i=n.onClick)==null?void 0:i.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??{},i={position:"absolute",right:"-5px",top:"50%",transform:"translateY(-50%)",cursor:"pointer",display:"none","font-size":"12px",color:r.iconColor||"#409EFF","user-select":"none"};return t.h("div",{class:"st_copy_wrapper",style:"width: 100%; position: relative; display: inline-block;"},[t.h("span",{class:"st_copy_text line-clamp-1",style:"padding-right: 10px; display: block;"},e),e&&t.h("span",{class:"st_copy_btn",style:i,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 o=document.createElement("textarea");o.value=e,o.style.position="fixed",o.style.opacity="0",document.body.appendChild(o),o.select();const l=document.execCommand("copy");document.body.removeChild(o),l?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)||{},o=e?Array.isArray(e)?e.filter(c=>c&&typeof c=="string"):[e]:[];if(o.length===0)return r.placeholder||"";const l={width:r.width||"80px",height:r.height||"80px",marginRight:o.length>1?"4px":"0",...r.style||{}};return o.length===1?t.h(w.ElImage,{src:o[0],previewSrcList:r.previewSrcList||o,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:o[0],previewSrcList:r.previewSrcList||o,fit:r.fit||"contain",style:l,...r}),o.length>1&&t.h("span",{class:"st_img_total",style:"position: absolute; top: 0; right: 0; ",title:`${o.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||{},i=r.options??[],o=r.showValue??!1;if(e==null||e==="")return"";const l=Array.isArray(e)?e.map(String):[String(e)],s=i.filter(g=>l.includes(String(g.value))),c=l.filter(g=>!i.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 o&&c.length>0&&d.push(t.h("span",{},c.join(" "))),t.h("div",{},d)}),se=B(n=>{var i;const e=C(n.row,n.col.key)??"",r=((i=n.col.renderProps)==null?void 0:i.options)??{};return e!=null?r[e]??"":""});function ae(n){return typeof n.formatter=="function"}const ce=B(n=>{var o;const{col:e,row:r}=n,i=C(n.row,n.col.key)??"";return ae(e)?(o=e.formatter)==null?void 0:o.call(e,i,r):i??""}),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 o="*:*:*",l=a=>{if(!a)return!0;const m=Array.isArray(a)?a:[a];return r.some(p=>p===o||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,i=e,o=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)=>i("cellChange",u,y),c=(u,y)=>i("cellBlur",u,y),d=(u,y)=>i("cellEnter",u,y),g=(u,y)=>i("cellClick",u,y);N(S());const h=t.computed(()=>{const u=S(),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(o(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),E=>(t.openBlock(),t.createBlock(x,{key:E.label,type:E.type||"primary",link:"",onClick:V=>E.action(v)},{default:t.withCtx(()=>[t.createTextVNode(t.toDisplayString(E.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 E,V,$,I;return[t.unref(l).render==="slot"&&u.$slots[((E=t.unref(l))==null?void 0:E.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(i=>[i.key,i]));return n.map(i=>{const o=r.get(i.key);return o?{...i,visible:typeof o.visible=="boolean"?o.visible:i.visible}:i})}function ge(n,e){const{cacheKey:r,storage:i=localStorage}=e||{},o=r?i.getItem(r):null,l=t.ref(L(n,o?JSON.parse(o):[]));return t.watch(l,s=>{if(!r)return;const c=s.map(d=>({key:d.key,visible:d.visible,columnOpts:d.columnOpts}));i.setItem(r,JSON.stringify(c))},{deep:!0}),{columns:l,setColumns(s){l.value=L(n,s),r&&i.setItem(r,JSON.stringify(s))},resetColumns(){l.value=n,r&&i.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 i=n,o=r,{columns:l}=ge(i.columns,{cacheKey:i.cacheKey??""});t.watch(l,f=>o("update:columns",f),{deep:!0,immediate:!0});const s=(f,k)=>o("cellChange",f,k),c=(f,k)=>{o("cellBlur",f,k)},d=(f,k)=>{console.log("enter"),o("cellEnter",f,k)},g=(f,k)=>{k&&o("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&&S().registerMultiple(e.renderers)}get(e){return this.config[e]}reset(){this.config={...K}}mergeConfig(e,r){const i={...e};for(const o in r)r[o]&&typeof r[o]=="object"&&!Array.isArray(r[o])?i[o]=this.mergeConfig(e[o]||{},r[o]):i[o]=r[o];return i}}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=S;exports.getSmartTableConfig=Ce;exports.registerBuiltInRenderers=N;exports.setSmartTableConfig=he;exports.validateRendererProps=H;exports.wrapSFCComponent=T;
|
|
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;
|
|
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 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 line-clamp-1',\r\n style: 'padding-right: 10px; display: block;',\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","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":"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"}
|
|
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"}
|