CustomizeColumns.vue 21 KB

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