index.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. <template>
  2. <el-select
  3. :key="config.code"
  4. v-model="value"
  5. :popper-class="'basic-component-select select-popper-' + config.code"
  6. :class="['basic-component-select', `select-${config.code}`]"
  7. :placeholder="`请选择${placeholder || newPlaceholder}`"
  8. clearable
  9. :filterable="filterable"
  10. @visible-change="visibleChange"
  11. @change="selectChange"
  12. @mouseenter.native="mouseenter"
  13. >
  14. <el-option
  15. v-for="(option, key) in optionData"
  16. :key="key"
  17. :label="option[config.dataSource.dimensionField]"
  18. :value="option[config.dataSource.metricField]"
  19. />
  20. </el-select>
  21. </template>
  22. <script>
  23. import { EventBus } from 'data-room-ui/js/utils/eventBus'
  24. import commonMixins from 'data-room-ui/js/mixins/commonMixins'
  25. import linkageMixins from 'data-room-ui/js/mixins/linkageMixins'
  26. import { getDataSetDetails } from 'data-room-ui/js/api/bigScreenApi'
  27. import { settingToTheme } from 'data-room-ui/js/utils/themeFormatting'
  28. import cloneDeep from 'lodash/cloneDeep'
  29. window.dataSetFields = []
  30. export default {
  31. name: 'BasicComponentSelect',
  32. components: {},
  33. mixins: [commonMixins, linkageMixins],
  34. props: {
  35. // 组件配置
  36. config: {
  37. type: Object,
  38. default: () => ({})
  39. }
  40. },
  41. data () {
  42. return {
  43. value: '',
  44. innerConfig: {},
  45. optionData: [],
  46. newPlaceholder: '',
  47. filterable: false
  48. }
  49. },
  50. computed: {
  51. isPreview () {
  52. return (this.$route.path === window?.BS_CONFIG?.routers?.previewUrl) || (this.$route.path === '/big-screen/preview')
  53. },
  54. placeholder: {
  55. get () {
  56. return window.dataSetFields.find(field => field.value === this.config.dataSource.dimensionField)?.label || ''
  57. },
  58. set (val) {
  59. this.newPlaceholder = val
  60. }
  61. }
  62. },
  63. watch: { },
  64. created () {
  65. },
  66. mounted () {
  67. window.dataSetFields = []
  68. this.changeStyle(this.config)
  69. EventBus.$on('changeBusinessKey', () => {
  70. window.dataSetFields = []
  71. })
  72. if (this.isPreview) {
  73. this.filterable = true
  74. document.querySelector(`.select-${this.config.code}`).style.pointerEvents = 'all'
  75. if (this.config.dataSource.businessKey && window.dataSetFields.length === 0) {
  76. getDataSetDetails(this.config.dataSource.businessKey).then(res => {
  77. window.dataSetFields = res.fields.map(field => {
  78. return {
  79. label: field.comment || field.fieldDesc,
  80. value: field.name || field.fieldName
  81. }
  82. })
  83. this.placeholder = window.dataSetFields.find(field => field.value === this.config.dataSource.dimensionField)?.label || ''
  84. })
  85. }
  86. } else {
  87. document.querySelector(`.select-${this.config.code}`).style.pointerEvents = 'none'
  88. }
  89. },
  90. beforeDestroy () {
  91. EventBus.$off('changeBusinessKey')
  92. },
  93. methods: {
  94. dataFormatting (config, data) {
  95. // 数据返回成功则赋值
  96. if (data.success) {
  97. data = data.data
  98. // 获取到后端返回的数据,有则赋值
  99. if (config.dataHandler) {
  100. try {
  101. // 此处函数处理data
  102. eval(config.dataHandler)
  103. } catch (e) {
  104. console.info(e)
  105. }
  106. }
  107. config.option.data = data
  108. this.optionData = data
  109. config.customize.title = config.option.data[config.dataSource.dimensionField] || config.customize.title
  110. if (window.dataSetFields.length === 0) {
  111. getDataSetDetails(this.config.dataSource.businessKey).then(res => {
  112. window.dataSetFields = res.fields.map(field => {
  113. return {
  114. label: field.comment || field.fieldDesc,
  115. value: field.name || field.fieldName
  116. }
  117. })
  118. this.placeholder = window.dataSetFields.find(field => field.value === this.config.dataSource.dimensionField)?.label || ''
  119. })
  120. }
  121. // 语音播报
  122. } else {
  123. // 数据返回失败则赋前端的模拟数据
  124. config.option.data = []
  125. this.optionData = []
  126. }
  127. return config
  128. },
  129. changeStyle (config) {
  130. config = { ...this.config, ...config }
  131. // 样式改变时更新主题配置
  132. config.theme = settingToTheme(cloneDeep(config), this.customTheme)
  133. this.changeChartConfig(config)
  134. this.innerConfig = config
  135. // 选择器元素
  136. const selectInputEl = document.querySelector(`.select-${config.code} .el-input__inner`)
  137. // 背景颜色
  138. selectInputEl.style.backgroundColor = config.customize.backgroundColor
  139. // 字体大小
  140. selectInputEl.style.fontSize = config.customize.fontSize + 'px'
  141. // 字体颜色
  142. selectInputEl.style.color = config.customize.fontColor
  143. // 下拉图标
  144. const selectDropdownIcon = document.querySelector(`.select-${config.code} .el-icon-arrow-up`)
  145. selectDropdownIcon.style.fontSize = config.customize.fontSize + 'px'
  146. // 选择器下拉框元素
  147. const selectDropdownEl = document.querySelector(`.select-${config.code} .el-select-dropdown`)
  148. // 箭头背景颜色和下拉框背景颜色一致
  149. if (selectDropdownEl) {
  150. // 下拉框无边框
  151. selectDropdownEl.style.border = 'none'
  152. // 背景颜色
  153. selectDropdownEl.style.backgroundColor = config.customize.dropDownBackgroundColor
  154. }
  155. },
  156. // 组件联动
  157. selectChange (val) {
  158. if (val) {
  159. this.linkage(this.config.option.data.find(item => item[this.config.dataSource.metricField] === val))
  160. }
  161. },
  162. visibleChange (val) {
  163. if (val) {
  164. // 修改下拉框背景颜色,让下拉框背景颜色和箭头背景颜色一致
  165. const selectDropdownEl = document.querySelector(`.select-popper-${this.innerConfig.code}`)
  166. selectDropdownEl.style.color = this.innerConfig.customize.dropDownBackgroundColor
  167. // 空状态
  168. const selectDropdownEmptyEl = document.querySelector(`.select-popper-${this.innerConfig.code} .el-select-dropdown__empty`)
  169. if (selectDropdownEmptyEl) {
  170. selectDropdownEmptyEl.style.backgroundColor = this.innerConfig.customize.dropDownBackgroundColor
  171. }
  172. // 下拉项hover颜色
  173. const selectDropdownWrap = document.querySelector(`.select-popper-${this.innerConfig.code} .el-select-dropdown__wrap`)
  174. selectDropdownWrap.style.setProperty('--dropDownHoverFontColor', this.innerConfig.customize.dropDownHoverFontColor)
  175. selectDropdownWrap.style.setProperty('--dropDownHoverBackgroundColor', this.innerConfig.customize.dropDownHoverBackgroundColor)
  176. }
  177. // 不是激活项的还是使用背景颜色
  178. const selectDropdownItemEl = document.querySelectorAll(`.select-popper-${this.innerConfig.code} .el-select-dropdown__item`)
  179. selectDropdownItemEl.forEach(item => {
  180. // 检查是否是激活项,不是则使用背景颜色
  181. if (!item.classList.contains('selected')) {
  182. item.style.color = this.innerConfig.customize.dropDownFontColor
  183. item.style.backgroundColor = this.innerConfig.customize.dropDownBackgroundColor
  184. }
  185. })
  186. },
  187. // 鼠标进入
  188. mouseenter () {
  189. if (this.value) {
  190. setTimeout(() => {
  191. // 清空图标
  192. const selectDropdownCloseIcon = document.querySelector(`.select-${this.innerConfig.code} .el-icon-circle-close`)
  193. if (selectDropdownCloseIcon) {
  194. selectDropdownCloseIcon.style.fontSize = this.innerConfig.customize.fontSize + 'px'
  195. }
  196. }, 30)
  197. }
  198. }
  199. }
  200. }
  201. </script>
  202. <style lang="scss">
  203. .basic-component-select{
  204. color: '';
  205. .el-select-dropdown__wrap {
  206. margin-bottom: 0px !important;
  207. }
  208. .el-select-group__wrap:not(:last-of-type)::after {
  209. background-color: transparent !important;
  210. }
  211. .popper__arrow{
  212. border-bottom-color:var(--color) !important;
  213. &::after{
  214. border-bottom-color:var(--color) !important;
  215. }
  216. }
  217. }
  218. </style>
  219. <style lang="scss" scoped>
  220. .basic-component-select {
  221. width: 100%;
  222. height: 100%;
  223. ::v-deep .el-input {
  224. height: 100% !important;
  225. .el-select__caret{
  226. width: 100%;
  227. height: 100%;
  228. display: flex;
  229. align-items: center;
  230. }
  231. // 选择器输入框样式
  232. .el-input__inner {
  233. height: 100% !important;
  234. border-color: var(--bs-el-border) !important;
  235. }
  236. }
  237. .el-select-dropdown__item.hover,
  238. .el-select-dropdown__item:hover {
  239. color: var(--dropDownHoverFontColor) !important;
  240. background-color: var(--dropDownHoverBackgroundColor) !important;
  241. }
  242. .el-tag.el-tag--info {
  243. color: var(--bs-el-text) !important;
  244. }
  245. .popper__arrow {
  246. bottom: 0 !important;
  247. &:after {
  248. bottom: 0 !important;
  249. }
  250. }
  251. }
  252. </style>