vue3-smart-table 2.1.1 → 2.1.3
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/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 +146 -145
- 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/index.vue +1 -0
- package/src/components/SmartTable/renderers/index.ts +21 -16
- package/src/components/SmartTable/renderers/input.vue +73 -73
- package/src/components/SmartTable/renderers/inputNumber.vue +64 -64
- package/src/components/SmartTable/renderers/select.vue +87 -87
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var X=Object.defineProperty;var Z=(n,e,l)=>e in n?X(n,e,{enumerable:!0,configurable:!0,writable:!0,value:l}):n[e]=l;var T=(n,e,l)=>Z(n,typeof e!="symbol"?e+"":e,l);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("vue"),_=require("element-plus"),q=require("@element-plus/icons-vue");function z(n){return n==="selection"||n==="index"||n==="operation"}function ee(n){return n?!z(n):!1}function H(n){return n.type==="operation"}function L(n,e){if(!(e!=null&&e.length))return n;const l=new Map(e.map(s=>[s.key,s]));return n.map(s=>{const c=l.get(s.key);return c?{...s,visible:typeof c.visible=="boolean"?c.visible:s.visible}:s})}function te(n,e){const{cacheKey:l,storage:s=localStorage}=e||{},c=l?s.getItem(l):null,d=t.ref(L(n,c?JSON.parse(c):[]));return t.watch(d,p=>{if(!l)return;const y=p.map(f=>({key:f.key,visible:f.visible,columnOpts:f.columnOpts}));s.setItem(l,JSON.stringify(y))},{deep:!0}),{columns:d,setColumns(p){d.value=L(n,p),l&&s.setItem(l,JSON.stringify(p))},resetColumns(){d.value=n,l&&s.removeItem(l)}}}function ne(n,e=10,l=[]){const c="*:*:*",d=r=>{if(!r)return!0;const m=Array.isArray(r)?r:[r];return l.some(C=>C===c||m.includes(C))},p=t.computed(()=>n.some(r=>d(r.permission))),y=t.computed(()=>n.filter(m=>d(m.permission)).slice(0,e).reduce((m,C)=>m+(C.width??55),0)),f=(r,m)=>d(r.permission)&&(r.visible?r.visible(m):!0),h=r=>n.filter(C=>f(C,r)).slice(0,e).reduce((C,S)=>C+(S.width??55),0);return{hasAnyButton:p,optWidth:y,hasAnyVisibleButton:r=>r!=null&&r.length?r.some(m=>n.some(C=>f(C,m))):!1,getMaxOptWidth:r=>r!=null&&r.length?r.reduce((m,C)=>Math.max(m,h(C)),0):y.value,getVisibleButtons:r=>n.filter(m=>f(m,r)).slice(0,e)}}class oe{constructor(){T(this,"renderers",new Map)}register(e,l){this.renderers.has(e)&&process.env.NODE_ENV==="development"&&console.debug(`[SmartTable] Renderer "${e}" already registered, skipping.`),this.renderers.set(e,l)}registerMultiple(e){Object.entries(e).forEach(([l,s])=>{this.renderers.has(l)||this.renderers.set(l,s)})}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 A=null;function M(){return A||(A=new oe),A}function R(n){return t.defineComponent({props:["row","col","index","onCellChange","onCellBlur","onCellEnter","onClick"],setup(e){return()=>t.h(n,e)}})}function x(n){return t.defineComponent({props:["row","col","index","onCellChange","onCellBlur","onCellEnter","onClick"],setup(e){return()=>n(e)}})}function re(n,e){if(process.env.NODE_ENV!=="production"&&e)switch(n){case"dict":(!e.options||!Array.isArray(e.options))&&console.warn("[SmartTable] 'dict' renderer requires 'options' array, received:",e.options);break;case"select":!e.options||!Array.isArray(e.options)?console.warn("[SmartTable] 'select' renderer requires 'options' array, received:",e.options):e.options.length===0&&console.warn("[SmartTable] 'select' renderer 'options' array is empty");break;case"map":(!e.options||typeof e.options!="object")&&console.warn("[SmartTable] 'map' renderer requires 'options' object, received:",e.options);break;case"link":(!e.href||typeof e.href!="string")&&console.warn("[SmartTable] 'link' renderer requires 'href' string, received:",e.href);break;case"input-number":e.min!==void 0&&e.max!==void 0&&e.min>e.max&&console.warn(`[SmartTable] 'input-number' renderer: min (${e.min}) should not be greater than max (${e.max})`);break}}function k(n,e){if(!(!n||!e))return e.split(".").reduce((l,s)=>l==null?void 0:l[s],n)}function P(n,e,l){if(!n||!e)return;const s=e.split("."),c=s.pop(),d=s.reduce((p,y)=>(p[y]||(p[y]={}),p[y]),n);d[c]=l}const le=t.defineComponent({__name:"input",props:{row:{},col:{},index:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,l=t.ref(k(e.row,e.col.key)),s=t.computed(()=>{const a=e.col.props||{},{onBlur:o,onFocus:i,onChange:r,onInput:m,onClear:C,onEnter:S,...F}=a;return{placeholder:"",size:"small",clearable:!0,...F}});t.watch(l,a=>{P(e.row,e.col.key,a)});const c=a=>{var o,i,r;(o=e.onCellChange)==null||o.call(e,e.row,e.col),(r=(i=e.col.props)==null?void 0:i.onChange)==null||r.call(i,a,e.row,e.col)},d=a=>{var o,i,r;(o=e.onCellBlur)==null||o.call(e,e.row,e.col),(r=(i=e.col.props)==null?void 0:i.onBlur)==null||r.call(i,a,e.row,e.col)},p=a=>{var o,i;(i=(o=e.col.props)==null?void 0:o.onFocus)==null||i.call(o,a,e.row,e.col)},y=a=>{var o,i;(i=(o=e.col.props)==null?void 0:o.onInput)==null||i.call(o,a,e.row,e.col)},f=a=>{var o,i,r;(o=e.onCellEnter)==null||o.call(e,e.row,e.col),(r=(i=e.col.props)==null?void 0:i.onEnter)==null||r.call(i,a,e.row,e.col)},h=()=>{var a,o;(o=(a=e.col.props)==null?void 0:a.onClear)==null||o.call(a,e.row,e.col)};return(a,o)=>{const i=t.resolveComponent("el-input");return t.openBlock(),t.createBlock(i,t.mergeProps({modelValue:l.value,"onUpdate:modelValue":o[0]||(o[0]=r=>l.value=r)},s.value,{onBlur:d,onFocus:p,onChange:c,onInput:y,onKeyup:t.withKeys(f,["enter"]),onClear:h}),null,16,["modelValue"])}}}),se=t.defineComponent({__name:"inputNumber",props:{row:{},col:{},index:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,l=t.ref(k(e.row,e.col.key)),s=t.computed(()=>{const f=e.col.props||{},{onBlur:h,onFocus:a,onChange:o,onEnter:i,...r}=f;return{min:0,max:99999,controls:!1,size:"small",...r}});t.watch(l,f=>{P(e.row,e.col.key,f)});const c=(f,h)=>{var a,o,i;(a=e.onCellChange)==null||a.call(e,e.row,e.col),(i=(o=e.col.props)==null?void 0:o.onChange)==null||i.call(o,f,h,e.row,e.col)},d=f=>{var h,a,o;(h=e.onCellBlur)==null||h.call(e,e.row,e.col),(o=(a=e.col.props)==null?void 0:a.onBlur)==null||o.call(a,f,e.row,e.col)},p=f=>{var h,a;(a=(h=e.col.props)==null?void 0:h.onFocus)==null||a.call(h,f,e.row,e.col)},y=f=>{var h,a,o;(h=e.onCellEnter)==null||h.call(e,e.row,e.col),(o=(a=e.col.props)==null?void 0:a.onEnter)==null||o.call(a,f,e.row,e.col)};return(f,h)=>{const a=t.resolveComponent("el-input-number");return t.openBlock(),t.createBlock(a,t.mergeProps({modelValue:l.value,"onUpdate:modelValue":h[0]||(h[0]=o=>l.value=o)},s.value,{onBlur:d,onFocus:p,onChange:c,onKeyup:t.withKeys(y,["enter"])}),null,16,["modelValue"])}}}),ie=t.defineComponent({__name:"select",props:{row:{},col:{},index:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,l=t.ref(k(e.row,e.col.key)),s=t.computed(()=>{const o=e.col.props||{},{options:i,onChange:r,onBlur:m,onFocus:C,onVisibleChange:S,onClear:F,onEnter:j,...O}=o;return{placeholder:"请选择",size:"small",clearable:!0,...O}}),c=t.computed(()=>(e.col.props||{}).options||[]);t.watch(l,o=>{P(e.row,e.col.key,o)});const d=o=>{var i,r,m;(i=e.onCellChange)==null||i.call(e,e.row,e.col),(m=(r=e.col.props)==null?void 0:r.onChange)==null||m.call(r,o,e.row,e.col)},p=o=>{var i,r,m;(i=e.onCellBlur)==null||i.call(e,e.row,e.col),(m=(r=e.col.props)==null?void 0:r.onBlur)==null||m.call(r,o,e.row,e.col)},y=o=>{var i,r;(r=(i=e.col.props)==null?void 0:i.onFocus)==null||r.call(i,o,e.row,e.col)},f=o=>{var i,r;(r=(i=e.col.props)==null?void 0:i.onVisibleChange)==null||r.call(i,o,e.row,e.col)},h=()=>{var o,i;(i=(o=e.col.props)==null?void 0:o.onClear)==null||i.call(o,e.row,e.col)},a=o=>{var i,r,m;(i=e.onCellEnter)==null||i.call(e,e.row,e.col),(m=(r=e.col.props)==null?void 0:r.onEnter)==null||m.call(r,o,e.row,e.col)};return(o,i)=>{const r=t.resolveComponent("el-option"),m=t.resolveComponent("el-select");return t.openBlock(),t.createBlock(m,t.mergeProps({modelValue:l.value,"onUpdate:modelValue":i[0]||(i[0]=C=>l.value=C)},s.value,{onChange:d,onBlur:p,onFocus:y,onVisibleChange:f,onClear:h,onKeyup:t.withKeys(a,["enter"])}),{default:t.withCtx(()=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(c.value,C=>(t.openBlock(),t.createBlock(r,{key:C.value,label:C.label,value:C.value,disabled:C.disabled},null,8,["label","value","disabled"]))),128))]),_:1},16,["modelValue"])}}}),ae=R(le),ce=R(se),ue=R(ie),pe=n=>{const e={},l={};return Object.keys(n).forEach(s=>{s.startsWith("on")&&typeof n[s]=="function"?e[s]=n[s]:l[s]=n[s]}),{events:e,props:l}},de=x(n=>{const e=n.col.props||{},l=k(n.row,n.col.key),{events:s,props:c}=pe(e);return t.h(_.ElButton,{type:"primary",...c,...s,onClick:d=>{var p,y;(p=n.onClick)==null||p.call(n,n.row,n.col),(y=e.onClick)==null||y.call(e,d,n.row,n.col)}},()=>e.label||l)}),me=x(n=>{const e=n.col.props||{},l=k(n.row,n.col.key),{href:s,blank:c,label:d,...p}=e;return t.h("a",{href:s||l||"#",target:c?"_blank":"_self",rel:c?"noopener noreferrer":void 0,style:"color:#409EFF;cursor:pointer;text-decoration:none;",...p},d||l)}),fe=x(n=>{var p;const e=k(n.row,n.col.key),l=((p=n.col)==null?void 0:p.props)||{},{style:s,class:c,...d}=l;return t.h("div",{class:c||"line-clamp-2",style:s,innerHTML:e??"",...d})}),ge=x(n=>{const e=k(n.row,n.col.key)??"",l=n.col.props??{},{iconColor:s,copyTitle:c,successText:d,errorText:p,lineClamp:y,textStyles:f,textClass:h,...a}=l,o={position:"absolute",right:"-5px",top:"50%",transform:"translateY(-50%)",cursor:"pointer",display:"none","font-size":"12px",color:s||"#409EFF","user-select":"none"},i={"padding-right":"10px",display:"-webkit-box","-webkit-box-orient":"vertical","-webkit-line-clamp":y??2,overflow:"hidden",...f};return t.h("div",{class:"st_copy_wrapper",style:"width: 100%; position: relative; display: inline-block;",...a},[t.h("span",{class:`st_copy_text ${h??""}`,style:i,title:e},e),e&&t.h("span",{class:"st_copy_btn",style:o,title:c||"复制",onClick:()=>{if(e)try{if(navigator.clipboard&&navigator.clipboard.writeText)navigator.clipboard.writeText(e).then(()=>{_.ElMessage.success(d??"复制成功")}).catch(()=>{_.ElMessage.error(p??"复制失败")});else{const r=document.createElement("textarea");r.value=e,r.style.position="fixed",r.style.opacity="0",document.body.appendChild(r),r.select();const m=document.execCommand("copy");document.body.removeChild(r),m?_.ElMessage.success(d??"复制成功"):_.ElMessage.error(p??"复制失败")}}catch{_.ElMessage.error(p??"复制失败")}}},[t.h(q.DocumentCopy,{style:"width: 1em; height: 1em;"})])].filter(Boolean))}),he=x(n=>{var m;const e=k(n.row,n.col.key)??"",l=((m=n.col)==null?void 0:m.props)||{},{width:s,height:c,fit:d,previewSrcList:p,placeholder:y,style:f,...h}=l,o=e?Array.isArray(e)?e.filter(C=>C&&typeof C=="string"):[e]:[];if(o.length===0)return y||"";const i={width:s||"80px",height:c||"80px",marginRight:o.length>1?"4px":"0",...typeof f=="object"?f:{}},r={previewSrcList:p||o,previewTeleported:!0,fit:d||"contain",style:i,...h};return o.length===1?t.h(_.ElImage,{src:o[0],...r}):t.h("div",{class:"st_img_wrapper",style:"display: flex; align-items: center; position: relative"},[t.h(_.ElImage,{src:o[0],...r}),o.length>1&&t.h("span",{class:"st_img_total",style:"position: absolute; top: 0; right: 0; ",title:`${o.length}`},[t.h(q.CopyDocument,{style:"width: 1em; height: 1em; "})])])}),ye=x(n=>{const e=k(n.row,n.col.key)??"",l=n.col.props||{},{options:s=[],showValue:c=!1,...d}=l;if(e==null||e==="")return"";const p=Array.isArray(e)?e.map(String):[String(e)],y=s.filter(a=>p.includes(String(a.value))),f=p.filter(a=>!s.some(o=>String(o.value)===a)),h=y.map(a=>{const{listClass:o,cssClass:i,tagProps:r,...m}=a;return t.h(_.ElTag,{key:a.value,type:o,class:i,disableTransitions:!0,...d,...r},{default:()=>a.label+" "})});return c&&f.length>0&&h.push(t.h("span",{},f.join(" "))),t.h("div",{style:"display: inline-flex; gap: 4px; flex-wrap: wrap;"},h)}),Ce=x(n=>{const e=k(n.row,n.col.key)??"",l=n.col.props||{},{options:s={},...c}=l,d=e!=null?s[e]??"":"";return t.h("span",{...c},d)});function be(n){return typeof n.formatter=="function"}const ve=x(n=>{var y;const{col:e,row:l,index:s}=n,c=k(n.row,n.col.key)??"",d=n.col.props||{};let p=c;return be(e)&&(p=((y=e.formatter)==null?void 0:y.call(e,c,l,s))??c),t.h("span",{...d},p)}),ke=x(n=>{const e=k(n.row,n.col.key)??"",l=n.col.props||{},{style:s,size:c,class:d,...p}=l;if(!e)return"";const y=c?`${c}px`:"20px";return/^https?:\/\//.test(e)?t.h(_.ElImage,{src:e,previewSrcList:[e],previewTeleported:!0,fit:"contain",style:{width:"40px",height:"40px",...typeof s=="object"?s:{}},...p}):/^\s*<svg[\s\S]*<\/svg>\s*$/.test(e)?t.h("div",{innerHTML:e,class:d,style:{width:"40px",height:"40px",display:"inline-block",...typeof s=="object"?s:{}},...p}):t.h("i",{class:[e,d].filter(Boolean).join(" "),style:{fontSize:y,...typeof s=="object"?s:{}},...p})}),K={input:ae,"input-number":ce,select:ue,button:de,link:me,html:fe,copy:ge,img:he,dict:ye,map:Ce,formatter:ve,icon:ke};function J(n){n.registerMultiple(K)}function we(){return K}const W={defaultPagination:{page:1,size:10,total:0},defaultTableProps:{},defaultColumnProps:{}};class Be{constructor(){T(this,"config",{...W});T(this,"_initialized",!1)}get initialized(){return this._initialized}init(){this._initialized||(J(M()),this._initialized=!0)}getConfig(){return{...this.config}}setConfig(e){this.config=this.mergeConfig(this.config,e),e.renderers&&M().registerMultiple(e.renderers)}get(e){return this.config[e]}reset(){this.config={...W}}mergeConfig(e,l){const s={...e};for(const c in l)l[c]&&typeof l[c]=="object"&&!Array.isArray(l[c])?s[c]=this.mergeConfig(e[c]||{},l[c]):s[c]=l[c];return s}}let I=null;function N(){return I||(I=new Be),I}function _e(n){N().setConfig(n)}function xe(){return N().getConfig()}const Ee=["title"],U=t.defineComponent({__name:"index",props:{data:{default:()=>[]},columns:{default:()=>[]},rowKey:{default:"id"},loading:{type:Boolean,default:!1},permissions:{default:()=>[]},cacheKey:{},pagination:{default:()=>({})}},emits:["update:columns","cellChange","cellBlur","cellEnter","cellClick"],setup(n,{expose:e,emit:l}){const s=n,c=l;N().init();const{columns:d}=te(s.columns,{cacheKey:s.cacheKey??""}),p=t.ref(!1);t.watch(d,u=>{p.value&&c("update:columns",u),p.value=!0},{deep:!0,immediate:!0});const y=t.computed(()=>d.value.filter(u=>u.type==="operation")),f=t.computed(()=>{const u=new Map;return y.value.forEach(g=>{const v=ne(g.buttons||[],g.maxbtn??10,s.permissions||[]);u.set(g.key,v)}),u}),h=u=>f.value.get(u.key),a=u=>{var w;if(!H(u))return!1;const g=h(u);return!g||!(u.buttons||[]).length?!1:(w=s.data)!=null&&w.length?g.hasAnyVisibleButton(s.data):g.hasAnyButton.value},o=u=>{var v;const g=h(u);return g?(v=s.data)!=null&&v.length?g.getMaxOptWidth(s.data):g.optWidth.value:0},i=(u,g)=>{const v=h(u);return v?(u.buttons||[]).length?v.getVisibleButtons(g):[]:[]},r=t.computed(()=>d.value.filter(u=>u.type==="operation"?a(u):z(u.type)?!0:u.visible!==!1)),m=(u,g)=>u.type==="selection"?`selection-${g}`:u.type==="index"?`index-${g}`:u.type==="operation"?`operation-${u.key}-${g}`:`${u.key}-${g}`,C=u=>{var w,V;const g=(w=s.pagination)==null?void 0:w.page,v=(V=s.pagination)==null?void 0:V.size;return g&&v?(g-1)*v+u+1:u+1},S=t.computed(()=>{const u=M(),g={};return u.names().forEach(v=>{const w=u.get(v);w&&(g[v]=w)}),g}),F=(u,g)=>{c("cellChange",u,g)},j=(u,g)=>{c("cellBlur",u,g)},O=(u,g)=>{c("cellEnter",u,g)},Y=(u,g)=>{g&&c("cellClick",u,g)},D=t.ref();return e({tableRef:D}),(u,g)=>{const v=t.resolveComponent("el-table-column"),w=t.resolveComponent("el-button"),V=t.resolveComponent("el-table"),G=t.resolveDirective("loading");return t.withDirectives((t.openBlock(),t.createBlock(V,t.mergeProps({ref_key:"tableRef",ref:D},u.$attrs,{data:n.data,"row-key":n.rowKey,class:"smart_table"}),{default:t.withCtx(()=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(r.value,(b,Q)=>(t.openBlock(),t.createElementBlock(t.Fragment,{key:m(b,Q)},[b.type==="selection"?(t.openBlock(),t.createBlock(v,t.mergeProps({key:0,type:"selection"},{ref_for:!0},b.columnProps),null,16)):b.type==="index"?(t.openBlock(),t.createBlock(v,t.mergeProps({key:1,type:"index",label:b.label||"#",align:"center"},{ref_for:!0},b.columnProps),{default:t.withCtx(({$index:B})=>[t.createTextVNode(t.toDisplayString(C(B)),1)]),_:1},16,["label"])):b.type==="operation"?(t.openBlock(),t.createBlock(v,t.mergeProps({key:2,label:b.label||"操作",align:"center"},{ref_for:!0},{...b.columnProps,width:o(b)}),{default:t.withCtx(({row:B})=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(i(b,B),E=>(t.openBlock(),t.createBlock(w,{key:E.label,type:E.type||"primary",link:"",onClick:$=>E.action(B)},{default:t.withCtx(()=>[t.createTextVNode(t.toDisplayString(E.label),1)]),_:2},1032,["type","onClick"]))),128))]),_:2},1040,["label"])):(t.openBlock(),t.createBlock(v,t.mergeProps({key:3,label:b.label,align:"center"},{ref_for:!0},b.columnProps||{}),{default:t.withCtx(B=>{var E,$;return[b.type==="slot"?(t.openBlock(),t.createElementBlock(t.Fragment,{key:0},[B.$index>=0?t.renderSlot(u.$slots,b.slot||b.key,t.mergeProps({key:0,ref_for:!0},B)):t.createCommentVNode("",!0)],64)):b.type&&S.value[b.type]?(t.openBlock(),t.createBlock(t.resolveDynamicComponent(S.value[b.type]),{key:1,row:B.row,col:b,index:B.$index,onCellChange:F,onCellBlur:j,onCellEnter:O,onClick:Y},null,40,["row","col","index"])):(t.openBlock(),t.createElementBlock("span",{key:2,style:t.normalizeStyle(((E=b.props)==null?void 0:E.style)||""),class:t.normalizeClass((($=b.props)==null?void 0:$.class)||""),title:t.unref(k)(B.row,b.key)},t.toDisplayString(t.unref(k)(B.row,b.key)),15,Ee))]}),_:2},1040,["label"]))],64))),128))]),_:3},16,["data","row-key"])),[[G,n.loading]])}}});function Se(n,e){return{key:n,...e}}exports.SmartTable=U;exports.builtInRenderers=K;exports.createFunctionalRenderer=x;exports.createRenderer=we;exports.default=U;exports.defineColumn=Se;exports.getRendererManager=M;exports.getSmartTableConfig=xe;exports.isOperationColumn=H;exports.isRendererType=ee;exports.isSpecialColumn=z;exports.registerBuiltInRenderers=J;exports.setSmartTableConfig=_e;exports.validateRendererProps=re;exports.wrapSFCComponent=R;
|
|
1
|
+
"use strict";var Z=Object.defineProperty;var ee=(n,e,l)=>e in n?Z(n,e,{enumerable:!0,configurable:!0,writable:!0,value:l}):n[e]=l;var T=(n,e,l)=>ee(n,typeof e!="symbol"?e+"":e,l);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("vue"),_=require("element-plus"),H=require("@element-plus/icons-vue");function P(n){return n==="selection"||n==="index"||n==="operation"}function te(n){return n?!P(n):!1}function J(n){return n.type==="operation"}function L(n,e){if(!(e!=null&&e.length))return n;const l=new Map(e.map(s=>[s.key,s]));return n.map(s=>{const c=l.get(s.key);return c?{...s,visible:typeof c.visible=="boolean"?c.visible:s.visible}:s})}function ne(n,e){const{cacheKey:l,storage:s=localStorage}=e||{},c=l?s.getItem(l):null,m=t.ref(L(n,c?JSON.parse(c):[]));return t.watch(m,p=>{if(!l)return;const y=p.map(f=>({key:f.key,visible:f.visible,columnOpts:f.columnOpts}));s.setItem(l,JSON.stringify(y))},{deep:!0}),{columns:m,setColumns(p){m.value=L(n,p),l&&s.setItem(l,JSON.stringify(p))},resetColumns(){m.value=n,l&&s.removeItem(l)}}}function oe(n,e=10,l=[]){const c="*:*:*",m=r=>{if(!r)return!0;const d=Array.isArray(r)?r:[r];return l.some(C=>C===c||d.includes(C))},p=t.computed(()=>n.some(r=>m(r.permission))),y=t.computed(()=>n.filter(d=>m(d.permission)).slice(0,e).reduce((d,C)=>d+(C.width??55),0)),f=(r,d)=>m(r.permission)&&(r.visible?r.visible(d):!0),h=r=>n.filter(C=>f(C,r)).slice(0,e).reduce((C,S)=>C+(S.width??55),0);return{hasAnyButton:p,optWidth:y,hasAnyVisibleButton:r=>r!=null&&r.length?r.some(d=>n.some(C=>f(C,d))):!1,getMaxOptWidth:r=>r!=null&&r.length?r.reduce((d,C)=>Math.max(d,h(C)),0):y.value,getVisibleButtons:r=>n.filter(d=>f(d,r)).slice(0,e)}}class re{constructor(){T(this,"renderers",new Map)}register(e,l){this.renderers.has(e)&&process.env.NODE_ENV==="development"&&console.debug(`[SmartTable] Renderer "${e}" already registered, skipping.`),this.renderers.set(e,l)}registerMultiple(e){Object.entries(e).forEach(([l,s])=>{this.renderers.has(l)||this.renderers.set(l,s)})}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 A=null;function M(){return A||(A=new re),A}function R(n){return t.defineComponent({props:["row","col","index","onCellChange","onCellBlur","onCellEnter","onClick"],setup(e){return()=>t.h(n,e)}})}function x(n){return t.defineComponent({props:["row","col","index","onCellChange","onCellBlur","onCellEnter","onClick"],setup(e){return()=>n(e)}})}function le(n,e){if(process.env.NODE_ENV!=="production"&&e)switch(n){case"dict":(!e.options||!Array.isArray(e.options))&&console.warn("[SmartTable] 'dict' renderer requires 'options' array, received:",e.options);break;case"select":!e.options||!Array.isArray(e.options)?console.warn("[SmartTable] 'select' renderer requires 'options' array, received:",e.options):e.options.length===0&&console.warn("[SmartTable] 'select' renderer 'options' array is empty");break;case"map":(!e.options||typeof e.options!="object")&&console.warn("[SmartTable] 'map' renderer requires 'options' object, received:",e.options);break;case"link":(!e.href||typeof e.href!="string")&&console.warn("[SmartTable] 'link' renderer requires 'href' string, received:",e.href);break;case"input-number":e.min!==void 0&&e.max!==void 0&&e.min>e.max&&console.warn(`[SmartTable] 'input-number' renderer: min (${e.min}) should not be greater than max (${e.max})`);break}}function k(n,e){if(!(!n||!e))return e.split(".").reduce((l,s)=>l==null?void 0:l[s],n)}function z(n,e,l){if(!n||!e)return;const s=e.split("."),c=s.pop(),m=s.reduce((p,y)=>(p[y]||(p[y]={}),p[y]),n);m[c]=l}const se=t.defineComponent({__name:"input",props:{row:{},col:{},index:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,l=t.ref(k(e.row,e.col.key)),s=t.computed(()=>{const a=e.col.props||{},{onBlur:o,onFocus:i,onChange:r,onInput:d,onClear:C,onEnter:S,...F}=a;return{placeholder:"",size:"small",clearable:!0,...F}});t.watch(l,a=>{z(e.row,e.col.key,a)});const c=a=>{var o,i,r;(o=e.onCellChange)==null||o.call(e,e.row,e.col),(r=(i=e.col.props)==null?void 0:i.onChange)==null||r.call(i,a,e.row,e.col)},m=a=>{var o,i,r;(o=e.onCellBlur)==null||o.call(e,e.row,e.col),(r=(i=e.col.props)==null?void 0:i.onBlur)==null||r.call(i,a,e.row,e.col)},p=a=>{var o,i;(i=(o=e.col.props)==null?void 0:o.onFocus)==null||i.call(o,a,e.row,e.col)},y=a=>{var o,i;(i=(o=e.col.props)==null?void 0:o.onInput)==null||i.call(o,a,e.row,e.col)},f=a=>{var o,i,r;(o=e.onCellEnter)==null||o.call(e,e.row,e.col),(r=(i=e.col.props)==null?void 0:i.onEnter)==null||r.call(i,a,e.row,e.col)},h=()=>{var a,o;(o=(a=e.col.props)==null?void 0:a.onClear)==null||o.call(a,e.row,e.col)};return(a,o)=>{const i=t.resolveComponent("el-input");return t.openBlock(),t.createBlock(i,t.mergeProps({modelValue:l.value,"onUpdate:modelValue":o[0]||(o[0]=r=>l.value=r)},s.value,{onBlur:m,onFocus:p,onChange:c,onInput:y,onKeyup:t.withKeys(f,["enter"]),onClear:h}),null,16,["modelValue"])}}}),ie=t.defineComponent({__name:"inputNumber",props:{row:{},col:{},index:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,l=t.ref(k(e.row,e.col.key)),s=t.computed(()=>{const f=e.col.props||{},{onBlur:h,onFocus:a,onChange:o,onEnter:i,...r}=f;return{min:0,max:99999,controls:!1,size:"small",...r}});t.watch(l,f=>{z(e.row,e.col.key,f)});const c=(f,h)=>{var a,o,i;(a=e.onCellChange)==null||a.call(e,e.row,e.col),(i=(o=e.col.props)==null?void 0:o.onChange)==null||i.call(o,f,h,e.row,e.col)},m=f=>{var h,a,o;(h=e.onCellBlur)==null||h.call(e,e.row,e.col),(o=(a=e.col.props)==null?void 0:a.onBlur)==null||o.call(a,f,e.row,e.col)},p=f=>{var h,a;(a=(h=e.col.props)==null?void 0:h.onFocus)==null||a.call(h,f,e.row,e.col)},y=f=>{var h,a,o;(h=e.onCellEnter)==null||h.call(e,e.row,e.col),(o=(a=e.col.props)==null?void 0:a.onEnter)==null||o.call(a,f,e.row,e.col)};return(f,h)=>{const a=t.resolveComponent("el-input-number");return t.openBlock(),t.createBlock(a,t.mergeProps({modelValue:l.value,"onUpdate:modelValue":h[0]||(h[0]=o=>l.value=o)},s.value,{onBlur:m,onFocus:p,onChange:c,onKeyup:t.withKeys(y,["enter"])}),null,16,["modelValue"])}}}),ae=t.defineComponent({__name:"select",props:{row:{},col:{},index:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,l=t.ref(k(e.row,e.col.key)),s=t.computed(()=>{const o=e.col.props||{},{options:i,onChange:r,onBlur:d,onFocus:C,onVisibleChange:S,onClear:F,onEnter:j,...O}=o;return{placeholder:"请选择",size:"small",clearable:!0,...O}}),c=t.computed(()=>(e.col.props||{}).options||[]);t.watch(l,o=>{z(e.row,e.col.key,o)});const m=o=>{var i,r,d;(i=e.onCellChange)==null||i.call(e,e.row,e.col),(d=(r=e.col.props)==null?void 0:r.onChange)==null||d.call(r,o,e.row,e.col)},p=o=>{var i,r,d;(i=e.onCellBlur)==null||i.call(e,e.row,e.col),(d=(r=e.col.props)==null?void 0:r.onBlur)==null||d.call(r,o,e.row,e.col)},y=o=>{var i,r;(r=(i=e.col.props)==null?void 0:i.onFocus)==null||r.call(i,o,e.row,e.col)},f=o=>{var i,r;(r=(i=e.col.props)==null?void 0:i.onVisibleChange)==null||r.call(i,o,e.row,e.col)},h=()=>{var o,i;(i=(o=e.col.props)==null?void 0:o.onClear)==null||i.call(o,e.row,e.col)},a=o=>{var i,r,d;(i=e.onCellEnter)==null||i.call(e,e.row,e.col),(d=(r=e.col.props)==null?void 0:r.onEnter)==null||d.call(r,o,e.row,e.col)};return(o,i)=>{const r=t.resolveComponent("el-option"),d=t.resolveComponent("el-select");return t.openBlock(),t.createBlock(d,t.mergeProps({modelValue:l.value,"onUpdate:modelValue":i[0]||(i[0]=C=>l.value=C)},s.value,{onChange:m,onBlur:p,onFocus:y,onVisibleChange:f,onClear:h,onKeyup:t.withKeys(a,["enter"])}),{default:t.withCtx(()=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(c.value,C=>(t.openBlock(),t.createBlock(r,{key:C.value,label:C.label,value:C.value,disabled:C.disabled},null,8,["label","value","disabled"]))),128))]),_:1},16,["modelValue"])}}}),ce=R(se),ue=R(ie),pe=R(ae),W=(n,e)=>n==null||n===""?e:typeof n=="number"?n+"px":n,me=n=>{const e={},l={};return Object.keys(n).forEach(s=>{s.startsWith("on")&&typeof n[s]=="function"?e[s]=n[s]:l[s]=n[s]}),{events:e,props:l}},de=x(n=>{const e=n.col.props||{},l=k(n.row,n.col.key),{events:s,props:c}=me(e);return t.h(_.ElButton,{type:"primary",...c,...s,onClick:m=>{var p,y;(p=n.onClick)==null||p.call(n,n.row,n.col),(y=e.onClick)==null||y.call(e,m,n.row,n.col)}},()=>e.label||l)}),fe=x(n=>{const e=n.col.props||{},l=k(n.row,n.col.key),{href:s,blank:c,label:m,...p}=e;return t.h("a",{href:s||l||"#",target:c?"_blank":"_self",rel:c?"noopener noreferrer":void 0,style:"color:#409EFF;cursor:pointer;text-decoration:none;",...p},m||l)}),ge=x(n=>{var p;const e=k(n.row,n.col.key),l=((p=n.col)==null?void 0:p.props)||{},{style:s,class:c,...m}=l;return t.h("div",{class:c||"line-clamp-2",style:s,innerHTML:e??"",...m})}),he=x(n=>{const e=k(n.row,n.col.key)??"",l=n.col.props??{},{iconColor:s,copyTitle:c,successText:m,errorText:p,lineClamp:y,textStyles:f,textClass:h,...a}=l,o={position:"absolute",right:"-5px",top:"50%",transform:"translateY(-50%)",cursor:"pointer",display:"none","font-size":"12px",color:s||"#409EFF","user-select":"none"},i={"padding-right":"10px",display:"-webkit-box","-webkit-box-orient":"vertical","-webkit-line-clamp":y??2,overflow:"hidden",...f};return t.h("div",{class:"st_copy_wrapper",style:"width: 100%; position: relative; display: inline-block;",...a},[t.h("span",{class:`st_copy_text ${h??""}`,style:i,title:e},e),e&&t.h("span",{class:"st_copy_btn",style:o,title:c||"复制",onClick:()=>{if(e)try{if(navigator.clipboard&&navigator.clipboard.writeText)navigator.clipboard.writeText(e).then(()=>{_.ElMessage.success(m??"复制成功")}).catch(()=>{_.ElMessage.error(p??"复制失败")});else{const r=document.createElement("textarea");r.value=e,r.style.position="fixed",r.style.opacity="0",document.body.appendChild(r),r.select();const d=document.execCommand("copy");document.body.removeChild(r),d?_.ElMessage.success(m??"复制成功"):_.ElMessage.error(p??"复制失败")}}catch{_.ElMessage.error(p??"复制失败")}}},[t.h(H.DocumentCopy,{style:"width: 1em; height: 1em;"})])].filter(Boolean))}),ye=x(n=>{var d;const e=k(n.row,n.col.key)??"",l=((d=n.col)==null?void 0:d.props)||{},{width:s,height:c,fit:m,previewSrcList:p,placeholder:y,style:f,...h}=l,o=e?Array.isArray(e)?e.filter(C=>C&&typeof C=="string"):[e]:[];if(o.length===0)return y||"";const i={width:W(s,"80px"),height:W(c,"80px"),marginRight:o.length>1?"4px":"0",...typeof f=="object"?f:{}},r={previewSrcList:p||o,previewTeleported:!0,fit:m||"contain",style:i,...h};return o.length===1?t.h(_.ElImage,{src:o[0],...r}):t.h("div",{class:"st_img_wrapper",style:"display: flex; align-items: center; position: relative"},[t.h(_.ElImage,{src:o[0],...r}),o.length>1&&t.h("span",{class:"st_img_total",style:"position: absolute; top: 0; right: 0; ",title:`${o.length}`},[t.h(H.CopyDocument,{style:"width: 1em; height: 1em; "})])])}),Ce=x(n=>{const e=k(n.row,n.col.key)??"",l=n.col.props||{},{options:s=[],showValue:c=!1,...m}=l;if(e==null||e==="")return"";const p=Array.isArray(e)?e.map(String):[String(e)],y=s.filter(a=>p.includes(String(a.value))),f=p.filter(a=>!s.some(o=>String(o.value)===a)),h=y.map(a=>{const{listClass:o,cssClass:i,tagProps:r,...d}=a;return t.h(_.ElTag,{key:a.value,type:o,class:i,disableTransitions:!0,...m,...r},{default:()=>a.label+" "})});return c&&f.length>0&&h.push(t.h("span",{},f.join(" "))),t.h("div",{style:"display: inline-flex; gap: 4px; flex-wrap: wrap;"},h)}),be=x(n=>{const e=k(n.row,n.col.key)??"",l=n.col.props||{},{options:s={},...c}=l,m=e!=null?s[e]??"":"";return t.h("span",{...c},m)});function ve(n){return typeof n.formatter=="function"}const ke=x(n=>{var y;const{col:e,row:l,index:s}=n,c=k(n.row,n.col.key)??"",m=n.col.props||{};let p=c;return ve(e)&&(p=((y=e.formatter)==null?void 0:y.call(e,c,l,s))??c),t.h("span",{...m},p)}),we=x(n=>{const e=k(n.row,n.col.key)??"",l=n.col.props||{},{style:s,size:c,class:m,...p}=l;if(!e)return"";const y=c?`${c}px`:"20px";return/^https?:\/\//.test(e)?t.h(_.ElImage,{src:e,previewSrcList:[e],previewTeleported:!0,fit:"contain",style:{width:"40px",height:"40px",...typeof s=="object"?s:{}},...p}):/^\s*<svg[\s\S]*<\/svg>\s*$/.test(e)?t.h("div",{innerHTML:e,class:m,style:{width:"40px",height:"40px",display:"inline-block",...typeof s=="object"?s:{}},...p}):t.h("i",{class:[e,m].filter(Boolean).join(" "),style:{fontSize:y,...typeof s=="object"?s:{}},...p})}),K={input:ce,"input-number":ue,select:pe,button:de,link:fe,html:ge,copy:he,img:ye,dict:Ce,map:be,formatter:ke,icon:we};function U(n){n.registerMultiple(K)}function Be(){return K}const q={defaultPagination:{page:1,size:10,total:0},defaultTableProps:{},defaultColumnProps:{}};class _e{constructor(){T(this,"config",{...q});T(this,"_initialized",!1)}get initialized(){return this._initialized}init(){this._initialized||(U(M()),this._initialized=!0)}getConfig(){return{...this.config}}setConfig(e){this.config=this.mergeConfig(this.config,e),e.renderers&&M().registerMultiple(e.renderers)}get(e){return this.config[e]}reset(){this.config={...q}}mergeConfig(e,l){const s={...e};for(const c in l)l[c]&&typeof l[c]=="object"&&!Array.isArray(l[c])?s[c]=this.mergeConfig(e[c]||{},l[c]):s[c]=l[c];return s}}let I=null;function N(){return I||(I=new _e),I}function xe(n){N().setConfig(n)}function Ee(){return N().getConfig()}const Se=["title"],Y=t.defineComponent({__name:"index",props:{data:{default:()=>[]},columns:{default:()=>[]},rowKey:{default:"id"},loading:{type:Boolean,default:!1},permissions:{default:()=>[]},cacheKey:{},pagination:{default:()=>({})}},emits:["update:columns","cellChange","cellBlur","cellEnter","cellClick"],setup(n,{expose:e,emit:l}){const s=n,c=l;N().init();const{columns:m}=ne(s.columns,{cacheKey:s.cacheKey??""}),p=t.ref(!1);t.watch(m,u=>{p.value&&c("update:columns",u),p.value=!0},{deep:!0,immediate:!0});const y=t.computed(()=>m.value.filter(u=>u.type==="operation")),f=t.computed(()=>{const u=new Map;return y.value.forEach(g=>{const v=oe(g.buttons||[],g.maxbtn??10,s.permissions||[]);u.set(g.key,v)}),u}),h=u=>f.value.get(u.key),a=u=>{var w;if(!J(u))return!1;const g=h(u);return!g||!(u.buttons||[]).length?!1:(w=s.data)!=null&&w.length?g.hasAnyVisibleButton(s.data):g.hasAnyButton.value},o=u=>{var v;const g=h(u);return g?(v=s.data)!=null&&v.length?g.getMaxOptWidth(s.data):g.optWidth.value:0},i=(u,g)=>{const v=h(u);return v?(u.buttons||[]).length?v.getVisibleButtons(g):[]:[]},r=t.computed(()=>m.value.filter(u=>u.type==="operation"?a(u):P(u.type)?!0:u.visible!==!1)),d=(u,g)=>u.type==="selection"?`selection-${g}`:u.type==="index"?`index-${g}`:u.type==="operation"?`operation-${u.key}-${g}`:`${u.key}-${g}`,C=u=>{var w,V;const g=(w=s.pagination)==null?void 0:w.page,v=(V=s.pagination)==null?void 0:V.size;return g&&v?(g-1)*v+u+1:u+1},S=t.computed(()=>{const u=M(),g={};return u.names().forEach(v=>{const w=u.get(v);w&&(g[v]=w)}),g}),F=(u,g)=>{c("cellChange",u,g)},j=(u,g)=>{c("cellBlur",u,g)},O=(u,g)=>{c("cellEnter",u,g)},G=(u,g)=>{g&&c("cellClick",u,g)},D=t.ref();return e({tableRef:D}),(u,g)=>{const v=t.resolveComponent("el-table-column"),w=t.resolveComponent("el-button"),V=t.resolveComponent("el-table"),Q=t.resolveDirective("loading");return t.withDirectives((t.openBlock(),t.createBlock(V,t.mergeProps({ref_key:"tableRef",ref:D},u.$attrs,{data:n.data,"row-key":n.rowKey,class:"smart_table"}),{default:t.withCtx(()=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(r.value,(b,X)=>(t.openBlock(),t.createElementBlock(t.Fragment,{key:d(b,X)},[b.type==="selection"?(t.openBlock(),t.createBlock(v,t.mergeProps({key:0,type:"selection"},{ref_for:!0},b.columnProps),null,16)):b.type==="index"?(t.openBlock(),t.createBlock(v,t.mergeProps({key:1,type:"index",label:b.label||"#",align:"center"},{ref_for:!0},b.columnProps),{default:t.withCtx(({$index:B})=>[t.createTextVNode(t.toDisplayString(C(B)),1)]),_:1},16,["label"])):b.type==="operation"?(t.openBlock(),t.createBlock(v,t.mergeProps({key:2,label:b.label||"操作",align:"center"},{ref_for:!0},{...b.columnProps,width:o(b)}),{default:t.withCtx(({row:B})=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(i(b,B),E=>(t.openBlock(),t.createBlock(w,{key:E.label,type:E.type||"primary",link:"",onClick:$=>E.action(B)},{default:t.withCtx(()=>[t.createTextVNode(t.toDisplayString(E.label),1)]),_:2},1032,["type","onClick"]))),128))]),_:2},1040,["label"])):(t.openBlock(),t.createBlock(v,t.mergeProps({key:3,prop:b.key,label:b.label,align:"center"},{ref_for:!0},b.columnProps||{}),{default:t.withCtx(B=>{var E,$;return[b.type==="slot"?(t.openBlock(),t.createElementBlock(t.Fragment,{key:0},[B.$index>=0?t.renderSlot(u.$slots,b.slot||b.key,t.mergeProps({key:0,ref_for:!0},B)):t.createCommentVNode("",!0)],64)):b.type&&S.value[b.type]?(t.openBlock(),t.createBlock(t.resolveDynamicComponent(S.value[b.type]),{key:1,row:B.row,col:b,index:B.$index,onCellChange:F,onCellBlur:j,onCellEnter:O,onClick:G},null,40,["row","col","index"])):(t.openBlock(),t.createElementBlock("span",{key:2,style:t.normalizeStyle(((E=b.props)==null?void 0:E.style)||""),class:t.normalizeClass((($=b.props)==null?void 0:$.class)||""),title:t.unref(k)(B.row,b.key)},t.toDisplayString(t.unref(k)(B.row,b.key)),15,Se))]}),_:2},1040,["prop","label"]))],64))),128))]),_:3},16,["data","row-key"])),[[Q,n.loading]])}}});function Fe(n,e){return{key:n,...e}}exports.SmartTable=Y;exports.builtInRenderers=K;exports.createFunctionalRenderer=x;exports.createRenderer=Be;exports.default=Y;exports.defineColumn=Fe;exports.getRendererManager=M;exports.getSmartTableConfig=Ee;exports.isOperationColumn=J;exports.isRendererType=te;exports.isSpecialColumn=P;exports.registerBuiltInRenderers=U;exports.setSmartTableConfig=xe;exports.validateRendererProps=le;exports.wrapSFCComponent=R;
|
|
2
2
|
//# sourceMappingURL=vue3-smart-table.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue3-smart-table.cjs.js","sources":["../src/components/SmartTable/types.ts","../src/components/SmartTable/hooks/useTableColumns.ts","../src/components/SmartTable/hooks/useOperationColumn.ts","../src/components/SmartTable/renderer.ts","../src/components/SmartTable/utils/path.ts","../src/components/SmartTable/renderers/input.vue","../src/components/SmartTable/renderers/inputNumber.vue","../src/components/SmartTable/renderers/select.vue","../src/components/SmartTable/renderers/index.ts","../src/components/SmartTable/config.ts","../src/components/SmartTable/index.vue","../src/types/enhanced.ts"],"sourcesContent":["import type { ButtonProps, TableColumnCtx } from 'element-plus'\r\nimport { DefaultRow } from 'element-plus/es/components/table/src/table/defaults'\r\nimport type { Component } from 'vue'\r\n\r\n// 导出验证函数类型\r\nexport type { validateRendererProps } from './renderer'\r\n\r\n/* ======================= 基础工具类型 ======================= */\r\n\r\n/** 支持额外参数(Element Plus 透传 props) */\r\nexport type WithRestProps<T> = T & {\r\n [key: string]: any\r\n}\r\n\r\n/* ======================= 渲染器系统 ======================= */\r\n\r\n/** Renderer 组件类型 */\r\nexport type Renderer = Component\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\nexport interface SmartTableConfig {\r\n /** 自定义渲染器 */\r\n renderers?: Record<string, Renderer>\r\n /** 默认分页配置 */\r\n defaultPagination?: {\r\n page?: number\r\n size?: number\r\n total?: number\r\n }\r\n /** 默认表格属性 */\r\n defaultTableProps?: Record<string, any>\r\n /** 默认列属性 */\r\n defaultColumnProps?: Record<string, any>\r\n}\r\n\r\n/* ======================= 分页配置 ======================= */\r\n\r\n/** 分页配置接口 */\r\nexport interface PaginationConfig {\r\n /** 当前页码 */\r\n page?: number\r\n /** 每页条数 */\r\n size?: number\r\n /** 总条数 */\r\n total?: number\r\n}\r\n\r\n/* ======================= 操作列按钮 ======================= */\r\n\r\nexport interface ButtonConfig<R = any> {\r\n permission?: string | string[]\r\n label: string\r\n type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'\r\n action: (row: R) => void\r\n visible?: (row: R) => boolean\r\n width?: number\r\n}\r\n\r\n/* ======================= 列类型 ======================= */\r\n\r\n/**\r\n * 列类型枚举\r\n * 包含特殊列类型和渲染器类型\r\n */\r\nexport type ColumnType =\r\n // 特殊列\r\n | 'selection'\r\n | 'index'\r\n | 'operation'\r\n // 内置渲染器\r\n | 'input'\r\n | 'input-number'\r\n | 'select'\r\n | 'dict'\r\n | 'map'\r\n | 'img'\r\n | 'link'\r\n | 'button'\r\n | 'copy'\r\n | 'html'\r\n | 'formatter'\r\n | 'icon'\r\n | 'slot'\r\n\r\n/* ======================= Props 类型映射 ======================= */\r\n\r\n/** 各类型对应的 props */\r\nexport interface ColumnPropsMap {\r\n // 特殊列\r\n selection: {}\r\n index: {}\r\n operation: {}\r\n\r\n // 渲染器\r\n html: WithRestProps<{\r\n style?: string | Record<string, any>\r\n class?: string\r\n }>\r\n\r\n copy: WithRestProps<{\r\n iconColor?: string\r\n copyTitle?: string\r\n successText?: string\r\n errorText?: string\r\n lineClamp?: number\r\n textStyles?: Record<string, any>\r\n textClass?: string\r\n }>\r\n\r\n img: WithRestProps<{\r\n width?: string | number\r\n height?: string | number\r\n fit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down'\r\n previewSrcList?: string[]\r\n placeholder?: string\r\n style?: string | Record<string, any>\r\n }>\r\n\r\n dict: WithRestProps<{\r\n options: Array<{\r\n label: string\r\n value: string | number\r\n listClass?: string\r\n cssClass?: string\r\n tagProps?: Record<string, any>\r\n }>\r\n showValue?: boolean\r\n }>\r\n\r\n map: WithRestProps<{\r\n options: Record<string | number, any>\r\n }>\r\n\r\n formatter: WithRestProps<{}>\r\n\r\n icon: WithRestProps<{\r\n style?: string | Record<string, any>\r\n size?: number\r\n class?: string\r\n }>\r\n\r\n input: WithRestProps<{\r\n placeholder?: string\r\n size?: 'small' | 'default' | 'large'\r\n clearable?: boolean\r\n maxlength?: number\r\n showWordLimit?: boolean\r\n disabled?: boolean\r\n // 事件\r\n onChange?: (val: string, row: any, col: any) => void\r\n onBlur?: (e: FocusEvent, row: any, col: any) => void\r\n onFocus?: (e: FocusEvent, row: any, col: any) => void\r\n onInput?: (val: string, row: any, col: any) => void\r\n onClear?: (row: any, col: any) => void\r\n onEnter?: (e: KeyboardEvent, row: any, col: any) => void\r\n }>\r\n\r\n 'input-number': WithRestProps<{\r\n min?: number\r\n max?: number\r\n step?: number\r\n precision?: number\r\n size?: 'small' | 'default' | 'large'\r\n controls?: boolean\r\n disabled?: boolean\r\n // 事件\r\n onChange?: (val: number | undefined, oldVal: number | undefined, row: any, col: any) => void\r\n onBlur?: (e: FocusEvent, row: any, col: any) => void\r\n onFocus?: (e: FocusEvent, row: any, col: any) => void\r\n onEnter?: (e: KeyboardEvent, row: any, col: any) => void\r\n }>\r\n\r\n select: WithRestProps<{\r\n options: Array<{\r\n label: string\r\n value: string | number\r\n disabled?: boolean\r\n }>\r\n placeholder?: string\r\n size?: 'small' | 'default' | 'large'\r\n clearable?: boolean\r\n filterable?: boolean\r\n multiple?: boolean\r\n disabled?: boolean\r\n // 事件\r\n onChange?: (val: any, row: any, col: any) => void\r\n onBlur?: (e: FocusEvent, row: any, col: any) => void\r\n onFocus?: (e: FocusEvent, row: any, col: any) => void\r\n onVisibleChange?: (visible: boolean, row: any, col: any) => void\r\n onClear?: (row: any, col: any) => void\r\n }>\r\n\r\n button: WithRestProps<ButtonProps & {\r\n label?: string\r\n style?: string | Record<string, any>\r\n class?: string\r\n onClick?: (e: Event, row: any, col: any) => void\r\n }>\r\n\r\n link: WithRestProps<{\r\n label?: string\r\n href?: string\r\n blank?: boolean\r\n style?: string | Record<string, any>\r\n class?: string\r\n }>\r\n\r\n slot: {}\r\n}\r\n\r\n/* ======================= ColumnConfig ======================= */\r\n\r\n/** 列配置基础接口 */\r\nexport interface BaseColumnConfig<R extends DefaultRow = any> {\r\n /** 字段名 */\r\n key: string\r\n /** 列类型 */\r\n type?: ColumnType | string\r\n /** 列标题 */\r\n label?: string\r\n /** 是否显示 */\r\n visible?: boolean\r\n /** 是否在列控制中显示 */\r\n inControl?: boolean\r\n /** el-table-column 原生属性 */\r\n columnProps?: Partial<TableColumnCtx<R>>\r\n /** 插槽名称(type 为 slot 时使用,默认用 key) */\r\n slot?: string\r\n /** 渲染器/组件属性 */\r\n props?: Record<string, any>\r\n}\r\n\r\n/** Selection 列 */\r\nexport interface SelectionColumn<R extends DefaultRow = any> extends BaseColumnConfig<R> {\r\n type: 'selection'\r\n}\r\n\r\n/** Index 列 */\r\nexport interface IndexColumn<R extends DefaultRow = any> extends BaseColumnConfig<R> {\r\n type: 'index'\r\n}\r\n\r\n/** Operation 列 */\r\nexport interface OperationColumn<R extends DefaultRow = any> extends BaseColumnConfig<R> {\r\n type: 'operation'\r\n buttons: ButtonConfig<R>[]\r\n /** 最大显示按钮数 */\r\n maxbtn?: number\r\n}\r\n\r\n/** 数据列 */\r\nexport interface DataColumn<R extends DefaultRow = any> extends BaseColumnConfig<R> {\r\n type?: Exclude<ColumnType, 'selection' | 'index' | 'operation'> | string\r\n /**\r\n * 格式化函数(type 为 formatter 时使用)\r\n */\r\n formatter?: (value: any, row: R, index: number) => any\r\n}\r\n\r\n/** 列配置联合类型 */\r\nexport type ColumnConfig<R extends DefaultRow = any> =\r\n | SelectionColumn<R>\r\n | IndexColumn<R>\r\n | OperationColumn<R>\r\n | DataColumn<R>\r\n\r\n/* ======================= 组件 Props ======================= */\r\n\r\n/**\r\n * SmartTable 组件 Props 接口\r\n */\r\nexport interface SmartTableProps<R extends DefaultRow = any> {\r\n /** 表格数据 */\r\n data: R[]\r\n /** 列配置 */\r\n columns: ColumnConfig<R>[]\r\n /** 行数据的唯一标识字段,默认 'id' */\r\n rowKey?: string\r\n /** 是否显示加载状态 */\r\n loading?: boolean\r\n /** 权限列表,用于操作列按钮权限控制 */\r\n permissions?: string[]\r\n /** 列配置缓存 key,用于持久化列显隐配置 */\r\n cacheKey?: string\r\n /** 分页配置,用于序号列计算 */\r\n pagination?: PaginationConfig\r\n}\r\n\r\n/**\r\n * SmartTable 组件 Emits 接口\r\n */\r\nexport interface SmartTableEmits<R extends DefaultRow = any> {\r\n /** 列配置更新(v-model:columns) */\r\n (e: 'update:columns', columns: ColumnConfig<R>[]): void\r\n /** 单元格值变更 */\r\n (e: 'cellChange', row: R, col: ColumnConfig<R>): void\r\n /** 单元格失焦 */\r\n (e: 'cellBlur', row: R, col: ColumnConfig<R>): void\r\n /** 单元格回车 */\r\n (e: 'cellEnter', row: R, col: ColumnConfig<R>): void\r\n /** 单元格点击(button 类型) */\r\n (e: 'cellClick', row: R, col: ColumnConfig<R>): void\r\n}\r\n\r\n/* ======================= 辅助类型 ======================= */\r\n\r\n/** 特殊列类型 */\r\nexport type SpecialColumnType = 'selection' | 'index' | 'operation'\r\n\r\n/** 判断是否为特殊列 */\r\nexport function isSpecialColumn(type?: string): type is SpecialColumnType {\r\n return type === 'selection' || type === 'index' || type === 'operation'\r\n}\r\n\r\n/** 判断是否为渲染器类型 */\r\nexport function isRendererType(type?: string): boolean {\r\n if (!type) return false\r\n return !isSpecialColumn(type)\r\n}\r\n\r\n/** 判断是否为 operation 列 */\r\nexport function isOperationColumn<R extends DefaultRow = any>(col: ColumnConfig<R>): col is OperationColumn<R> {\r\n return col.type === 'operation'\r\n}\r\n","import { ref, watch } from 'vue'\r\n\r\n\r\n/**\r\n * 合并默认列配置和缓存配置\r\n *\r\n * 设计原则:\r\n * 1️⃣ 列顺序:以 defaultColumns 为准\r\n * 2️⃣ 列增减:以 defaultColumns 为准\r\n * 3️⃣ 缓存只覆盖用户可配置字段(如 visible)\r\n */\r\nfunction mergeColumns(\r\n defaultColumns: any[],\r\n cacheColumns: Array<{ key: string; visible?: boolean }>\r\n) {\r\n if (!cacheColumns?.length) return defaultColumns\r\n\r\n // 建立 key => cache 映射表,提升查找效率\r\n const cacheMap = new Map(\r\n cacheColumns.map(c => [c.key, c])\r\n )\r\n\r\n return defaultColumns.map(col => {\r\n const cacheCol = cacheMap.get(col.key)\r\n\r\n // 只允许缓存覆盖「可配置字段」\r\n if (!cacheCol) return col\r\n\r\n return {\r\n ...col,\r\n visible:\r\n typeof cacheCol.visible === 'boolean'\r\n ? cacheCol.visible\r\n : col.visible\r\n }\r\n })\r\n}\r\n\r\n\r\n/**\r\n * useTableColumns\r\n *\r\n * 表格列管理 Hook\r\n *\r\n * 职责:\r\n * - 管理表格列顺序\r\n * - 管理列显示 / 隐藏\r\n * - 持久化用户配置\r\n */\r\nexport function useTableColumns(\r\n defaultColumns: any[],\r\n options?: {\r\n /** 缓存唯一标识 */\r\n cacheKey?: string\r\n /** 存储介质,默认 localStorage */\r\n storage?: Storage\r\n }\r\n) {\r\n\r\n /** 解构参数并设置默认值 */\r\n const { cacheKey, storage = localStorage } = options || {}\r\n\r\n /**\r\n * 如果没有 cacheKey,则不启用缓存\r\n * (例如公共页面、未登录页面)\r\n * 从缓存中读取列配置\r\n */\r\n const cache = cacheKey ? storage.getItem(cacheKey) : null\r\n\r\n /**\r\n * 响应式列配置\r\n * 初始化时合并默认列和缓存列\r\n */\r\n const columns = ref(\r\n mergeColumns(\r\n defaultColumns,\r\n cache ? JSON.parse(cache) : []\r\n )\r\n )\r\n\r\n /**\r\n * 监听列变化,自动写入缓存\r\n */\r\n watch(\r\n columns,\r\n (newVal: any) => {\r\n if (!cacheKey) return\r\n\r\n /**\r\n * ⚠️ 只保存“轻量配置”\r\n * 避免把 render / action / 函数序列化进 localStorage\r\n */\r\n const lightColumns = newVal.map((col: any) => ({\r\n key: col.key,\r\n visible: col.visible,\r\n columnOpts: col.columnOpts\r\n }))\r\n\r\n storage.setItem(\r\n cacheKey,\r\n JSON.stringify(lightColumns)\r\n )\r\n },\r\n { deep: true }\r\n )\r\n\r\n /**\r\n * 对外暴露的 API\r\n */\r\n return {\r\n /** 当前列配置(响应式) */\r\n columns,\r\n\r\n /**\r\n * 主动设置列配置\r\n * 常用于:列设置弹窗 / 拖拽排序完成\r\n */\r\n setColumns(newColumns: any[]) {\r\n columns.value = mergeColumns(\r\n defaultColumns,\r\n newColumns\r\n )\r\n\r\n if (cacheKey) {\r\n storage.setItem(\r\n cacheKey,\r\n JSON.stringify(newColumns)\r\n )\r\n }\r\n },\r\n\r\n /**\r\n * 重置为默认列配置\r\n */\r\n resetColumns() {\r\n columns.value = defaultColumns\r\n\r\n if (cacheKey) {\r\n storage.removeItem(cacheKey)\r\n }\r\n }\r\n }\r\n}\r\n","import { computed } from 'vue'\r\n\r\nimport { ButtonConfig } from \"../types\"\r\n\r\n/**\r\n * useOperationColumn\r\n *\r\n * 操作列专用逻辑 Hook,负责:\r\n * 1. 根据权限判断操作列是否需要显示\r\n * 2. 计算操作列宽度(支持按钮自定义宽度)\r\n * 3. 支持行级 visible 配置\r\n * @param buttonConfigs 操作列按钮配置\r\n * @param maxbtn 操作列最多显示按钮数量(超过的不参与宽度计算)\r\n * @param userPermissions 当前用户权限列表\r\n */\r\nexport function useOperationColumn(\r\n buttonConfigs: ButtonConfig[],\r\n maxbtn = 10,\r\n userPermissions: string[] = []\r\n) {\r\n /** 默认按钮宽度 */\r\n const defaultWidth = 55\r\n\r\n /** 超级权限标识 */\r\n const all_permission = '*:*:*'\r\n\r\n /** --------------------------\r\n * 权限判断\r\n * -------------------------- */\r\n\r\n /**\r\n * 判断是否具备按钮权限\r\n *\r\n * 规则:\r\n * - permission 未配置 ⇒ 永远有权限\r\n * - permission 为 string | string[] ⇒ 与用户权限匹配\r\n */\r\n const hasPermi = (value?: string | string[]) => {\r\n if (!value) return true\r\n\r\n const permArray = Array.isArray(value) ? value : [value]\r\n return userPermissions.some(\r\n p => p === all_permission || permArray.includes(p)\r\n )\r\n }\r\n\r\n /** --------------------------\r\n * 仅基于权限(不考虑行级 visible)\r\n * 适用于:表格未加载数据时的判断\r\n * -------------------------- */\r\n\r\n /**\r\n * 是否至少存在一个有权限的按钮\r\n * 用于判断操作列是否需要渲染\r\n */\r\n const hasAnyButton = computed(() => {\r\n return buttonConfigs.some(btn => hasPermi(btn.permission))\r\n })\r\n\r\n /**\r\n * 操作列宽度(仅基于权限)\r\n * 用于无行数据时的兜底宽度计算\r\n *\r\n * 注意:这里不考虑 visible,因为没有 row 数据无法执行 visible 函数\r\n * 实际使用时会根据行数据重新计算\r\n */\r\n const optWidth = computed(() => {\r\n const permittedBtns = buttonConfigs\r\n .filter(btn => hasPermi(btn.permission))\r\n .slice(0, maxbtn)\r\n\r\n return permittedBtns.reduce(\r\n (sum, btn) => sum + (btn.width ?? defaultWidth),\r\n 0\r\n )\r\n })\r\n\r\n /** --------------------------\r\n * 权限 + 行级 visible\r\n * -------------------------- */\r\n\r\n /**\r\n * 判断某个按钮在某一行是否可见\r\n */\r\n const isButtonVisible = (btn: ButtonConfig, row: any) => {\r\n return (\r\n hasPermi(btn.permission) &&\r\n (btn.visible ? btn.visible(row) : true)\r\n )\r\n }\r\n\r\n /**\r\n * 单行操作列宽度\r\n */\r\n const optRowWidth = (row: any) => {\r\n const visibleBtns = buttonConfigs\r\n .filter(btn => isButtonVisible(btn, row))\r\n .slice(0, maxbtn)\r\n\r\n return visibleBtns.reduce(\r\n (sum, btn) => sum + (btn.width ?? defaultWidth),\r\n 0\r\n )\r\n }\r\n\r\n /**\r\n * 遍历所有行,获取最大操作列宽度\r\n */\r\n const getMaxOptWidth = (rows: any[]) => {\r\n if (!rows?.length) return optWidth.value\r\n return rows.reduce(\r\n (max, row) => Math.max(max, optRowWidth(row)),\r\n 0\r\n )\r\n }\r\n\r\n /**\r\n * 判断是否至少有一行存在可见按钮\r\n */\r\n const hasAnyVisibleButton = (rows: any[]) => {\r\n if (!rows?.length) return false\r\n return rows.some(row =>\r\n buttonConfigs.some(btn => isButtonVisible(btn, row))\r\n )\r\n }\r\n\r\n const getVisibleButtons = (row: any) => {\r\n return buttonConfigs\r\n .filter(btn => isButtonVisible(btn, row))\r\n .slice(0, maxbtn)\r\n }\r\n\r\n return {\r\n hasAnyButton,\r\n optWidth,\r\n hasAnyVisibleButton,\r\n getMaxOptWidth,\r\n getVisibleButtons\r\n }\r\n}\r\n","/**\r\n * SmartTable 内部渲染器管理系统\r\n * 移动到组件内部,保证组件的自包含性\r\n */\r\nimport { defineComponent, h, Component } from 'vue'\r\nimport type { Renderer } from './types'\r\n\r\n/**\r\n * 渲染器注册表接口\r\n */\r\nexport interface RendererRegistry {\r\n register(name: string, renderer: Renderer): void\r\n registerMultiple(renderers: Record<string, Renderer>): void\r\n get(name: string): Renderer | undefined\r\n has(name: string): boolean\r\n unregister(name: string): boolean\r\n clear(): void\r\n names(): string[]\r\n}\r\n\r\n/**\r\n * 渲染器管理器类\r\n */\r\nclass RendererManager implements RendererRegistry {\r\n private renderers: Map<string, Renderer> = new Map()\r\n\r\n register(name: string, renderer: Renderer): void {\r\n if (this.renderers.has(name)) {\r\n // 批量注册时不警告,只在单独注册时警告\r\n if (process.env.NODE_ENV === 'development') {\r\n console.debug(`[SmartTable] Renderer \"${name}\" already registered, skipping.`)\r\n }\r\n }\r\n this.renderers.set(name, renderer)\r\n }\r\n\r\n registerMultiple(renderers: Record<string, Renderer>): void {\r\n Object.entries(renderers).forEach(([name, renderer]) => {\r\n if (!this.renderers.has(name)) {\r\n this.renderers.set(name, renderer)\r\n }\r\n })\r\n }\r\n\r\n get(name: string): Renderer | undefined {\r\n return this.renderers.get(name)\r\n }\r\n\r\n has(name: string): boolean {\r\n return this.renderers.has(name)\r\n }\r\n\r\n unregister(name: string): boolean {\r\n return this.renderers.delete(name)\r\n }\r\n\r\n clear(): void {\r\n this.renderers.clear()\r\n }\r\n\r\n names(): string[] {\r\n return Array.from(this.renderers.keys())\r\n }\r\n}\r\n\r\n/**\r\n * 全局渲染器管理器单例\r\n */\r\nlet globalRendererManager: RendererManager | null = null\r\n\r\n/**\r\n * 获取渲染器管理器\r\n */\r\nexport function getRendererManager(): RendererManager {\r\n if (!globalRendererManager) {\r\n globalRendererManager = new RendererManager()\r\n }\r\n return globalRendererManager\r\n}\r\n\r\n/**\r\n * 包装 SFC 组件为渲染器\r\n */\r\nexport function wrapSFCComponent(comp: Component): Renderer {\r\n return defineComponent({\r\n props: ['row', 'col', 'index', '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 index: number\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', 'index', '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=\"inputProps\"\n @blur=\"onBlur\"\n @focus=\"onFocus\"\n @change=\"onChange\"\n @input=\"onInput\"\n @keyup.enter=\"onEnter\"\n @clear=\"onClear\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch, computed } 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 readonly index: number\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\n// 合并默认属性和用户自定义属性\nconst inputProps = computed(() => {\n const rp = props.col.props || {}\n const { onBlur, onFocus, onChange, onInput, onClear, onEnter, ...rest } = rp\n return {\n placeholder: '',\n size: 'small' as const,\n clearable: true,\n ...rest\n }\n})\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n})\n\nconst onChange = (val: string) => {\n props.onCellChange?.(props.row, props.col)\n props.col.props?.onChange?.(val, props.row, props.col)\n}\n\nconst onBlur = (e: FocusEvent) => {\n props.onCellBlur?.(props.row, props.col)\n props.col.props?.onBlur?.(e, props.row, props.col)\n}\n\nconst onFocus = (e: FocusEvent) => {\n props.col.props?.onFocus?.(e, props.row, props.col)\n}\n\nconst onInput = (val: string) => {\n props.col.props?.onInput?.(val, props.row, props.col)\n}\n\nconst onEnter = (e: KeyboardEvent) => {\n props.onCellEnter?.(props.row, props.col)\n props.col.props?.onEnter?.(e, props.row, props.col)\n}\n\nconst onClear = () => {\n props.col.props?.onClear?.(props.row, props.col)\n}\n</script>\n","<template>\n <el-input-number\n v-model=\"value\"\n v-bind=\"inputProps\"\n @blur=\"onBlur\"\n @focus=\"onFocus\"\n @change=\"onChange\"\n @keyup.enter=\"onEnter\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch, computed } 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 readonly index: number\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\n// 合并默认属性和用户自定义属性\nconst inputProps = computed(() => {\n const rp = props.col.props || {}\n const { onBlur, onFocus, onChange, onEnter, ...rest } = rp\n return {\n min: 0,\n max: 99999,\n controls: false,\n size: 'small' as const,\n ...rest\n }\n})\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n})\n\nconst onChange = (val: number | undefined, oldVal: number | undefined) => {\n props.onCellChange?.(props.row, props.col)\n props.col.props?.onChange?.(val, oldVal, props.row, props.col)\n}\n\nconst onBlur = (e: FocusEvent) => {\n props.onCellBlur?.(props.row, props.col)\n props.col.props?.onBlur?.(e, props.row, props.col)\n}\n\nconst onFocus = (e: FocusEvent) => {\n props.col.props?.onFocus?.(e, props.row, props.col)\n}\n\nconst onEnter = (e: KeyboardEvent) => {\n props.onCellEnter?.(props.row, props.col)\n props.col.props?.onEnter?.(e, props.row, props.col)\n}\n</script>\n","<template>\n <el-select\n v-model=\"value\"\n v-bind=\"selectProps\"\n @change=\"onChange\"\n @blur=\"onBlur\"\n @focus=\"onFocus\"\n @visible-change=\"onVisibleChange\"\n @clear=\"onClear\"\n @keyup.enter=\"onEnter\"\n >\n <el-option\n v-for=\"opt in options\"\n :key=\"opt.value\"\n :label=\"opt.label\"\n :value=\"opt.value\"\n :disabled=\"opt.disabled\"\n />\n </el-select>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch, computed } 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 readonly index: number\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\n// 合并默认属性和用户自定义属性\nconst selectProps = computed(() => {\n const rp = props.col.props || {}\n const { options, onChange, onBlur, onFocus, onVisibleChange, onClear, onEnter, ...rest } = rp\n return {\n placeholder: '请选择',\n size: 'small' as const,\n clearable: true,\n ...rest\n }\n})\n\n// 选项列表\nconst options = computed(() => {\n const rp = props.col.props || {}\n return rp.options || []\n})\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n})\n\nconst onChange = (val: any) => {\n props.onCellChange?.(props.row, props.col)\n props.col.props?.onChange?.(val, props.row, props.col)\n}\n\nconst onBlur = (e: FocusEvent) => {\n props.onCellBlur?.(props.row, props.col)\n props.col.props?.onBlur?.(e, props.row, props.col)\n}\n\nconst onFocus = (e: FocusEvent) => {\n props.col.props?.onFocus?.(e, props.row, props.col)\n}\n\nconst onVisibleChange = (visible: boolean) => {\n props.col.props?.onVisibleChange?.(visible, props.row, props.col)\n}\n\nconst onClear = () => {\n props.col.props?.onClear?.(props.row, props.col)\n}\n\nconst onEnter = (e: KeyboardEvent) => {\n props.onCellEnter?.(props.row, props.col)\n props.col.props?.onEnter?.(e, props.row, props.col)\n}\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 * 提取 props 中的事件(on 开头的属性)\r\n */\r\nconst extractEvents = (rp: Record<string, any>) => {\r\n const events: Record<string, any> = {}\r\n const props: Record<string, any> = {}\r\n \r\n Object.keys(rp).forEach(key => {\r\n if (key.startsWith('on') && typeof rp[key] === 'function') {\r\n events[key] = rp[key]\r\n } else {\r\n props[key] = rp[key]\r\n }\r\n })\r\n \r\n return { events, props }\r\n}\r\n\r\n/**\r\n * button 渲染�?\r\n */\r\nconst button = createFunctionalRenderer((props) => {\r\n const rp = props.col.props || {}\r\n const val = getValueByPath(props.row, props.col.key)\r\n const { events, props: restProps } = extractEvents(rp)\r\n \r\n return h(ElButton as any, {\r\n type: 'primary',\r\n ...restProps,\r\n ...events,\r\n onClick: (e: Event) => {\r\n props.onClick?.(props.row, props.col)\r\n // 支持用户自定�?onClick\r\n rp.onClick?.(e, props.row, props.col)\r\n }\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.props || {}\r\n const val = getValueByPath(props.row, props.col.key)\r\n const { href, blank, label, ...restProps } = rp\r\n \r\n return h('a', {\r\n href: href || val || '#',\r\n target: blank ? '_blank' : '_self',\r\n rel: blank ? 'noopener noreferrer' : undefined,\r\n style: 'color:#409EFF;cursor:pointer;text-decoration:none;',\r\n ...restProps,\r\n }, 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 const rp = props.col?.props || {}\r\n const { style, class: className, ...restProps } = rp\r\n \r\n return h('div', {\r\n class: className || 'line-clamp-2',\r\n style,\r\n innerHTML: val ?? '',\r\n ...restProps\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.props ?? {}\r\n const { iconColor, copyTitle, successText, errorText, lineClamp, textStyles, textClass, ...restProps } = rp\r\n \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': iconColor || '#409EFF',\r\n 'user-select': 'none'\r\n }\r\n const textStyleObj = {\r\n 'padding-right': '10px',\r\n 'display': '-webkit-box',\r\n '-webkit-box-orient': 'vertical',\r\n '-webkit-line-clamp': lineClamp ?? 2,\r\n 'overflow': 'hidden',\r\n ...textStyles\r\n }\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 ...restProps\r\n },\r\n [\r\n h('span', {\r\n class: `st_copy_text ${textClass ?? ''}`,\r\n style: textStyleObj,\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: 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(successText ?? '复制成功')\r\n }).catch(() => {\r\n ElMessage.error(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(successText ?? '复制成功')\r\n } else {\r\n ElMessage.error(errorText ?? '复制失败')\r\n }\r\n }\r\n } catch (err) {\r\n ElMessage.error(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?.props || {}\r\n const { width, height, fit, previewSrcList, placeholder, style, ...restProps } = rp\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 placeholder || ''\r\n }\r\n\r\n const defaultStyle = {\r\n width: width || '80px',\r\n height: height || '80px',\r\n marginRight: imageList.length > 1 ? '4px' : '0',\r\n ...(typeof style === 'object' ? style : {})\r\n }\r\n\r\n const imageProps = {\r\n previewSrcList: previewSrcList || imageList,\r\n previewTeleported: true, \r\n fit: fit || 'contain',\r\n style: defaultStyle,\r\n ...restProps\r\n }\r\n\r\n if (imageList.length === 1) {\r\n return h(ElImage, {\r\n src: imageList[0],\r\n ...imageProps\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 ...imageProps\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.props || {}\r\n const { options = [], showValue = false, ...restProps } = rp\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: string) => !options.some((opt: any) => String(opt.value) === v))\r\n\r\n const children = matchedOptions.map((item: any) => {\r\n const { listClass, cssClass, tagProps, ...itemRest } = item\r\n return h(\r\n ElTag,\r\n { \r\n key: item.value, \r\n type: listClass, \r\n class: cssClass, \r\n disableTransitions: true,\r\n ...restProps,\r\n ...tagProps\r\n },\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', { style: 'display: inline-flex; gap: 4px; flex-wrap: wrap;' }, 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 rp = props.col.props || {}\r\n const { options = {}, ...restProps } = rp\r\n const mappedVal = val != null ? options[val] ?? '' : ''\r\n \r\n return h('span', { ...restProps }, mappedVal)\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, index } = props\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.props || {}\r\n \r\n let content = val\r\n if (isDataColumn(col)) {\r\n content = col.formatter?.(val, row, index) ?? val\r\n }\r\n \r\n return h('span', { ...rp }, content)\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.props || {}\r\n const { style, size, class: className, ...restProps } = rp\r\n \r\n if (!val) return ''\r\n \r\n const iconSize = size ? `${size}px` : '20px'\r\n \r\n // 判断网络图片\r\n if (/^https?:\\/\\//.test(val)) {\r\n return h(ElImage, {\r\n src: val,\r\n previewSrcList: [val],\r\n previewTeleported: true, \r\n fit: 'contain',\r\n style: { width: '40px', height: '40px', ...(typeof style === 'object' ? style : {}) },\r\n ...restProps\r\n })\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 class: className,\r\n style: { \r\n width: '40px', \r\n height: '40px', \r\n display: 'inline-block',\r\n ...(typeof style === 'object' ? style : {})\r\n },\r\n ...restProps\r\n })\r\n }\r\n \r\n // 默认当作 iconfont\r\n return h('i', {\r\n class: [val, className].filter(Boolean).join(' '),\r\n style: { \r\n fontSize: iconSize,\r\n ...(typeof style === 'object' ? style : {})\r\n },\r\n ...restProps\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","/**\r\n * 全局配置管理\r\n */\r\nimport type { SmartTableConfig } from './types'\r\nimport { getRendererManager } from './renderer'\r\nimport { registerBuiltInRenderers } from './renderers'\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 private _initialized = false\r\n\r\n /**\r\n * 是否已初始化\r\n */\r\n get initialized(): boolean {\r\n return this._initialized\r\n }\r\n\r\n /**\r\n * 初始化(注册内置渲染器)\r\n */\r\n init(): void {\r\n if (this._initialized) return\r\n registerBuiltInRenderers(getRendererManager())\r\n this._initialized = true\r\n }\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 // 初始化内置渲染器\r\n manager.init()\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","<template>\r\n <el-table ref=\"tableRef\"\r\n v-bind=\"$attrs\"\r\n :data=\"data\"\r\n :row-key=\"rowKey\"\r\n class=\"smart_table\"\r\n v-loading=\"loading\">\r\n\r\n <template v-for=\"(col, idx) in visibleColumns\" :key=\"getColumnKey(col, idx)\">\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'\"\r\n :label=\"col.label || '操作'\"\r\n align=\"center\"\r\n v-bind=\"{\r\n ...col.columnProps,\r\n width: getOperationWidth(col)\r\n }\"\r\n >\r\n <template #default=\"{ row }\">\r\n <el-button\r\n v-for=\"btn in getVisibleButtons(col, row)\"\r\n :key=\"btn.label\"\r\n :type=\"btn.type || 'primary'\"\r\n link\r\n @click=\"btn.action(row)\"\r\n >\r\n {{ btn.label }}\r\n </el-button>\r\n </template>\r\n </el-table-column>\r\n\r\n <!-- ========== 数据列 ========== -->\r\n <el-table-column\r\n v-else\r\n :label=\"col.label\"\r\n align=\"center\"\r\n v-bind=\"col.columnProps || {}\"\r\n >\r\n <template #default=\"scope\">\r\n <!-- slot 类型 -->\r\n <template v-if=\"col.type === 'slot'\">\r\n <slot v-if=\"scope.$index >= 0\" :name=\"col.slot || col.key\" v-bind=\"scope\" />\r\n </template>\r\n\r\n <!-- 渲染器类型 -->\r\n <component\r\n v-else-if=\"col.type && renderer[col.type]\"\r\n :is=\"renderer[col.type]\"\r\n :row=\"scope.row\"\r\n :col=\"col\"\r\n :index=\"scope.$index\"\r\n :onCellChange=\"handleCellChange\"\r\n :onCellBlur=\"handleCellBlur\"\r\n :onCellEnter=\"handleCellEnter\"\r\n :onClick=\"handleCellClick\"\r\n />\r\n\r\n <!-- 默认文本 -->\r\n <span v-else\r\n :style=\"col.props?.style || ''\"\r\n :class=\"col.props?.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 </template>\r\n </el-table>\r\n</template>\r\n\r\n<script setup lang=\"ts\" name=\"SmartTable\">\r\n import { ref, watch, computed } from 'vue'\r\n import type { ColumnConfig, SmartTableProps, SmartTableEmits, OperationColumn } from './types'\r\n import { isSpecialColumn, isOperationColumn } from './types'\r\n import { useTableColumns } from \"./hooks/useTableColumns\"\r\n import { useOperationColumn } from './hooks/useOperationColumn'\r\n import { getRendererManager } from './renderer'\r\n import { getConfigManager } from './config'\r\n import { getValueByPath } from './utils/path'\r\n\r\n // Props 定义\r\n const props = withDefaults(defineProps<SmartTableProps>(), {\r\n data: () => [],\r\n columns: () => [],\r\n rowKey: 'id',\r\n loading: false,\r\n permissions: () => [],\r\n pagination: () => ({}),\r\n })\r\n\r\n // Emits 定义\r\n const emit = defineEmits<SmartTableEmits>()\r\n\r\n // ------------------ 初始化渲染器(仅首次) ------------------\r\n getConfigManager().init()\r\n\r\n // ------------------ columns 处理 ------------------\r\n const { columns: cachedColumns } = useTableColumns(props.columns, {\r\n cacheKey: props.cacheKey ?? '',\r\n })\r\n \r\n // 标记是否已初始化,避免初始化时触发不必要的更新\r\n const isInitialized = ref(false)\r\n watch(\r\n cachedColumns,\r\n (val: ColumnConfig[]) => {\r\n if (isInitialized.value) {\r\n emit(\"update:columns\", val)\r\n }\r\n isInitialized.value = true\r\n },\r\n { deep: true, immediate: true },\r\n )\r\n\r\n // ------------------ operation 列逻辑(需要在 visibleColumns 之前定义) ------------------\r\n // operation 列集合\r\n const operationColumns = computed(() =>\r\n cachedColumns.value.filter(col => col.type === 'operation')\r\n )\r\n\r\n // 为每个 operation 列创建 useOperationColumn 实例\r\n const operationColumnMap = computed(() => {\r\n const map = new Map<string, ReturnType<typeof useOperationColumn>>()\r\n\r\n operationColumns.value.forEach(col => {\r\n const hook = useOperationColumn(\r\n col.buttons || [],\r\n col.maxbtn ?? 10,\r\n props.permissions || []\r\n )\r\n map.set(col.key, hook)\r\n })\r\n\r\n return map\r\n })\r\n\r\n const getOperationColumnHook = (col: ColumnConfig) => {\r\n return operationColumnMap.value.get(col.key)\r\n }\r\n\r\n // 判断 operation 列是否应该显示\r\n const isOperationVisible = (col: ColumnConfig) => {\r\n if (!isOperationColumn(col)) return false\r\n \r\n const hook = getOperationColumnHook(col)\r\n if (!hook) return false\r\n\r\n const buttons = col.buttons || []\r\n if (!buttons.length) return false\r\n\r\n // 无数据时,只要有权限的按钮就显示\r\n if (!props.data?.length) return hook.hasAnyButton.value\r\n\r\n // 有数据时,检查是否至少有一行有可见按钮\r\n return hook.hasAnyVisibleButton(props.data)\r\n }\r\n\r\n const getOperationWidth = (col: ColumnConfig) => {\r\n const hook = getOperationColumnHook(col)\r\n if (!hook) return 0\r\n\r\n // 无行数据,用静态宽度\r\n if (!props.data?.length) return hook.optWidth.value\r\n // 有行数据,取最大宽度\r\n return hook.getMaxOptWidth(props.data)\r\n }\r\n\r\n const getVisibleButtons = (col: OperationColumn, row: any) => {\r\n const hook = getOperationColumnHook(col)\r\n if (!hook) return []\r\n\r\n const buttons = col.buttons || []\r\n if (!buttons.length) return []\r\n\r\n return hook.getVisibleButtons(row)\r\n }\r\n\r\n // ------------------ 列处理 ------------------\r\n \r\n // 可见列(按用户配置顺序)\r\n const visibleColumns = computed(() =>\r\n cachedColumns.value.filter(col => {\r\n // operation 列需要判断是否有可见按钮\r\n if (col.type === 'operation') {\r\n return isOperationVisible(col)\r\n }\r\n // selection/index 始终显示\r\n if (isSpecialColumn(col.type)) return true\r\n // 数据列根据 visible 控制\r\n return col.visible !== false\r\n })\r\n )\r\n\r\n // 生成列的唯一 key\r\n const getColumnKey = (col: ColumnConfig, idx: number) => {\r\n if (col.type === 'selection') return `selection-${idx}`\r\n if (col.type === 'index') return `index-${idx}`\r\n if (col.type === 'operation') return `operation-${col.key}-${idx}`\r\n return `${col.key}-${idx}`\r\n }\r\n\r\n // ------------------ index 列序号计算 ------------------\r\n const computeIndex = (index: number) => {\r\n const page = props.pagination?.page\r\n const size = props.pagination?.size\r\n return page && size ? (page - 1) * size + index + 1 : index + 1\r\n }\r\n\r\n // ------------------ renderer 获取 ------------------\r\n const renderer = computed(() => {\r\n const manager = getRendererManager()\r\n const allRenderers: Record<string, any> = {}\r\n\r\n manager.names().forEach((name: string) => {\r\n const r = manager.get(name)\r\n if (r) allRenderers[name] = r\r\n })\r\n\r\n return allRenderers\r\n })\r\n\r\n // ------------------ 事件封装 ------------------\r\n const handleCellChange = (row: any, col: ColumnConfig) => {\r\n emit('cellChange', row, col)\r\n }\r\n const handleCellBlur = (row: any, col: ColumnConfig) => {\r\n emit('cellBlur', row, col)\r\n }\r\n const handleCellEnter = (row: any, col: ColumnConfig) => {\r\n emit('cellEnter', row, col)\r\n }\r\n const handleCellClick = (row: any, col: ColumnConfig) => {\r\n if (!col) return\r\n emit('cellClick', 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 { ColumnConfig, ColumnType } 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 ColumnType> =\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":["isSpecialColumn","type","isRendererType","isOperationColumn","col","mergeColumns","defaultColumns","cacheColumns","cacheMap","c","cacheCol","useTableColumns","options","cacheKey","storage","cache","columns","ref","watch","newVal","lightColumns","newColumns","useOperationColumn","buttonConfigs","maxbtn","userPermissions","all_permission","hasPermi","value","permArray","p","hasAnyButton","computed","btn","optWidth","sum","isButtonVisible","row","optRowWidth","rows","max","RendererManager","__publicField","name","renderer","renderers","globalRendererManager","getRendererManager","wrapSFCComponent","comp","defineComponent","props","h","createFunctionalRenderer","render","validateRendererProps","rendererName","renderProps","getValueByPath","obj","path","acc","key","setValueByPath","keys","lastKey","target","__props","inputProps","rp","onBlur","onFocus","onChange","onInput","onClear","onEnter","rest","v","val","_a","_c","_b","e","_openBlock","_createBlock","_component_el_input","_mergeProps","$event","oldVal","_component_el_input_number","selectProps","onVisibleChange","visible","_component_el_select","_createElementBlock","_Fragment","_renderList","opt","_component_el_option","input","EditableInput","inputNumber","EditableNumber","select","EditableSelect","extractEvents","events","button","restProps","ElButton","link","href","blank","label","html","style","className","copy","iconColor","copyTitle","successText","errorText","lineClamp","textStyles","textClass","butStyle","textStyleObj","ElMessage","textarea","successful","DocumentCopy","img","width","height","fit","previewSrcList","placeholder","imageList","item","defaultStyle","imageProps","ElImage","CopyDocument","dict","showValue","values","matchedOptions","unmatched","children","listClass","cssClass","tagProps","itemRest","ElTag","map","mappedVal","isDataColumn","formatter","index","content","icon","size","iconSize","builtInRenderers","registerBuiltInRenderers","registry","createRenderer","defaultConfig","ConfigManager","config","source","result","globalConfigManager","getConfigManager","setSmartTableConfig","getSmartTableConfig","emit","__emit","cachedColumns","isInitialized","operationColumns","operationColumnMap","hook","getOperationColumnHook","isOperationVisible","getOperationWidth","getVisibleButtons","visibleColumns","getColumnKey","idx","computeIndex","page","manager","allRenderers","r","handleCellChange","handleCellBlur","handleCellEnter","handleCellClick","tableRef","__expose","_withDirectives","_component_el_table","$attrs","_component_el_table_column","_withCtx","$index","_createTextVNode","_toDisplayString","_component_el_button","scope","_renderSlot","_ctx","_resolveDynamicComponent","_normalizeStyle","_normalizeClass","_unref","_hoisted_1","defineColumn"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vue3-smart-table.cjs.js","sources":["../src/components/SmartTable/types.ts","../src/components/SmartTable/hooks/useTableColumns.ts","../src/components/SmartTable/hooks/useOperationColumn.ts","../src/components/SmartTable/renderer.ts","../src/components/SmartTable/utils/path.ts","../src/components/SmartTable/renderers/input.vue","../src/components/SmartTable/renderers/inputNumber.vue","../src/components/SmartTable/renderers/select.vue","../src/components/SmartTable/renderers/index.ts","../src/components/SmartTable/config.ts","../src/components/SmartTable/index.vue","../src/types/enhanced.ts"],"sourcesContent":["import type { ButtonProps, TableColumnCtx } from 'element-plus'\r\nimport { DefaultRow } from 'element-plus/es/components/table/src/table/defaults'\r\nimport type { Component } from 'vue'\r\n\r\n// 导出验证函数类型\r\nexport type { validateRendererProps } from './renderer'\r\n\r\n/* ======================= 基础工具类型 ======================= */\r\n\r\n/** 支持额外参数(Element Plus 透传 props) */\r\nexport type WithRestProps<T> = T & {\r\n [key: string]: any\r\n}\r\n\r\n/* ======================= 渲染器系统 ======================= */\r\n\r\n/** Renderer 组件类型 */\r\nexport type Renderer = Component\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\nexport interface SmartTableConfig {\r\n /** 自定义渲染器 */\r\n renderers?: Record<string, Renderer>\r\n /** 默认分页配置 */\r\n defaultPagination?: {\r\n page?: number\r\n size?: number\r\n total?: number\r\n }\r\n /** 默认表格属性 */\r\n defaultTableProps?: Record<string, any>\r\n /** 默认列属性 */\r\n defaultColumnProps?: Record<string, any>\r\n}\r\n\r\n/* ======================= 分页配置 ======================= */\r\n\r\n/** 分页配置接口 */\r\nexport interface PaginationConfig {\r\n /** 当前页码 */\r\n page?: number\r\n /** 每页条数 */\r\n size?: number\r\n /** 总条数 */\r\n total?: number\r\n}\r\n\r\n/* ======================= 操作列按钮 ======================= */\r\n\r\nexport interface ButtonConfig<R = any> {\r\n permission?: string | string[]\r\n label: string\r\n type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'\r\n action: (row: R) => void\r\n visible?: (row: R) => boolean\r\n width?: number\r\n}\r\n\r\n/* ======================= 列类型 ======================= */\r\n\r\n/**\r\n * 列类型枚举\r\n * 包含特殊列类型和渲染器类型\r\n */\r\nexport type ColumnType =\r\n // 特殊列\r\n | 'selection'\r\n | 'index'\r\n | 'operation'\r\n // 内置渲染器\r\n | 'input'\r\n | 'input-number'\r\n | 'select'\r\n | 'dict'\r\n | 'map'\r\n | 'img'\r\n | 'link'\r\n | 'button'\r\n | 'copy'\r\n | 'html'\r\n | 'formatter'\r\n | 'icon'\r\n | 'slot'\r\n\r\n/* ======================= Props 类型映射 ======================= */\r\n\r\n/** 各类型对应的 props */\r\nexport interface ColumnPropsMap {\r\n // 特殊列\r\n selection: {}\r\n index: {}\r\n operation: {}\r\n\r\n // 渲染器\r\n html: WithRestProps<{\r\n style?: string | Record<string, any>\r\n class?: string\r\n }>\r\n\r\n copy: WithRestProps<{\r\n iconColor?: string\r\n copyTitle?: string\r\n successText?: string\r\n errorText?: string\r\n lineClamp?: number\r\n textStyles?: Record<string, any>\r\n textClass?: string\r\n }>\r\n\r\n img: WithRestProps<{\r\n width?: string | number\r\n height?: string | number\r\n fit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down'\r\n previewSrcList?: string[]\r\n placeholder?: string\r\n style?: string | Record<string, any>\r\n }>\r\n\r\n dict: WithRestProps<{\r\n options: Array<{\r\n label: string\r\n value: string | number\r\n listClass?: string\r\n cssClass?: string\r\n tagProps?: Record<string, any>\r\n }>\r\n showValue?: boolean\r\n }>\r\n\r\n map: WithRestProps<{\r\n options: Record<string | number, any>\r\n }>\r\n\r\n formatter: WithRestProps<{}>\r\n\r\n icon: WithRestProps<{\r\n style?: string | Record<string, any>\r\n size?: number\r\n class?: string\r\n }>\r\n\r\n input: WithRestProps<{\r\n placeholder?: string\r\n size?: 'small' | 'default' | 'large'\r\n clearable?: boolean\r\n maxlength?: number\r\n showWordLimit?: boolean\r\n disabled?: boolean\r\n // 事件\r\n onChange?: (val: string, row: any, col: any) => void\r\n onBlur?: (e: FocusEvent, row: any, col: any) => void\r\n onFocus?: (e: FocusEvent, row: any, col: any) => void\r\n onInput?: (val: string, row: any, col: any) => void\r\n onClear?: (row: any, col: any) => void\r\n onEnter?: (e: KeyboardEvent, row: any, col: any) => void\r\n }>\r\n\r\n 'input-number': WithRestProps<{\r\n min?: number\r\n max?: number\r\n step?: number\r\n precision?: number\r\n size?: 'small' | 'default' | 'large'\r\n controls?: boolean\r\n disabled?: boolean\r\n // 事件\r\n onChange?: (val: number | undefined, oldVal: number | undefined, row: any, col: any) => void\r\n onBlur?: (e: FocusEvent, row: any, col: any) => void\r\n onFocus?: (e: FocusEvent, row: any, col: any) => void\r\n onEnter?: (e: KeyboardEvent, row: any, col: any) => void\r\n }>\r\n\r\n select: WithRestProps<{\r\n options: Array<{\r\n label: string\r\n value: string | number\r\n disabled?: boolean\r\n }>\r\n placeholder?: string\r\n size?: 'small' | 'default' | 'large'\r\n clearable?: boolean\r\n filterable?: boolean\r\n multiple?: boolean\r\n disabled?: boolean\r\n // 事件\r\n onChange?: (val: any, row: any, col: any) => void\r\n onBlur?: (e: FocusEvent, row: any, col: any) => void\r\n onFocus?: (e: FocusEvent, row: any, col: any) => void\r\n onVisibleChange?: (visible: boolean, row: any, col: any) => void\r\n onClear?: (row: any, col: any) => void\r\n }>\r\n\r\n button: WithRestProps<ButtonProps & {\r\n label?: string\r\n style?: string | Record<string, any>\r\n class?: string\r\n onClick?: (e: Event, row: any, col: any) => void\r\n }>\r\n\r\n link: WithRestProps<{\r\n label?: string\r\n href?: string\r\n blank?: boolean\r\n style?: string | Record<string, any>\r\n class?: string\r\n }>\r\n\r\n slot: {}\r\n}\r\n\r\n/* ======================= ColumnConfig ======================= */\r\n\r\n/** 列配置基础接口 */\r\nexport interface BaseColumnConfig<R extends DefaultRow = any> {\r\n /** 字段名 */\r\n key: string\r\n /** 列类型 */\r\n type?: ColumnType | string\r\n /** 列标题 */\r\n label?: string\r\n /** 是否显示 */\r\n visible?: boolean\r\n /** 是否在列控制中显示 */\r\n inControl?: boolean\r\n /** el-table-column 原生属性 */\r\n columnProps?: Partial<TableColumnCtx<R>>\r\n /** 插槽名称(type 为 slot 时使用,默认用 key) */\r\n slot?: string\r\n /** 渲染器/组件属性 */\r\n props?: Record<string, any>\r\n}\r\n\r\n/** Selection 列 */\r\nexport interface SelectionColumn<R extends DefaultRow = any> extends BaseColumnConfig<R> {\r\n type: 'selection'\r\n}\r\n\r\n/** Index 列 */\r\nexport interface IndexColumn<R extends DefaultRow = any> extends BaseColumnConfig<R> {\r\n type: 'index'\r\n}\r\n\r\n/** Operation 列 */\r\nexport interface OperationColumn<R extends DefaultRow = any> extends BaseColumnConfig<R> {\r\n type: 'operation'\r\n buttons: ButtonConfig<R>[]\r\n /** 最大显示按钮数 */\r\n maxbtn?: number\r\n}\r\n\r\n/** 数据列 */\r\nexport interface DataColumn<R extends DefaultRow = any> extends BaseColumnConfig<R> {\r\n type?: Exclude<ColumnType, 'selection' | 'index' | 'operation'> | string\r\n /**\r\n * 格式化函数(type 为 formatter 时使用)\r\n */\r\n formatter?: (value: any, row: R, index: number) => any\r\n}\r\n\r\n/** 列配置联合类型 */\r\nexport type ColumnConfig<R extends DefaultRow = any> =\r\n | SelectionColumn<R>\r\n | IndexColumn<R>\r\n | OperationColumn<R>\r\n | DataColumn<R>\r\n\r\n/* ======================= 组件 Props ======================= */\r\n\r\n/**\r\n * SmartTable 组件 Props 接口\r\n */\r\nexport interface SmartTableProps<R extends DefaultRow = any> {\r\n /** 表格数据 */\r\n data: R[]\r\n /** 列配置 */\r\n columns: ColumnConfig<R>[]\r\n /** 行数据的唯一标识字段,默认 'id' */\r\n rowKey?: string\r\n /** 是否显示加载状态 */\r\n loading?: boolean\r\n /** 权限列表,用于操作列按钮权限控制 */\r\n permissions?: string[]\r\n /** 列配置缓存 key,用于持久化列显隐配置 */\r\n cacheKey?: string\r\n /** 分页配置,用于序号列计算 */\r\n pagination?: PaginationConfig\r\n}\r\n\r\n/**\r\n * SmartTable 组件 Emits 接口\r\n */\r\nexport interface SmartTableEmits<R extends DefaultRow = any> {\r\n /** 列配置更新(v-model:columns) */\r\n (e: 'update:columns', columns: ColumnConfig<R>[]): void\r\n /** 单元格值变更 */\r\n (e: 'cellChange', row: R, col: ColumnConfig<R>): void\r\n /** 单元格失焦 */\r\n (e: 'cellBlur', row: R, col: ColumnConfig<R>): void\r\n /** 单元格回车 */\r\n (e: 'cellEnter', row: R, col: ColumnConfig<R>): void\r\n /** 单元格点击(button 类型) */\r\n (e: 'cellClick', row: R, col: ColumnConfig<R>): void\r\n}\r\n\r\n/* ======================= 辅助类型 ======================= */\r\n\r\n/** 特殊列类型 */\r\nexport type SpecialColumnType = 'selection' | 'index' | 'operation'\r\n\r\n/** 判断是否为特殊列 */\r\nexport function isSpecialColumn(type?: string): type is SpecialColumnType {\r\n return type === 'selection' || type === 'index' || type === 'operation'\r\n}\r\n\r\n/** 判断是否为渲染器类型 */\r\nexport function isRendererType(type?: string): boolean {\r\n if (!type) return false\r\n return !isSpecialColumn(type)\r\n}\r\n\r\n/** 判断是否为 operation 列 */\r\nexport function isOperationColumn<R extends DefaultRow = any>(col: ColumnConfig<R>): col is OperationColumn<R> {\r\n return col.type === 'operation'\r\n}\r\n","import { ref, watch } from 'vue'\r\n\r\n\r\n/**\r\n * 合并默认列配置和缓存配置\r\n *\r\n * 设计原则:\r\n * 1️⃣ 列顺序:以 defaultColumns 为准\r\n * 2️⃣ 列增减:以 defaultColumns 为准\r\n * 3️⃣ 缓存只覆盖用户可配置字段(如 visible)\r\n */\r\nfunction mergeColumns(\r\n defaultColumns: any[],\r\n cacheColumns: Array<{ key: string; visible?: boolean }>\r\n) {\r\n if (!cacheColumns?.length) return defaultColumns\r\n\r\n // 建立 key => cache 映射表,提升查找效率\r\n const cacheMap = new Map(\r\n cacheColumns.map(c => [c.key, c])\r\n )\r\n\r\n return defaultColumns.map(col => {\r\n const cacheCol = cacheMap.get(col.key)\r\n\r\n // 只允许缓存覆盖「可配置字段」\r\n if (!cacheCol) return col\r\n\r\n return {\r\n ...col,\r\n visible:\r\n typeof cacheCol.visible === 'boolean'\r\n ? cacheCol.visible\r\n : col.visible\r\n }\r\n })\r\n}\r\n\r\n\r\n/**\r\n * useTableColumns\r\n *\r\n * 表格列管理 Hook\r\n *\r\n * 职责:\r\n * - 管理表格列顺序\r\n * - 管理列显示 / 隐藏\r\n * - 持久化用户配置\r\n */\r\nexport function useTableColumns(\r\n defaultColumns: any[],\r\n options?: {\r\n /** 缓存唯一标识 */\r\n cacheKey?: string\r\n /** 存储介质,默认 localStorage */\r\n storage?: Storage\r\n }\r\n) {\r\n\r\n /** 解构参数并设置默认值 */\r\n const { cacheKey, storage = localStorage } = options || {}\r\n\r\n /**\r\n * 如果没有 cacheKey,则不启用缓存\r\n * (例如公共页面、未登录页面)\r\n * 从缓存中读取列配置\r\n */\r\n const cache = cacheKey ? storage.getItem(cacheKey) : null\r\n\r\n /**\r\n * 响应式列配置\r\n * 初始化时合并默认列和缓存列\r\n */\r\n const columns = ref(\r\n mergeColumns(\r\n defaultColumns,\r\n cache ? JSON.parse(cache) : []\r\n )\r\n )\r\n\r\n /**\r\n * 监听列变化,自动写入缓存\r\n */\r\n watch(\r\n columns,\r\n (newVal: any) => {\r\n if (!cacheKey) return\r\n\r\n /**\r\n * ⚠️ 只保存“轻量配置”\r\n * 避免把 render / action / 函数序列化进 localStorage\r\n */\r\n const lightColumns = newVal.map((col: any) => ({\r\n key: col.key,\r\n visible: col.visible,\r\n columnOpts: col.columnOpts\r\n }))\r\n\r\n storage.setItem(\r\n cacheKey,\r\n JSON.stringify(lightColumns)\r\n )\r\n },\r\n { deep: true }\r\n )\r\n\r\n /**\r\n * 对外暴露的 API\r\n */\r\n return {\r\n /** 当前列配置(响应式) */\r\n columns,\r\n\r\n /**\r\n * 主动设置列配置\r\n * 常用于:列设置弹窗 / 拖拽排序完成\r\n */\r\n setColumns(newColumns: any[]) {\r\n columns.value = mergeColumns(\r\n defaultColumns,\r\n newColumns\r\n )\r\n\r\n if (cacheKey) {\r\n storage.setItem(\r\n cacheKey,\r\n JSON.stringify(newColumns)\r\n )\r\n }\r\n },\r\n\r\n /**\r\n * 重置为默认列配置\r\n */\r\n resetColumns() {\r\n columns.value = defaultColumns\r\n\r\n if (cacheKey) {\r\n storage.removeItem(cacheKey)\r\n }\r\n }\r\n }\r\n}\r\n","import { computed } from 'vue'\r\n\r\nimport { ButtonConfig } from \"../types\"\r\n\r\n/**\r\n * useOperationColumn\r\n *\r\n * 操作列专用逻辑 Hook,负责:\r\n * 1. 根据权限判断操作列是否需要显示\r\n * 2. 计算操作列宽度(支持按钮自定义宽度)\r\n * 3. 支持行级 visible 配置\r\n * @param buttonConfigs 操作列按钮配置\r\n * @param maxbtn 操作列最多显示按钮数量(超过的不参与宽度计算)\r\n * @param userPermissions 当前用户权限列表\r\n */\r\nexport function useOperationColumn(\r\n buttonConfigs: ButtonConfig[],\r\n maxbtn = 10,\r\n userPermissions: string[] = []\r\n) {\r\n /** 默认按钮宽度 */\r\n const defaultWidth = 55\r\n\r\n /** 超级权限标识 */\r\n const all_permission = '*:*:*'\r\n\r\n /** --------------------------\r\n * 权限判断\r\n * -------------------------- */\r\n\r\n /**\r\n * 判断是否具备按钮权限\r\n *\r\n * 规则:\r\n * - permission 未配置 ⇒ 永远有权限\r\n * - permission 为 string | string[] ⇒ 与用户权限匹配\r\n */\r\n const hasPermi = (value?: string | string[]) => {\r\n if (!value) return true\r\n\r\n const permArray = Array.isArray(value) ? value : [value]\r\n return userPermissions.some(\r\n p => p === all_permission || permArray.includes(p)\r\n )\r\n }\r\n\r\n /** --------------------------\r\n * 仅基于权限(不考虑行级 visible)\r\n * 适用于:表格未加载数据时的判断\r\n * -------------------------- */\r\n\r\n /**\r\n * 是否至少存在一个有权限的按钮\r\n * 用于判断操作列是否需要渲染\r\n */\r\n const hasAnyButton = computed(() => {\r\n return buttonConfigs.some(btn => hasPermi(btn.permission))\r\n })\r\n\r\n /**\r\n * 操作列宽度(仅基于权限)\r\n * 用于无行数据时的兜底宽度计算\r\n *\r\n * 注意:这里不考虑 visible,因为没有 row 数据无法执行 visible 函数\r\n * 实际使用时会根据行数据重新计算\r\n */\r\n const optWidth = computed(() => {\r\n const permittedBtns = buttonConfigs\r\n .filter(btn => hasPermi(btn.permission))\r\n .slice(0, maxbtn)\r\n\r\n return permittedBtns.reduce(\r\n (sum, btn) => sum + (btn.width ?? defaultWidth),\r\n 0\r\n )\r\n })\r\n\r\n /** --------------------------\r\n * 权限 + 行级 visible\r\n * -------------------------- */\r\n\r\n /**\r\n * 判断某个按钮在某一行是否可见\r\n */\r\n const isButtonVisible = (btn: ButtonConfig, row: any) => {\r\n return (\r\n hasPermi(btn.permission) &&\r\n (btn.visible ? btn.visible(row) : true)\r\n )\r\n }\r\n\r\n /**\r\n * 单行操作列宽度\r\n */\r\n const optRowWidth = (row: any) => {\r\n const visibleBtns = buttonConfigs\r\n .filter(btn => isButtonVisible(btn, row))\r\n .slice(0, maxbtn)\r\n\r\n return visibleBtns.reduce(\r\n (sum, btn) => sum + (btn.width ?? defaultWidth),\r\n 0\r\n )\r\n }\r\n\r\n /**\r\n * 遍历所有行,获取最大操作列宽度\r\n */\r\n const getMaxOptWidth = (rows: any[]) => {\r\n if (!rows?.length) return optWidth.value\r\n return rows.reduce(\r\n (max, row) => Math.max(max, optRowWidth(row)),\r\n 0\r\n )\r\n }\r\n\r\n /**\r\n * 判断是否至少有一行存在可见按钮\r\n */\r\n const hasAnyVisibleButton = (rows: any[]) => {\r\n if (!rows?.length) return false\r\n return rows.some(row =>\r\n buttonConfigs.some(btn => isButtonVisible(btn, row))\r\n )\r\n }\r\n\r\n const getVisibleButtons = (row: any) => {\r\n return buttonConfigs\r\n .filter(btn => isButtonVisible(btn, row))\r\n .slice(0, maxbtn)\r\n }\r\n\r\n return {\r\n hasAnyButton,\r\n optWidth,\r\n hasAnyVisibleButton,\r\n getMaxOptWidth,\r\n getVisibleButtons\r\n }\r\n}\r\n","/**\r\n * SmartTable 内部渲染器管理系统\r\n * 移动到组件内部,保证组件的自包含性\r\n */\r\nimport { defineComponent, h, Component } from 'vue'\r\nimport type { Renderer } from './types'\r\n\r\n/**\r\n * 渲染器注册表接口\r\n */\r\nexport interface RendererRegistry {\r\n register(name: string, renderer: Renderer): void\r\n registerMultiple(renderers: Record<string, Renderer>): void\r\n get(name: string): Renderer | undefined\r\n has(name: string): boolean\r\n unregister(name: string): boolean\r\n clear(): void\r\n names(): string[]\r\n}\r\n\r\n/**\r\n * 渲染器管理器类\r\n */\r\nclass RendererManager implements RendererRegistry {\r\n private renderers: Map<string, Renderer> = new Map()\r\n\r\n register(name: string, renderer: Renderer): void {\r\n if (this.renderers.has(name)) {\r\n // 批量注册时不警告,只在单独注册时警告\r\n if (process.env.NODE_ENV === 'development') {\r\n console.debug(`[SmartTable] Renderer \"${name}\" already registered, skipping.`)\r\n }\r\n }\r\n this.renderers.set(name, renderer)\r\n }\r\n\r\n registerMultiple(renderers: Record<string, Renderer>): void {\r\n Object.entries(renderers).forEach(([name, renderer]) => {\r\n if (!this.renderers.has(name)) {\r\n this.renderers.set(name, renderer)\r\n }\r\n })\r\n }\r\n\r\n get(name: string): Renderer | undefined {\r\n return this.renderers.get(name)\r\n }\r\n\r\n has(name: string): boolean {\r\n return this.renderers.has(name)\r\n }\r\n\r\n unregister(name: string): boolean {\r\n return this.renderers.delete(name)\r\n }\r\n\r\n clear(): void {\r\n this.renderers.clear()\r\n }\r\n\r\n names(): string[] {\r\n return Array.from(this.renderers.keys())\r\n }\r\n}\r\n\r\n/**\r\n * 全局渲染器管理器单例\r\n */\r\nlet globalRendererManager: RendererManager | null = null\r\n\r\n/**\r\n * 获取渲染器管理器\r\n */\r\nexport function getRendererManager(): RendererManager {\r\n if (!globalRendererManager) {\r\n globalRendererManager = new RendererManager()\r\n }\r\n return globalRendererManager\r\n}\r\n\r\n/**\r\n * 包装 SFC 组件为渲染器\r\n */\r\nexport function wrapSFCComponent(comp: Component): Renderer {\r\n return defineComponent({\r\n props: ['row', 'col', 'index', '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 index: number\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', 'index', '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>\r\n <el-input\r\n v-model=\"value\"\r\n v-bind=\"inputProps\"\r\n @blur=\"onBlur\"\r\n @focus=\"onFocus\"\r\n @change=\"onChange\"\r\n @input=\"onInput\"\r\n @keyup.enter=\"onEnter\"\r\n @clear=\"onClear\"\r\n />\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, watch, computed } from 'vue'\r\nimport type { ColumnConfig } from '../types'\r\nimport { getValueByPath, setValueByPath } from '../utils/path'\r\n\r\ninterface Props {\r\n readonly row: any\r\n readonly col: ColumnConfig\r\n readonly index: number\r\n onCellChange?: (row: any, col: ColumnConfig) => void\r\n onCellBlur?: (row: any, col: ColumnConfig) => void\r\n onCellEnter?: (row: any, col: ColumnConfig) => void\r\n}\r\n\r\nconst props = defineProps<Props>()\r\nconst value = ref(getValueByPath(props.row, props.col.key))\r\n\r\n// 合并默认属性和用户自定义属性\r\nconst inputProps = computed(() => {\r\n const rp = props.col.props || {}\r\n const { onBlur, onFocus, onChange, onInput, onClear, onEnter, ...rest } = rp\r\n return {\r\n placeholder: '',\r\n size: 'small' as const,\r\n clearable: true,\r\n ...rest\r\n }\r\n})\r\n\r\nwatch(value, (v) => {\r\n setValueByPath(props.row, props.col.key, v)\r\n})\r\n\r\nconst onChange = (val: string) => {\r\n props.onCellChange?.(props.row, props.col)\r\n props.col.props?.onChange?.(val, props.row, props.col)\r\n}\r\n\r\nconst onBlur = (e: FocusEvent) => {\r\n props.onCellBlur?.(props.row, props.col)\r\n props.col.props?.onBlur?.(e, props.row, props.col)\r\n}\r\n\r\nconst onFocus = (e: FocusEvent) => {\r\n props.col.props?.onFocus?.(e, props.row, props.col)\r\n}\r\n\r\nconst onInput = (val: string) => {\r\n props.col.props?.onInput?.(val, props.row, props.col)\r\n}\r\n\r\nconst onEnter = (e: KeyboardEvent) => {\r\n props.onCellEnter?.(props.row, props.col)\r\n props.col.props?.onEnter?.(e, props.row, props.col)\r\n}\r\n\r\nconst onClear = () => {\r\n props.col.props?.onClear?.(props.row, props.col)\r\n}\r\n</script>\r\n","<template>\r\n <el-input-number\r\n v-model=\"value\"\r\n v-bind=\"inputProps\"\r\n @blur=\"onBlur\"\r\n @focus=\"onFocus\"\r\n @change=\"onChange\"\r\n @keyup.enter=\"onEnter\"\r\n />\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, watch, computed } from 'vue'\r\nimport type { ColumnConfig } from '../types'\r\nimport { getValueByPath, setValueByPath } from '../utils/path'\r\n\r\ninterface Props {\r\n readonly row: any\r\n readonly col: ColumnConfig\r\n readonly index: number\r\n onCellChange?: (row: any, col: ColumnConfig) => void\r\n onCellBlur?: (row: any, col: ColumnConfig) => void\r\n onCellEnter?: (row: any, col: ColumnConfig) => void\r\n}\r\n\r\nconst props = defineProps<Props>()\r\nconst value = ref(getValueByPath(props.row, props.col.key))\r\n\r\n// 合并默认属性和用户自定义属性\r\nconst inputProps = computed(() => {\r\n const rp = props.col.props || {}\r\n const { onBlur, onFocus, onChange, onEnter, ...rest } = rp\r\n return {\r\n min: 0,\r\n max: 99999,\r\n controls: false,\r\n size: 'small' as const,\r\n ...rest\r\n }\r\n})\r\n\r\nwatch(value, (v) => {\r\n setValueByPath(props.row, props.col.key, v)\r\n})\r\n\r\nconst onChange = (val: number | undefined, oldVal: number | undefined) => {\r\n props.onCellChange?.(props.row, props.col)\r\n props.col.props?.onChange?.(val, oldVal, props.row, props.col)\r\n}\r\n\r\nconst onBlur = (e: FocusEvent) => {\r\n props.onCellBlur?.(props.row, props.col)\r\n props.col.props?.onBlur?.(e, props.row, props.col)\r\n}\r\n\r\nconst onFocus = (e: FocusEvent) => {\r\n props.col.props?.onFocus?.(e, props.row, props.col)\r\n}\r\n\r\nconst onEnter = (e: KeyboardEvent) => {\r\n props.onCellEnter?.(props.row, props.col)\r\n props.col.props?.onEnter?.(e, props.row, props.col)\r\n}\r\n</script>\r\n","<template>\r\n <el-select\r\n v-model=\"value\"\r\n v-bind=\"selectProps\"\r\n @change=\"onChange\"\r\n @blur=\"onBlur\"\r\n @focus=\"onFocus\"\r\n @visible-change=\"onVisibleChange\"\r\n @clear=\"onClear\"\r\n @keyup.enter=\"onEnter\"\r\n >\r\n <el-option\r\n v-for=\"opt in options\"\r\n :key=\"opt.value\"\r\n :label=\"opt.label\"\r\n :value=\"opt.value\"\r\n :disabled=\"opt.disabled\"\r\n />\r\n </el-select>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, watch, computed } from 'vue'\r\nimport type { ColumnConfig } from '../types'\r\nimport { getValueByPath, setValueByPath } from '../utils/path'\r\n\r\ninterface Props {\r\n readonly row: any\r\n readonly col: ColumnConfig\r\n readonly index: number\r\n onCellChange?: (row: any, col: ColumnConfig) => void\r\n onCellBlur?: (row: any, col: ColumnConfig) => void\r\n onCellEnter?: (row: any, col: ColumnConfig) => void\r\n}\r\n\r\nconst props = defineProps<Props>()\r\nconst value = ref(getValueByPath(props.row, props.col.key))\r\n\r\n// 合并默认属性和用户自定义属性\r\nconst selectProps = computed(() => {\r\n const rp = props.col.props || {}\r\n const { options, onChange, onBlur, onFocus, onVisibleChange, onClear, onEnter, ...rest } = rp\r\n return {\r\n placeholder: '请选择',\r\n size: 'small' as const,\r\n clearable: true,\r\n ...rest\r\n }\r\n})\r\n\r\n// 选项列表\r\nconst options = computed(() => {\r\n const rp = props.col.props || {}\r\n return rp.options || []\r\n})\r\n\r\nwatch(value, (v) => {\r\n setValueByPath(props.row, props.col.key, v)\r\n})\r\n\r\nconst onChange = (val: any) => {\r\n props.onCellChange?.(props.row, props.col)\r\n props.col.props?.onChange?.(val, props.row, props.col)\r\n}\r\n\r\nconst onBlur = (e: FocusEvent) => {\r\n props.onCellBlur?.(props.row, props.col)\r\n props.col.props?.onBlur?.(e, props.row, props.col)\r\n}\r\n\r\nconst onFocus = (e: FocusEvent) => {\r\n props.col.props?.onFocus?.(e, props.row, props.col)\r\n}\r\n\r\nconst onVisibleChange = (visible: boolean) => {\r\n props.col.props?.onVisibleChange?.(visible, props.row, props.col)\r\n}\r\n\r\nconst onClear = () => {\r\n props.col.props?.onClear?.(props.row, props.col)\r\n}\r\n\r\nconst onEnter = (e: KeyboardEvent) => {\r\n props.onCellEnter?.(props.row, props.col)\r\n props.col.props?.onEnter?.(e, props.row, props.col)\r\n}\r\n</script>\r\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\nconst normalizeCssSize = (size: string | number | undefined, fallback: string) => {\r\n if (size === undefined || size === null || size === '') return fallback\r\n return typeof size === 'number' ? size + 'px' : size\r\n}\r\n\r\n\r\n/**\r\n * 提取 props 中的事件(on 开头的属性)\r\n */\r\nconst extractEvents = (rp: Record<string, any>) => {\r\n const events: Record<string, any> = {}\r\n const props: Record<string, any> = {}\r\n \r\n Object.keys(rp).forEach(key => {\r\n if (key.startsWith('on') && typeof rp[key] === 'function') {\r\n events[key] = rp[key]\r\n } else {\r\n props[key] = rp[key]\r\n }\r\n })\r\n \r\n return { events, props }\r\n}\r\n\r\n/**\r\n * button 渲染�?\r\n */\r\nconst button = createFunctionalRenderer((props) => {\r\n const rp = props.col.props || {}\r\n const val = getValueByPath(props.row, props.col.key)\r\n const { events, props: restProps } = extractEvents(rp)\r\n \r\n return h(ElButton as any, {\r\n type: 'primary',\r\n ...restProps,\r\n ...events,\r\n onClick: (e: Event) => {\r\n props.onClick?.(props.row, props.col)\r\n // 支持用户自定�?onClick\r\n rp.onClick?.(e, props.row, props.col)\r\n }\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.props || {}\r\n const val = getValueByPath(props.row, props.col.key)\r\n const { href, blank, label, ...restProps } = rp\r\n \r\n return h('a', {\r\n href: href || val || '#',\r\n target: blank ? '_blank' : '_self',\r\n rel: blank ? 'noopener noreferrer' : undefined,\r\n style: 'color:#409EFF;cursor:pointer;text-decoration:none;',\r\n ...restProps,\r\n }, 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 const rp = props.col?.props || {}\r\n const { style, class: className, ...restProps } = rp\r\n \r\n return h('div', {\r\n class: className || 'line-clamp-2',\r\n style,\r\n innerHTML: val ?? '',\r\n ...restProps\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.props ?? {}\r\n const { iconColor, copyTitle, successText, errorText, lineClamp, textStyles, textClass, ...restProps } = rp\r\n \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': iconColor || '#409EFF',\r\n 'user-select': 'none'\r\n }\r\n const textStyleObj = {\r\n 'padding-right': '10px',\r\n 'display': '-webkit-box',\r\n '-webkit-box-orient': 'vertical',\r\n '-webkit-line-clamp': lineClamp ?? 2,\r\n 'overflow': 'hidden',\r\n ...textStyles\r\n }\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 ...restProps\r\n },\r\n [\r\n h('span', {\r\n class: `st_copy_text ${textClass ?? ''}`,\r\n style: textStyleObj,\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: 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(successText ?? '复制成功')\r\n }).catch(() => {\r\n ElMessage.error(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(successText ?? '复制成功')\r\n } else {\r\n ElMessage.error(errorText ?? '复制失败')\r\n }\r\n }\r\n } catch (err) {\r\n ElMessage.error(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?.props || {}\r\n const { width, height, fit, previewSrcList, placeholder, style, ...restProps } = rp\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 placeholder || ''\r\n }\r\n\r\n const defaultStyle = {\r\n width: normalizeCssSize(width, '80px'),\r\n height: normalizeCssSize(height, '80px'),\r\n marginRight: imageList.length > 1 ? '4px' : '0',\r\n ...(typeof style === 'object' ? style : {})\r\n }\r\n\r\n const imageProps = {\r\n previewSrcList: previewSrcList || imageList,\r\n previewTeleported: true, \r\n fit: fit || 'contain',\r\n style: defaultStyle,\r\n ...restProps\r\n }\r\n\r\n if (imageList.length === 1) {\r\n return h(ElImage, {\r\n src: imageList[0],\r\n ...imageProps\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 ...imageProps\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.props || {}\r\n const { options = [], showValue = false, ...restProps } = rp\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: string) => !options.some((opt: any) => String(opt.value) === v))\r\n\r\n const children = matchedOptions.map((item: any) => {\r\n const { listClass, cssClass, tagProps, ...itemRest } = item\r\n return h(\r\n ElTag,\r\n { \r\n key: item.value, \r\n type: listClass, \r\n class: cssClass, \r\n disableTransitions: true,\r\n ...restProps,\r\n ...tagProps\r\n },\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', { style: 'display: inline-flex; gap: 4px; flex-wrap: wrap;' }, 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 rp = props.col.props || {}\r\n const { options = {}, ...restProps } = rp\r\n const mappedVal = val != null ? options[val] ?? '' : ''\r\n \r\n return h('span', { ...restProps }, mappedVal)\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, index } = props\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.props || {}\r\n \r\n let content = val\r\n if (isDataColumn(col)) {\r\n content = col.formatter?.(val, row, index) ?? val\r\n }\r\n \r\n return h('span', { ...rp }, content)\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.props || {}\r\n const { style, size, class: className, ...restProps } = rp\r\n \r\n if (!val) return ''\r\n \r\n const iconSize = size ? `${size}px` : '20px'\r\n \r\n // 判断网络图片\r\n if (/^https?:\\/\\//.test(val)) {\r\n return h(ElImage, {\r\n src: val,\r\n previewSrcList: [val],\r\n previewTeleported: true, \r\n fit: 'contain',\r\n style: { width: '40px', height: '40px', ...(typeof style === 'object' ? style : {}) },\r\n ...restProps\r\n })\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 class: className,\r\n style: { \r\n width: '40px', \r\n height: '40px', \r\n display: 'inline-block',\r\n ...(typeof style === 'object' ? style : {})\r\n },\r\n ...restProps\r\n })\r\n }\r\n \r\n // 默认当作 iconfont\r\n return h('i', {\r\n class: [val, className].filter(Boolean).join(' '),\r\n style: { \r\n fontSize: iconSize,\r\n ...(typeof style === 'object' ? style : {})\r\n },\r\n ...restProps\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","/**\r\n * 全局配置管理\r\n */\r\nimport type { SmartTableConfig } from './types'\r\nimport { getRendererManager } from './renderer'\r\nimport { registerBuiltInRenderers } from './renderers'\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 private _initialized = false\r\n\r\n /**\r\n * 是否已初始化\r\n */\r\n get initialized(): boolean {\r\n return this._initialized\r\n }\r\n\r\n /**\r\n * 初始化(注册内置渲染器)\r\n */\r\n init(): void {\r\n if (this._initialized) return\r\n registerBuiltInRenderers(getRendererManager())\r\n this._initialized = true\r\n }\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 // 初始化内置渲染器\r\n manager.init()\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","<template>\r\n <el-table ref=\"tableRef\"\r\n v-bind=\"$attrs\"\r\n :data=\"data\"\r\n :row-key=\"rowKey\"\r\n class=\"smart_table\"\r\n v-loading=\"loading\">\r\n\r\n <template v-for=\"(col, idx) in visibleColumns\" :key=\"getColumnKey(col, idx)\">\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'\"\r\n :label=\"col.label || '操作'\"\r\n align=\"center\"\r\n v-bind=\"{\r\n ...col.columnProps,\r\n width: getOperationWidth(col)\r\n }\"\r\n >\r\n <template #default=\"{ row }\">\r\n <el-button\r\n v-for=\"btn in getVisibleButtons(col, row)\"\r\n :key=\"btn.label\"\r\n :type=\"btn.type || 'primary'\"\r\n link\r\n @click=\"btn.action(row)\"\r\n >\r\n {{ btn.label }}\r\n </el-button>\r\n </template>\r\n </el-table-column>\r\n\r\n <!-- ========== 数据列 ========== -->\r\n <el-table-column\r\n v-else\r\n :prop=\"col.key\"\r\n :label=\"col.label\"\r\n align=\"center\"\r\n v-bind=\"col.columnProps || {}\"\r\n >\r\n <template #default=\"scope\">\r\n <!-- slot 类型 -->\r\n <template v-if=\"col.type === 'slot'\">\r\n <slot v-if=\"scope.$index >= 0\" :name=\"col.slot || col.key\" v-bind=\"scope\" />\r\n </template>\r\n\r\n <!-- 渲染器类型 -->\r\n <component\r\n v-else-if=\"col.type && renderer[col.type]\"\r\n :is=\"renderer[col.type]\"\r\n :row=\"scope.row\"\r\n :col=\"col\"\r\n :index=\"scope.$index\"\r\n :onCellChange=\"handleCellChange\"\r\n :onCellBlur=\"handleCellBlur\"\r\n :onCellEnter=\"handleCellEnter\"\r\n :onClick=\"handleCellClick\"\r\n />\r\n\r\n <!-- 默认文本 -->\r\n <span v-else\r\n :style=\"col.props?.style || ''\"\r\n :class=\"col.props?.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 </template>\r\n </el-table>\r\n</template>\r\n\r\n<script setup lang=\"ts\" name=\"SmartTable\">\r\n import { ref, watch, computed } from 'vue'\r\n import type { ColumnConfig, SmartTableProps, SmartTableEmits, OperationColumn } from './types'\r\n import { isSpecialColumn, isOperationColumn } from './types'\r\n import { useTableColumns } from \"./hooks/useTableColumns\"\r\n import { useOperationColumn } from './hooks/useOperationColumn'\r\n import { getRendererManager } from './renderer'\r\n import { getConfigManager } from './config'\r\n import { getValueByPath } from './utils/path'\r\n\r\n // Props 定义\r\n const props = withDefaults(defineProps<SmartTableProps>(), {\r\n data: () => [],\r\n columns: () => [],\r\n rowKey: 'id',\r\n loading: false,\r\n permissions: () => [],\r\n pagination: () => ({}),\r\n })\r\n\r\n // Emits 定义\r\n const emit = defineEmits<SmartTableEmits>()\r\n\r\n // ------------------ 初始化渲染器(仅首次) ------------------\r\n getConfigManager().init()\r\n\r\n // ------------------ columns 处理 ------------------\r\n const { columns: cachedColumns } = useTableColumns(props.columns, {\r\n cacheKey: props.cacheKey ?? '',\r\n })\r\n \r\n // 标记是否已初始化,避免初始化时触发不必要的更新\r\n const isInitialized = ref(false)\r\n watch(\r\n cachedColumns,\r\n (val: ColumnConfig[]) => {\r\n if (isInitialized.value) {\r\n emit(\"update:columns\", val)\r\n }\r\n isInitialized.value = true\r\n },\r\n { deep: true, immediate: true },\r\n )\r\n\r\n // ------------------ operation 列逻辑(需要在 visibleColumns 之前定义) ------------------\r\n // operation 列集合\r\n const operationColumns = computed(() =>\r\n cachedColumns.value.filter(col => col.type === 'operation')\r\n )\r\n\r\n // 为每个 operation 列创建 useOperationColumn 实例\r\n const operationColumnMap = computed(() => {\r\n const map = new Map<string, ReturnType<typeof useOperationColumn>>()\r\n\r\n operationColumns.value.forEach(col => {\r\n const hook = useOperationColumn(\r\n col.buttons || [],\r\n col.maxbtn ?? 10,\r\n props.permissions || []\r\n )\r\n map.set(col.key, hook)\r\n })\r\n\r\n return map\r\n })\r\n\r\n const getOperationColumnHook = (col: ColumnConfig) => {\r\n return operationColumnMap.value.get(col.key)\r\n }\r\n\r\n // 判断 operation 列是否应该显示\r\n const isOperationVisible = (col: ColumnConfig) => {\r\n if (!isOperationColumn(col)) return false\r\n \r\n const hook = getOperationColumnHook(col)\r\n if (!hook) return false\r\n\r\n const buttons = col.buttons || []\r\n if (!buttons.length) return false\r\n\r\n // 无数据时,只要有权限的按钮就显示\r\n if (!props.data?.length) return hook.hasAnyButton.value\r\n\r\n // 有数据时,检查是否至少有一行有可见按钮\r\n return hook.hasAnyVisibleButton(props.data)\r\n }\r\n\r\n const getOperationWidth = (col: ColumnConfig) => {\r\n const hook = getOperationColumnHook(col)\r\n if (!hook) return 0\r\n\r\n // 无行数据,用静态宽度\r\n if (!props.data?.length) return hook.optWidth.value\r\n // 有行数据,取最大宽度\r\n return hook.getMaxOptWidth(props.data)\r\n }\r\n\r\n const getVisibleButtons = (col: OperationColumn, row: any) => {\r\n const hook = getOperationColumnHook(col)\r\n if (!hook) return []\r\n\r\n const buttons = col.buttons || []\r\n if (!buttons.length) return []\r\n\r\n return hook.getVisibleButtons(row)\r\n }\r\n\r\n // ------------------ 列处理 ------------------\r\n \r\n // 可见列(按用户配置顺序)\r\n const visibleColumns = computed(() =>\r\n cachedColumns.value.filter(col => {\r\n // operation 列需要判断是否有可见按钮\r\n if (col.type === 'operation') {\r\n return isOperationVisible(col)\r\n }\r\n // selection/index 始终显示\r\n if (isSpecialColumn(col.type)) return true\r\n // 数据列根据 visible 控制\r\n return col.visible !== false\r\n })\r\n )\r\n\r\n // 生成列的唯一 key\r\n const getColumnKey = (col: ColumnConfig, idx: number) => {\r\n if (col.type === 'selection') return `selection-${idx}`\r\n if (col.type === 'index') return `index-${idx}`\r\n if (col.type === 'operation') return `operation-${col.key}-${idx}`\r\n return `${col.key}-${idx}`\r\n }\r\n\r\n // ------------------ index 列序号计算 ------------------\r\n const computeIndex = (index: number) => {\r\n const page = props.pagination?.page\r\n const size = props.pagination?.size\r\n return page && size ? (page - 1) * size + index + 1 : index + 1\r\n }\r\n\r\n // ------------------ renderer 获取 ------------------\r\n const renderer = computed(() => {\r\n const manager = getRendererManager()\r\n const allRenderers: Record<string, any> = {}\r\n\r\n manager.names().forEach((name: string) => {\r\n const r = manager.get(name)\r\n if (r) allRenderers[name] = r\r\n })\r\n\r\n return allRenderers\r\n })\r\n\r\n // ------------------ 事件封装 ------------------\r\n const handleCellChange = (row: any, col: ColumnConfig) => {\r\n emit('cellChange', row, col)\r\n }\r\n const handleCellBlur = (row: any, col: ColumnConfig) => {\r\n emit('cellBlur', row, col)\r\n }\r\n const handleCellEnter = (row: any, col: ColumnConfig) => {\r\n emit('cellEnter', row, col)\r\n }\r\n const handleCellClick = (row: any, col: ColumnConfig) => {\r\n if (!col) return\r\n emit('cellClick', 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 { ColumnConfig, ColumnType } 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 ColumnType> =\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":["isSpecialColumn","type","isRendererType","isOperationColumn","col","mergeColumns","defaultColumns","cacheColumns","cacheMap","c","cacheCol","useTableColumns","options","cacheKey","storage","cache","columns","ref","watch","newVal","lightColumns","newColumns","useOperationColumn","buttonConfigs","maxbtn","userPermissions","all_permission","hasPermi","value","permArray","p","hasAnyButton","computed","btn","optWidth","sum","isButtonVisible","row","optRowWidth","rows","max","RendererManager","__publicField","name","renderer","renderers","globalRendererManager","getRendererManager","wrapSFCComponent","comp","defineComponent","props","h","createFunctionalRenderer","render","validateRendererProps","rendererName","renderProps","getValueByPath","obj","path","acc","key","setValueByPath","keys","lastKey","target","__props","inputProps","rp","onBlur","onFocus","onChange","onInput","onClear","onEnter","rest","v","val","_a","_c","_b","e","_openBlock","_createBlock","_component_el_input","_mergeProps","$event","oldVal","_component_el_input_number","selectProps","onVisibleChange","visible","_component_el_select","_createElementBlock","_Fragment","_renderList","opt","_component_el_option","input","EditableInput","inputNumber","EditableNumber","select","EditableSelect","normalizeCssSize","size","fallback","extractEvents","events","button","restProps","ElButton","link","href","blank","label","html","style","className","copy","iconColor","copyTitle","successText","errorText","lineClamp","textStyles","textClass","butStyle","textStyleObj","ElMessage","textarea","successful","DocumentCopy","img","width","height","fit","previewSrcList","placeholder","imageList","item","defaultStyle","imageProps","ElImage","CopyDocument","dict","showValue","values","matchedOptions","unmatched","children","listClass","cssClass","tagProps","itemRest","ElTag","map","mappedVal","isDataColumn","formatter","index","content","icon","iconSize","builtInRenderers","registerBuiltInRenderers","registry","createRenderer","defaultConfig","ConfigManager","config","source","result","globalConfigManager","getConfigManager","setSmartTableConfig","getSmartTableConfig","emit","__emit","cachedColumns","isInitialized","operationColumns","operationColumnMap","hook","getOperationColumnHook","isOperationVisible","getOperationWidth","getVisibleButtons","visibleColumns","getColumnKey","idx","computeIndex","page","manager","allRenderers","r","handleCellChange","handleCellBlur","handleCellEnter","handleCellClick","tableRef","__expose","_withDirectives","_component_el_table","$attrs","_component_el_table_column","_withCtx","$index","_createTextVNode","_toDisplayString","_component_el_button","scope","_renderSlot","_ctx","_resolveDynamicComponent","_normalizeStyle","_normalizeClass","_unref","_hoisted_1","defineColumn"],"mappings":"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"}
|