index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <template>
  2. <div
  3. style="width: 100%;height: 100%"
  4. class="bs-design-wrap "
  5. >
  6. <!-- :border="this.config.customize.border" -->
  7. <el-table
  8. :id="config.code"
  9. ref="table"
  10. class="custom-table"
  11. height="100%"
  12. :stripe="config.customize.stripe"
  13. :data="config.option.tableData"
  14. :header-cell-style="headerCellStyle"
  15. :cell-style="cellStyle"
  16. :row-class-name="tableRowClassName"
  17. >
  18. <el-table-column
  19. v-for="(col, index) in config.option.columnData"
  20. :key="index"
  21. show-overflow-tooltip
  22. :label="col.remark"
  23. :prop="col.alias"
  24. align="center"
  25. />
  26. </el-table>
  27. </div>
  28. </template>
  29. <script>
  30. import commonMixins from 'packages/js/mixins/commonMixins'
  31. import paramsMixins from 'packages/js/mixins/paramsMixins'
  32. import linkageMixins from 'packages/js/mixins/linkageMixins'
  33. export default {
  34. name: 'TableChart',
  35. mixins: [paramsMixins, commonMixins, linkageMixins],
  36. props: {
  37. id: {
  38. type: String,
  39. default: ''
  40. },
  41. config: {
  42. type: Object,
  43. default: () => ({})
  44. }
  45. },
  46. data () {
  47. return {
  48. headerCellStyleObj: {
  49. backgroundColor: 'transparent'
  50. },
  51. cellStyleObj: {
  52. backgroundColor: 'transparent'
  53. }
  54. }
  55. },
  56. computed: {
  57. headerCellStyle () {
  58. const headerBackgroundColor = {
  59. dark: '#141414',
  60. light: '#ffffff',
  61. auto: 'transparent'
  62. }
  63. if (document.getElementById(this.config.code)?.querySelector('tr')) {
  64. document
  65. .getElementById(this.config.code)
  66. .querySelector('tr').style.backgroundColor =
  67. this.customTheme !== 'custom'
  68. ? this.config.customize.headerBackgroundColor || headerBackgroundColor[this.customTheme]
  69. : this.headerCellStyleObj.backgroundColor
  70. }
  71. const style = {
  72. height: '48px',
  73. borderBottom: 'solid 2px #007aff',
  74. backgroundColor:
  75. this.customTheme !== 'custom'
  76. ? this.config.customize.headerBackgroundColor || headerBackgroundColor[this.customTheme]
  77. : this.headerCellStyleObj.backgroundColor,
  78. color:
  79. this.customTheme === 'light'
  80. ? '#000000'
  81. : this.config.customize.headerFontColor || '#ffffff',
  82. fontSize: this.config.customize.headerFontSize + 'px' || '14px'
  83. }
  84. return style
  85. },
  86. cellStyle () {
  87. const bodyBackgroundColor = {
  88. dark: '#141414',
  89. light: '#ffffff',
  90. auto: 'transparent'
  91. }
  92. const style = {
  93. backgroundColor:
  94. this.customTheme !== 'custom'
  95. ? this.config.customize.bodyBackgroundColor || bodyBackgroundColor[this.customTheme]
  96. : this.headerCellStyleObj.backgroundColor,
  97. color:
  98. this.customTheme === 'light'
  99. ? '#000000'
  100. : this.config.customize.bodyFontColor || '#ffffff',
  101. fontSize: this.config.customize.bodyFontSize + 'px' || '14px',
  102. border: `solid 1px ${this.customTheme !== 'custom'
  103. ? this.config.customize.bodyBackgroundColor || bodyBackgroundColor[this.customTheme]
  104. : this.headerCellStyleObj.backgroundColor}`
  105. }
  106. return style
  107. }
  108. },
  109. created () { },
  110. mounted () {
  111. this.chartInit()
  112. this.initStyle()
  113. },
  114. methods: {
  115. initStyle () {
  116. if (this.customTheme === 'custom') {
  117. this.headerCellStyleToObj()
  118. this.cellStyleToObj()
  119. }
  120. if (this.customTheme === 'custom') {
  121. this.headerCellStyleToObj()
  122. this.cellStyleToObj()
  123. }
  124. if (this.config.customize.stripe) {
  125. const trs = document
  126. .getElementById(this.config.code)
  127. ?.querySelectorAll('tr.el-table__row--striped')
  128. if (trs) {
  129. trs.forEach(tr => {
  130. tr.style.opacity = '0.9'
  131. // 透明度
  132. // const overlay = document.createElement("div");
  133. // overlay.classList.add("overlay");
  134. // // 将蒙版添加到容器中
  135. // tr.appendChild(overlay);
  136. })
  137. }
  138. } else {
  139. const trs = document
  140. .getElementById(this.config.code)
  141. ?.querySelectorAll('tr.el-table__row--striped')
  142. if (trs) {
  143. trs.forEach(tr => {
  144. tr.style.opacity = '1'
  145. // 透明度
  146. // const overlay = document.createElement("div");
  147. // overlay.classList.add("overlay");
  148. // // 将蒙版添加到容器中
  149. // tr.appendChild(overlay);
  150. })
  151. }
  152. // document.querySelectorAll(".overlay").forEach(overlay => {
  153. // overlay.remove();
  154. // });
  155. }
  156. // this.chartInit();
  157. if (this.config.customize.evenRowBackgroundColor && !this.config.customize.oddRowBackgroundColor) {
  158. this.config.customize.oddRowBackgroundColor = this.config.customize.bodyBackgroundColor
  159. } else if (!this.config.customize.evenRowBackgroundColor && this.config.customize.oddRowBackgroundColor) {
  160. this.config.customize.evenRowBackgroundColor = this.config.customize.bodyBackgroundColor
  161. } else if (!(!this.config.customize.evenRowBackgroundColor && !this.config.customize.oddRowBackgroundColor)) {
  162. this.config.customize.bodyBackgroundColor = ''
  163. }
  164. window.requestAnimationFrame(() => {
  165. document.querySelectorAll(`.even-row${this.config.code}`).forEach(node => {
  166. node.style.backgroundColor = this.config.customize.evenRowBackgroundColor
  167. })
  168. document.querySelectorAll(`.odd-row${this.config.code}`).forEach(node => {
  169. node.style.backgroundColor = this.config.customize.oddRowBackgroundColor
  170. })
  171. })
  172. },
  173. // 表格行样式
  174. tableRowClassName ({ row, rowIndex }) {
  175. return rowIndex % 2 === 0 ? `even-row${this.config.code}` : `odd-row${this.config.code}`
  176. },
  177. buildOption (config, data) {
  178. config.option.tableData = data?.data
  179. const filteredData = {}
  180. const columnData = data?.columnData || {}
  181. if (config.dataSource.dimensionFieldList && config.dataSource.dimensionFieldList.length > 0) {
  182. Object?.keys(columnData).forEach(key => {
  183. if (
  184. config.dataSource.dimensionFieldList.includes(columnData[key].alias)
  185. ) {
  186. filteredData[key] = columnData[key]
  187. }
  188. })
  189. config.option.columnData = filteredData
  190. } else {
  191. config.option.columnData = columnData
  192. }
  193. return config
  194. },
  195. // 更新数据
  196. updateData () {
  197. this.getCurrentOption().then(({ data, config }) => {
  198. if (data.success) {
  199. this.config.option.tableData = data?.data
  200. this.config.option.columnData = data?.columnData || {}
  201. this.$refs.table.doLayout()
  202. }
  203. })
  204. },
  205. // 将样式字符串转成对象, 用于自定义主题,表格头部样式
  206. headerCellStyleToObj () {
  207. const str = this.themeJson.themeCss
  208. // 匹配包含header-cell-style的样式字符串
  209. // 匹配包含header-cell-style的样式字符串
  210. const regex = /\.header-cell-style\{([^{}]+)\}/
  211. const match = str.match(regex)
  212. if (match) {
  213. // 将样式字符串转成对象
  214. const styleStr = match[1].trim().replace(/\s*;\s*$/, '') // 去掉末尾的空格和分号
  215. // const styleObj = {};
  216. styleStr.split(';').forEach(s => {
  217. const [key, value] = s.split(':')
  218. if (key && value) {
  219. // 判断是否为空字符串
  220. this.headerCellStyleObj[key.trim()] = value.trim()
  221. }
  222. })
  223. } else {
  224. this.headerCellStyleObj = {}
  225. }
  226. },
  227. // 将样式字符串转成对象, 用于自定义主题,表格主体样式
  228. cellStyleToObj () {
  229. const str = this.themeJson.themeCss
  230. // 匹配包含header-cell-style的样式字符串
  231. // 匹配包含header-cell-style的样式字符串
  232. const regex = /\.cell-style\{([^{}]+)\}/
  233. const match = str.match(regex)
  234. if (match) {
  235. // 将样式字符串转成对象
  236. const styleStr = match[1].trim().replace(/\s*;\s*$/, '') // 去掉末尾的空格和分号
  237. styleStr.split(';').forEach(s => {
  238. const [key, value] = s.split(':')
  239. if (key && value) {
  240. // 判断是否为空字符串
  241. this.cellStyleObj[key.trim()] = value.trim()
  242. }
  243. })
  244. } else {
  245. this.cellStyleObj = {}
  246. }
  247. }
  248. }
  249. }
  250. </script>
  251. <style lang="scss" scoped>
  252. .bs-design-wrap {
  253. position: relative;
  254. width: 100%;
  255. height: 100%;
  256. background-color: transparent;
  257. border-radius: 4px;
  258. box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.1);
  259. box-sizing: border-box;
  260. }
  261. ::v-deep .el-table {
  262. height: 100%;
  263. background-color: transparent;
  264. }
  265. ::v-deep .el-table tr {
  266. background-color: transparent;
  267. }
  268. // ::v-deep .el-table th.gutter {
  269. // border-bottom: 2px solid var(--bs-el-color-primary) !important;
  270. // }
  271. ::v-deep .el-table__body {
  272. height: 100%;
  273. }
  274. ::v-deep .el-table .el-table__header tr {
  275. background-color: transparent;
  276. }
  277. ::v-deep tr.el-table__row--striped {
  278. z-index: 1;
  279. /*将容器的 z-index 设为 1,以便其在蒙版之上*/
  280. position: relative;
  281. /*设置容器为相对定位*/
  282. opacity: 0.9;
  283. }
  284. ::v-deep tr.el-table__row--striped::before {
  285. position: absolute;
  286. /*设置蒙版为绝对定位*/
  287. top: 0;
  288. left: 0;
  289. width: 100%;
  290. height: 100%;
  291. background-color: rgba(0, 0, 0, 0.2);
  292. /*设置半透明的灰色背景色*/
  293. z-index: 2;
  294. /*将蒙版的 z-index 设为 2,以便其覆盖在容器之上*/
  295. }
  296. ::v-deep .overlay {
  297. position: absolute;
  298. /*设置蒙版为绝对定位*/
  299. top: 0;
  300. left: 0;
  301. width: 100%;
  302. height: 100%;
  303. background-color: rgba(0, 0, 0, 0.2) !important;
  304. /*设置半透明的灰色背景色*/
  305. z-index: 2;
  306. /*将蒙版的 z-index 设为 2,以便其覆盖在容器之上*/
  307. }
  308. ::v-deep .cell.el-tooltip {
  309. z-index: 3;
  310. min-width: 50px;
  311. white-space: nowrap;
  312. position: inherit;
  313. }
  314. ::v-deep .el-table {
  315. .el-table__cell {
  316. border-bottom: none !important;
  317. }
  318. &:before {
  319. display: none !important;
  320. }
  321. th.gutter,
  322. colgroup.gutter {
  323. width: 0px !important; //此处的宽度值,对应你自定义滚动条的宽度即可
  324. }
  325. }
  326. // 关键css代码
  327. ::v-deep .el-table__header colgroup col[name="gutter"] {
  328. display: table-cell !important;
  329. }
  330. /deep/ .el-table__body-wrapper::-webkit-scrollbar {
  331. width: 10px; // 横向滚动条
  332. height: 10px; // 纵向滚动条 必写
  333. background-color: transparent;
  334. }
  335. // 滚动条的滑块
  336. /deep/ .el-table__body-wrapper::-webkit-scrollbar-thumb {
  337. background-color: #9093994D;
  338. border-radius: 5px;
  339. &:hover {
  340. background-color: #90939980;
  341. }
  342. }
  343. </style>