index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. <template>
  2. <el-date-picker
  3. :key="config.customize.type"
  4. v-model="value"
  5. :picker-options="config.customize.pickerOptions"
  6. :type="config.customize.type"
  7. clearable
  8. :class="['basic-component-date-picker', `date-picker-${config.code}`]"
  9. :popper-class="'basic-component-date-picker date-picker-popper-' + config.code"
  10. :value-format="config.customize.valueFormat"
  11. :default-value="value"
  12. size="large"
  13. @focus="focusEvent"
  14. @change="changeValue"
  15. @mouseenter.native="mouseenter"
  16. />
  17. </template>
  18. <script>
  19. import moment from 'moment'
  20. import cloneDeep from 'lodash/cloneDeep'
  21. import commonMixins from 'data-room-ui/js/mixins/commonMixins'
  22. import linkageMixins from 'data-room-ui/js/mixins/linkageMixins'
  23. import { settingToTheme } from 'data-room-ui/js/utils/themeFormatting'
  24. import { mapState } from 'vuex'
  25. window.dataSetFields = []
  26. export default {
  27. name: 'BasicComponentSelect',
  28. components: {},
  29. mixins: [commonMixins, linkageMixins],
  30. props: {
  31. // 组件配置
  32. config: {
  33. type: Object,
  34. default: () => ({})
  35. }
  36. },
  37. data () {
  38. return {
  39. value: '',
  40. innerConfig: {}
  41. }
  42. },
  43. computed: {
  44. ...mapState({
  45. chartList: state => state.bigScreen.pageInfo.chartList
  46. }),
  47. isPreview () {
  48. return (this.$route.path === window?.BS_CONFIG?.routers?.previewUrl) || (this.$route.path === '/big-screen/preview')
  49. }
  50. },
  51. watch: {
  52. 'config.customize.formatType': {
  53. handler (val) {
  54. if (val === 'timestamp') {
  55. this.value = 0
  56. this.valueFormat = 'timestamp'
  57. } else if (val === 'custom') {
  58. this.value = ''
  59. this.valueFormat = 'YYYY-MM-DD HH:mm:ss'
  60. }
  61. },
  62. immediate: true
  63. },
  64. 'config.customize.type': {
  65. handler (val) {
  66. this.$nextTick(() => {
  67. if (!this.isPreview) {
  68. document.querySelector(`.date-picker-${this.config.code}`).style.pointerEvents = 'none'
  69. }
  70. })
  71. if (['year', 'month', 'date', 'week', 'datetime'].includes(val)) {
  72. this.value = moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
  73. } else {
  74. this.value = [
  75. moment(new Date()).subtract(7, 'days').format('YYYY-MM-DD HH:mm:ss'),
  76. moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
  77. ]
  78. }
  79. },
  80. immediate: true
  81. }
  82. },
  83. created () { },
  84. mounted () {
  85. if (!this.isPreview) {
  86. document.querySelector(`.date-picker-${this.config.code}`).style.pointerEvents = 'none'
  87. }
  88. this.changeStyle(this.config)
  89. if (this.value === '') {
  90. this.value = [
  91. moment(new Date()).subtract(7, 'days').format('YYYY-MM-DD HH:mm:ss'),
  92. moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
  93. ]
  94. }
  95. },
  96. beforeDestroy () {
  97. },
  98. methods: {
  99. dataFormatting (config, data) {
  100. config.option.data = []
  101. return config
  102. },
  103. changeStyle (config) {
  104. config = { ...this.config, ...config }
  105. // 样式改变时更新主题配置
  106. config.theme = settingToTheme(cloneDeep(config), this.customTheme)
  107. this.changeChartConfig(config)
  108. this.innerConfig = config
  109. // 时间选择器元素
  110. const { bgColor, fontColor, fontSize } = config.customize
  111. this.$nextTick(() => {
  112. const timePickerEl = document.querySelector(`.date-picker-${config.code}`)
  113. timePickerEl.style.backgroundColor = bgColor
  114. // 时间选择器输入框元素
  115. const timePickerInput = timePickerEl.querySelector('.el-input__inner')
  116. if (timePickerInput) {
  117. // 时间选择器输入框背景颜色
  118. timePickerInput.style.backgroundColor = bgColor
  119. // 时间选择器输入框字体颜色
  120. timePickerInput.style.color = fontColor
  121. // 时间选择器输入框字体大小
  122. timePickerInput.style.fontSize = fontSize + 'px'
  123. }
  124. // 时间范围选择器输入框元素
  125. const timePickerRangeInput = timePickerEl.querySelectorAll('.el-range-input')
  126. if (timePickerRangeInput.length > 0) {
  127. // 连接符
  128. const timePickerRangeSeparator = timePickerEl.querySelector('.el-range-separator')
  129. if (timePickerRangeSeparator) {
  130. // 宽度和字体大小保持一致
  131. timePickerRangeSeparator.style.width = fontSize + 'px'
  132. timePickerRangeSeparator.style.color = fontColor
  133. timePickerRangeSeparator.style.fontSize = fontSize + 'px'
  134. }
  135. timePickerRangeInput.forEach((el) => {
  136. // 时间范围选择器输入框背景颜色
  137. el.style.backgroundColor = bgColor
  138. // 时间范围选择器输入框字体颜色
  139. el.style.color = fontColor
  140. // 时间范围选择器输入框字体大小
  141. el.style.fontSize = fontSize + 'px'
  142. })
  143. }
  144. // 时间选择器图标
  145. const timePickerIcon = timePickerEl.querySelector('.el-input__icon')
  146. if (timePickerIcon) {
  147. timePickerIcon.style.width = fontSize + 'px'
  148. timePickerIcon.style.fontSize = fontSize + 'px'
  149. }
  150. })
  151. },
  152. // 组件联动
  153. changeValue (val) {
  154. // 判断如果val是数组,需要将它转成字符串
  155. if (Array.isArray(val)) {
  156. val = val.join(',')
  157. }
  158. this.linkage({ [this.config.code]: val })
  159. },
  160. focusEvent () {
  161. this.$nextTick(() => {
  162. const { code } = this.innerConfig
  163. const { bgColor, fontColor, hoverFontColor, hoverBgColor, selectedFontColor, rangeBgColor, inputBgColor } = this.innerConfig.customize.dropDownBox
  164. const timePickerPopper = document.querySelector(`.date-picker-popper-${code}`)
  165. if (timePickerPopper) {
  166. // 去除边框
  167. timePickerPopper.style.border = 'none'
  168. // 确保下拉项的箭头颜色与下拉框的背景颜色保持一致
  169. timePickerPopper.style.color = bgColor
  170. }
  171. // 下拉项元素
  172. const pickerDropdownPanleContent = document.querySelector(`.date-picker-popper-${code}`)
  173. if (pickerDropdownPanleContent) {
  174. // 文字颜色
  175. pickerDropdownPanleContent.style.color = fontColor
  176. // 背景颜色
  177. pickerDropdownPanleContent.style.backgroundColor = bgColor
  178. // 下拉项添加var变量
  179. const dropdown = pickerDropdownPanleContent.style
  180. dropdown.setProperty('--fontColor', fontColor)
  181. dropdown.setProperty('--hoverFontColor', hoverFontColor)
  182. dropdown.setProperty('--bgColor', bgColor)
  183. dropdown.setProperty('--inputBgColor', inputBgColor)
  184. dropdown.setProperty('--selectedFontColor', selectedFontColor)
  185. dropdown.setProperty('--hoverBgColor', hoverBgColor)
  186. dropdown.setProperty('--rangeBgColor', rangeBgColor)
  187. // 选中项字体颜色
  188. const selectedEl = pickerDropdownPanleContent.querySelector('.selected')
  189. if (selectedEl) {
  190. selectedEl.style.color = selectedFontColor
  191. }
  192. // 选择过的,需要将选中颜色重置
  193. const pickerItemEl = document.querySelectorAll(`.date-picker-popper-${code} .el-time-spinner__item`)
  194. pickerItemEl.forEach((el) => {
  195. el.style.color = fontColor
  196. })
  197. }
  198. })
  199. },
  200. mouseenter () {
  201. if (this.value) {
  202. setTimeout(() => {
  203. // 清空图标
  204. const timePickerCloseIcon = document.querySelector(`.date-picker-${this.innerConfig.code} .el-icon-circle-close`)
  205. if (timePickerCloseIcon) {
  206. timePickerCloseIcon.style.fontSize = this.innerConfig.customize.fontSize + 'px'
  207. }
  208. }, 25)
  209. }
  210. }
  211. }
  212. }
  213. </script>
  214. <style lang="scss">
  215. .basic-component-date-picker {
  216. color: '';
  217. // 清空图标
  218. .el-icon-circle-close {
  219. display: flex ;
  220. align-items: center ;
  221. }
  222. // 时间选择器
  223. .el-icon-time {
  224. display: flex ;
  225. align-items: center ;
  226. }
  227. .el-time-panel {
  228. border: none ;
  229. background-color: var(--bgColor) ;
  230. }
  231. // 选择日期 时间区域
  232. .el-date-picker__time-header {
  233. border-bottom: var(--bgColor) ;
  234. .el-input__inner {
  235. border: none ;
  236. // 添加一点阴影
  237. box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1) ;
  238. color: var(--fontColor) ;
  239. background-color: var(--inputBgColor) ;
  240. }
  241. }
  242. // 头部,修改文字颜色和图标颜色
  243. .el-date-picker__header {
  244. color: var(--fontColor) ;
  245. .el-date-picker__header-label {
  246. color: var(--fontColor) ;
  247. }
  248. // 左右箭头图标颜色
  249. .el-picker-panel__icon-btn {
  250. color: var(--fontColor) ;
  251. }
  252. }
  253. // datetimerange
  254. .el-date-range-picker__time-header {
  255. border-color: var(--fontColor);
  256. // 中间箭头图标颜色
  257. .el-icon-arrow-right {
  258. color: var(--fontColor) ;
  259. }
  260. // 时间选择器输入框
  261. .el-input__inner{
  262. border: none;
  263. color: var(--fontColor);
  264. // 添加一点阴影
  265. background-color: var(--inputBgColor) ;
  266. box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1) ;
  267. }
  268. }
  269. // datetimerange
  270. .el-picker-panel__content{
  271. .el-icon-d-arrow-left{
  272. color: var(--fontColor) ;
  273. &:after{
  274. color: var(--fontColor) ;
  275. }
  276. }
  277. .el-icon-arrow-left{
  278. color: var(--fontColor) ;
  279. &:after{
  280. color: var(--fontColor) ;
  281. }
  282. }
  283. .el-icon-d-arrow-right{
  284. color: var(--fontColor) ;
  285. &:after{
  286. color: var(--fontColor) ;
  287. }
  288. }
  289. .el-icon-arrow-right{
  290. color: var(--fontColor) ;
  291. &:after{
  292. color: var(--fontColor) ;
  293. }
  294. }
  295. }
  296. .el-date-range-picker__content.is-left{
  297. border-color: var(--fontColor) ;
  298. }
  299. .el-date-table{
  300. th{
  301. border-color: var(--fontColor) ;
  302. }
  303. td{
  304. div{
  305. color: var(--fontColor) ;
  306. &:hover{
  307. color: var(--hoverFontColor) ;
  308. }
  309. }
  310. }
  311. }
  312. // 范围选择器背景颜色
  313. .in-range {
  314. div {
  315. // 下拉范围选中背景颜色
  316. background-color: var(--rangeBgColor) !important;
  317. }
  318. }
  319. .today {
  320. span {
  321. color: var(--selectedFontColor) !important;
  322. }
  323. }
  324. .el-time-panel__content::before {
  325. content: "";
  326. top: 50%;
  327. position: absolute;
  328. margin-top: -15px;
  329. height: 32px;
  330. z-index: 1;
  331. left: 0;
  332. right: 0;
  333. box-sizing: border-box;
  334. padding-top: 6px;
  335. text-align: left;
  336. border-top: 1px solid var(--fontColor);
  337. border-bottom: 1px solid var(--fontColor);
  338. }
  339. // 脚部
  340. .el-picker-panel__footer {
  341. border-color: var(--fontColor);
  342. background-color: var(--bgColor) ;
  343. // 清空按钮
  344. .el-picker-panel__link-btn {
  345. span {
  346. color: var(--fontColor) ;
  347. }
  348. }
  349. // 确定按钮
  350. .el-button--default {
  351. border: none ;
  352. color: var(--fontColor) ;
  353. background-color: var(--bgColor) ;
  354. }
  355. .is-disabled {
  356. span {
  357. color: #999 ;
  358. }
  359. }
  360. }
  361. .el-time-spinner {
  362. margin-bottom: 0px ;
  363. .el-time-spinner__item {
  364. &:hover {
  365. color: var(--hoverFontColor) ;
  366. background-color: var(--hoverBgColor) ;
  367. }
  368. }
  369. .active {
  370. color: var(--selectedFontColor) ;
  371. &:hover {
  372. color: var(--selectedFontColor) ;
  373. background-color: transparent ;
  374. }
  375. }
  376. }
  377. .popper__arrow {
  378. bottom: -6px ;
  379. border-bottom-color: var(--bgColor) !important;
  380. border-top-color: var(--bgColor) !important;
  381. &::after {
  382. bottom: 0px ;
  383. border-bottom-color: var(--bgColor) !important;
  384. border-top-color: var(--bgColor) !important;
  385. }
  386. }
  387. .cancel {
  388. color: var(--fontColor) ;
  389. }
  390. .confirm {
  391. color: var(--selectedFontColor);
  392. }
  393. .el-time-panel__footer {
  394. border-top: 1px solid var(--fontColor) ;
  395. .cancel {
  396. span {
  397. color: var(--fontColor) ;
  398. }
  399. }
  400. // 确定按钮
  401. .confirm {
  402. border: none ;
  403. color: var(--fontColor) ;
  404. background-color: var(--bgColor) ;
  405. }
  406. }
  407. // 年选择器
  408. .el-year-table {
  409. a{
  410. color: var(--fontColor) ;
  411. &:hover{
  412. color: var(--hoverFontColor) ;
  413. }
  414. }
  415. }
  416. // 月选择器
  417. .el-month-table {
  418. a{
  419. color: var(--fontColor) ;
  420. &:hover{
  421. color: var(--hoverFontColor) ;
  422. }
  423. }
  424. }
  425. // 上月 下月 字体颜色置灰
  426. .prev-month{
  427. span{
  428. color: #999 !important;
  429. &:hover{
  430. color: var(--hoverFontColor) !important;
  431. }
  432. }
  433. }
  434. .next-month{
  435. span{
  436. color: #999 !important;
  437. &:hover{
  438. color: var(--hoverFontColor) !important;
  439. }
  440. }
  441. }
  442. }
  443. </style>
  444. <style lang="scss" scoped>
  445. .basic-component-date-picker {
  446. width: 100% !important;
  447. height: 100% !important;
  448. // 范围时间选择器连接符
  449. ::v-deep .el-range-separator {
  450. display: flex !important;
  451. align-items: center !important;
  452. }
  453. .el-input--mini ::v-deep .el-input__inner {
  454. height: 100% !important;
  455. line-height: 100% !important;
  456. }
  457. .el-tag.el-tag--info {
  458. color: var(--bs-el-text) !important;
  459. }
  460. }
  461. ::v-deep .el-input__inner {
  462. height: 100% !important;
  463. line-height: 100% !important;
  464. }
  465. ::v-deep .el-range-input{
  466. width: 45% !important;
  467. }
  468. </style>