@idooel/components 0.0.2-beta.2 → 0.0.2-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1951,6 +1951,7 @@ var __vue_render__$C = function () {
1951
1951
  bordered: _vm.bordered,
1952
1952
  pagination: false,
1953
1953
  loading: _vm.loading,
1954
+ size: "middle",
1954
1955
  columns: _vm.innerColumns,
1955
1956
  "row-selection": _vm.rowSelection,
1956
1957
  "row-class-name": _vm.setRowClassName,
@@ -2009,11 +2010,11 @@ __vue_render__$C._withStripped = true;
2009
2010
  /* style */
2010
2011
  const __vue_inject_styles__$C = function (inject) {
2011
2012
  if (!inject) return
2012
- inject("data-v-7943901f_0", { source: "@charset \"UTF-8\";\n.g-table__wrapper[data-v-7943901f] {\n /* 外层采用列布局,确保分页始终可见,表格充满剩余空间 */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n /* 表格区域占满剩余空间,启用纵向滚动 */\n /* 确保表体能够正常纵向滚动 */\n /* 分页区域固定在底部,不被挤出视口 */\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-wrapper {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-7943901f] .ant-spin-nested-loading {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-7943901f] .ant-spin-container {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-content {\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-scroll {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-header {\n flex: 0 0 auto;\n overflow: hidden;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-selection-column {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-selection-column {\n background-color: var(--idooel-row-odd-color);\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-odd-color);\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-body {\n flex: 1 1 auto;\n overflow: auto !important;\n /* 确保滚动条稳定,避免列宽抖动 */\n scrollbar-gutter: stable;\n}\n.g-table__wrapper .g-table__pagination[data-v-7943901f] {\n flex: 0 0 auto;\n display: flex;\n flex-direction: row;\n justify-content: end;\n border-top: unset;\n padding-top: 8px;\n padding-bottom: 8px;\n background: #fff;\n z-index: 999;\n}\n\n/*# sourceMappingURL=index.vue.map */", map: {"version":3,"sources":["index.vue","/Users/huangshan/Goldgov/front/ganjiao/base-elearning-frontend-model/packages/components/packages/table/src/index.vue"],"names":[],"mappings":"AAAA,gBAAgB;ACwNhB;EACA,8BAAA;EACA,aAAA;EACA,sBAAA;EACA,gBAAA;EAEA,sBAAA;EA6BA,iBAAA;EA6CA,qBAAA;AD/RA;ACsNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADpNA;ACuNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADrNA;ACwNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADtNA;ACyNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADvNA;AC2NA;EACA,cAAA;EACA,aAAA;EACA,gBAAA;ADzNA;AC4NA;EACA,YAAA;EACA,aAAA;EACA,sBAAA;AD1NA;AC6NA;EACA,cAAA;EACA,gBAAA;AD3NA;ACiOA;EACA,0DAAA;AD/NA;ACiOA;EACA,0DAAA;AD/NA;ACkOA;EACA,6CAAA;ADhOA;ACkOA;EACA,6CAAA;ADhOA;ACsOA;EACA,cAAA;EACA,yBAAA;EACA,mBAAA;EACA,wBAAA;ADpOA;ACwOA;EACA,cAAA;EACA,aAAA;EACA,mBAAA;EACA,oBAAA;EACA,iBAAA;EACA,gBAAA;EACA,mBAAA;EACA,gBAAA;EACA,YAAA;ADtOA;;AAEA,oCAAoC","file":"index.vue","sourcesContent":["@charset \"UTF-8\";\n.g-table__wrapper {\n /* 外层采用列布局,确保分页始终可见,表格充满剩余空间 */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n /* 表格区域占满剩余空间,启用纵向滚动 */\n /* 确保表体能够正常纵向滚动 */\n /* 分页区域固定在底部,不被挤出视口 */\n}\n.g-table__wrapper ::v-deep .ant-table-wrapper {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-spin-nested-loading {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-spin-container {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-table {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-table-content {\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n}\n.g-table__wrapper ::v-deep .ant-table-scroll {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-table-header {\n flex: 0 0 auto;\n overflow: hidden;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-selection-column {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-selection-column {\n background-color: var(--idooel-row-odd-color);\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-odd-color);\n}\n.g-table__wrapper ::v-deep .ant-table-body {\n flex: 1 1 auto;\n overflow: auto !important;\n /* 确保滚动条稳定,避免列宽抖动 */\n scrollbar-gutter: stable;\n}\n.g-table__wrapper .g-table__pagination {\n flex: 0 0 auto;\n display: flex;\n flex-direction: row;\n justify-content: end;\n border-top: unset;\n padding-top: 8px;\n padding-bottom: 8px;\n background: #fff;\n z-index: 999;\n}\n\n/*# sourceMappingURL=index.vue.map */","<template>\n <div class=\"g-table__wrapper\" :style=\"wrapperStyle\" :class=\"{ 'g-table--no-scroll-y': !needScrollY }\">\n <a-table\n :bordered=\"bordered\"\n :class=\"[isNoData && 'g-table__no-data']\"\n :pagination=\"false\"\n :loading=\"loading\"\n :columns=\"innerColumns\"\n :row-selection=\"rowSelection\"\n :row-class-name=\"setRowClassName\"\n :data-source=\"dataSource\"\n :scroll=\"getScroll\">\n <template slot=\"action\" slot-scope=\"record\">\n <Actions v-on=\"$listeners\" :data-source=\"actions\" :record=\"record\"></Actions>\n </template>\n </a-table>\n <div class=\"g-table__pagination\">\n <a-pagination\n :show-total=\"all => `共 ${all} 条数据`\"\n show-size-changer \n show-quick-jumper\n :pageSize=\"innerPageSize\"\n :current=\"innerCurrentPage\"\n :pageSizeOptions=\"pageSizeOptions\"\n @change=\"onChangePagination\"\n @showSizeChange=\"onShowSizeChange\"\n :total=\"total\">\n </a-pagination>\n </div>\n </div>\n</template>\n\n<script>\nimport Actions from './action.vue'\nexport default {\n name: 'ele-table',\n components: {\n Actions\n },\n props: {\n // ant table wrapper\n height: {\n type: Number\n },\n width: {\n type: Number\n },\n x: {\n type: Number,\n default: 1200\n },\n y: {\n type: Number,\n default: 200\n },\n scroll: {\n type: Object\n },\n rowSelection: {\n type: Object\n },\n actions: {\n type: Array,\n default: () => []\n },\n total: {\n type: Number,\n default: 0\n },\n loading: {\n type: Boolean,\n default: false\n },\n columns: {\n type: Array,\n default: () => []\n },\n dataSource: {\n type: Array,\n default: () => []\n },\n pageSize: {\n type: Number,\n default: 10\n },\n pageSizeOptions: {\n type: Array,\n default: () => ['10', '20', '30', '40']\n },\n bordered: {\n type: Boolean,\n default: true\n }\n },\n data() {\n return {\n tableHeaderHeight: 0,\n paginationHeight: 0,\n innerPageSize: 10,\n innerCurrentPage: 1,\n tableContentHeight: 0,\n obs: []\n }\n },\n computed: {\n wrapperStyle () {\n // 外层容器样式:确保分页始终可见,表格充满剩余空间\n if (!this.height) return {}\n return { height: `${this.height}px` }\n },\n needScrollY () {\n // 判断是否需要 y 轴滚动:基于数据行数与可用高度预估\n if (!this.height) return false\n \n const availableHeight = this.getScrollHeightByHeight\n if (availableHeight <= 0) return false\n \n // 预估每行高度(包含边框),antd 默认约 54px\n const estimatedRowHeight = 54\n const estimatedTableHeight = this.dataSource.length * estimatedRowHeight\n \n return estimatedTableHeight > availableHeight\n },\n innerColumns () {\n return this.columns.filter(col => !Object.keys(col).includes('multiple'))\n },\n isNoData () {\n return !this.dataSource.length\n },\n getScrollHeightByHeight () {\n // 始终返回可用的剩余高度,让表格内容不足时也能占满容器\n return this.height - this.tableHeaderHeight - this.paginationHeight\n },\n isFlexColumn () {\n return this.columns.every(col => !col.width)\n },\n getScroll () {\n if (this.scroll) {\n return this.scroll\n } else {\n const baseX = this.isFlexColumn ? 0 : (this.width > this.x ? 0 : this.x)\n if (this.height) {\n // 计算表体可用高度\n const availableHeight = this.tableHeaderHeight && this.paginationHeight \n ? this.getScrollHeightByHeight \n : this.height - 100 // 预估值,给表头和分页留空间\n \n if (availableHeight > 50) { // 确保有足够的最小高度\n console.log('Table scroll config:', { x: baseX, y: availableHeight, height: this.height, headerHeight: this.tableHeaderHeight, paginationHeight: this.paginationHeight })\n return { x: baseX, y: availableHeight }\n }\n }\n return { x: baseX }\n }\n }\n },\n watch: {\n pageSize: {\n handler (pageSize) {\n this.innerPageSize = pageSize\n },\n immediate: true\n }\n },\n methods: {\n onShowSizeChange (current, pageSize) {\n this.innerCurrentPage = current\n this.innerPageSize = pageSize\n this.$emit('change-page', current, pageSize)\n },\n setPaginationHeight () {\n this.$nextTick(() => {\n const { height } = document.querySelector('.g-table__pagination').getBoundingClientRect()\n this.paginationHeight = height\n })\n },\n setTableHeaderHeight () {\n this.$nextTick(() => {\n const el = document.querySelector('.ant-table-header')\n if (!el) return\n const { height } = el.getBoundingClientRect()\n this.tableHeaderHeight = height\n })\n },\n setTableTbodyHeight () {\n // 简化:仅需要获取表头高度,不再依赖表体高度的动态监听\n this.$nextTick(() => {\n this.setTableHeaderHeight()\n })\n },\n setRowClassName (record, idx) {\n return idx % 2 === 0 ? 'g-table__row--even' : 'g-table__row--odd'\n },\n onChangePagination (page, pageSize) {\n this.innerCurrentPage = page\n this.innerPageSize = pageSize\n this.$emit('change-page', page, pageSize)\n }\n },\n mounted() {\n this.$nextTick(() => {\n this.setPaginationHeight()\n setTimeout(() => {\n this.setTableTbodyHeight()\n // 再测一次分页高度,确保初次渲染完成后数值准确\n this.setPaginationHeight()\n }, 200)\n })\n },\n destroyed () {\n this.obs.forEach(ob => ob.disconnect())\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.g-table__wrapper {\n /* 外层采用列布局,确保分页始终可见,表格充满剩余空间 */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n\n /* 表格区域占满剩余空间,启用纵向滚动 */\n ::v-deep .ant-table-wrapper {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-spin-nested-loading {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-spin-container {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-table {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n /* 确保表体能够正常纵向滚动 */\n ::v-deep .ant-table-content {\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n }\n\n ::v-deep .ant-table-scroll {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-table-header {\n flex: 0 0 auto;\n overflow: hidden;\n }\n ::v-deep .ant-table-fixed {\n .ant-table-tbody {\n .g-table__row--odd {\n &.ant-table-row-hover {\n .ant-table-selection-column {\n background-color: var(--idooel-row-hover-color) !important;\n }\n .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-hover-color) !important;\n }\n }\n .ant-table-selection-column {\n background-color: var(--idooel-row-odd-color);\n }\n .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-odd-color);\n }\n }\n }\n }\n\n ::v-deep .ant-table-body {\n flex: 1 1 auto;\n overflow: auto !important;\n /* 确保滚动条稳定,避免列宽抖动 */\n scrollbar-gutter: stable;\n }\n\n /* 分页区域固定在底部,不被挤出视口 */\n .g-table__pagination {\n flex: 0 0 auto;\n display: flex;\n flex-direction: row;\n justify-content: end;\n border-top: unset;\n padding-top: 8px;\n padding-bottom: 8px;\n background: #fff;\n z-index: 999;\n }\n}\n</style>"]}, media: undefined });
2013
+ inject("data-v-3f1790f0_0", { source: "@charset \"UTF-8\";\n.g-table__wrapper[data-v-3f1790f0] {\n /* 外层采用列布局,确保分页始终可见,表格充满剩余空间 */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n /* 表格区域占满剩余空间,启用纵向滚动 */\n /* 确保表体能够正常纵向滚动 */\n /* 分页区域固定在底部,不被挤出视口 */\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-wrapper {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-spin-nested-loading {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-spin-container {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-content {\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-scroll {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-header {\n flex: 0 0 auto;\n overflow: hidden;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover td {\n background-color: var(--idooel-row-hover-color);\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-selection-column {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-tbody .g-table__row--odd td {\n background-color: var(--idooel-row-odd-color);\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-selection-column {\n background-color: var(--idooel-row-odd-color) !important;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-odd-color) !important;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-thead {\n background: rgba(0, 0, 0, 0.03) !important;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-body {\n flex: 1 1 auto;\n overflow: auto !important;\n /* 确保滚动条稳定,避免列宽抖动 */\n scrollbar-gutter: stable;\n}\n.g-table__wrapper .g-table__pagination[data-v-3f1790f0] {\n flex: 0 0 auto;\n display: flex;\n flex-direction: row;\n justify-content: end;\n border-top: unset;\n padding-top: 8px;\n padding-bottom: 8px;\n background: #fff;\n z-index: 999;\n}\n\n/*# sourceMappingURL=index.vue.map */", map: {"version":3,"sources":["index.vue","/Users/huangshan/Goldgov/front/ganjiao/base-elearning-frontend-model/packages/components/packages/table/src/index.vue"],"names":[],"mappings":"AAAA,gBAAgB;ACyNhB;EACA,8BAAA;EACA,aAAA;EACA,sBAAA;EACA,gBAAA;EAEA,sBAAA;EA6BA,iBAAA;EAsDA,qBAAA;ADzSA;ACuNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADrNA;ACwNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADtNA;ACyNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADvNA;AC0NA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADxNA;AC4NA;EACA,cAAA;EACA,aAAA;EACA,gBAAA;AD1NA;AC6NA;EACA,YAAA;EACA,aAAA;EACA,sBAAA;AD3NA;AC8NA;EACA,cAAA;EACA,gBAAA;AD5NA;ACkOA;EACA,+CAAA;ADhOA;ACkOA;EACA,0DAAA;ADhOA;ACkOA;EACA,0DAAA;ADhOA;ACmOA;EACA,6CAAA;ADjOA;ACmOA;EACA,wDAAA;ADjOA;ACmOA;EACA,wDAAA;ADjOA;ACqOA;EACA,0CAAA;ADnOA;ACuOA;EACA,cAAA;EACA,yBAAA;EACA,mBAAA;EACA,wBAAA;ADrOA;ACyOA;EACA,cAAA;EACA,aAAA;EACA,mBAAA;EACA,oBAAA;EACA,iBAAA;EACA,gBAAA;EACA,mBAAA;EACA,gBAAA;EACA,YAAA;ADvOA;;AAEA,oCAAoC","file":"index.vue","sourcesContent":["@charset \"UTF-8\";\n.g-table__wrapper {\n /* 外层采用列布局,确保分页始终可见,表格充满剩余空间 */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n /* 表格区域占满剩余空间,启用纵向滚动 */\n /* 确保表体能够正常纵向滚动 */\n /* 分页区域固定在底部,不被挤出视口 */\n}\n.g-table__wrapper ::v-deep .ant-table-wrapper {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-spin-nested-loading {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-spin-container {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-table {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-table-content {\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n}\n.g-table__wrapper ::v-deep .ant-table-scroll {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-table-header {\n flex: 0 0 auto;\n overflow: hidden;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover td {\n background-color: var(--idooel-row-hover-color);\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-selection-column {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd td {\n background-color: var(--idooel-row-odd-color);\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-selection-column {\n background-color: var(--idooel-row-odd-color) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-odd-color) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-thead {\n background: rgba(0, 0, 0, 0.03) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-body {\n flex: 1 1 auto;\n overflow: auto !important;\n /* 确保滚动条稳定,避免列宽抖动 */\n scrollbar-gutter: stable;\n}\n.g-table__wrapper .g-table__pagination {\n flex: 0 0 auto;\n display: flex;\n flex-direction: row;\n justify-content: end;\n border-top: unset;\n padding-top: 8px;\n padding-bottom: 8px;\n background: #fff;\n z-index: 999;\n}\n\n/*# sourceMappingURL=index.vue.map */","<template>\n <div class=\"g-table__wrapper\" :style=\"wrapperStyle\" :class=\"{ 'g-table--no-scroll-y': !needScrollY }\">\n <a-table\n :bordered=\"bordered\"\n :class=\"[isNoData && 'g-table__no-data']\"\n :pagination=\"false\"\n :loading=\"loading\"\n size=\"middle\"\n :columns=\"innerColumns\"\n :row-selection=\"rowSelection\"\n :row-class-name=\"setRowClassName\"\n :data-source=\"dataSource\"\n :scroll=\"getScroll\">\n <template slot=\"action\" slot-scope=\"record\">\n <Actions v-on=\"$listeners\" :data-source=\"actions\" :record=\"record\"></Actions>\n </template>\n </a-table>\n <div class=\"g-table__pagination\">\n <a-pagination\n :show-total=\"all => `共 ${all} 条数据`\"\n show-size-changer \n show-quick-jumper\n :pageSize=\"innerPageSize\"\n :current=\"innerCurrentPage\"\n :pageSizeOptions=\"pageSizeOptions\"\n @change=\"onChangePagination\"\n @showSizeChange=\"onShowSizeChange\"\n :total=\"total\">\n </a-pagination>\n </div>\n </div>\n</template>\n\n<script>\nimport Actions from './action.vue'\nexport default {\n name: 'ele-table',\n components: {\n Actions\n },\n props: {\n // ant table wrapper\n height: {\n type: Number\n },\n width: {\n type: Number\n },\n x: {\n type: Number,\n default: 1200\n },\n y: {\n type: Number,\n default: 200\n },\n scroll: {\n type: Object\n },\n rowSelection: {\n type: Object\n },\n actions: {\n type: Array,\n default: () => []\n },\n total: {\n type: Number,\n default: 0\n },\n loading: {\n type: Boolean,\n default: false\n },\n columns: {\n type: Array,\n default: () => []\n },\n dataSource: {\n type: Array,\n default: () => []\n },\n pageSize: {\n type: Number,\n default: 10\n },\n pageSizeOptions: {\n type: Array,\n default: () => ['10', '20', '30', '40']\n },\n bordered: {\n type: Boolean,\n default: true\n }\n },\n data() {\n return {\n tableHeaderHeight: 0,\n paginationHeight: 0,\n innerPageSize: 10,\n innerCurrentPage: 1,\n tableContentHeight: 0,\n obs: []\n }\n },\n computed: {\n wrapperStyle () {\n // 外层容器样式:确保分页始终可见,表格充满剩余空间\n if (!this.height) return {}\n return { height: `${this.height}px` }\n },\n needScrollY () {\n // 判断是否需要 y 轴滚动:基于数据行数与可用高度预估\n if (!this.height) return false\n \n const availableHeight = this.getScrollHeightByHeight\n if (availableHeight <= 0) return false\n \n // 预估每行高度(包含边框),antd 默认约 54px\n const estimatedRowHeight = 54\n const estimatedTableHeight = this.dataSource.length * estimatedRowHeight\n \n return estimatedTableHeight > availableHeight\n },\n innerColumns () {\n return this.columns.filter(col => !Object.keys(col).includes('multiple'))\n },\n isNoData () {\n return !this.dataSource.length\n },\n getScrollHeightByHeight () {\n // 始终返回可用的剩余高度,让表格内容不足时也能占满容器\n return this.height - this.tableHeaderHeight - this.paginationHeight\n },\n isFlexColumn () {\n return this.columns.every(col => !col.width)\n },\n getScroll () {\n if (this.scroll) {\n return this.scroll\n } else {\n const baseX = this.isFlexColumn ? 0 : (this.width > this.x ? 0 : this.x)\n if (this.height) {\n // 计算表体可用高度\n const availableHeight = this.tableHeaderHeight && this.paginationHeight \n ? this.getScrollHeightByHeight \n : this.height - 100 // 预估值,给表头和分页留空间\n \n if (availableHeight > 50) { // 确保有足够的最小高度\n console.log('Table scroll config:', { x: baseX, y: availableHeight, height: this.height, headerHeight: this.tableHeaderHeight, paginationHeight: this.paginationHeight })\n return { x: baseX, y: availableHeight }\n }\n }\n return { x: baseX }\n }\n }\n },\n watch: {\n pageSize: {\n handler (pageSize) {\n this.innerPageSize = pageSize\n },\n immediate: true\n }\n },\n methods: {\n onShowSizeChange (current, pageSize) {\n this.innerCurrentPage = current\n this.innerPageSize = pageSize\n this.$emit('change-page', current, pageSize)\n },\n setPaginationHeight () {\n this.$nextTick(() => {\n const { height } = document.querySelector('.g-table__pagination').getBoundingClientRect()\n this.paginationHeight = height\n })\n },\n setTableHeaderHeight () {\n this.$nextTick(() => {\n const el = document.querySelector('.ant-table-header')\n if (!el) return\n const { height } = el.getBoundingClientRect()\n this.tableHeaderHeight = height\n })\n },\n setTableTbodyHeight () {\n // 简化:仅需要获取表头高度,不再依赖表体高度的动态监听\n this.$nextTick(() => {\n this.setTableHeaderHeight()\n })\n },\n setRowClassName (record, idx) {\n return idx % 2 === 0 ? 'g-table__row--even' : 'g-table__row--odd'\n },\n onChangePagination (page, pageSize) {\n this.innerCurrentPage = page\n this.innerPageSize = pageSize\n this.$emit('change-page', page, pageSize)\n }\n },\n mounted() {\n this.$nextTick(() => {\n this.setPaginationHeight()\n setTimeout(() => {\n this.setTableTbodyHeight()\n // 再测一次分页高度,确保初次渲染完成后数值准确\n this.setPaginationHeight()\n }, 200)\n })\n },\n destroyed () {\n this.obs.forEach(ob => ob.disconnect())\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.g-table__wrapper {\n /* 外层采用列布局,确保分页始终可见,表格充满剩余空间 */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n\n /* 表格区域占满剩余空间,启用纵向滚动 */\n ::v-deep .ant-table-wrapper {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-spin-nested-loading {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-spin-container {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-table {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n /* 确保表体能够正常纵向滚动 */\n ::v-deep .ant-table-content {\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n }\n\n ::v-deep .ant-table-scroll {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-table-header {\n flex: 0 0 auto;\n overflow: hidden;\n }\n ::v-deep .ant-table-fixed {\n .ant-table-tbody {\n .g-table__row--odd {\n &.ant-table-row-hover {\n td {\n background-color: var(--idooel-row-hover-color);\n }\n .ant-table-selection-column {\n background-color: var(--idooel-row-hover-color) !important;\n }\n .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-hover-color) !important;\n }\n }\n td {\n background-color: var(--idooel-row-odd-color);\n }\n .ant-table-selection-column {\n background-color: var(--idooel-row-odd-color) !important;\n }\n .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-odd-color) !important;\n }\n }\n }\n .ant-table-thead {\n background: rgba(0, 0, 0, 0.03) !important;\n }\n }\n\n ::v-deep .ant-table-body {\n flex: 1 1 auto;\n overflow: auto !important;\n /* 确保滚动条稳定,避免列宽抖动 */\n scrollbar-gutter: stable;\n }\n\n /* 分页区域固定在底部,不被挤出视口 */\n .g-table__pagination {\n flex: 0 0 auto;\n display: flex;\n flex-direction: row;\n justify-content: end;\n border-top: unset;\n padding-top: 8px;\n padding-bottom: 8px;\n background: #fff;\n z-index: 999;\n }\n}\n</style>"]}, media: undefined });
2013
2014
 
2014
2015
  };
2015
2016
  /* scoped */
2016
- const __vue_scope_id__$C = "data-v-7943901f";
2017
+ const __vue_scope_id__$C = "data-v-3f1790f0";
2017
2018
  /* module identifier */
2018
2019
  const __vue_module_identifier__$C = undefined;
2019
2020
  /* functional template */
@@ -3637,6 +3638,7 @@ var script$y = {
3637
3638
  setFieldsValue: this.setFieldsValue,
3638
3639
  validateFields: this.validateFields,
3639
3640
  getFieldsValue: this.getFieldsValue,
3641
+ executeExpressions: this.executeExpressions,
3640
3642
  route: this.$route,
3641
3643
  [BUILT_IN_METHODS_NAMES.SUBMIT_FORM]: this.submitRequestTrigger
3642
3644
  };
@@ -3831,6 +3833,9 @@ var script$y = {
3831
3833
  getFieldsValue(fieldNames) {
3832
3834
  return this.$refs[this.formRef].getFieldsValue(fieldNames);
3833
3835
  },
3836
+ executeExpressions() {
3837
+ return this.$refs[this.formRef].evalShowExpression();
3838
+ },
3834
3839
  validateFields() {
3835
3840
  return this.$refs[this.formRef].validateFields();
3836
3841
  },
@@ -3928,11 +3933,11 @@ __vue_render__$y._withStripped = true;
3928
3933
  /* style */
3929
3934
  const __vue_inject_styles__$y = function (inject) {
3930
3935
  if (!inject) return
3931
- inject("data-v-f6310b92_0", { source: ".form__model--wrapper[data-v-f6310b92] {\n width: 100%;\n height: 100%;\n overflow: auto;\n background: #fff;\n}\n.form__model--wrapper .form-model__title[data-v-f6310b92] {\n height: 56px;\n padding: 0 16px;\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: 1px solid var(--idooel-form-title-border-color);\n}\n.form__model--wrapper .form-model__content[data-v-f6310b92] {\n padding: 16px;\n}\n.form__model--wrapper .form-model__footer[data-v-f6310b92] {\n /* width: 100%; */\n height: 64px;\n position: fixed;\n bottom: 0;\n display: flex;\n float: right;\n flex-direction: row;\n align-items: center;\n justify-content: end;\n}\n\n/*# sourceMappingURL=index.vue.map */", map: {"version":3,"sources":["/Users/huangshan/Goldgov/front/ganjiao/base-elearning-frontend-model/packages/components/packages/models/form-model/src/index.vue","index.vue"],"names":[],"mappings":"AA4MA;EACA,WAAA;EACA,YAAA;EACA,cAAA;EACA,gBAAA;AC3MA;AD4MA;EACA,YAAA;EACA,eAAA;EACA,aAAA;EACA,mBAAA;EACA,mBAAA;EACA,8DAAA;AC1MA;AD4MA;EACA,aAAA;AC1MA;AD4MA;EACA,iBAAA;EACA,YAAA;EACA,eAAA;EACA,SAAA;EACA,aAAA;EACA,YAAA;EACA,mBAAA;EACA,mBAAA;EACA,oBAAA;AC1MA;;AAEA,oCAAoC","file":"index.vue","sourcesContent":["<template>\n <div class=\"form__model--wrapper\">\n <div class=\"form-model__title\" v-if=\"title\">\n {{ title }}\n </div>\n <div class=\"form-model__content\">\n <ele-alert style=\"margin-bottom: 16px;\" v-if=\"alertMeta\" v-bind=\"alertMeta\"></ele-alert>\n <ele-form :ref=\"formRef\" @change=\"onChangeFormStatus($event)\" :elements=\"elements\" :disabled=\"globalDisabled\"></ele-form>\n </div>\n <div class=\"form-model__footer\" v-if=\"footerMeta\">\n <ele-button-group v-on=\"assignAttrForEvents\" :data-source=\"footerElements\"></ele-button-group>\n </div>\n </div>\n</template>\n\n<script>\nimport { BUILT_IN_EVENT_NAMES, parseFieldMap, RESERVE_EVENT_NAMES, PAGE_STATUS, CONTEXT, BUILT_IN_METHODS_NAMES } from '../../../utils'\nimport { v4 as uuidv4 } from 'uuid'\nimport { net, type } from '@idooel/shared'\nimport { parse } from '@idooel/expression'\nexport default {\n name: 'ele-form-model',\n props: {\n disabled: {\n type: [Boolean, String],\n default: '_routeMeta.disabled'\n },\n title: {\n type: String\n },\n formMeta: {\n type: Object\n },\n footerMeta: {\n type: Object\n }\n },\n data() {\n return {}\n },\n provide () {\n return {\n [CONTEXT]: () => {\n return {\n exposed: this.exposed\n }\n }\n }\n },\n computed: {\n globalDisabled () {\n return this.executeExpression(this.disabled)\n },\n formRef () {\n return uuidv4()\n },\n exposed () {\n return {\n setFieldsValue: this.setFieldsValue,\n validateFields: this.validateFields,\n getFieldsValue: this.getFieldsValue,\n route: this.$route,\n [BUILT_IN_METHODS_NAMES.SUBMIT_FORM]: this.submitRequestTrigger\n }\n },\n assignAttrForEvents () {\n const events = this.footerElements.reduce((ret, ele) => {\n ret[ele.eventName] = (e) => {\n this.$emit(ele.eventName || 'click', { ...e, formModel: this.formModels(), exposed: this.exposed })\n }\n return ret\n }, {})\n return {\n ...this.$listeners,\n ...events,\n [BUILT_IN_EVENT_NAMES.SUBMIT]: this[BUILT_IN_EVENT_NAMES.SUBMIT],\n [BUILT_IN_EVENT_NAMES.CANCEL]: this[BUILT_IN_EVENT_NAMES.CANCEL]\n }\n },\n elements () {\n const { elements } = this.formMeta\n return elements\n },\n preRequest () {\n const { preRequest = {} } = this.formMeta\n return preRequest\n },\n infoRequest () {\n const { infoRequest = {} } = this.formMeta\n return infoRequest\n },\n alertMeta () {\n const { alert = {} } = this.formMeta\n return type.isEmpty(alert) ? null : alert\n },\n submitRequest () {\n const { submitRequest = {} } = this.formMeta\n return submitRequest\n },\n footerElements () {\n const { elements } = this.footerMeta\n return elements.call(this)\n },\n expressionData () {\n return {\n _route: this.$route.query,\n _routeMeta: this.$route.meta\n }\n },\n routeMetaMode () {\n return this.$route.meta.mode\n }\n },\n methods: {\n collectDefaultValues () {\n const ret = this.elements.reduce((ret, props) => {\n const { name, defaultValue } = props\n if (defaultValue) {\n ret[name] = defaultValue\n }\n return ret\n }, {})\n return ret\n },\n onChangeFormStatus (props) {\n this.$emit(RESERVE_EVENT_NAMES.WATCH_FORM_STATUS, { ...props })\n },\n formModels (fieldNames) {\n return this.$refs[this.formRef] ? this.$refs[this.formRef].getFieldsValue(fieldNames) : {}\n },\n executeExpression (expression, dataSource = {}) {\n if (type.isBool(expression)) return expression\n if (type.isEmpty(expression)) return false\n return parse(expression, { ...this.expressionData, ...this.formModels(), ...dataSource })\n },\n execFieldMap (fieldMap = {}, dataSource = {}) {\n const ret = parseFieldMap(fieldMap, { ...this.expressionData, ...dataSource})\n return ret\n },\n async submitRequestTrigger (props = {}) {\n const { url, requestType, headers = {}, params = {}, fieldMap = {} } = this.submitRequest\n const currentUrl = this.executeExpressionForUrl(url)\n if (!currentUrl) return\n const ret = await net[requestType.toLowerCase()](currentUrl, { ...params, ...this.execFieldMap(fieldMap, { ...this.formModels() }), ...this.formModels() }, { headers }).then(resp => {\n this.$emit(BUILT_IN_EVENT_NAMES.SUBMIT, { ...props, formModel: { ...this.formModels(), ...resp.data || {} } })\n return resp.data\n })\n return ret\n },\n async infoRequestTrigger () {\n if (PAGE_STATUS.CREATE == this.routeMetaMode) return\n const { url, requestType, params = {}, fieldMap = {}, headers = {} } = this.infoRequest\n const currentUrl = this.executeExpressionForUrl(url)\n if (!currentUrl) return\n net[requestType.toLowerCase()](currentUrl, { ...params, ...this.execFieldMap(fieldMap) }, { ...headers }).then(resp => {\n const { data = {} } = resp\n this.setFieldsValue(data)\n this.$emit(RESERVE_EVENT_NAMES.INIT_FORM, { ...data })\n })\n },\n async preRequestTrigger () {\n const { url, requestType = 'GET', params = {}, fieldMap = {}, headers = {} } = this.preRequest\n const currentUrl = this.executeExpressionForUrl(url)\n if (!currentUrl) return\n const { data } = await net[requestType.toLowerCase()](currentUrl, { ...params, ...this.execFieldMap(fieldMap) }, { ...headers })\n this.setFieldsValue(data)\n this.$emit(RESERVE_EVENT_NAMES.INIT_FORM, { ...data })\n },\n executeExpressionForUrl (url) {\n return type.isApi(url) ? url : this.executeExpression(url)\n },\n setFieldsValue (props) {\n this.$refs[this.formRef].setFieldsValue(props)\n },\n getFieldsValue (fieldNames) {\n return this.$refs[this.formRef].getFieldsValue(fieldNames)\n },\n validateFields () {\n return this.$refs[this.formRef].validateFields()\n },\n [BUILT_IN_EVENT_NAMES.SUBMIT] (props = {}) {\n if (this.globalDisabled) return\n const status = this.$refs[this.formRef].validateFields()\n if (status) {\n //TODO fieldMap\n return this.submitRequestTrigger(props)\n } else {\n return false\n }\n },\n [BUILT_IN_EVENT_NAMES.CANCEL] (props = {}) {\n this.$emit(BUILT_IN_EVENT_NAMES.CANCEL, { ...props })\n }\n },\n async mounted() {\n this.setFieldsValue(this.collectDefaultValues())\n await this.preRequestTrigger()\n await this.infoRequestTrigger()\n this.$emit(RESERVE_EVENT_NAMES.INIT_FORM, { exposed: this.exposed })\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.form__model--wrapper {\n width: 100%;\n height: 100%;\n overflow: auto;\n background: #fff;\n .form-model__title {\n height: 56px;\n padding: 0 16px;\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: 1px solid var(--idooel-form-title-border-color);\n }\n .form-model__content {\n padding: 16px;\n }\n .form-model__footer {\n /* width: 100%; */\n height: 64px;\n position: fixed;\n bottom: 0;\n display: flex;\n float: right;\n flex-direction: row;\n align-items: center;\n justify-content: end;\n }\n}\n</style>",".form__model--wrapper {\n width: 100%;\n height: 100%;\n overflow: auto;\n background: #fff;\n}\n.form__model--wrapper .form-model__title {\n height: 56px;\n padding: 0 16px;\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: 1px solid var(--idooel-form-title-border-color);\n}\n.form__model--wrapper .form-model__content {\n padding: 16px;\n}\n.form__model--wrapper .form-model__footer {\n /* width: 100%; */\n height: 64px;\n position: fixed;\n bottom: 0;\n display: flex;\n float: right;\n flex-direction: row;\n align-items: center;\n justify-content: end;\n}\n\n/*# sourceMappingURL=index.vue.map */"]}, media: undefined });
3936
+ inject("data-v-c8ada56a_0", { source: ".form__model--wrapper[data-v-c8ada56a] {\n width: 100%;\n height: 100%;\n overflow: auto;\n background: #fff;\n}\n.form__model--wrapper .form-model__title[data-v-c8ada56a] {\n height: 56px;\n padding: 0 16px;\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: 1px solid var(--idooel-form-title-border-color);\n}\n.form__model--wrapper .form-model__content[data-v-c8ada56a] {\n padding: 16px;\n}\n.form__model--wrapper .form-model__footer[data-v-c8ada56a] {\n /* width: 100%; */\n height: 64px;\n position: fixed;\n bottom: 0;\n display: flex;\n float: right;\n flex-direction: row;\n align-items: center;\n justify-content: end;\n}\n\n/*# sourceMappingURL=index.vue.map */", map: {"version":3,"sources":["/Users/huangshan/Goldgov/front/ganjiao/base-elearning-frontend-model/packages/components/packages/models/form-model/src/index.vue","index.vue"],"names":[],"mappings":"AAgNA;EACA,WAAA;EACA,YAAA;EACA,cAAA;EACA,gBAAA;AC/MA;ADgNA;EACA,YAAA;EACA,eAAA;EACA,aAAA;EACA,mBAAA;EACA,mBAAA;EACA,8DAAA;AC9MA;ADgNA;EACA,aAAA;AC9MA;ADgNA;EACA,iBAAA;EACA,YAAA;EACA,eAAA;EACA,SAAA;EACA,aAAA;EACA,YAAA;EACA,mBAAA;EACA,mBAAA;EACA,oBAAA;AC9MA;;AAEA,oCAAoC","file":"index.vue","sourcesContent":["<template>\n <div class=\"form__model--wrapper\">\n <div class=\"form-model__title\" v-if=\"title\">\n {{ title }}\n </div>\n <div class=\"form-model__content\">\n <ele-alert style=\"margin-bottom: 16px;\" v-if=\"alertMeta\" v-bind=\"alertMeta\"></ele-alert>\n <ele-form :ref=\"formRef\" @change=\"onChangeFormStatus($event)\" :elements=\"elements\" :disabled=\"globalDisabled\"></ele-form>\n </div>\n <div class=\"form-model__footer\" v-if=\"footerMeta\">\n <ele-button-group v-on=\"assignAttrForEvents\" :data-source=\"footerElements\"></ele-button-group>\n </div>\n </div>\n</template>\n\n<script>\nimport { BUILT_IN_EVENT_NAMES, parseFieldMap, RESERVE_EVENT_NAMES, PAGE_STATUS, CONTEXT, BUILT_IN_METHODS_NAMES } from '../../../utils'\nimport { v4 as uuidv4 } from 'uuid'\nimport { net, type } from '@idooel/shared'\nimport { parse } from '@idooel/expression'\nexport default {\n name: 'ele-form-model',\n props: {\n disabled: {\n type: [Boolean, String],\n default: '_routeMeta.disabled'\n },\n title: {\n type: String\n },\n formMeta: {\n type: Object\n },\n footerMeta: {\n type: Object\n }\n },\n data() {\n return {}\n },\n provide () {\n return {\n [CONTEXT]: () => {\n return {\n exposed: this.exposed\n }\n }\n }\n },\n computed: {\n globalDisabled () {\n return this.executeExpression(this.disabled)\n },\n formRef () {\n return uuidv4()\n },\n exposed () {\n return {\n setFieldsValue: this.setFieldsValue,\n validateFields: this.validateFields,\n getFieldsValue: this.getFieldsValue,\n executeExpressions: this.executeExpressions,\n route: this.$route,\n [BUILT_IN_METHODS_NAMES.SUBMIT_FORM]: this.submitRequestTrigger\n }\n },\n assignAttrForEvents () {\n const events = this.footerElements.reduce((ret, ele) => {\n ret[ele.eventName] = (e) => {\n this.$emit(ele.eventName || 'click', { ...e, formModel: this.formModels(), exposed: this.exposed })\n }\n return ret\n }, {})\n return {\n ...this.$listeners,\n ...events,\n [BUILT_IN_EVENT_NAMES.SUBMIT]: this[BUILT_IN_EVENT_NAMES.SUBMIT],\n [BUILT_IN_EVENT_NAMES.CANCEL]: this[BUILT_IN_EVENT_NAMES.CANCEL]\n }\n },\n elements () {\n const { elements } = this.formMeta\n return elements\n },\n preRequest () {\n const { preRequest = {} } = this.formMeta\n return preRequest\n },\n infoRequest () {\n const { infoRequest = {} } = this.formMeta\n return infoRequest\n },\n alertMeta () {\n const { alert = {} } = this.formMeta\n return type.isEmpty(alert) ? null : alert\n },\n submitRequest () {\n const { submitRequest = {} } = this.formMeta\n return submitRequest\n },\n footerElements () {\n const { elements } = this.footerMeta\n return elements.call(this)\n },\n expressionData () {\n return {\n _route: this.$route.query,\n _routeMeta: this.$route.meta\n }\n },\n routeMetaMode () {\n return this.$route.meta.mode\n }\n },\n methods: {\n collectDefaultValues () {\n const ret = this.elements.reduce((ret, props) => {\n const { name, defaultValue } = props\n if (defaultValue) {\n ret[name] = defaultValue\n }\n return ret\n }, {})\n return ret\n },\n onChangeFormStatus (props) {\n this.$emit(RESERVE_EVENT_NAMES.WATCH_FORM_STATUS, { ...props })\n },\n formModels (fieldNames) {\n return this.$refs[this.formRef] ? this.$refs[this.formRef].getFieldsValue(fieldNames) : {}\n },\n executeExpression (expression, dataSource = {}) {\n if (type.isBool(expression)) return expression\n if (type.isEmpty(expression)) return false\n return parse(expression, { ...this.expressionData, ...this.formModels(), ...dataSource })\n },\n execFieldMap (fieldMap = {}, dataSource = {}) {\n const ret = parseFieldMap(fieldMap, { ...this.expressionData, ...dataSource})\n return ret\n },\n async submitRequestTrigger (props = {}) {\n const { url, requestType, headers = {}, params = {}, fieldMap = {} } = this.submitRequest\n const currentUrl = this.executeExpressionForUrl(url)\n if (!currentUrl) return\n const ret = await net[requestType.toLowerCase()](currentUrl, { ...params, ...this.execFieldMap(fieldMap, { ...this.formModels() }), ...this.formModels() }, { headers }).then(resp => {\n this.$emit(BUILT_IN_EVENT_NAMES.SUBMIT, { ...props, formModel: { ...this.formModels(), ...resp.data || {} } })\n return resp.data\n })\n return ret\n },\n async infoRequestTrigger () {\n if (PAGE_STATUS.CREATE == this.routeMetaMode) return\n const { url, requestType, params = {}, fieldMap = {}, headers = {} } = this.infoRequest\n const currentUrl = this.executeExpressionForUrl(url)\n if (!currentUrl) return\n net[requestType.toLowerCase()](currentUrl, { ...params, ...this.execFieldMap(fieldMap) }, { ...headers }).then(resp => {\n const { data = {} } = resp\n this.setFieldsValue(data)\n this.$emit(RESERVE_EVENT_NAMES.INIT_FORM, { ...data })\n })\n },\n async preRequestTrigger () {\n const { url, requestType = 'GET', params = {}, fieldMap = {}, headers = {} } = this.preRequest\n const currentUrl = this.executeExpressionForUrl(url)\n if (!currentUrl) return\n const { data } = await net[requestType.toLowerCase()](currentUrl, { ...params, ...this.execFieldMap(fieldMap) }, { ...headers })\n this.setFieldsValue(data)\n this.$emit(RESERVE_EVENT_NAMES.INIT_FORM, { ...data })\n },\n executeExpressionForUrl (url) {\n return type.isApi(url) ? url : this.executeExpression(url)\n },\n setFieldsValue (props) {\n this.$refs[this.formRef].setFieldsValue(props)\n },\n getFieldsValue (fieldNames) {\n return this.$refs[this.formRef].getFieldsValue(fieldNames)\n },\n executeExpressions () {\n return this.$refs[this.formRef].evalShowExpression()\n },\n validateFields () {\n return this.$refs[this.formRef].validateFields()\n },\n [BUILT_IN_EVENT_NAMES.SUBMIT] (props = {}) {\n if (this.globalDisabled) return\n const status = this.$refs[this.formRef].validateFields()\n if (status) {\n //TODO fieldMap\n return this.submitRequestTrigger(props)\n } else {\n return false\n }\n },\n [BUILT_IN_EVENT_NAMES.CANCEL] (props = {}) {\n this.$emit(BUILT_IN_EVENT_NAMES.CANCEL, { ...props })\n }\n },\n async mounted() {\n this.setFieldsValue(this.collectDefaultValues())\n await this.preRequestTrigger()\n await this.infoRequestTrigger()\n this.$emit(RESERVE_EVENT_NAMES.INIT_FORM, { exposed: this.exposed })\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.form__model--wrapper {\n width: 100%;\n height: 100%;\n overflow: auto;\n background: #fff;\n .form-model__title {\n height: 56px;\n padding: 0 16px;\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: 1px solid var(--idooel-form-title-border-color);\n }\n .form-model__content {\n padding: 16px;\n }\n .form-model__footer {\n /* width: 100%; */\n height: 64px;\n position: fixed;\n bottom: 0;\n display: flex;\n float: right;\n flex-direction: row;\n align-items: center;\n justify-content: end;\n }\n}\n</style>",".form__model--wrapper {\n width: 100%;\n height: 100%;\n overflow: auto;\n background: #fff;\n}\n.form__model--wrapper .form-model__title {\n height: 56px;\n padding: 0 16px;\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: 1px solid var(--idooel-form-title-border-color);\n}\n.form__model--wrapper .form-model__content {\n padding: 16px;\n}\n.form__model--wrapper .form-model__footer {\n /* width: 100%; */\n height: 64px;\n position: fixed;\n bottom: 0;\n display: flex;\n float: right;\n flex-direction: row;\n align-items: center;\n justify-content: end;\n}\n\n/*# sourceMappingURL=index.vue.map */"]}, media: undefined });
3932
3937
 
3933
3938
  };
3934
3939
  /* scoped */
3935
- const __vue_scope_id__$y = "data-v-f6310b92";
3940
+ const __vue_scope_id__$y = "data-v-c8ada56a";
3936
3941
  /* module identifier */
3937
3942
  const __vue_module_identifier__$y = undefined;
3938
3943
  /* functional template */
@@ -1958,6 +1958,7 @@
1958
1958
  bordered: _vm.bordered,
1959
1959
  pagination: false,
1960
1960
  loading: _vm.loading,
1961
+ size: "middle",
1961
1962
  columns: _vm.innerColumns,
1962
1963
  "row-selection": _vm.rowSelection,
1963
1964
  "row-class-name": _vm.setRowClassName,
@@ -2016,11 +2017,11 @@
2016
2017
  /* style */
2017
2018
  const __vue_inject_styles__$C = function (inject) {
2018
2019
  if (!inject) return
2019
- inject("data-v-7943901f_0", { source: "@charset \"UTF-8\";\n.g-table__wrapper[data-v-7943901f] {\n /* 外层采用列布局,确保分页始终可见,表格充满剩余空间 */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n /* 表格区域占满剩余空间,启用纵向滚动 */\n /* 确保表体能够正常纵向滚动 */\n /* 分页区域固定在底部,不被挤出视口 */\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-wrapper {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-7943901f] .ant-spin-nested-loading {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-7943901f] .ant-spin-container {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-content {\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-scroll {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-header {\n flex: 0 0 auto;\n overflow: hidden;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-selection-column {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-selection-column {\n background-color: var(--idooel-row-odd-color);\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-odd-color);\n}\n.g-table__wrapper[data-v-7943901f] .ant-table-body {\n flex: 1 1 auto;\n overflow: auto !important;\n /* 确保滚动条稳定,避免列宽抖动 */\n scrollbar-gutter: stable;\n}\n.g-table__wrapper .g-table__pagination[data-v-7943901f] {\n flex: 0 0 auto;\n display: flex;\n flex-direction: row;\n justify-content: end;\n border-top: unset;\n padding-top: 8px;\n padding-bottom: 8px;\n background: #fff;\n z-index: 999;\n}\n\n/*# sourceMappingURL=index.vue.map */", map: {"version":3,"sources":["index.vue","/Users/huangshan/Goldgov/front/ganjiao/base-elearning-frontend-model/packages/components/packages/table/src/index.vue"],"names":[],"mappings":"AAAA,gBAAgB;ACwNhB;EACA,8BAAA;EACA,aAAA;EACA,sBAAA;EACA,gBAAA;EAEA,sBAAA;EA6BA,iBAAA;EA6CA,qBAAA;AD/RA;ACsNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADpNA;ACuNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADrNA;ACwNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADtNA;ACyNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADvNA;AC2NA;EACA,cAAA;EACA,aAAA;EACA,gBAAA;ADzNA;AC4NA;EACA,YAAA;EACA,aAAA;EACA,sBAAA;AD1NA;AC6NA;EACA,cAAA;EACA,gBAAA;AD3NA;ACiOA;EACA,0DAAA;AD/NA;ACiOA;EACA,0DAAA;AD/NA;ACkOA;EACA,6CAAA;ADhOA;ACkOA;EACA,6CAAA;ADhOA;ACsOA;EACA,cAAA;EACA,yBAAA;EACA,mBAAA;EACA,wBAAA;ADpOA;ACwOA;EACA,cAAA;EACA,aAAA;EACA,mBAAA;EACA,oBAAA;EACA,iBAAA;EACA,gBAAA;EACA,mBAAA;EACA,gBAAA;EACA,YAAA;ADtOA;;AAEA,oCAAoC","file":"index.vue","sourcesContent":["@charset \"UTF-8\";\n.g-table__wrapper {\n /* 外层采用列布局,确保分页始终可见,表格充满剩余空间 */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n /* 表格区域占满剩余空间,启用纵向滚动 */\n /* 确保表体能够正常纵向滚动 */\n /* 分页区域固定在底部,不被挤出视口 */\n}\n.g-table__wrapper ::v-deep .ant-table-wrapper {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-spin-nested-loading {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-spin-container {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-table {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-table-content {\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n}\n.g-table__wrapper ::v-deep .ant-table-scroll {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-table-header {\n flex: 0 0 auto;\n overflow: hidden;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-selection-column {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-selection-column {\n background-color: var(--idooel-row-odd-color);\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-odd-color);\n}\n.g-table__wrapper ::v-deep .ant-table-body {\n flex: 1 1 auto;\n overflow: auto !important;\n /* 确保滚动条稳定,避免列宽抖动 */\n scrollbar-gutter: stable;\n}\n.g-table__wrapper .g-table__pagination {\n flex: 0 0 auto;\n display: flex;\n flex-direction: row;\n justify-content: end;\n border-top: unset;\n padding-top: 8px;\n padding-bottom: 8px;\n background: #fff;\n z-index: 999;\n}\n\n/*# sourceMappingURL=index.vue.map */","<template>\n <div class=\"g-table__wrapper\" :style=\"wrapperStyle\" :class=\"{ 'g-table--no-scroll-y': !needScrollY }\">\n <a-table\n :bordered=\"bordered\"\n :class=\"[isNoData && 'g-table__no-data']\"\n :pagination=\"false\"\n :loading=\"loading\"\n :columns=\"innerColumns\"\n :row-selection=\"rowSelection\"\n :row-class-name=\"setRowClassName\"\n :data-source=\"dataSource\"\n :scroll=\"getScroll\">\n <template slot=\"action\" slot-scope=\"record\">\n <Actions v-on=\"$listeners\" :data-source=\"actions\" :record=\"record\"></Actions>\n </template>\n </a-table>\n <div class=\"g-table__pagination\">\n <a-pagination\n :show-total=\"all => `共 ${all} 条数据`\"\n show-size-changer \n show-quick-jumper\n :pageSize=\"innerPageSize\"\n :current=\"innerCurrentPage\"\n :pageSizeOptions=\"pageSizeOptions\"\n @change=\"onChangePagination\"\n @showSizeChange=\"onShowSizeChange\"\n :total=\"total\">\n </a-pagination>\n </div>\n </div>\n</template>\n\n<script>\nimport Actions from './action.vue'\nexport default {\n name: 'ele-table',\n components: {\n Actions\n },\n props: {\n // ant table wrapper\n height: {\n type: Number\n },\n width: {\n type: Number\n },\n x: {\n type: Number,\n default: 1200\n },\n y: {\n type: Number,\n default: 200\n },\n scroll: {\n type: Object\n },\n rowSelection: {\n type: Object\n },\n actions: {\n type: Array,\n default: () => []\n },\n total: {\n type: Number,\n default: 0\n },\n loading: {\n type: Boolean,\n default: false\n },\n columns: {\n type: Array,\n default: () => []\n },\n dataSource: {\n type: Array,\n default: () => []\n },\n pageSize: {\n type: Number,\n default: 10\n },\n pageSizeOptions: {\n type: Array,\n default: () => ['10', '20', '30', '40']\n },\n bordered: {\n type: Boolean,\n default: true\n }\n },\n data() {\n return {\n tableHeaderHeight: 0,\n paginationHeight: 0,\n innerPageSize: 10,\n innerCurrentPage: 1,\n tableContentHeight: 0,\n obs: []\n }\n },\n computed: {\n wrapperStyle () {\n // 外层容器样式:确保分页始终可见,表格充满剩余空间\n if (!this.height) return {}\n return { height: `${this.height}px` }\n },\n needScrollY () {\n // 判断是否需要 y 轴滚动:基于数据行数与可用高度预估\n if (!this.height) return false\n \n const availableHeight = this.getScrollHeightByHeight\n if (availableHeight <= 0) return false\n \n // 预估每行高度(包含边框),antd 默认约 54px\n const estimatedRowHeight = 54\n const estimatedTableHeight = this.dataSource.length * estimatedRowHeight\n \n return estimatedTableHeight > availableHeight\n },\n innerColumns () {\n return this.columns.filter(col => !Object.keys(col).includes('multiple'))\n },\n isNoData () {\n return !this.dataSource.length\n },\n getScrollHeightByHeight () {\n // 始终返回可用的剩余高度,让表格内容不足时也能占满容器\n return this.height - this.tableHeaderHeight - this.paginationHeight\n },\n isFlexColumn () {\n return this.columns.every(col => !col.width)\n },\n getScroll () {\n if (this.scroll) {\n return this.scroll\n } else {\n const baseX = this.isFlexColumn ? 0 : (this.width > this.x ? 0 : this.x)\n if (this.height) {\n // 计算表体可用高度\n const availableHeight = this.tableHeaderHeight && this.paginationHeight \n ? this.getScrollHeightByHeight \n : this.height - 100 // 预估值,给表头和分页留空间\n \n if (availableHeight > 50) { // 确保有足够的最小高度\n console.log('Table scroll config:', { x: baseX, y: availableHeight, height: this.height, headerHeight: this.tableHeaderHeight, paginationHeight: this.paginationHeight })\n return { x: baseX, y: availableHeight }\n }\n }\n return { x: baseX }\n }\n }\n },\n watch: {\n pageSize: {\n handler (pageSize) {\n this.innerPageSize = pageSize\n },\n immediate: true\n }\n },\n methods: {\n onShowSizeChange (current, pageSize) {\n this.innerCurrentPage = current\n this.innerPageSize = pageSize\n this.$emit('change-page', current, pageSize)\n },\n setPaginationHeight () {\n this.$nextTick(() => {\n const { height } = document.querySelector('.g-table__pagination').getBoundingClientRect()\n this.paginationHeight = height\n })\n },\n setTableHeaderHeight () {\n this.$nextTick(() => {\n const el = document.querySelector('.ant-table-header')\n if (!el) return\n const { height } = el.getBoundingClientRect()\n this.tableHeaderHeight = height\n })\n },\n setTableTbodyHeight () {\n // 简化:仅需要获取表头高度,不再依赖表体高度的动态监听\n this.$nextTick(() => {\n this.setTableHeaderHeight()\n })\n },\n setRowClassName (record, idx) {\n return idx % 2 === 0 ? 'g-table__row--even' : 'g-table__row--odd'\n },\n onChangePagination (page, pageSize) {\n this.innerCurrentPage = page\n this.innerPageSize = pageSize\n this.$emit('change-page', page, pageSize)\n }\n },\n mounted() {\n this.$nextTick(() => {\n this.setPaginationHeight()\n setTimeout(() => {\n this.setTableTbodyHeight()\n // 再测一次分页高度,确保初次渲染完成后数值准确\n this.setPaginationHeight()\n }, 200)\n })\n },\n destroyed () {\n this.obs.forEach(ob => ob.disconnect())\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.g-table__wrapper {\n /* 外层采用列布局,确保分页始终可见,表格充满剩余空间 */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n\n /* 表格区域占满剩余空间,启用纵向滚动 */\n ::v-deep .ant-table-wrapper {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-spin-nested-loading {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-spin-container {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-table {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n /* 确保表体能够正常纵向滚动 */\n ::v-deep .ant-table-content {\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n }\n\n ::v-deep .ant-table-scroll {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-table-header {\n flex: 0 0 auto;\n overflow: hidden;\n }\n ::v-deep .ant-table-fixed {\n .ant-table-tbody {\n .g-table__row--odd {\n &.ant-table-row-hover {\n .ant-table-selection-column {\n background-color: var(--idooel-row-hover-color) !important;\n }\n .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-hover-color) !important;\n }\n }\n .ant-table-selection-column {\n background-color: var(--idooel-row-odd-color);\n }\n .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-odd-color);\n }\n }\n }\n }\n\n ::v-deep .ant-table-body {\n flex: 1 1 auto;\n overflow: auto !important;\n /* 确保滚动条稳定,避免列宽抖动 */\n scrollbar-gutter: stable;\n }\n\n /* 分页区域固定在底部,不被挤出视口 */\n .g-table__pagination {\n flex: 0 0 auto;\n display: flex;\n flex-direction: row;\n justify-content: end;\n border-top: unset;\n padding-top: 8px;\n padding-bottom: 8px;\n background: #fff;\n z-index: 999;\n }\n}\n</style>"]}, media: undefined });
2020
+ inject("data-v-3f1790f0_0", { source: "@charset \"UTF-8\";\n.g-table__wrapper[data-v-3f1790f0] {\n /* 外层采用列布局,确保分页始终可见,表格充满剩余空间 */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n /* 表格区域占满剩余空间,启用纵向滚动 */\n /* 确保表体能够正常纵向滚动 */\n /* 分页区域固定在底部,不被挤出视口 */\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-wrapper {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-spin-nested-loading {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-spin-container {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-content {\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-scroll {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-header {\n flex: 0 0 auto;\n overflow: hidden;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover td {\n background-color: var(--idooel-row-hover-color);\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-selection-column {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-tbody .g-table__row--odd td {\n background-color: var(--idooel-row-odd-color);\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-selection-column {\n background-color: var(--idooel-row-odd-color) !important;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-odd-color) !important;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-fixed .ant-table-thead {\n background: rgba(0, 0, 0, 0.03) !important;\n}\n.g-table__wrapper[data-v-3f1790f0] .ant-table-body {\n flex: 1 1 auto;\n overflow: auto !important;\n /* 确保滚动条稳定,避免列宽抖动 */\n scrollbar-gutter: stable;\n}\n.g-table__wrapper .g-table__pagination[data-v-3f1790f0] {\n flex: 0 0 auto;\n display: flex;\n flex-direction: row;\n justify-content: end;\n border-top: unset;\n padding-top: 8px;\n padding-bottom: 8px;\n background: #fff;\n z-index: 999;\n}\n\n/*# sourceMappingURL=index.vue.map */", map: {"version":3,"sources":["index.vue","/Users/huangshan/Goldgov/front/ganjiao/base-elearning-frontend-model/packages/components/packages/table/src/index.vue"],"names":[],"mappings":"AAAA,gBAAgB;ACyNhB;EACA,8BAAA;EACA,aAAA;EACA,sBAAA;EACA,gBAAA;EAEA,sBAAA;EA6BA,iBAAA;EAsDA,qBAAA;ADzSA;ACuNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADrNA;ACwNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADtNA;ACyNA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADvNA;AC0NA;EACA,cAAA;EACA,aAAA;EACA,aAAA;EACA,sBAAA;ADxNA;AC4NA;EACA,cAAA;EACA,aAAA;EACA,gBAAA;AD1NA;AC6NA;EACA,YAAA;EACA,aAAA;EACA,sBAAA;AD3NA;AC8NA;EACA,cAAA;EACA,gBAAA;AD5NA;ACkOA;EACA,+CAAA;ADhOA;ACkOA;EACA,0DAAA;ADhOA;ACkOA;EACA,0DAAA;ADhOA;ACmOA;EACA,6CAAA;ADjOA;ACmOA;EACA,wDAAA;ADjOA;ACmOA;EACA,wDAAA;ADjOA;ACqOA;EACA,0CAAA;ADnOA;ACuOA;EACA,cAAA;EACA,yBAAA;EACA,mBAAA;EACA,wBAAA;ADrOA;ACyOA;EACA,cAAA;EACA,aAAA;EACA,mBAAA;EACA,oBAAA;EACA,iBAAA;EACA,gBAAA;EACA,mBAAA;EACA,gBAAA;EACA,YAAA;ADvOA;;AAEA,oCAAoC","file":"index.vue","sourcesContent":["@charset \"UTF-8\";\n.g-table__wrapper {\n /* 外层采用列布局,确保分页始终可见,表格充满剩余空间 */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n /* 表格区域占满剩余空间,启用纵向滚动 */\n /* 确保表体能够正常纵向滚动 */\n /* 分页区域固定在底部,不被挤出视口 */\n}\n.g-table__wrapper ::v-deep .ant-table-wrapper {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-spin-nested-loading {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-spin-container {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-table {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-table-content {\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n}\n.g-table__wrapper ::v-deep .ant-table-scroll {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n.g-table__wrapper ::v-deep .ant-table-header {\n flex: 0 0 auto;\n overflow: hidden;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover td {\n background-color: var(--idooel-row-hover-color);\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-selection-column {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd.ant-table-row-hover .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-hover-color) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd td {\n background-color: var(--idooel-row-odd-color);\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-selection-column {\n background-color: var(--idooel-row-odd-color) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-tbody .g-table__row--odd .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-odd-color) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-fixed .ant-table-thead {\n background: rgba(0, 0, 0, 0.03) !important;\n}\n.g-table__wrapper ::v-deep .ant-table-body {\n flex: 1 1 auto;\n overflow: auto !important;\n /* 确保滚动条稳定,避免列宽抖动 */\n scrollbar-gutter: stable;\n}\n.g-table__wrapper .g-table__pagination {\n flex: 0 0 auto;\n display: flex;\n flex-direction: row;\n justify-content: end;\n border-top: unset;\n padding-top: 8px;\n padding-bottom: 8px;\n background: #fff;\n z-index: 999;\n}\n\n/*# sourceMappingURL=index.vue.map */","<template>\n <div class=\"g-table__wrapper\" :style=\"wrapperStyle\" :class=\"{ 'g-table--no-scroll-y': !needScrollY }\">\n <a-table\n :bordered=\"bordered\"\n :class=\"[isNoData && 'g-table__no-data']\"\n :pagination=\"false\"\n :loading=\"loading\"\n size=\"middle\"\n :columns=\"innerColumns\"\n :row-selection=\"rowSelection\"\n :row-class-name=\"setRowClassName\"\n :data-source=\"dataSource\"\n :scroll=\"getScroll\">\n <template slot=\"action\" slot-scope=\"record\">\n <Actions v-on=\"$listeners\" :data-source=\"actions\" :record=\"record\"></Actions>\n </template>\n </a-table>\n <div class=\"g-table__pagination\">\n <a-pagination\n :show-total=\"all => `共 ${all} 条数据`\"\n show-size-changer \n show-quick-jumper\n :pageSize=\"innerPageSize\"\n :current=\"innerCurrentPage\"\n :pageSizeOptions=\"pageSizeOptions\"\n @change=\"onChangePagination\"\n @showSizeChange=\"onShowSizeChange\"\n :total=\"total\">\n </a-pagination>\n </div>\n </div>\n</template>\n\n<script>\nimport Actions from './action.vue'\nexport default {\n name: 'ele-table',\n components: {\n Actions\n },\n props: {\n // ant table wrapper\n height: {\n type: Number\n },\n width: {\n type: Number\n },\n x: {\n type: Number,\n default: 1200\n },\n y: {\n type: Number,\n default: 200\n },\n scroll: {\n type: Object\n },\n rowSelection: {\n type: Object\n },\n actions: {\n type: Array,\n default: () => []\n },\n total: {\n type: Number,\n default: 0\n },\n loading: {\n type: Boolean,\n default: false\n },\n columns: {\n type: Array,\n default: () => []\n },\n dataSource: {\n type: Array,\n default: () => []\n },\n pageSize: {\n type: Number,\n default: 10\n },\n pageSizeOptions: {\n type: Array,\n default: () => ['10', '20', '30', '40']\n },\n bordered: {\n type: Boolean,\n default: true\n }\n },\n data() {\n return {\n tableHeaderHeight: 0,\n paginationHeight: 0,\n innerPageSize: 10,\n innerCurrentPage: 1,\n tableContentHeight: 0,\n obs: []\n }\n },\n computed: {\n wrapperStyle () {\n // 外层容器样式:确保分页始终可见,表格充满剩余空间\n if (!this.height) return {}\n return { height: `${this.height}px` }\n },\n needScrollY () {\n // 判断是否需要 y 轴滚动:基于数据行数与可用高度预估\n if (!this.height) return false\n \n const availableHeight = this.getScrollHeightByHeight\n if (availableHeight <= 0) return false\n \n // 预估每行高度(包含边框),antd 默认约 54px\n const estimatedRowHeight = 54\n const estimatedTableHeight = this.dataSource.length * estimatedRowHeight\n \n return estimatedTableHeight > availableHeight\n },\n innerColumns () {\n return this.columns.filter(col => !Object.keys(col).includes('multiple'))\n },\n isNoData () {\n return !this.dataSource.length\n },\n getScrollHeightByHeight () {\n // 始终返回可用的剩余高度,让表格内容不足时也能占满容器\n return this.height - this.tableHeaderHeight - this.paginationHeight\n },\n isFlexColumn () {\n return this.columns.every(col => !col.width)\n },\n getScroll () {\n if (this.scroll) {\n return this.scroll\n } else {\n const baseX = this.isFlexColumn ? 0 : (this.width > this.x ? 0 : this.x)\n if (this.height) {\n // 计算表体可用高度\n const availableHeight = this.tableHeaderHeight && this.paginationHeight \n ? this.getScrollHeightByHeight \n : this.height - 100 // 预估值,给表头和分页留空间\n \n if (availableHeight > 50) { // 确保有足够的最小高度\n console.log('Table scroll config:', { x: baseX, y: availableHeight, height: this.height, headerHeight: this.tableHeaderHeight, paginationHeight: this.paginationHeight })\n return { x: baseX, y: availableHeight }\n }\n }\n return { x: baseX }\n }\n }\n },\n watch: {\n pageSize: {\n handler (pageSize) {\n this.innerPageSize = pageSize\n },\n immediate: true\n }\n },\n methods: {\n onShowSizeChange (current, pageSize) {\n this.innerCurrentPage = current\n this.innerPageSize = pageSize\n this.$emit('change-page', current, pageSize)\n },\n setPaginationHeight () {\n this.$nextTick(() => {\n const { height } = document.querySelector('.g-table__pagination').getBoundingClientRect()\n this.paginationHeight = height\n })\n },\n setTableHeaderHeight () {\n this.$nextTick(() => {\n const el = document.querySelector('.ant-table-header')\n if (!el) return\n const { height } = el.getBoundingClientRect()\n this.tableHeaderHeight = height\n })\n },\n setTableTbodyHeight () {\n // 简化:仅需要获取表头高度,不再依赖表体高度的动态监听\n this.$nextTick(() => {\n this.setTableHeaderHeight()\n })\n },\n setRowClassName (record, idx) {\n return idx % 2 === 0 ? 'g-table__row--even' : 'g-table__row--odd'\n },\n onChangePagination (page, pageSize) {\n this.innerCurrentPage = page\n this.innerPageSize = pageSize\n this.$emit('change-page', page, pageSize)\n }\n },\n mounted() {\n this.$nextTick(() => {\n this.setPaginationHeight()\n setTimeout(() => {\n this.setTableTbodyHeight()\n // 再测一次分页高度,确保初次渲染完成后数值准确\n this.setPaginationHeight()\n }, 200)\n })\n },\n destroyed () {\n this.obs.forEach(ob => ob.disconnect())\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.g-table__wrapper {\n /* 外层采用列布局,确保分页始终可见,表格充满剩余空间 */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n\n /* 表格区域占满剩余空间,启用纵向滚动 */\n ::v-deep .ant-table-wrapper {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-spin-nested-loading {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-spin-container {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-table {\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n /* 确保表体能够正常纵向滚动 */\n ::v-deep .ant-table-content {\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n }\n\n ::v-deep .ant-table-scroll {\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n\n ::v-deep .ant-table-header {\n flex: 0 0 auto;\n overflow: hidden;\n }\n ::v-deep .ant-table-fixed {\n .ant-table-tbody {\n .g-table__row--odd {\n &.ant-table-row-hover {\n td {\n background-color: var(--idooel-row-hover-color);\n }\n .ant-table-selection-column {\n background-color: var(--idooel-row-hover-color) !important;\n }\n .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-hover-color) !important;\n }\n }\n td {\n background-color: var(--idooel-row-odd-color);\n }\n .ant-table-selection-column {\n background-color: var(--idooel-row-odd-color) !important;\n }\n .ant-table-row-cell-break-word {\n background-color: var(--idooel-row-odd-color) !important;\n }\n }\n }\n .ant-table-thead {\n background: rgba(0, 0, 0, 0.03) !important;\n }\n }\n\n ::v-deep .ant-table-body {\n flex: 1 1 auto;\n overflow: auto !important;\n /* 确保滚动条稳定,避免列宽抖动 */\n scrollbar-gutter: stable;\n }\n\n /* 分页区域固定在底部,不被挤出视口 */\n .g-table__pagination {\n flex: 0 0 auto;\n display: flex;\n flex-direction: row;\n justify-content: end;\n border-top: unset;\n padding-top: 8px;\n padding-bottom: 8px;\n background: #fff;\n z-index: 999;\n }\n}\n</style>"]}, media: undefined });
2020
2021
 
2021
2022
  };
2022
2023
  /* scoped */
2023
- const __vue_scope_id__$C = "data-v-7943901f";
2024
+ const __vue_scope_id__$C = "data-v-3f1790f0";
2024
2025
  /* module identifier */
2025
2026
  const __vue_module_identifier__$C = undefined;
2026
2027
  /* functional template */
@@ -3644,6 +3645,7 @@
3644
3645
  setFieldsValue: this.setFieldsValue,
3645
3646
  validateFields: this.validateFields,
3646
3647
  getFieldsValue: this.getFieldsValue,
3648
+ executeExpressions: this.executeExpressions,
3647
3649
  route: this.$route,
3648
3650
  [BUILT_IN_METHODS_NAMES.SUBMIT_FORM]: this.submitRequestTrigger
3649
3651
  };
@@ -3838,6 +3840,9 @@
3838
3840
  getFieldsValue(fieldNames) {
3839
3841
  return this.$refs[this.formRef].getFieldsValue(fieldNames);
3840
3842
  },
3843
+ executeExpressions() {
3844
+ return this.$refs[this.formRef].evalShowExpression();
3845
+ },
3841
3846
  validateFields() {
3842
3847
  return this.$refs[this.formRef].validateFields();
3843
3848
  },
@@ -3935,11 +3940,11 @@
3935
3940
  /* style */
3936
3941
  const __vue_inject_styles__$y = function (inject) {
3937
3942
  if (!inject) return
3938
- inject("data-v-f6310b92_0", { source: ".form__model--wrapper[data-v-f6310b92] {\n width: 100%;\n height: 100%;\n overflow: auto;\n background: #fff;\n}\n.form__model--wrapper .form-model__title[data-v-f6310b92] {\n height: 56px;\n padding: 0 16px;\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: 1px solid var(--idooel-form-title-border-color);\n}\n.form__model--wrapper .form-model__content[data-v-f6310b92] {\n padding: 16px;\n}\n.form__model--wrapper .form-model__footer[data-v-f6310b92] {\n /* width: 100%; */\n height: 64px;\n position: fixed;\n bottom: 0;\n display: flex;\n float: right;\n flex-direction: row;\n align-items: center;\n justify-content: end;\n}\n\n/*# sourceMappingURL=index.vue.map */", map: {"version":3,"sources":["/Users/huangshan/Goldgov/front/ganjiao/base-elearning-frontend-model/packages/components/packages/models/form-model/src/index.vue","index.vue"],"names":[],"mappings":"AA4MA;EACA,WAAA;EACA,YAAA;EACA,cAAA;EACA,gBAAA;AC3MA;AD4MA;EACA,YAAA;EACA,eAAA;EACA,aAAA;EACA,mBAAA;EACA,mBAAA;EACA,8DAAA;AC1MA;AD4MA;EACA,aAAA;AC1MA;AD4MA;EACA,iBAAA;EACA,YAAA;EACA,eAAA;EACA,SAAA;EACA,aAAA;EACA,YAAA;EACA,mBAAA;EACA,mBAAA;EACA,oBAAA;AC1MA;;AAEA,oCAAoC","file":"index.vue","sourcesContent":["<template>\n <div class=\"form__model--wrapper\">\n <div class=\"form-model__title\" v-if=\"title\">\n {{ title }}\n </div>\n <div class=\"form-model__content\">\n <ele-alert style=\"margin-bottom: 16px;\" v-if=\"alertMeta\" v-bind=\"alertMeta\"></ele-alert>\n <ele-form :ref=\"formRef\" @change=\"onChangeFormStatus($event)\" :elements=\"elements\" :disabled=\"globalDisabled\"></ele-form>\n </div>\n <div class=\"form-model__footer\" v-if=\"footerMeta\">\n <ele-button-group v-on=\"assignAttrForEvents\" :data-source=\"footerElements\"></ele-button-group>\n </div>\n </div>\n</template>\n\n<script>\nimport { BUILT_IN_EVENT_NAMES, parseFieldMap, RESERVE_EVENT_NAMES, PAGE_STATUS, CONTEXT, BUILT_IN_METHODS_NAMES } from '../../../utils'\nimport { v4 as uuidv4 } from 'uuid'\nimport { net, type } from '@idooel/shared'\nimport { parse } from '@idooel/expression'\nexport default {\n name: 'ele-form-model',\n props: {\n disabled: {\n type: [Boolean, String],\n default: '_routeMeta.disabled'\n },\n title: {\n type: String\n },\n formMeta: {\n type: Object\n },\n footerMeta: {\n type: Object\n }\n },\n data() {\n return {}\n },\n provide () {\n return {\n [CONTEXT]: () => {\n return {\n exposed: this.exposed\n }\n }\n }\n },\n computed: {\n globalDisabled () {\n return this.executeExpression(this.disabled)\n },\n formRef () {\n return uuidv4()\n },\n exposed () {\n return {\n setFieldsValue: this.setFieldsValue,\n validateFields: this.validateFields,\n getFieldsValue: this.getFieldsValue,\n route: this.$route,\n [BUILT_IN_METHODS_NAMES.SUBMIT_FORM]: this.submitRequestTrigger\n }\n },\n assignAttrForEvents () {\n const events = this.footerElements.reduce((ret, ele) => {\n ret[ele.eventName] = (e) => {\n this.$emit(ele.eventName || 'click', { ...e, formModel: this.formModels(), exposed: this.exposed })\n }\n return ret\n }, {})\n return {\n ...this.$listeners,\n ...events,\n [BUILT_IN_EVENT_NAMES.SUBMIT]: this[BUILT_IN_EVENT_NAMES.SUBMIT],\n [BUILT_IN_EVENT_NAMES.CANCEL]: this[BUILT_IN_EVENT_NAMES.CANCEL]\n }\n },\n elements () {\n const { elements } = this.formMeta\n return elements\n },\n preRequest () {\n const { preRequest = {} } = this.formMeta\n return preRequest\n },\n infoRequest () {\n const { infoRequest = {} } = this.formMeta\n return infoRequest\n },\n alertMeta () {\n const { alert = {} } = this.formMeta\n return type.isEmpty(alert) ? null : alert\n },\n submitRequest () {\n const { submitRequest = {} } = this.formMeta\n return submitRequest\n },\n footerElements () {\n const { elements } = this.footerMeta\n return elements.call(this)\n },\n expressionData () {\n return {\n _route: this.$route.query,\n _routeMeta: this.$route.meta\n }\n },\n routeMetaMode () {\n return this.$route.meta.mode\n }\n },\n methods: {\n collectDefaultValues () {\n const ret = this.elements.reduce((ret, props) => {\n const { name, defaultValue } = props\n if (defaultValue) {\n ret[name] = defaultValue\n }\n return ret\n }, {})\n return ret\n },\n onChangeFormStatus (props) {\n this.$emit(RESERVE_EVENT_NAMES.WATCH_FORM_STATUS, { ...props })\n },\n formModels (fieldNames) {\n return this.$refs[this.formRef] ? this.$refs[this.formRef].getFieldsValue(fieldNames) : {}\n },\n executeExpression (expression, dataSource = {}) {\n if (type.isBool(expression)) return expression\n if (type.isEmpty(expression)) return false\n return parse(expression, { ...this.expressionData, ...this.formModels(), ...dataSource })\n },\n execFieldMap (fieldMap = {}, dataSource = {}) {\n const ret = parseFieldMap(fieldMap, { ...this.expressionData, ...dataSource})\n return ret\n },\n async submitRequestTrigger (props = {}) {\n const { url, requestType, headers = {}, params = {}, fieldMap = {} } = this.submitRequest\n const currentUrl = this.executeExpressionForUrl(url)\n if (!currentUrl) return\n const ret = await net[requestType.toLowerCase()](currentUrl, { ...params, ...this.execFieldMap(fieldMap, { ...this.formModels() }), ...this.formModels() }, { headers }).then(resp => {\n this.$emit(BUILT_IN_EVENT_NAMES.SUBMIT, { ...props, formModel: { ...this.formModels(), ...resp.data || {} } })\n return resp.data\n })\n return ret\n },\n async infoRequestTrigger () {\n if (PAGE_STATUS.CREATE == this.routeMetaMode) return\n const { url, requestType, params = {}, fieldMap = {}, headers = {} } = this.infoRequest\n const currentUrl = this.executeExpressionForUrl(url)\n if (!currentUrl) return\n net[requestType.toLowerCase()](currentUrl, { ...params, ...this.execFieldMap(fieldMap) }, { ...headers }).then(resp => {\n const { data = {} } = resp\n this.setFieldsValue(data)\n this.$emit(RESERVE_EVENT_NAMES.INIT_FORM, { ...data })\n })\n },\n async preRequestTrigger () {\n const { url, requestType = 'GET', params = {}, fieldMap = {}, headers = {} } = this.preRequest\n const currentUrl = this.executeExpressionForUrl(url)\n if (!currentUrl) return\n const { data } = await net[requestType.toLowerCase()](currentUrl, { ...params, ...this.execFieldMap(fieldMap) }, { ...headers })\n this.setFieldsValue(data)\n this.$emit(RESERVE_EVENT_NAMES.INIT_FORM, { ...data })\n },\n executeExpressionForUrl (url) {\n return type.isApi(url) ? url : this.executeExpression(url)\n },\n setFieldsValue (props) {\n this.$refs[this.formRef].setFieldsValue(props)\n },\n getFieldsValue (fieldNames) {\n return this.$refs[this.formRef].getFieldsValue(fieldNames)\n },\n validateFields () {\n return this.$refs[this.formRef].validateFields()\n },\n [BUILT_IN_EVENT_NAMES.SUBMIT] (props = {}) {\n if (this.globalDisabled) return\n const status = this.$refs[this.formRef].validateFields()\n if (status) {\n //TODO fieldMap\n return this.submitRequestTrigger(props)\n } else {\n return false\n }\n },\n [BUILT_IN_EVENT_NAMES.CANCEL] (props = {}) {\n this.$emit(BUILT_IN_EVENT_NAMES.CANCEL, { ...props })\n }\n },\n async mounted() {\n this.setFieldsValue(this.collectDefaultValues())\n await this.preRequestTrigger()\n await this.infoRequestTrigger()\n this.$emit(RESERVE_EVENT_NAMES.INIT_FORM, { exposed: this.exposed })\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.form__model--wrapper {\n width: 100%;\n height: 100%;\n overflow: auto;\n background: #fff;\n .form-model__title {\n height: 56px;\n padding: 0 16px;\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: 1px solid var(--idooel-form-title-border-color);\n }\n .form-model__content {\n padding: 16px;\n }\n .form-model__footer {\n /* width: 100%; */\n height: 64px;\n position: fixed;\n bottom: 0;\n display: flex;\n float: right;\n flex-direction: row;\n align-items: center;\n justify-content: end;\n }\n}\n</style>",".form__model--wrapper {\n width: 100%;\n height: 100%;\n overflow: auto;\n background: #fff;\n}\n.form__model--wrapper .form-model__title {\n height: 56px;\n padding: 0 16px;\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: 1px solid var(--idooel-form-title-border-color);\n}\n.form__model--wrapper .form-model__content {\n padding: 16px;\n}\n.form__model--wrapper .form-model__footer {\n /* width: 100%; */\n height: 64px;\n position: fixed;\n bottom: 0;\n display: flex;\n float: right;\n flex-direction: row;\n align-items: center;\n justify-content: end;\n}\n\n/*# sourceMappingURL=index.vue.map */"]}, media: undefined });
3943
+ inject("data-v-c8ada56a_0", { source: ".form__model--wrapper[data-v-c8ada56a] {\n width: 100%;\n height: 100%;\n overflow: auto;\n background: #fff;\n}\n.form__model--wrapper .form-model__title[data-v-c8ada56a] {\n height: 56px;\n padding: 0 16px;\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: 1px solid var(--idooel-form-title-border-color);\n}\n.form__model--wrapper .form-model__content[data-v-c8ada56a] {\n padding: 16px;\n}\n.form__model--wrapper .form-model__footer[data-v-c8ada56a] {\n /* width: 100%; */\n height: 64px;\n position: fixed;\n bottom: 0;\n display: flex;\n float: right;\n flex-direction: row;\n align-items: center;\n justify-content: end;\n}\n\n/*# sourceMappingURL=index.vue.map */", map: {"version":3,"sources":["/Users/huangshan/Goldgov/front/ganjiao/base-elearning-frontend-model/packages/components/packages/models/form-model/src/index.vue","index.vue"],"names":[],"mappings":"AAgNA;EACA,WAAA;EACA,YAAA;EACA,cAAA;EACA,gBAAA;AC/MA;ADgNA;EACA,YAAA;EACA,eAAA;EACA,aAAA;EACA,mBAAA;EACA,mBAAA;EACA,8DAAA;AC9MA;ADgNA;EACA,aAAA;AC9MA;ADgNA;EACA,iBAAA;EACA,YAAA;EACA,eAAA;EACA,SAAA;EACA,aAAA;EACA,YAAA;EACA,mBAAA;EACA,mBAAA;EACA,oBAAA;AC9MA;;AAEA,oCAAoC","file":"index.vue","sourcesContent":["<template>\n <div class=\"form__model--wrapper\">\n <div class=\"form-model__title\" v-if=\"title\">\n {{ title }}\n </div>\n <div class=\"form-model__content\">\n <ele-alert style=\"margin-bottom: 16px;\" v-if=\"alertMeta\" v-bind=\"alertMeta\"></ele-alert>\n <ele-form :ref=\"formRef\" @change=\"onChangeFormStatus($event)\" :elements=\"elements\" :disabled=\"globalDisabled\"></ele-form>\n </div>\n <div class=\"form-model__footer\" v-if=\"footerMeta\">\n <ele-button-group v-on=\"assignAttrForEvents\" :data-source=\"footerElements\"></ele-button-group>\n </div>\n </div>\n</template>\n\n<script>\nimport { BUILT_IN_EVENT_NAMES, parseFieldMap, RESERVE_EVENT_NAMES, PAGE_STATUS, CONTEXT, BUILT_IN_METHODS_NAMES } from '../../../utils'\nimport { v4 as uuidv4 } from 'uuid'\nimport { net, type } from '@idooel/shared'\nimport { parse } from '@idooel/expression'\nexport default {\n name: 'ele-form-model',\n props: {\n disabled: {\n type: [Boolean, String],\n default: '_routeMeta.disabled'\n },\n title: {\n type: String\n },\n formMeta: {\n type: Object\n },\n footerMeta: {\n type: Object\n }\n },\n data() {\n return {}\n },\n provide () {\n return {\n [CONTEXT]: () => {\n return {\n exposed: this.exposed\n }\n }\n }\n },\n computed: {\n globalDisabled () {\n return this.executeExpression(this.disabled)\n },\n formRef () {\n return uuidv4()\n },\n exposed () {\n return {\n setFieldsValue: this.setFieldsValue,\n validateFields: this.validateFields,\n getFieldsValue: this.getFieldsValue,\n executeExpressions: this.executeExpressions,\n route: this.$route,\n [BUILT_IN_METHODS_NAMES.SUBMIT_FORM]: this.submitRequestTrigger\n }\n },\n assignAttrForEvents () {\n const events = this.footerElements.reduce((ret, ele) => {\n ret[ele.eventName] = (e) => {\n this.$emit(ele.eventName || 'click', { ...e, formModel: this.formModels(), exposed: this.exposed })\n }\n return ret\n }, {})\n return {\n ...this.$listeners,\n ...events,\n [BUILT_IN_EVENT_NAMES.SUBMIT]: this[BUILT_IN_EVENT_NAMES.SUBMIT],\n [BUILT_IN_EVENT_NAMES.CANCEL]: this[BUILT_IN_EVENT_NAMES.CANCEL]\n }\n },\n elements () {\n const { elements } = this.formMeta\n return elements\n },\n preRequest () {\n const { preRequest = {} } = this.formMeta\n return preRequest\n },\n infoRequest () {\n const { infoRequest = {} } = this.formMeta\n return infoRequest\n },\n alertMeta () {\n const { alert = {} } = this.formMeta\n return type.isEmpty(alert) ? null : alert\n },\n submitRequest () {\n const { submitRequest = {} } = this.formMeta\n return submitRequest\n },\n footerElements () {\n const { elements } = this.footerMeta\n return elements.call(this)\n },\n expressionData () {\n return {\n _route: this.$route.query,\n _routeMeta: this.$route.meta\n }\n },\n routeMetaMode () {\n return this.$route.meta.mode\n }\n },\n methods: {\n collectDefaultValues () {\n const ret = this.elements.reduce((ret, props) => {\n const { name, defaultValue } = props\n if (defaultValue) {\n ret[name] = defaultValue\n }\n return ret\n }, {})\n return ret\n },\n onChangeFormStatus (props) {\n this.$emit(RESERVE_EVENT_NAMES.WATCH_FORM_STATUS, { ...props })\n },\n formModels (fieldNames) {\n return this.$refs[this.formRef] ? this.$refs[this.formRef].getFieldsValue(fieldNames) : {}\n },\n executeExpression (expression, dataSource = {}) {\n if (type.isBool(expression)) return expression\n if (type.isEmpty(expression)) return false\n return parse(expression, { ...this.expressionData, ...this.formModels(), ...dataSource })\n },\n execFieldMap (fieldMap = {}, dataSource = {}) {\n const ret = parseFieldMap(fieldMap, { ...this.expressionData, ...dataSource})\n return ret\n },\n async submitRequestTrigger (props = {}) {\n const { url, requestType, headers = {}, params = {}, fieldMap = {} } = this.submitRequest\n const currentUrl = this.executeExpressionForUrl(url)\n if (!currentUrl) return\n const ret = await net[requestType.toLowerCase()](currentUrl, { ...params, ...this.execFieldMap(fieldMap, { ...this.formModels() }), ...this.formModels() }, { headers }).then(resp => {\n this.$emit(BUILT_IN_EVENT_NAMES.SUBMIT, { ...props, formModel: { ...this.formModels(), ...resp.data || {} } })\n return resp.data\n })\n return ret\n },\n async infoRequestTrigger () {\n if (PAGE_STATUS.CREATE == this.routeMetaMode) return\n const { url, requestType, params = {}, fieldMap = {}, headers = {} } = this.infoRequest\n const currentUrl = this.executeExpressionForUrl(url)\n if (!currentUrl) return\n net[requestType.toLowerCase()](currentUrl, { ...params, ...this.execFieldMap(fieldMap) }, { ...headers }).then(resp => {\n const { data = {} } = resp\n this.setFieldsValue(data)\n this.$emit(RESERVE_EVENT_NAMES.INIT_FORM, { ...data })\n })\n },\n async preRequestTrigger () {\n const { url, requestType = 'GET', params = {}, fieldMap = {}, headers = {} } = this.preRequest\n const currentUrl = this.executeExpressionForUrl(url)\n if (!currentUrl) return\n const { data } = await net[requestType.toLowerCase()](currentUrl, { ...params, ...this.execFieldMap(fieldMap) }, { ...headers })\n this.setFieldsValue(data)\n this.$emit(RESERVE_EVENT_NAMES.INIT_FORM, { ...data })\n },\n executeExpressionForUrl (url) {\n return type.isApi(url) ? url : this.executeExpression(url)\n },\n setFieldsValue (props) {\n this.$refs[this.formRef].setFieldsValue(props)\n },\n getFieldsValue (fieldNames) {\n return this.$refs[this.formRef].getFieldsValue(fieldNames)\n },\n executeExpressions () {\n return this.$refs[this.formRef].evalShowExpression()\n },\n validateFields () {\n return this.$refs[this.formRef].validateFields()\n },\n [BUILT_IN_EVENT_NAMES.SUBMIT] (props = {}) {\n if (this.globalDisabled) return\n const status = this.$refs[this.formRef].validateFields()\n if (status) {\n //TODO fieldMap\n return this.submitRequestTrigger(props)\n } else {\n return false\n }\n },\n [BUILT_IN_EVENT_NAMES.CANCEL] (props = {}) {\n this.$emit(BUILT_IN_EVENT_NAMES.CANCEL, { ...props })\n }\n },\n async mounted() {\n this.setFieldsValue(this.collectDefaultValues())\n await this.preRequestTrigger()\n await this.infoRequestTrigger()\n this.$emit(RESERVE_EVENT_NAMES.INIT_FORM, { exposed: this.exposed })\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.form__model--wrapper {\n width: 100%;\n height: 100%;\n overflow: auto;\n background: #fff;\n .form-model__title {\n height: 56px;\n padding: 0 16px;\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: 1px solid var(--idooel-form-title-border-color);\n }\n .form-model__content {\n padding: 16px;\n }\n .form-model__footer {\n /* width: 100%; */\n height: 64px;\n position: fixed;\n bottom: 0;\n display: flex;\n float: right;\n flex-direction: row;\n align-items: center;\n justify-content: end;\n }\n}\n</style>",".form__model--wrapper {\n width: 100%;\n height: 100%;\n overflow: auto;\n background: #fff;\n}\n.form__model--wrapper .form-model__title {\n height: 56px;\n padding: 0 16px;\n display: flex;\n flex-direction: row;\n align-items: center;\n border-bottom: 1px solid var(--idooel-form-title-border-color);\n}\n.form__model--wrapper .form-model__content {\n padding: 16px;\n}\n.form__model--wrapper .form-model__footer {\n /* width: 100%; */\n height: 64px;\n position: fixed;\n bottom: 0;\n display: flex;\n float: right;\n flex-direction: row;\n align-items: center;\n justify-content: end;\n}\n\n/*# sourceMappingURL=index.vue.map */"]}, media: undefined });
3939
3944
 
3940
3945
  };
3941
3946
  /* scoped */
3942
- const __vue_scope_id__$y = "data-v-f6310b92";
3947
+ const __vue_scope_id__$y = "data-v-c8ada56a";
3943
3948
  /* module identifier */
3944
3949
  const __vue_module_identifier__$y = undefined;
3945
3950
  /* functional template */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idooel/components",
3
- "version": "0.0.2-beta.2",
3
+ "version": "0.0.2-beta.4",
4
4
  "description": "",
5
5
  "private": false,
6
6
  "main": "dist/@idooel/components.umd.js",
@@ -59,6 +59,7 @@ export default {
59
59
  setFieldsValue: this.setFieldsValue,
60
60
  validateFields: this.validateFields,
61
61
  getFieldsValue: this.getFieldsValue,
62
+ executeExpressions: this.executeExpressions,
62
63
  route: this.$route,
63
64
  [BUILT_IN_METHODS_NAMES.SUBMIT_FORM]: this.submitRequestTrigger
64
65
  }
@@ -175,6 +176,9 @@ export default {
175
176
  getFieldsValue (fieldNames) {
176
177
  return this.$refs[this.formRef].getFieldsValue(fieldNames)
177
178
  },
179
+ executeExpressions () {
180
+ return this.$refs[this.formRef].evalShowExpression()
181
+ },
178
182
  validateFields () {
179
183
  return this.$refs[this.formRef].validateFields()
180
184
  },
@@ -5,6 +5,7 @@
5
5
  :class="[isNoData && 'g-table__no-data']"
6
6
  :pagination="false"
7
7
  :loading="loading"
8
+ size="middle"
8
9
  :columns="innerColumns"
9
10
  :row-selection="rowSelection"
10
11
  :row-class-name="setRowClassName"
@@ -270,6 +271,9 @@ export default {
270
271
  .ant-table-tbody {
271
272
  .g-table__row--odd {
272
273
  &.ant-table-row-hover {
274
+ td {
275
+ background-color: var(--idooel-row-hover-color);
276
+ }
273
277
  .ant-table-selection-column {
274
278
  background-color: var(--idooel-row-hover-color) !important;
275
279
  }
@@ -277,14 +281,20 @@ export default {
277
281
  background-color: var(--idooel-row-hover-color) !important;
278
282
  }
279
283
  }
280
- .ant-table-selection-column {
284
+ td {
281
285
  background-color: var(--idooel-row-odd-color);
282
286
  }
287
+ .ant-table-selection-column {
288
+ background-color: var(--idooel-row-odd-color) !important;
289
+ }
283
290
  .ant-table-row-cell-break-word {
284
- background-color: var(--idooel-row-odd-color);
291
+ background-color: var(--idooel-row-odd-color) !important;
285
292
  }
286
293
  }
287
294
  }
295
+ .ant-table-thead {
296
+ background: rgba(0, 0, 0, 0.03) !important;
297
+ }
288
298
  }
289
299
 
290
300
  ::v-deep .ant-table-body {