CustomizeColumns.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. <script setup lang="ts">
  2. import { VueDraggable } from 'vue-draggable-plus'
  3. import { useRoute } from 'vue-router'
  4. const route = useRoute()
  5. const dialogVisible = ref(false)
  6. // search筛选的字段
  7. const searchColumn = ref('')
  8. // search筛选的options
  9. const searchOptions: any = ref()
  10. // 右侧箭头消失所需要translateX的值
  11. const rightArrowHideDistance = ref(0)
  12. // 控制tab栏的左右切换箭头
  13. const handleTabArrow = () => {
  14. const parentElement: HTMLElement | null = document.querySelector('.left-all-columns')
  15. if (!parentElement) return
  16. // 左侧切换箭头
  17. const leftArrow: HTMLElement | null = parentElement.querySelector('.el-tabs__nav-prev')
  18. // 右侧切换箭头
  19. const rightArrow: HTMLElement | null = parentElement.querySelector('.el-tabs__nav-next')
  20. const targetObserverElement = parentElement.querySelector('.el-tabs__nav')
  21. if (!targetObserverElement || !leftArrow || !rightArrow) return
  22. // 创建一个函数来获取 translateX
  23. const getTranslateX = () => {
  24. const style = window.getComputedStyle(targetObserverElement)
  25. const matrix = style.transform
  26. if (matrix !== 'none' && matrix) {
  27. // 提取 matrix 中的 translateX 值
  28. const values = matrix.match(/matrix\(([^)]+)\)/)?.[1].split(', ')
  29. if (!values) return 0
  30. const translateX = parseFloat(values[4])
  31. return translateX
  32. }
  33. return 0 // 如果没有 transform 或 translateX,默认返回 0
  34. }
  35. // 检查并更新箭头显示状态
  36. const updateArrowVisibility = () => {
  37. const translateX = getTranslateX()
  38. if (translateX === 0) {
  39. leftArrow.style.display = 'none'
  40. } else {
  41. leftArrow.style.display = 'inline-block'
  42. }
  43. if (translateX === rightArrowHideDistance.value) {
  44. rightArrow.style.display = 'none'
  45. } else {
  46. rightArrow.style.display = 'inline-block'
  47. }
  48. }
  49. // 监听 transitionend 事件,等待动画结束后再获取 translateX 值
  50. targetObserverElement.addEventListener('transitionend', (event: any) => {
  51. if (event.propertyName === 'transform') {
  52. // 只有 transform 动画结束时才触发
  53. updateArrowVisibility()
  54. }
  55. })
  56. // 初次运行时手动检查一次
  57. updateArrowVisibility()
  58. }
  59. // 筛选选中时滚动到对应的元素
  60. const handleDocumentClick = (event: any) => {
  61. if (!scrollTargetElement.value.contains(event.target)) {
  62. scrollTargetElement.value.className = scrollTargetElement.value.className.replace(
  63. 'search-select-item',
  64. ''
  65. )
  66. scrollTargetElement.value = null
  67. document.removeEventListener('click', handleDocumentClick)
  68. }
  69. }
  70. const scrollTargetElement = ref()
  71. const scrollToItem = (itemId: string) => {
  72. if (activeName.value !== 'All') {
  73. activeName.value = 'All'
  74. }
  75. setTimeout(() => {
  76. // 重置
  77. if (scrollTargetElement.value) {
  78. scrollTargetElement.value.className = scrollTargetElement.value.className.replace(
  79. 'search-select-item',
  80. ''
  81. )
  82. }
  83. // 获取目标元素
  84. scrollTargetElement.value = document.querySelector(`[data-field='${itemId}']`)
  85. if (scrollTargetElement.value) {
  86. // 使用 scrollIntoView 滚动到该元素
  87. scrollTargetElement.value.scrollIntoView({ behavior: 'smooth', block: 'center' })
  88. scrollTargetElement.value.className += ' search-select-item'
  89. // 或者使用自定义滚动
  90. // const container = this.$refs.dataContainer
  91. // container.scrollTop = targetElement.offsetTop - container.offsetTop
  92. document.addEventListener('click', handleDocumentClick)
  93. setTimeout(() => {
  94. searchColumn.value = ''
  95. }, 600)
  96. }
  97. }, 100)
  98. }
  99. // 系统首次加载时,会有引导操作
  100. let firstLoad = ref()
  101. const step1 = ref()
  102. const open1 = ref(false)
  103. const isShowStep1 = ref(false)
  104. const step2 = ref()
  105. const open2 = ref(false)
  106. const isShowStep2 = ref(false)
  107. const handleCloseTour = (stepStr: string) => {
  108. if (stepStr === 'step1') {
  109. isShowStep1.value = false
  110. open1.value = false
  111. } else {
  112. isShowStep2.value = false
  113. open2.value = false
  114. }
  115. localStorage.setItem('firstLoadCustomizeColumns', 'true')
  116. // firstLoad = 'true'
  117. }
  118. // 左侧选中的tab
  119. const activeName = ref()
  120. // 分组列
  121. const groupColumns: any = ref([])
  122. // 所有数据
  123. const allDataCopy: any = ref()
  124. const loading = ref(false)
  125. // 获取数据
  126. const getData = async (reset?: string) => {
  127. loading.value = true
  128. let paramsData: any = { ...params.value.getData }
  129. if (reset === 'yes') {
  130. paramsData.reset = 'yes'
  131. }
  132. await $api.getTableSettingColumns(paramsData).then((res: any) => {
  133. if (res.code === 200) {
  134. // allDataCopy就是所有的数据
  135. allDataCopy.value = res.data.GroupColumnsAll
  136. groupColumns.value = res.data.GroupColumnsLeft
  137. activeName.value = allDataCopy.value?.[0]?.name
  138. searchOptions.value = res.data.GroupColumnsLeft?.[0]?.children
  139. // 右侧选中的数据
  140. selectColumns.value = res.data.GroupColumnsRight
  141. nextTick(() => {
  142. handleTabArrow()
  143. // 八秒后关闭引导
  144. if (!firstLoad.value) {
  145. setTimeout(() => {
  146. handleCloseTour('step1')
  147. handleCloseTour('step2')
  148. }, 8000)
  149. }
  150. })
  151. }
  152. })
  153. loading.value = false
  154. }
  155. const params = ref()
  156. const tipsString = ref('')
  157. // rightDistance是右侧箭头消失所需要translateX的值
  158. const openDialog = async (paramsData: Object, rightDistance: number, tips: string) => {
  159. firstLoad.value = localStorage.getItem('firstLoadCustomizeColumns')
  160. params.value = paramsData
  161. tipsString.value = tips
  162. dialogVisible.value = true
  163. await getData()
  164. rightArrowHideDistance.value = rightDistance
  165. nextTick(() => {
  166. if (!firstLoad.value) {
  167. open1.value = true
  168. isShowStep1.value = true
  169. open2.value = true
  170. isShowStep2.value = true
  171. }
  172. })
  173. }
  174. const selectColumns: any = ref([])
  175. // 左侧Icon的显隐
  176. const hoverAllIcon = ref('')
  177. // 右侧Icon的显隐
  178. const hoverSelectIcon = ref('')
  179. const handleAddSelect = (item: any) => {
  180. groupColumns.value.forEach((groupItem: any) => {
  181. groupItem.children.forEach((child: any, index: number) => {
  182. if (child.field === item.field) {
  183. groupItem.children.splice(index, 1)
  184. }
  185. })
  186. })
  187. selectColumns.value.push(item)
  188. }
  189. // 从左侧拖拽到右侧时,删除其他分组中相同的数据
  190. const handleLeftRemove = (e: any) => {
  191. if (e.to === e.from) return
  192. const curItem = e.data
  193. groupColumns.value.forEach((groupItem: any) => {
  194. groupItem.children.forEach((child: any, index: number) => {
  195. if (child.field === curItem.field) {
  196. groupItem.children.splice(index, 1)
  197. }
  198. })
  199. })
  200. }
  201. // 从右侧拖拽到左侧时,左侧根据分组添加数据
  202. const handleRightRemove = (e: any) => {
  203. if (e.to === e.from) return
  204. const curItem = e.data
  205. // 获取当前移动项移入到了那一组
  206. const curGroup = groupColumns.value.find((item: any) => {
  207. return item.name == activeName.value
  208. })
  209. // 获取当前项应该对应哪一组
  210. const originalGroup = allDataCopy.value.find((item: any) => {
  211. if (item.name === 'All') {
  212. return false
  213. }
  214. const index = item.children.findIndex((child: any) => {
  215. return child.field === curItem.field
  216. })
  217. return index !== -1
  218. })
  219. if (curGroup.name !== originalGroup?.name && curGroup.name !== 'All') {
  220. // 从当前分组中删除移入的数据
  221. curGroup.children.forEach((item: any, index: number) => {
  222. item.field === curItem.field && curGroup.children.splice(index, 1)
  223. })
  224. // 在对应分组中添加移入的数据
  225. groupColumns.value.forEach((item: any) => {
  226. item.name === originalGroup?.name && item.children.push(curItem)
  227. })
  228. // 添加到All分组里
  229. groupColumns.value[0].children.push(curItem)
  230. } else if (curGroup.name === 'All') {
  231. // 在对应分组中添加移入的数据
  232. groupColumns.value.forEach((item: any) => {
  233. item.name === originalGroup?.name && item.children.push(curItem)
  234. })
  235. } else if (curGroup.name === originalGroup?.name) {
  236. groupColumns.value[0].children.push(curItem)
  237. }
  238. }
  239. // 点击右侧的减号删除选中的列,并添加到左侧
  240. const handleDeleteSelect = (curItem: any) => {
  241. selectColumns.value.forEach((item: any, index: number) => {
  242. if (item.field === curItem.field) {
  243. selectColumns.value.splice(index, 1)
  244. }
  245. })
  246. // 获取当前项应该对应哪一组
  247. const originalGroup = allDataCopy.value.find((item: any) => {
  248. if (item.name === 'All') {
  249. return false
  250. }
  251. const index = item.children.findIndex((child: any) => {
  252. return child.field === curItem.field
  253. })
  254. return index !== -1
  255. })
  256. // 在对应分组中添加移入的数据
  257. groupColumns.value.forEach((item: any) => {
  258. item.name === originalGroup?.name && item.children.push(curItem)
  259. })
  260. // 添加到All分组里
  261. groupColumns.value[0].children.push(curItem)
  262. }
  263. const handleMoveUpSelect = (item: any) => {
  264. const index = selectColumns.value.findIndex((i: any) => i.field === item.field)
  265. if (index === 0) return
  266. const temp = selectColumns.value[index]
  267. selectColumns.value[index] = selectColumns.value[index - 1]
  268. selectColumns.value[index - 1] = temp
  269. }
  270. const handleMoveDownSelect = (item: any) => {
  271. const index = selectColumns.value.findIndex((i: any) => i.field === item.field)
  272. if (index === selectColumns.value.length - 1) return
  273. const temp = selectColumns.value[index]
  274. selectColumns.value[index] = selectColumns.value[index + 1]
  275. selectColumns.value[index + 1] = temp
  276. }
  277. const emits = defineEmits<{
  278. customize: []
  279. reset: []
  280. }>()
  281. const handleReset = () => {
  282. getData('yes')
  283. }
  284. const handleApply = () => {
  285. const columnsList = selectColumns.value.map((item: any) => {
  286. return item.ids
  287. })
  288. $api
  289. .saveTableSettingColumns({
  290. ...params.value.saveData,
  291. ids: columnsList
  292. })
  293. .then((res: any) => {
  294. if (res.code === 200) {
  295. // ElMessage.success('Save successfully')
  296. emits('customize')
  297. dialogVisible.value = false
  298. }
  299. })
  300. }
  301. const clearData = () => {
  302. open1.value = false
  303. open2.value = false
  304. activeName.value = ''
  305. groupColumns.value = []
  306. selectColumns.value = []
  307. searchColumn.value = ''
  308. }
  309. defineExpose({
  310. openDialog
  311. })
  312. </script>
  313. <template>
  314. <el-dialog
  315. class="customize-columns"
  316. v-model="dialogVisible"
  317. :width="1000"
  318. title="Customize Columns"
  319. @close="clearData"
  320. >
  321. <div class="search-header">
  322. <div class="search-input" ref="searchRef">
  323. <el-select
  324. v-model="searchColumn"
  325. @change="scrollToItem"
  326. filterable
  327. placeholder="Search columns you preffered"
  328. >
  329. <template #prefix>
  330. <span class="font_family icon-icon_search_b"></span>
  331. </template>
  332. <el-option
  333. v-for="item in searchOptions"
  334. :key="item.field"
  335. :label="item.label"
  336. :value="item.field"
  337. />
  338. </el-select>
  339. </div>
  340. <div class="tips">
  341. <span style="font-size: 16px">* </span>
  342. <span>{{ tipsString }}</span>
  343. </div>
  344. </div>
  345. <div class="draggable-list">
  346. <div class="left-all-columns" v-vloading="loading">
  347. <div class="tabs">
  348. <el-tabs v-model="activeName">
  349. <el-tab-pane
  350. v-for="groupItem in groupColumns"
  351. :key="groupItem.name"
  352. :label="groupItem.name"
  353. :name="groupItem.name"
  354. >
  355. <VueDraggable
  356. v-model="groupItem.children"
  357. class="column-list"
  358. ghost-class="ghost-column"
  359. :forceFallback="true"
  360. fallbackClass="fallback-class"
  361. group="customizeColumns"
  362. item-key="field"
  363. @end="handleLeftRemove"
  364. >
  365. <template v-for="(item, index) in groupItem.children" :key="item.field">
  366. <div
  367. :data-field="item.field"
  368. class="column-item"
  369. @mouseenter="hoverAllIcon = item.field"
  370. @mouseleave="hoverAllIcon = ''"
  371. >
  372. <span class="font_family icon-icon_dragsort__b draggable-icon"></span>
  373. <span class="title">{{ item.label }}</span>
  374. <span
  375. ref="step1"
  376. v-if="hoverAllIcon === item.field || (index === 0 && isShowStep1)"
  377. class="font_family icon-icon_add_b move-icon"
  378. @click="handleAddSelect(item)"
  379. ></span>
  380. </div>
  381. </template>
  382. </VueDraggable>
  383. </el-tab-pane>
  384. </el-tabs>
  385. </div>
  386. </div>
  387. <div class="right-select-columns">
  388. <div class="title">
  389. Selected columns on your
  390. {{ route.path.includes('booking') ? 'booking' : 'shipment' }} list
  391. </div>
  392. <VueDraggable
  393. v-vloading="loading"
  394. v-model="selectColumns"
  395. class="column-list"
  396. ghost-class="ghost-column"
  397. :forceFallback="true"
  398. fallback-class="fallback-class"
  399. group="customizeColumns"
  400. item-key="field"
  401. @end="handleRightRemove"
  402. >
  403. <template v-for="(item, index) in selectColumns" :key="item.field">
  404. <div
  405. class="column-item"
  406. @mouseenter="hoverSelectIcon = item.field"
  407. @mouseleave="hoverSelectIcon = ''"
  408. >
  409. <span
  410. class="font_family icon-icon_dragsort__b draggable-icon"
  411. style="font-size: 16px"
  412. ></span>
  413. <span class="title">{{ item.label }}</span>
  414. <span
  415. v-if="hoverSelectIcon === item.field || (index === 0 && isShowStep2)"
  416. class="font_family icon-icon_moveup_b move-icon"
  417. @click="handleMoveUpSelect(item)"
  418. ></span>
  419. <span
  420. v-if="hoverSelectIcon === item.field || (index === 0 && isShowStep2)"
  421. class="font_family icon-icon_movedown_b move-icon"
  422. @click="handleMoveDownSelect(item)"
  423. ></span>
  424. <span
  425. ref="step2"
  426. v-if="hoverSelectIcon === item.field || (index === 0 && isShowStep2)"
  427. class="font_family icon-icon_reduce_b move-icon"
  428. @click="handleDeleteSelect(item)"
  429. ></span>
  430. </div>
  431. </template>
  432. </VueDraggable>
  433. </div>
  434. </div>
  435. <template #footer>
  436. <el-button
  437. type="default"
  438. style="height: 40px; padding: 8px 40px"
  439. @click="dialogVisible = false"
  440. >Cancel</el-button
  441. >
  442. <el-button type="default" style="height: 40px; padding: 8px 20px" @click="handleReset"
  443. >Reset to default</el-button
  444. >
  445. <el-button
  446. class="el-button--dark"
  447. style="height: 40px; padding: 8px 40px"
  448. @click="handleApply"
  449. >
  450. Apply
  451. </el-button>
  452. </template>
  453. <el-tour
  454. :target-area-clickable="false"
  455. class="step1-tour"
  456. v-model="open1"
  457. :mask="false"
  458. type="primary"
  459. v-if="step1?.[0]"
  460. >
  461. <el-tour-step :show-close="false" :target="step1?.[0]">
  462. <template #default>
  463. <div class="description">
  464. <span>Drag</span> items to the right group or click the "<span>Add</span>" icon to add
  465. columns to the {{ route.path.includes('booking') ? 'booking' : 'shipment' }} list.
  466. </div>
  467. <div class="got-it-text" @click="handleCloseTour('step1')">Got it</div>
  468. </template>
  469. </el-tour-step>
  470. </el-tour>
  471. <el-tour
  472. :target-area-clickable="false"
  473. class="step2-tour"
  474. v-model="open2"
  475. type="primary"
  476. :mask="false"
  477. v-if="step2?.[0]"
  478. >
  479. <el-tour-step :show-close="false" :target="step2?.[0]">
  480. <template #default>
  481. <div class="description">
  482. <span>Drag</span> items to the left group or click the "<span>Remove</span>" icon to
  483. delete columns from the
  484. {{ route.path.includes('booking') ? 'booking' : 'shipment' }} list.
  485. </div>
  486. <div class="description">
  487. <span>Drag</span> items up or down to reorder the
  488. {{ route.path.includes('booking') ? 'booking' : 'shipment' }} list, or use the "<span
  489. >Move up</span
  490. >" and "<span>Move down</span>" icons.
  491. </div>
  492. <div class="got-it-text" @click="handleCloseTour('step2')">Got it</div>
  493. </template>
  494. </el-tour-step>
  495. </el-tour>
  496. </el-dialog>
  497. </template>
  498. <style lang="scss">
  499. .customize-columns {
  500. .search-header {
  501. display: flex;
  502. justify-content: space-between;
  503. align-items: center;
  504. gap: 8px;
  505. padding: 10px 0;
  506. .search-input {
  507. width: 50%;
  508. padding-right: 16px;
  509. }
  510. .tips {
  511. display: flex;
  512. align-items: flex-start;
  513. gap: 3px;
  514. width: 50%;
  515. padding-left: 5px;
  516. vertical-align: middle;
  517. span {
  518. font-size: 12px;
  519. color: var(--color-neutral-2);
  520. }
  521. }
  522. }
  523. .draggable-list {
  524. display: flex;
  525. user-select: none;
  526. gap: 8px;
  527. }
  528. }
  529. .right-select-columns,
  530. .left-all-columns {
  531. width: 50%;
  532. .column-list {
  533. height: 400px;
  534. overflow: auto;
  535. .column-item {
  536. display: flex;
  537. align-items: center;
  538. height: 40px;
  539. margin-bottom: 5px;
  540. padding-left: 12px;
  541. border: 1px solid var(--color-border);
  542. border-radius: 6px;
  543. background-color: var(--color-customize-column-item-bg);
  544. &:hover {
  545. background-color: var(--color-customize-column-item-hover-bg);
  546. box-shadow: 4px 4px 32px 0px rgba(0, 0, 0, 0.1);
  547. }
  548. & > .title {
  549. flex: 1;
  550. }
  551. span.draggable-icon {
  552. margin-right: 12px;
  553. color: var(--color-customize-column-item-drag-icon);
  554. }
  555. .font_family {
  556. font-size: 16px;
  557. cursor: pointer;
  558. margin-right: 16px;
  559. }
  560. .move-icon {
  561. &:hover {
  562. color: var(--color-theme);
  563. }
  564. }
  565. }
  566. }
  567. .ghost-column {
  568. cursor: move !important;
  569. span {
  570. opacity: 0;
  571. }
  572. border: 1px dashed var(--color-customize-column-item-drag-border) !important;
  573. background-color: var(--color-customize-column-item-drag-bg) !important;
  574. box-shadow: none !important;
  575. }
  576. .fallback-class {
  577. opacity: 1 !important;
  578. background-color: var(--color-customize-column-item-hover-bg) !important;
  579. cursor: move !important;
  580. }
  581. }
  582. .left-all-columns {
  583. border: 1px solid var(--color-border);
  584. border-radius: 12px;
  585. .tabs {
  586. position: relative;
  587. height: 100%;
  588. .el-tabs {
  589. .el-tabs__header {
  590. margin-bottom: 0px;
  591. border-bottom: 1px solid var(--color-customize-column-tabs-header-border);
  592. }
  593. .el-tabs__item {
  594. padding: 10px;
  595. }
  596. }
  597. }
  598. .column-list {
  599. padding: 8px;
  600. padding-bottom: 0px;
  601. }
  602. .search-select-item {
  603. border: 1px solid var(--color-theme) !important;
  604. box-shadow: 2px 2px 12px 0px rgba(237, 109, 0, 0.2);
  605. .title {
  606. color: var(--color-theme) !important;
  607. }
  608. }
  609. }
  610. .right-select-columns {
  611. background-color: var(--color-customize-column-right-section-bg);
  612. padding-top: 0;
  613. border: 1px dashed var(--color-customize-column-right-section-border);
  614. border-radius: 12px;
  615. & > .title {
  616. height: 40px;
  617. padding: 8px;
  618. line-height: 24px;
  619. font-size: 16px;
  620. font-weight: 700;
  621. }
  622. .column-list {
  623. padding: 8px;
  624. padding-bottom: 0px;
  625. }
  626. }
  627. </style>
  628. <style lang="scss">
  629. .left-all-columns {
  630. .el-tabs__nav-prev,
  631. .el-tabs__nav-next {
  632. height: 40px;
  633. width: 40px;
  634. }
  635. .el-tabs__item {
  636. color: var(--color-neutral-1);
  637. font-weight: 400;
  638. font-size: 14px;
  639. }
  640. .el-tabs__item.is-active,
  641. .el-tabs__item:hover {
  642. font-weight: 700;
  643. font-size: 14px;
  644. color: var(--color-neutral-1);
  645. }
  646. .el-tabs__nav-prev {
  647. border-right: 1px solid var(--color-border);
  648. box-shadow: 2px 0px 12px rgba(0, 0, 0, 0.3);
  649. // .el-icon {
  650. // color: white;
  651. // }
  652. /* 左侧阴影 */
  653. }
  654. .el-tabs__nav-next {
  655. border-left: 1px solid var(--color-border);
  656. box-shadow: -2px 0px 12px rgba(0, 0, 0, 0.2);
  657. /* 左侧阴影 */
  658. }
  659. .el-tabs__nav-wrap {
  660. padding: 0 40px;
  661. }
  662. .el-tabs__item.is-active,
  663. .el-tabs__item:hover {
  664. color: var(--color-theme);
  665. }
  666. .el-tabs__active-bar {
  667. background-color: var(--color-theme);
  668. }
  669. }
  670. .search-header {
  671. & > .search-input {
  672. .el-select {
  673. width: 100%;
  674. .el-select__wrapper {
  675. border-radius: 20px;
  676. }
  677. }
  678. }
  679. }
  680. </style>
  681. <style lang="scss">
  682. .step1-tour {
  683. .el-tour__content {
  684. width: 240px;
  685. height: 124px;
  686. background-color: var(--color-theme);
  687. z-index: 9999 !important;
  688. }
  689. .el-tour__arrow {
  690. background-color: var(--color-theme);
  691. }
  692. .el-tour__footer {
  693. display: none;
  694. }
  695. }
  696. .step2-tour {
  697. .el-tour__content {
  698. width: 240px;
  699. height: 200px;
  700. background-color: var(--color-theme);
  701. z-index: 9999 !important;
  702. }
  703. .el-tour__arrow {
  704. background-color: var(--color-theme);
  705. }
  706. .el-tour__footer {
  707. display: none;
  708. }
  709. }
  710. .step1-tour,
  711. .step2-tour {
  712. .el-tour__header {
  713. display: none;
  714. }
  715. .description {
  716. margin-bottom: 16px;
  717. color: white;
  718. line-height: 22px;
  719. span {
  720. color: white;
  721. font-weight: 600;
  722. }
  723. }
  724. .got-it-text {
  725. float: right;
  726. color: white;
  727. font-weight: 700;
  728. cursor: pointer;
  729. }
  730. }
  731. </style>