foggy-data-viewer 1.0.1-beta.0

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.
Files changed (34) hide show
  1. package/README.md +273 -0
  2. package/dist/favicon.svg +4 -0
  3. package/dist/index.js +1531 -0
  4. package/dist/index.umd +1 -0
  5. package/dist/style.css +1 -0
  6. package/package.json +51 -0
  7. package/src/App.vue +469 -0
  8. package/src/api/viewer.ts +163 -0
  9. package/src/components/DataTable.test.ts +533 -0
  10. package/src/components/DataTable.vue +810 -0
  11. package/src/components/DataTableWithSearch.test.ts +628 -0
  12. package/src/components/DataTableWithSearch.vue +277 -0
  13. package/src/components/DataViewer.vue +310 -0
  14. package/src/components/SearchToolbar.test.ts +521 -0
  15. package/src/components/SearchToolbar.vue +406 -0
  16. package/src/components/composables/index.ts +2 -0
  17. package/src/components/composables/useTableSelection.test.ts +248 -0
  18. package/src/components/composables/useTableSelection.ts +44 -0
  19. package/src/components/composables/useTableSummary.test.ts +341 -0
  20. package/src/components/composables/useTableSummary.ts +129 -0
  21. package/src/components/filters/BoolFilter.vue +103 -0
  22. package/src/components/filters/DateRangeFilter.vue +194 -0
  23. package/src/components/filters/NumberRangeFilter.vue +160 -0
  24. package/src/components/filters/SelectFilter.vue +464 -0
  25. package/src/components/filters/TextFilter.vue +230 -0
  26. package/src/components/filters/index.ts +5 -0
  27. package/src/examples/EnhancedTableExample.vue +136 -0
  28. package/src/index.ts +32 -0
  29. package/src/main.ts +14 -0
  30. package/src/types/index.ts +159 -0
  31. package/src/utils/README.md +140 -0
  32. package/src/utils/schemaHelper.test.ts +215 -0
  33. package/src/utils/schemaHelper.ts +44 -0
  34. package/src/vite-env.d.ts +7 -0
package/dist/index.umd ADDED
@@ -0,0 +1 @@
1
+ (function(F,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("axios")):typeof define=="function"&&define.amd?define(["exports","vue","axios"],e):(F=typeof globalThis<"u"?globalThis:F||self,e(F.FoggyDataViewer={},F.Vue,F.axios))})(this,function(F,e,ee){"use strict";const te={class:"input-wrapper"},ae=["placeholder"],le={key:0,class:"filter-dropdown"},ne=["onClick","onMouseenter"],oe=e.defineComponent({__name:"TextFilter",props:{field:{},modelValue:{},placeholder:{default:"搜索..."}},emits:["update:modelValue"],setup(u,{emit:y}){const c=u,f=y,t=e.ref(""),n=e.ref(!1),k=e.ref(),a=e.ref(0);e.watch(()=>c.modelValue,o=>{if(!o||o.length===0){t.value="";return}const h=o[0];h.op==="in"&&Array.isArray(h.value)?t.value=h.value.join(", "):t.value=String(h.value||"").replace(/%/g,"")},{immediate:!0});const i=e.computed(()=>{const o=t.value.trim();return o?[{op:"=",label:`等于:${o}`},{op:"right_like",label:`左匹配:${o}***`},{op:"in",label:`批量查找:${o}`}]:[]});function l(){t.value.trim()?(n.value=!0,a.value=0):(n.value=!1,f("update:modelValue",null))}function s(o){const h=t.value.trim();if(!h)return;let b;if(o==="in"){const m=h.split(/[,,\s]+/).filter(C=>C.trim());m.length===1?b={field:c.field,op:"=",value:m[0]}:b={field:c.field,op:"in",value:m}}else b={field:c.field,op:o,value:h};f("update:modelValue",[b]),n.value=!1}function d(o){if(!n.value||i.value.length===0){o.key==="Enter"&&t.value.trim()&&(n.value=!0,a.value=0);return}switch(o.key){case"ArrowDown":o.preventDefault(),a.value=(a.value+1)%i.value.length;break;case"ArrowUp":o.preventDefault(),a.value=(a.value-1+i.value.length)%i.value.length;break;case"Enter":o.preventDefault(),s(i.value[a.value].op);break;case"Escape":n.value=!1;break}}function v(){t.value="",n.value=!1,f("update:modelValue",null)}function S(o){k.value&&!k.value.contains(o.target)&&(n.value=!1)}return e.onMounted(()=>{document.addEventListener("click",S)}),e.onUnmounted(()=>{document.removeEventListener("click",S)}),(o,h)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"containerRef",ref:k,class:"filter-text"},[e.createElementVNode("div",te,[e.withDirectives(e.createElementVNode("input",{"onUpdate:modelValue":h[0]||(h[0]=b=>t.value=b),type:"text",placeholder:u.placeholder,onInput:l,onKeydown:d,onFocus:h[1]||(h[1]=b=>t.value.trim()&&(n.value=!0))},null,40,ae),[[e.vModelText,t.value]]),t.value?(e.openBlock(),e.createElementBlock("span",{key:0,class:"clear-btn",onClick:e.withModifiers(v,["stop"])},"×")):e.createCommentVNode("",!0)]),n.value&&i.value.length>0?(e.openBlock(),e.createElementBlock("div",le,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(i.value,(b,m)=>(e.openBlock(),e.createElementBlock("div",{key:b.op,class:e.normalizeClass(["filter-option",{highlighted:m===a.value}]),onClick:C=>s(b.op),onMouseenter:C=>a.value=m},e.toDisplayString(b.label),43,ne))),128))])):e.createCommentVNode("",!0)],512))}}),I=(u,y)=>{const c=u.__vccOpts||u;for(const[f,t]of y)c[f]=t;return c},R=I(oe,[["__scopeId","data-v-8fef729c"]]),re={class:"filter-number-range"},se=["placeholder"],ie=["placeholder"],j=I(e.defineComponent({__name:"NumberRangeFilter",props:{field:{},modelValue:{},placeholderMin:{default:"最小"},placeholderMax:{default:"最大"}},emits:["update:modelValue"],setup(u,{emit:y}){const c=u,f=y,t=e.ref(""),n=e.ref("");e.watch(()=>c.modelValue,i=>{if(!i||i.length===0){t.value="",n.value="";return}const l=i.find(s=>s.op==="[]"||s.op==="[)");if(l&&Array.isArray(l.value)){const[s,d]=l.value;t.value=s!=null?String(s):"",n.value=d!=null?String(d):""}else{const s=i.find(v=>v.op===">="),d=i.find(v=>v.op==="<=");t.value=(s==null?void 0:s.value)!=null?String(s.value):"",n.value=(d==null?void 0:d.value)!=null?String(d.value):""}},{immediate:!0});function k(){const i=t.value.trim(),l=n.value.trim();if(!i&&!l){f("update:modelValue",null);return}const s=i?parseFloat(i):null,d=l?parseFloat(l):null;i&&isNaN(s)||l&&isNaN(d)||(s!==null&&d!==null?f("update:modelValue",[{field:c.field,op:"[]",value:[s,d]}]):s!==null?f("update:modelValue",[{field:c.field,op:">=",value:s}]):d!==null&&f("update:modelValue",[{field:c.field,op:"<=",value:d}]))}function a(){t.value="",n.value="",f("update:modelValue",null)}return(i,l)=>(e.openBlock(),e.createElementBlock("div",re,[e.withDirectives(e.createElementVNode("input",{"onUpdate:modelValue":l[0]||(l[0]=s=>t.value=s),type:"text",placeholder:u.placeholderMin,onChange:k,onKeyup:e.withKeys(k,["enter"])},null,40,se),[[e.vModelText,t.value]]),l[2]||(l[2]=e.createElementVNode("span",{class:"separator"},"-",-1)),e.withDirectives(e.createElementVNode("input",{"onUpdate:modelValue":l[1]||(l[1]=s=>n.value=s),type:"text",placeholder:u.placeholderMax,onChange:k,onKeyup:e.withKeys(k,["enter"])},null,40,ie),[[e.vModelText,n.value]]),t.value||n.value?(e.openBlock(),e.createElementBlock("span",{key:0,class:"clear-btn",onClick:a},"×")):e.createCommentVNode("",!0)]))}}),[["__scopeId","data-v-e6401327"]]),ce={class:"filter-date-range"},P=I(e.defineComponent({__name:"DateRangeFilter",props:{field:{},modelValue:{},format:{default:"YYYY-MM-DD"},showTime:{type:Boolean,default:!1}},emits:["update:modelValue"],setup(u,{emit:y}){const c=u,f=y,t=e.ref(null),n=e.computed(()=>{var l;return c.showTime||((l=c.format)==null?void 0:l.includes("HH"))}),k=e.computed(()=>n.value?"YYYY-MM-DD HH:mm":"YYYY-MM-DD");e.watch(()=>c.modelValue,l=>{if(!l||l.length===0){t.value=null;return}const s=l.find(d=>d.op==="[)"||d.op==="[]");if(s&&Array.isArray(s.value)){const[d,v]=s.value;t.value=[new Date(d.replace(" ","T")),new Date(v.replace(" ","T"))]}else{const d=l.find(S=>S.op===">="),v=l.find(S=>S.op==="<="||S.op==="<");if(d||v){const S=d?new Date(String(d.value).replace(" ","T")):null,o=v?new Date(String(v.value).replace(" ","T")):null;S&&o?t.value=[S,o]:S?t.value=[S,S]:o&&(t.value=[o,o])}else t.value=null}},{immediate:!0});function a(l){const s=l.getFullYear(),d=String(l.getMonth()+1).padStart(2,"0"),v=String(l.getDate()).padStart(2,"0");if(n.value){const S=String(l.getHours()).padStart(2,"0"),o=String(l.getMinutes()).padStart(2,"0"),h=String(l.getSeconds()).padStart(2,"0");return`${s}-${d}-${v} ${S}:${o}:${h}`}return`${s}-${d}-${v}`}function i(l){if(!l||l.length!==2){f("update:modelValue",null);return}const[s,d]=l,v=a(s);let S;if(n.value)S=a(d);else{const o=new Date(d);o.setDate(o.getDate()+1),S=a(o)}f("update:modelValue",[{field:c.field,op:"[)",value:[v,S]}])}return(l,s)=>{const d=e.resolveComponent("el-date-picker");return e.openBlock(),e.createElementBlock("div",ce,[e.createVNode(d,{modelValue:t.value,"onUpdate:modelValue":s[0]||(s[0]=v=>t.value=v),type:n.value?"datetimerange":"daterange",format:k.value,"range-separator":"~","start-placeholder":"开始","end-placeholder":"结束",size:"small",clearable:!0,editable:!1,onChange:i},null,8,["modelValue","type","format"])])}}}),[["__scopeId","data-v-4db2cb60"]]),ue={key:0,class:"selected-text"},de={key:1,class:"placeholder-text"},fe=["title"],me={key:0,class:"filter-dropdown"},pe={class:"search-box"},he={class:"options-container"},ge={key:0,class:"loading-hint"},ye=["onClick","onMouseenter"],be=["checked"],ke={class:"option-label"},Ce={key:0,class:"no-data"},ve={key:0,class:"more-hint"},we={key:1,class:"confirm-bar"},Ee={class:"selected-count"},z=I(e.defineComponent({__name:"SelectFilter",props:{field:{},modelValue:{},options:{},placeholder:{default:"请选择..."},loading:{type:Boolean,default:!1},maxDisplayItems:{default:100}},emits:["update:modelValue"],setup(u,{emit:y}){const c=u,f=y,t=e.ref(!1),n=e.ref(!1),k=e.ref(""),a=e.ref(new Set),i=e.ref(),l=e.ref(0),s=e.ref();e.watch(()=>c.modelValue,w=>{if(a.value.clear(),!w||w.length===0)return;const _=w[0];_.op==="in"&&Array.isArray(_.value)?(n.value=!0,_.value.forEach(x=>a.value.add(x))):_.op==="="&&(n.value=!1,a.value.add(_.value))},{immediate:!0});const d=e.computed(()=>{if(!k.value.trim())return c.options;const w=k.value.toLowerCase();return c.options.filter(_=>_.label.toLowerCase().includes(w)||String(_.value).toLowerCase().includes(w))}),v=e.computed(()=>d.value.slice(0,c.maxDisplayItems)),S=e.computed(()=>d.value.length>c.maxDisplayItems),o=e.computed(()=>{if(a.value.size===0)return"";const w=c.options.filter(_=>a.value.has(_.value));return w.length===0?Array.from(a.value).join(", "):w.length<=2?w.map(_=>_.label).join(", "):`已选 ${w.length} 项`});function h(){t.value=!t.value,t.value&&(k.value="",l.value=0,setTimeout(()=>{var w;return(w=s.value)==null?void 0:w.focus()},0))}function b(){if(n.value=!n.value,!n.value&&a.value.size>1){const w=a.value.values().next().value;a.value.clear(),w!==void 0&&a.value.add(w),M()}}function m(w){return a.value.has(w.value)}function C(w){n.value?a.value.has(w.value)?a.value.delete(w.value):a.value.add(w.value):(a.value.clear(),a.value.add(w.value),M(),t.value=!1)}function D(){M(),t.value=!1}function M(){if(a.value.size===0){f("update:modelValue",null);return}n.value||a.value.size>1?f("update:modelValue",[{field:c.field,op:"in",value:Array.from(a.value)}]):f("update:modelValue",[{field:c.field,op:"=",value:a.value.values().next().value}])}function L(){a.value.clear(),k.value="",t.value=!1,f("update:modelValue",null)}function V(){l.value=0}function N(w){if(!t.value)return;const _=v.value;if(_.length!==0)switch(w.key){case"ArrowDown":w.preventDefault(),l.value=(l.value+1)%_.length;break;case"ArrowUp":w.preventDefault(),l.value=(l.value-1+_.length)%_.length;break;case"Enter":w.preventDefault(),_[l.value]&&C(_[l.value]);break;case"Escape":t.value=!1;break}}function O(w){i.value&&!i.value.contains(w.target)&&(t.value&&n.value&&M(),t.value=!1)}return e.onMounted(()=>{document.addEventListener("click",O)}),e.onUnmounted(()=>{document.removeEventListener("click",O)}),(w,_)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"containerRef",ref:i,class:"filter-select"},[e.createElementVNode("div",{class:"select-input",onClick:h},[o.value?(e.openBlock(),e.createElementBlock("span",ue,e.toDisplayString(o.value),1)):(e.openBlock(),e.createElementBlock("span",de,e.toDisplayString(u.placeholder),1)),e.createElementVNode("span",{class:"toggle-multi",onClick:e.withModifiers(b,["stop"]),title:n.value?"切换单选":"切换多选"},e.toDisplayString(n.value?"多":"单"),9,fe),o.value?(e.openBlock(),e.createElementBlock("span",{key:2,class:"clear-btn",onClick:e.withModifiers(L,["stop"])},"×")):e.createCommentVNode("",!0)]),t.value?(e.openBlock(),e.createElementBlock("div",me,[e.createElementVNode("div",pe,[e.withDirectives(e.createElementVNode("input",{ref_key:"searchInputRef",ref:s,"onUpdate:modelValue":_[0]||(_[0]=x=>k.value=x),type:"text",placeholder:"搜索...",onClick:_[1]||(_[1]=e.withModifiers(()=>{},["stop"])),onInput:V,onKeydown:N},null,544),[[e.vModelText,k.value]])]),e.createElementVNode("div",he,[u.loading?(e.openBlock(),e.createElementBlock("div",ge," 加载中... ")):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(v.value,(x,A)=>(e.openBlock(),e.createElementBlock("div",{key:String(x.value),class:e.normalizeClass(["filter-option",{selected:m(x),highlighted:A===l.value}]),onClick:Y=>C(x),onMouseenter:Y=>l.value=A},[n.value?(e.openBlock(),e.createElementBlock("input",{key:0,type:"checkbox",checked:m(x),onClick:_[2]||(_[2]=e.withModifiers(()=>{},["stop"]))},null,8,be)):e.createCommentVNode("",!0),e.createElementVNode("span",ke,e.toDisplayString(x.label),1)],42,ye))),128)),v.value.length===0?(e.openBlock(),e.createElementBlock("div",Ce," 无匹配数据 ")):e.createCommentVNode("",!0)],64))]),S.value?(e.openBlock(),e.createElementBlock("div",ve," 还有 "+e.toDisplayString(d.value.length-u.maxDisplayItems)+" 条,请输入关键词搜索 ",1)):e.createCommentVNode("",!0),n.value?(e.openBlock(),e.createElementBlock("div",we,[e.createElementVNode("span",Ee,"已选 "+e.toDisplayString(a.value.size)+" 项",1),e.createElementVNode("button",{class:"confirm-btn",onClick:D},"确定")])):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0)],512))}}),[["__scopeId","data-v-051a86c4"]]),Se={class:"filter-bool"},G=I(e.defineComponent({__name:"BoolFilter",props:{field:{},modelValue:{},trueLabel:{default:"是"},falseLabel:{default:"否"}},emits:["update:modelValue"],setup(u,{emit:y}){const c=u,f=y,t=e.ref(null);e.watch(()=>c.modelValue,k=>{if(!k||k.length===0){t.value=null;return}const a=k[0];a.op==="="?t.value=a.value===!0||a.value==="true"||a.value===1:t.value=null},{immediate:!0});function n(k){t.value=k,k===null?f("update:modelValue",null):f("update:modelValue",[{field:c.field,op:"=",value:k}])}return(k,a)=>(e.openBlock(),e.createElementBlock("div",Se,[e.createElementVNode("button",{class:e.normalizeClass({active:t.value===null}),onClick:a[0]||(a[0]=i=>n(null))}," 全部 ",2),e.createElementVNode("button",{class:e.normalizeClass({active:t.value===!0}),onClick:a[1]||(a[1]=i=>n(!0))},e.toDisplayString(u.trueLabel),3),e.createElementVNode("button",{class:e.normalizeClass({active:t.value===!1}),onClick:a[2]||(a[2]=i=>n(!1))},e.toDisplayString(u.falseLabel),3)]))}}),[["__scopeId","data-v-b6f20e4b"]]);function H(){const u=e.ref([]);function y({records:n}){u.value=n}function c({records:n}){u.value=n}function f(){u.value=[]}function t(){return u.value.length}return{selectedRows:u,onCheckboxChange:y,onCheckboxAll:c,clearSelection:f,getSelectedCount:t}}const K=["NUMBER","MONEY","BIGDECIMAL","INTEGER","BIGINT","LONG"];function Q(u){const y=e.ref(null),c=e.computed(()=>u.value.filter(a=>{var i;return K.includes(((i=a.type)==null?void 0:i.toUpperCase())||"")}));function f(a){const i={_count:a.length};for(const l of c.value)i[l.name]=a.reduce((s,d)=>{const v=d[l.name];return s+(typeof v=="number"?v:0)},0);return i}function t(a,i){if(a==null)return"";if(typeof a!="number")return String(a);const l=i==null?void 0:i.toUpperCase();return l==="MONEY"||l==="NUMBER"||l==="BIGDECIMAL"?a.toLocaleString("zh-CN",{minimumFractionDigits:2,maximumFractionDigits:2}):a.toLocaleString("zh-CN")}function n(a,i){var d,v,S;const l=[],s=[];for(let o=0;o<a.length;o++){const b=a[o].field;if(o===0){l.push("选中"),s.push("合计");continue}if(o===1){const m=i._count||0,C=((d=y.value)==null?void 0:d.total)||0;l.push(`${m} 条`),s.push(`${C} 条`);continue}if(b){const m=u.value.find(D=>D.name===b);if(m&&K.includes(((v=m.type)==null?void 0:v.toUpperCase())||"")){const D=i[b],M=(S=y.value)==null?void 0:S[b];l.push(t(D,m==null?void 0:m.type)),s.push(t(M,m==null?void 0:m.type))}else l.push(null),s.push(null)}else l.push(null),s.push(null)}return[l,s]}function k(a){y.value=a}return{serverSummary:y,measureColumns:c,calculateSelectedSummary:f,generateFooterData:n,setServerSummary:k,formatValue:t}}const Ve={class:"data-table"},_e={key:0,class:"data-table-toolbar"},Be={class:"table-wrapper"},Ne={key:1,class:"data-table-footer"},q=I(e.defineComponent({inheritAttrs:!1,__name:"DataTable",props:{columns:{},data:{},total:{},loading:{type:Boolean},pageSize:{default:50},showFilters:{type:Boolean,default:!0},initialSlice:{},serverSummary:{},filterOptionsLoader:{},customFilterComponents:{}},emits:["page-change","sort-change","filter-change","row-click","row-dblclick"],setup(u,{expose:y,emit:c}){const f=e.useAttrs(),t=u,n=c,k=e.useSlots(),a=e.ref(),i=e.ref({currentPage:1,pageSize:t.pageSize,total:t.total}),l=e.ref({field:null,order:null}),s=e.ref({}),d=e.ref({}),v=e.ref({}),S=e.computed(()=>t.columns),{selectedRows:o,onCheckboxChange:h,onCheckboxAll:b,clearSelection:m}=H(),{serverSummary:C,calculateSelectedSummary:D,generateFooterData:M,setServerSummary:L}=Q(S);e.watch(()=>t.serverSummary,r=>{L(r??null)},{immediate:!0});const V=e.computed(()=>{var E;const r=D(o.value),g=((E=Z.value)==null?void 0:E.map(p=>{var B;return{field:p.field,type:(B=t.columns.find(T=>T.name===p.field))==null?void 0:B.type}}))||[];return M(g,r)});e.watch(()=>t.total,r=>{i.value.total=r}),e.watch(()=>t.initialSlice,r=>{if(!r||r.length===0)return;const g={};for(const E of r)E.field&&(g[E.field]||(g[E.field]=[]),g[E.field].push(E));s.value=g},{immediate:!0});async function N(r){if(d.value[r])return d.value[r];if(!t.filterOptionsLoader)return[];v.value[r]=!0;try{const g=await t.filterOptionsLoader(r);return d.value[r]=g,g}catch(g){return console.error("Failed to load dimension options:",g),[]}finally{v.value[r]=!1}}function O(r){var E;const g=(E=r.type)==null?void 0:E.toUpperCase();switch(g){case"DAY":case"DATE":return"date";case"DATETIME":return"datetime"}if(r.filterType)return r.filterType;switch(g){case"NUMBER":case"MONEY":case"BIGDECIMAL":case"INTEGER":case"BIGINT":case"LONG":return"number";case"BOOL":case"BOOLEAN":return"bool";case"DICT":return"dict";default:return"text"}}function w(r){if(r.customFilterComponent)return r.customFilterComponent;const g=O(r);if(t.customFilterComponents&&t.customFilterComponents[g])return t.customFilterComponents[g];switch(g){case"text":return R;case"number":return j;case"date":return P;case"datetime":return P;case"dict":return z;case"dimension":return z;case"bool":return G;default:return R}}function _(r){return r.endsWith("$id")?r:r.includes("$")?`${r.substring(0,r.indexOf("$"))}$id`:`${r}$id`}function x(r){const g=O(r),E={field:r.name,modelValue:s.value[r.name]||null,"onUpdate:modelValue":p=>A(r.name,p)};switch(g){case"datetime":return{...E,showTime:!0,format:r.format};case"date":return{...E,format:r.format};case"dict":return{...E,options:r.dictItems||[],placeholder:r.title||"请选择"};case"dimension":{d.value[r.name]||N(r.name);const p=_(r.name);return{...E,field:p,modelValue:s.value[p]||s.value[r.name]||null,"onUpdate:modelValue":B=>A(p,B),options:d.value[r.name]||[],loading:v.value[r.name],placeholder:r.title||"请选择"}}default:return E}}function A(r,g){g===null||g.length===0?delete s.value[r]:s.value[r]=g,Y()}function Y(){const r=[];for(const g of Object.values(s.value))g&&g.length>0&&r.push(...g);n("filter-change",r)}function et(r){var E;if(r.customFormatter)return{formatter:({cellValue:p})=>r.customFormatter(p)};switch((E=r.type)==null?void 0:E.toUpperCase()){case"MONEY":case"NUMBER":case"BIGDECIMAL":return{formatter:({cellValue:p})=>p==null?"":typeof p=="number"?p.toLocaleString("zh-CN",{minimumFractionDigits:2,maximumFractionDigits:2}):p};case"INTEGER":case"BIGINT":case"LONG":return{formatter:({cellValue:p})=>p==null?"":typeof p=="number"?p.toLocaleString("zh-CN"):p};case"DAY":case"DATE":return{formatter:({cellValue:p})=>p?String(p).split("T")[0]:""};case"DATETIME":return{minWidth:160,formatter:({cellValue:p})=>p?String(p).replace("T"," ").substring(0,19):""};case"BOOL":case"BOOLEAN":return{formatter:({cellValue:p})=>p===!0?"是":p===!1?"否":""};default:return{}}}function tt(r){const g=l.value.field===r?l.value.order:null;let E;g===null?E="asc":g==="asc"?E="desc":E=null,l.value.field=E?r:null,l.value.order=E,n("sort-change",l.value.field,l.value.order)}const Z=e.computed(()=>{const r=l.value,g={type:"checkbox",width:50,fixed:"left"},E=t.columns.map(p=>{const B={field:p.name,title:p.title||p.name,width:p.width,minWidth:p.minWidth??120,fixed:p.fixed,sortable:!1,...et(p),slots:{header:()=>{const $=r.field===p.name?r.order:null;return e.h("div",{class:"column-header-wrapper"},[e.h("div",{class:"column-title",onClick:()=>tt(p.name)},[e.h("span",{class:"title-text"},p.title||p.name),e.h("span",{class:["sort-icon",$?`sort-${$}`:""]},$==="asc"?" ↑":$==="desc"?" ↓":" ↕")]),t.showFilters&&e.h("div",{class:"column-filter"},[at(p)])])}}},T=`column-${p.name}`;return k[T]?B.slots={...B.slots,default:({row:$})=>k[T]({row:$,column:p,value:$[p.name]})}:p.customRender&&(B.slots={...B.slots,default:({row:$})=>p.customRender({row:$,value:$[p.name]})}),B});return[g,...E]});function at(r){const g=`filter-${r.name}`;if(k[g])return k[g]({column:r,field:r.name,modelValue:s.value[r.name]||null,onChange:B=>A(r.name,B)});const E=w(r),p=x(r);return e.h(E,p)}const lt=e.computed(()=>{const r=Object.keys(f).filter(E=>!E.startsWith("on")).reduce((E,p)=>({...E,[p]:f[p]}),{});return{...{border:!0,stripe:!0,showOverflow:!0,height:"auto",loading:t.loading,columnConfig:{resizable:!0},rowConfig:{isHover:!0},checkboxConfig:{highlight:!0,trigger:"cell"},showFooter:!0,footerData:V.value,headerRowClassName:t.showFilters?"header-with-filter":"",pagerConfig:{enabled:!0,currentPage:i.value.currentPage,pageSize:i.value.pageSize,total:i.value.total,pageSizes:[20,50,100,200],layouts:["PrevPage","JumpNumber","NextPage","Sizes","FullJump","Total"]},sortConfig:{remote:!0},columns:Z.value,data:t.data},...r}}),nt=e.computed(()=>{const r={};Object.keys(f).forEach(B=>{if(B.startsWith("on")){const T=B.slice(2,3).toLowerCase()+B.slice(3);r[T]=f[B]}});const g=(B,T)=>(...$)=>{B(...$),r[T]&&r[T](...$)},p={...{pageChange:g(({currentPage:B,pageSize:T})=>{i.value.currentPage=B,i.value.pageSize=T,n("page-change",B,T)},"pageChange"),cellClick:g(({row:B,column:T})=>{const $=t.columns.find(W=>W.name===T.field);$&&n("row-click",B,$)},"cellClick"),cellDblclick:g(({row:B,column:T})=>{const $=t.columns.find(W=>W.name===T.field);$&&n("row-dblclick",B,$)},"cellDblclick"),checkboxChange:g(h,"checkboxChange"),checkboxAll:g(b,"checkboxAll")}};return Object.keys(r).forEach(B=>{p[B]||(p[B]=r[B])}),p});function ot(){i.value.currentPage=1}function rt(){s.value={},Y()}return y({resetPagination:ot,clearFilters:rt,getFilters:()=>{const r=[];for(const g of Object.values(s.value))g&&g.length>0&&r.push(...g);return r},setFilter:A,getGridInstance:()=>a.value}),e.provide("dataTableContext",{columns:e.computed(()=>t.columns),filters:s,updateFilter:A}),(r,g)=>{const E=e.resolveComponent("vxe-grid");return e.openBlock(),e.createElementBlock("div",Ve,[r.$slots.toolbar?(e.openBlock(),e.createElementBlock("div",_e,[e.renderSlot(r.$slots,"toolbar",{},void 0,!0)])):e.createCommentVNode("",!0),e.createElementVNode("div",Be,[e.createVNode(E,e.mergeProps({ref_key:"gridRef",ref:a},lt.value,e.toHandlers(nt.value)),{empty:e.withCtx(()=>[e.renderSlot(r.$slots,"empty",{},()=>[g[0]||(g[0]=e.createElementVNode("div",{class:"empty-data"},"暂无数据",-1))],!0)]),_:3},16)]),r.$slots.footer?(e.openBlock(),e.createElementBlock("div",Ne,[e.renderSlot(r.$slots,"footer",{},void 0,!0)])):e.createCommentVNode("",!0)])}}}),[["__scopeId","data-v-e12c7b39"]]),U=ee.create({baseURL:"/data-viewer/api",timeout:3e4,headers:{"Content-Type":"application/json"}});async function De(u){var c;const y=await U.get(`/query/${u}/meta`);if(!y.data||y.data.code!==200)throw new Error(((c=y.data)==null?void 0:c.msg)||"获取查询元数据失败");return y.data.data}async function Fe(u,y){var f,t,n;const c=await U.post(`/query/${u}/data`,y);if(!c.data||c.data.code!==200){if((t=(f=c.data)==null?void 0:f.data)!=null&&t.expired)return c.data.data;throw new Error(((n=c.data)==null?void 0:n.msg)||"查询数据失败")}return c.data.data}async function $e(u,y){return(await U.get(`/query/${u}/filter-options/${encodeURIComponent(y)}`)).data}async function Te(u){var t;const y=await U.get(`/schema/${encodeURIComponent(u)}`);if(!y.data||y.data.code!==200)throw new Error(((t=y.data)==null?void 0:t.msg)||"获取 QM Schema 失败");const c=y.data.data;if(!c||!c.fields)return[];const f=[];for(const[n,k]of Object.entries(c.fields)){const a=k;f.push({name:n,title:a.name||n,type:a.type||"TEXT",filterable:a.filterable!==!1,aggregatable:a.aggregatable||!1,measure:a.measure||!1,filterType:a.filterType,dictId:a.dictId,format:a.format})}return f}U.interceptors.response.use(u=>u,u=>{var y,c;return((y=u.response)==null?void 0:y.status)===410?Promise.reject(new Error("查询链接已过期,请重新获取")):((c=u.response)==null?void 0:c.status)===404?Promise.reject(new Error("查询不存在")):Promise.reject(u)});function J(u,y){var k;const c=new Map(u.map(a=>[a.name,a])),f=new Map(((k=y.customizations)==null?void 0:k.map(a=>[a.name,a]))||[]);return(y.showAll||!y.visibleColumns||y.visibleColumns.length===0?u.map(a=>a.name):y.visibleColumns).map(a=>{const i=c.get(a);if(!i)return console.warn(`Column "${a}" not found in QM schema`),null;const l=f.get(a);return{...i,width:l==null?void 0:l.width,minWidth:(l==null?void 0:l.minWidth)??120,fixed:l==null?void 0:l.fixed,customRender:l==null?void 0:l.render,customFilterComponent:l==null?void 0:l.filterComponent,customFormatter:l==null?void 0:l.formatter}}).filter(a=>a!==null)}const xe={class:"data-viewer"},Me={class:"viewer-header"},Ie={class:"viewer-title"},Oe={class:"viewer-info"},Ae={key:0,class:"info-item"},Le={key:1,class:"info-item"},Re={key:2,class:"info-item"},Pe=["disabled"],ze={key:0,class:"viewer-expired"},Ue={key:1,class:"viewer-error"},Ye={class:"error-content"},je={key:2,class:"viewer-main"},Ge=I(e.defineComponent({__name:"DataViewer",props:{queryId:{}},setup(u){const y=u,c=e.ref(!1),f=e.ref(null),t=e.ref(!1),n=e.ref(null),k=e.ref([]),a=e.ref([]),i=e.ref([]),l=e.ref(0),s=e.ref(null),d=e.ref({start:0,limit:50,slice:[],orderBy:[]}),v=e.ref(),S=e.computed(()=>{var V;return((V=n.value)==null?void 0:V.title)||"数据浏览器"}),o=e.computed(()=>{var V;return(V=n.value)!=null&&V.expiresAt?new Date(n.value.expiresAt).toLocaleString("zh-CN"):""});async function h(){try{c.value=!0,f.value=null,n.value=await De(y.queryId),n.value.tableConfig.qmModel&&(k.value=await Te(n.value.tableConfig.qmModel),a.value=J(k.value,n.value.tableConfig))}catch(V){f.value=V instanceof Error?V.message:"加载元数据失败"}finally{c.value=!1}}async function b(){if(n.value)try{c.value=!0,f.value=null;const V=await Fe(y.queryId,d.value);if(V.expired){t.value=!0,f.value=V.errorMessage||"查询已过期";return}if(!V.success){f.value=V.errorMessage||"查询失败";return}i.value=V.items,l.value=V.total,s.value=V.totalData??null}catch(V){f.value=V instanceof Error?V.message:"加载数据失败"}finally{c.value=!1}}function m(V,N){d.value.start=(V-1)*N,d.value.limit=N,b()}function C(V,N){V&&N?d.value.orderBy=[{field:V,order:N}]:d.value.orderBy=[],b()}function D(V){var N;d.value.slice=V,d.value.start=0,(N=v.value)==null||N.resetPagination(),b()}async function M(V){try{return(await $e(y.queryId,V)).options||[]}catch(N){return console.error("Failed to load filter options:",N),[]}}function L(){b()}return e.onMounted(async()=>{await h(),n.value&&(n.value.initialSlice&&n.value.initialSlice.length>0&&(d.value.slice=n.value.initialSlice),await b())}),(V,N)=>{var O,w,_,x;return e.openBlock(),e.createElementBlock("div",xe,[e.createElementVNode("header",Me,[e.createElementVNode("h1",Ie,e.toDisplayString(S.value),1),e.createElementVNode("div",Oe,[(w=(O=n.value)==null?void 0:O.tableConfig)!=null&&w.qmModel?(e.openBlock(),e.createElementBlock("span",Ae,[N[0]||(N[0]=e.createTextVNode(" 模型: ",-1)),e.createElementVNode("strong",null,e.toDisplayString(n.value.tableConfig.qmModel),1)])):e.createCommentVNode("",!0),(_=n.value)!=null&&_.estimatedRowCount?(e.openBlock(),e.createElementBlock("span",Le,[N[1]||(N[1]=e.createTextVNode(" 预估行数: ",-1)),e.createElementVNode("strong",null,e.toDisplayString(n.value.estimatedRowCount.toLocaleString()),1)])):e.createCommentVNode("",!0),o.value?(e.openBlock(),e.createElementBlock("span",Re,[N[2]||(N[2]=e.createTextVNode(" 过期时间: ",-1)),e.createElementVNode("strong",null,e.toDisplayString(o.value),1)])):e.createCommentVNode("",!0),e.createElementVNode("button",{class:"refresh-btn",onClick:L,disabled:c.value}," 刷新 ",8,Pe)])]),t.value?(e.openBlock(),e.createElementBlock("div",ze,[...N[3]||(N[3]=[e.createElementVNode("div",{class:"expired-content"},[e.createElementVNode("h2",null,"链接已过期"),e.createElementVNode("p",null,"请联系AI助手重新生成查询链接")],-1)])])):f.value&&!i.value.length?(e.openBlock(),e.createElementBlock("div",Ue,[e.createElementVNode("div",Ye,[N[4]||(N[4]=e.createElementVNode("h2",null,"加载失败",-1)),e.createElementVNode("p",null,e.toDisplayString(f.value),1),e.createElementVNode("button",{onClick:b},"重试")])])):(e.openBlock(),e.createElementBlock("main",je,[e.createVNode(q,{ref_key:"dataTableRef",ref:v,columns:a.value,data:i.value,total:l.value,loading:c.value,"initial-slice":(x=n.value)==null?void 0:x.initialSlice,"filter-options-loader":M,"server-summary":s.value,onPageChange:m,onSortChange:C,onFilterChange:D},null,8,["columns","data","total","loading","initial-slice","server-summary"])])),N[5]||(N[5]=e.createElementVNode("footer",{class:"viewer-footer"},[e.createElementVNode("span",null,"Foggy Data Viewer")],-1))])}}}),[["__scopeId","data-v-25b92aeb"]]),qe={class:"search-fields"},We={class:"field-label"},He={class:"field-filter"},Ke={key:0,class:"search-actions"},X=I(e.defineComponent({__name:"SearchToolbar",props:{columns:{},searchableFields:{},modelValue:{},layout:{default:"horizontal"},showActions:{type:Boolean,default:!0},filterOptionsLoader:{}},emits:["update:modelValue","search","reset"],setup(u,{expose:y,emit:c}){const f=u,t=c,n=e.ref({}),k=e.computed(()=>{let o=f.columns.filter(h=>h.filterable!==!1);return f.searchableFields&&f.searchableFields.length>0&&(o=o.filter(h=>f.searchableFields.includes(h.name))),o});e.watch(()=>f.modelValue,o=>{if(!o||o.length===0){n.value={};return}const h={};for(const b of o)b.field&&(h[b.field]||(h[b.field]=[]),h[b.field].push(b));n.value=h},{immediate:!0});function a(o){var b;const h=(b=o.type)==null?void 0:b.toUpperCase();switch(h){case"DAY":case"DATE":return"date";case"DATETIME":return"datetime"}if(o.filterType)return o.filterType;switch(h){case"NUMBER":case"MONEY":case"BIGDECIMAL":case"INTEGER":case"BIGINT":case"LONG":return"number";case"BOOL":case"BOOLEAN":return"bool";case"DICT":return"dict";default:return"text"}}function i(o){if(o.customFilterComponent)return o.customFilterComponent;switch(a(o)){case"text":return R;case"number":return j;case"date":return P;case"datetime":return P;case"dict":return z;case"dimension":return z;case"bool":return G;default:return R}}function l(o){const h=a(o),b={field:o.name,modelValue:n.value[o.name]||null,"onUpdate:modelValue":m=>s(o.name,m)};switch(h){case"datetime":return{...b,showTime:!0,format:o.format};case"date":return{...b,format:o.format};case"dict":return{...b,options:o.dictItems||[],placeholder:`请选择${o.title||o.name}`};case"dimension":return{...b,options:[],loading:!1,placeholder:`请选择${o.title||o.name}`};default:return{...b,placeholder:`搜索${o.title||o.name}...`}}}function s(o,h){h===null||h.length===0?delete n.value[o]:n.value[o]=h,d()}function d(){const o=[];for(const h of Object.values(n.value))h&&h.length>0&&o.push(...h);t("update:modelValue",o)}function v(){d(),t("search")}function S(){n.value={},t("update:modelValue",[]),t("reset")}return y({clearFilters:S,getFilters:()=>{const o=[];for(const h of Object.values(n.value))h&&h.length>0&&o.push(...h);return o}}),(o,h)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["search-toolbar",`layout-${u.layout}`])},[e.createElementVNode("div",qe,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(k.value,b=>(e.openBlock(),e.createElementBlock("div",{key:b.name,class:"search-field-item"},[e.createElementVNode("label",We,e.toDisplayString(b.title||b.name),1),e.createElementVNode("div",He,[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(i(b)),e.mergeProps({ref_for:!0},l(b)),null,16))])]))),128))]),u.showActions?(e.openBlock(),e.createElementBlock("div",Ke,[e.createElementVNode("button",{class:"btn btn-primary",onClick:v},[...h[0]||(h[0]=[e.createElementVNode("span",{class:"btn-icon"},"🔍",-1),e.createTextVNode(" 搜索 ",-1)])]),e.createElementVNode("button",{class:"btn btn-default",onClick:S},[...h[1]||(h[1]=[e.createElementVNode("span",{class:"btn-icon"},"↻",-1),e.createTextVNode(" 重置 ",-1)])])])):e.createCommentVNode("",!0)],2))}}),[["__scopeId","data-v-efd07e5e"]]),Qe={class:"data-table-with-search"},Je={key:0,class:"search-toolbar-wrapper"},Xe={class:"data-table-wrapper"},Ze=I(e.defineComponent({inheritAttrs:!1,__name:"DataTableWithSearch",props:{columns:{},data:{},total:{},loading:{type:Boolean},pageSize:{default:50},showFilters:{type:Boolean,default:!0},initialSlice:{},serverSummary:{},filterOptionsLoader:{},customFilterComponents:{},showSearchToolbar:{type:Boolean,default:!0},searchableFields:{},searchLayout:{default:"horizontal"},showSearchActions:{type:Boolean,default:!0},filterMergeMode:{default:"merge"}},emits:["page-change","sort-change","filter-change","row-click","row-dblclick","search","reset"],setup(u,{expose:y,emit:c}){const f=e.useAttrs(),t=u,n=c,k=e.ref(),a=e.ref(),i=e.ref([]),l=e.ref([]),s=e.computed(()=>{if(t.filterMergeMode==="replace")return i.value.length>0?i.value:l.value;{const m=[...i.value],C=new Set(i.value.map(D=>D.field));for(const D of l.value)C.has(D.field)||m.push(D);return m}});function d(m){i.value=m,n("filter-change",s.value)}function v(){n("search",i.value),n("filter-change",s.value)}function S(){i.value=[],n("reset"),n("filter-change",s.value)}function o(m){l.value=m,n("filter-change",s.value)}const h=e.computed(()=>{const m=Object.keys(f).filter(C=>!C.startsWith("on")).reduce((C,D)=>({...C,[D]:f[D]}),{});return{columns:t.columns,data:t.data,total:t.total,loading:t.loading,pageSize:t.pageSize,showFilters:t.showFilters,initialSlice:t.initialSlice,serverSummary:t.serverSummary,filterOptionsLoader:t.filterOptionsLoader,customFilterComponents:t.customFilterComponents,...m}}),b=e.computed(()=>{const m={};return Object.keys(f).forEach(C=>{if(C.startsWith("on")){const D=C.slice(2,3).toLowerCase()+C.slice(3);m[D]=f[C]}}),{"page-change":(...C)=>{n("page-change",...C),m.pageChange&&m.pageChange(...C)},"sort-change":(...C)=>{n("sort-change",...C),m.sortChange&&m.sortChange(...C)},"filter-change":o,"row-click":(...C)=>{n("row-click",...C),m.rowClick&&m.rowClick(...C)},"row-dblclick":(...C)=>{n("row-dblclick",...C),m.rowDblclick&&m.rowDblclick(...C)}}});return y({getSearchToolbar:()=>k.value,getDataTable:()=>a.value,clearSearchFilters:()=>{var m;return(m=k.value)==null?void 0:m.clearFilters()},clearTableFilters:()=>{var m;return(m=a.value)==null?void 0:m.clearFilters()},clearAllFilters:()=>{var m,C;(m=k.value)==null||m.clearFilters(),(C=a.value)==null||C.clearFilters()},getMergedFilters:()=>s.value,resetPagination:()=>{var m;return(m=a.value)==null?void 0:m.resetPagination()}}),(m,C)=>(e.openBlock(),e.createElementBlock("div",Qe,[u.showSearchToolbar?(e.openBlock(),e.createElementBlock("div",Je,[e.createVNode(X,{ref_key:"searchToolbarRef",ref:k,columns:u.columns,"searchable-fields":u.searchableFields,layout:u.searchLayout,"show-actions":u.showSearchActions,"filter-options-loader":u.filterOptionsLoader,modelValue:i.value,"onUpdate:modelValue":[C[0]||(C[0]=D=>i.value=D),d],onSearch:v,onReset:S},null,8,["columns","searchable-fields","layout","show-actions","filter-options-loader","modelValue"])])):e.createCommentVNode("",!0),e.createElementVNode("div",Xe,[e.createVNode(q,e.mergeProps({ref_key:"dataTableRef",ref:a},h.value,e.toHandlers(b.value)),e.createSlots({_:2},[e.renderList(m.$slots,(D,M)=>({name:M,fn:e.withCtx(L=>[e.renderSlot(m.$slots,M,e.normalizeProps(e.guardReactiveProps(L||{})),void 0,!0)])}))]),1040)])]))}}),[["__scopeId","data-v-690f5c67"]]);F.BoolFilter=G,F.DataTable=q,F.DataTableWithSearch=Ze,F.DataViewer=Ge,F.DateRangeFilter=P,F.NumberRangeFilter=j,F.SearchToolbar=X,F.SelectFilter=z,F.TextFilter=R,F.buildTableColumns=J,F.useTableSelection=H,F.useTableSummary=Q,Object.defineProperty(F,Symbol.toStringTag,{value:"Module"})});