当前位置:   article > 正文

时间刻度组件_范围标记 时间刻度组件

范围标记 时间刻度组件

最近遇到一个类似钉钉时刻的需求,如图所示:

代码:

  1. <template>
  2. <!-- <van-pull-refresh v-model="refreshLoading" @refresh="onRefresh"> -->
  3. <div class="sign-wrap">
  4. <div class="meeting-sign-wraper" :class="{ isMember: !memberFlag }">
  5. <!-- <div class="close_box" @click="close"><img src="../img/x.svg" alt="" /></div> -->
  6. <div class="screen-guide" @click="jump">
  7. <span>投屏指引</span>
  8. <img src="../img/箭头.svg" alt="" />
  9. </div>
  10. <div v-if="waitSignData && waitSignData.beginTime" class="sign-top">
  11. <div v-if="memberFlag" class="meeting-name">{{ waitSignData.title || '会议室签到' }}</div>
  12. <div class="meeting-time">
  13. <div class="time left">
  14. <div>{{ momentTime(waitSignData.beginTime) }}</div>
  15. <p>{{ todayDate }}</p>
  16. </div>
  17. <div class="center">
  18. <div class="line"></div>
  19. <div class="middle">{{ diffTime(waitSignData) }}</div>
  20. <div class="line"></div>
  21. </div>
  22. <div class="time right">
  23. <div>{{ momentTime(waitSignData.endTime) }}</div>
  24. <p>{{ todayDate }}</p>
  25. </div>
  26. </div>
  27. <div class="meeting-users" v-if="waitSignData.members && memberFlag">
  28. <span>参会人:</span>
  29. <span v-for="(item, index) in membersList" :key="index">
  30. <span>{{ item }}</span>
  31. <span v-if="index != membersList.length - 1"></span>
  32. </span>
  33. <span v-if="waitSignData.members">{{
  34. waitSignData.members.length > 0 ? `等${waitSignData.members.length}人` : `无`
  35. }}</span>
  36. </div>
  37. <div class="meeting-id">
  38. <!-- <span>会议ID:8007157101</span> -->
  39. <span>会议室:{{ waitSignData.room }}</span>
  40. </div>
  41. <div class="btn-box">
  42. <div v-if="memberFlag" class="btn" :class="{ active: isActive }" @click="signClick">
  43. {{ isActiveTxt }}
  44. </div>
  45. <div v-if="!memberFlag" class="no-sign">
  46. <img src="../img/提示.svg" alt="" />
  47. <span>您不是本次会议参会人,无法签到!</span>
  48. </div>
  49. </div>
  50. </div>
  51. <div v-if="!(waitSignData && waitSignData.beginTime)">
  52. <div v-if="!signOut" class="no-waitSign">
  53. <img src="../img/白色提示.svg" alt="" />
  54. <span>暂无预约</span>
  55. </div>
  56. </div>
  57. <div class="sign-content" ref="signContent">
  58. <img v-show="btnFlag" class="img-line" src="../img/线.svg" alt="" @click="handleClick" />
  59. <img v-show="!btnFlag" class="img-down" src="../img/下拉.svg" alt="" @click="handleClick" />
  60. <div class="sign-content-wrap" ref="contentWrap">
  61. <ul class="scroll-box">
  62. <li>
  63. <div class="date">{{ todayDate }}</div>
  64. <div class="time-kedu-box">
  65. <div class="m-s-header-container scroll-wrapper">
  66. <table
  67. class="transform-element scroll-content"
  68. :style="{
  69. transform: `translateX(${translateX}px)`,
  70. width: itemWidth * timeList.length + leftPadding + 'px',
  71. }"
  72. >
  73. <tr>
  74. <th :style="{ width: 0 + 'px' }"></th>
  75. <th
  76. :style="{ width: itemWidth + 'px' }"
  77. v-for="(item, index) in timeList"
  78. :key="item.name"
  79. >
  80. <div class="header-item">
  81. {{ item.name }}
  82. </div>
  83. </th>
  84. </tr>
  85. <div
  86. v-if="isToday"
  87. :style="{
  88. left: timeLeftValue + 'px',
  89. }"
  90. class="current-time-line"
  91. ></div>
  92. <div
  93. v-for="(lis, index) in timestampList"
  94. :key="index"
  95. :style="{
  96. width: positionWidth(lis) + 'px',
  97. left: timeToPosition(momentTime(lis.beginTime)) + 'px',
  98. right: 0 - timeToPosition(momentTime(lis.endTime)) + 'px',
  99. }"
  100. class="m-s-activity overflow-hidden"
  101. ></div>
  102. </table>
  103. <!-- <button
  104. @click.stop="translateHandle(1, $event)"
  105. class="translate-handle translate-left"
  106. >
  107. <i class="el-icon-arrow-left"></i>
  108. </button>
  109. <button
  110. @click.stop="translateHandle(2, $event)"
  111. class="translate-handle translate-right"
  112. >
  113. <i class="el-icon-arrow-right"></i>
  114. </button> -->
  115. </div>
  116. </div>
  117. <div class="time-content">
  118. <div class="content-box" v-for="(item, index) in meetingData" :key="index">
  119. <div class="content-top">
  120. <div class="time left">{{ momentTime(item.beginTime) }}</div>
  121. <div class="line"></div>
  122. <div class="middle">{{ diffTime(item) }}</div>
  123. <div class="line"></div>
  124. <div class="time right">{{ momentTime(item.endTime) }}</div>
  125. </div>
  126. <div class="content-bottom">
  127. 主持人:<span>{{ item.sponsorName }}</span>
  128. </div>
  129. </div>
  130. </div>
  131. </li>
  132. </ul>
  133. </div>
  134. </div>
  135. </div>
  136. </div>
  137. <!-- </van-pull-refresh> -->
  138. </template>
  139. <script>
  140. import moment from 'moment';
  141. import BScroll from '@better-scroll/core';
  142. import { meetingList, waitSign, meetingSign } from '../api';
  143. let currentTimer = null;
  144. import { closeWindow } from '@/utils/jsBridge';
  145. export default {
  146. props: {
  147. defaultDate: {
  148. type: String,
  149. default: moment().format('YYYY-MM-DD'),
  150. },
  151. },
  152. data() {
  153. return {
  154. btnFlag: true,
  155. memberFlag: true, // 是否为参会人
  156. signOut: false, // 已签退
  157. isActive: false, // 待签到
  158. isActiveTxt: '会议室签到',
  159. timeStart: 0,
  160. timeEnd: 24,
  161. itemWidth: 28 / 4, //会议时间间隔宽度
  162. translateX: 0, //横向滚动距离
  163. max_translateX: 0, //最大可滚动距离
  164. currentTimeLeftValue: 0,
  165. currentTime: '00:00',
  166. currentTimeValue: 0,
  167. activeDate: {}, //默认日期
  168. meetingData: [],
  169. waitSignData: {},
  170. todayDate: moment().format('YYYY/MM/DD'),
  171. roomCode: '',
  172. refreshLoading: false,
  173. scroll: ''
  174. };
  175. },
  176. watch: {
  177. defaultDate(val) {
  178. if (val) {
  179. this.activeDate = moment(val);
  180. }
  181. },
  182. meetingData() {
  183. this.$nextTick(() => {
  184. this.scroll.refresh()
  185. })
  186. }
  187. },
  188. created() {
  189. this.roomCode = this.getQueryString('roomCode');
  190. this.getCurrentTime();
  191. clearInterval(currentTimer);
  192. currentTimer = setInterval(this.getCurrentTime, 1e3 * 60);
  193. this.activeDate = this.defaultDate ? moment(this.defaultDate) : moment();
  194. },
  195. async mounted() {
  196. this.init();
  197. this.initScroll();
  198. this.initYZScroll();
  199. await this.waitSign();
  200. await this.meetingList();
  201. },
  202. beforeDestroy() {
  203. clearInterval(currentTimer);
  204. },
  205. computed: {
  206. timestampList() {
  207. let arrList = [];
  208. let mtList = [];
  209. let waitList = [];
  210. if (this.meetingData.length > 0) {
  211. mtList = this.meetingData.map((el) => {
  212. return {
  213. beginTime: el.beginTime,
  214. endTime: el.endTime,
  215. };
  216. });
  217. }
  218. if (this.waitSignData && this.waitSignData.beginTime) {
  219. waitList.push({
  220. beginTime: this.waitSignData.beginTime,
  221. endTime: this.waitSignData.endTime,
  222. });
  223. }
  224. return [...waitList ,...mtList];
  225. },
  226. membersList() {
  227. let arr = this.waitSignData.members || [];
  228. if (arr.length < 5) {
  229. return arr;
  230. }
  231. return arr.slice(0, 4);
  232. },
  233. timeDiff() {
  234. return (this.timeEnd - this.timeStart) * 4;
  235. },
  236. timeList() {
  237. const timeList = [];
  238. for (let i = 0; i < this.timeDiff; i++) {
  239. const item = {};
  240. if (i % 4 == 0) {
  241. // item.name = `${Math.floor(i / 4)}:00`;
  242. item.name = `${Math.floor(i / 4)}`;
  243. } else {
  244. item.name = `${Math.floor(i / 4)}:${(i % 4) * 15}`;
  245. }
  246. item.time = i / 4;
  247. timeList.push(item);
  248. }
  249. return timeList;
  250. },
  251. leftPadding() {
  252. return this.itemWidth;
  253. },
  254. isToday() {
  255. return moment().format('YYYY-MM-DD') === this.activeDate.format('YYYY-MM-DD');
  256. },
  257. isPast() {
  258. return (
  259. moment(this.activeDate.format('YYYY-MM-DD')).unix() <
  260. moment(moment().format('YYYY-MM-DD')).unix()
  261. );
  262. },
  263. maxWidth() {
  264. return this.itemWidth * this.timeList.length + this.leftPadding;
  265. },
  266. timeLeftValue() {
  267. return this.isToday
  268. ? this.currentTimeLeftValue
  269. : this.isPast
  270. ? this.maxWidth
  271. : this.leftPadding;
  272. },
  273. timeValue() {
  274. return this.isToday ? this.currentTimeValue : this.isPast ? this.timeList.length - 1 : -1;
  275. },
  276. },
  277. methods: {
  278. onRefresh() {
  279. Promise.all([this.meetingList(), this.waitSign()])
  280. .then((result) => (this.refreshLoading = false))
  281. .catch((e) => console.log(e));
  282. },
  283. close() {
  284. closeWindow();
  285. },
  286. userAgent() {
  287. const userAgent = window.navigator.userAgent.toLocaleLowerCase();
  288. if (!userAgent.includes('360teams')) {
  289. this.$router.push({ path: '/meetingSignWX', query: { roomCode: this.roomCode } });
  290. }
  291. },
  292. getQueryString(name) {
  293. var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
  294. var r = window.location.search.substr(1).match(reg);
  295. if (r != null) return unescape(decodeURI(r[2]));
  296. return null;
  297. },
  298. momentTime(time) {
  299. return moment(time).format('HH:mm');
  300. },
  301. diffTime(item) {
  302. let diffVal = moment(item.endTime).diff(moment(item.beginTime), 'minute');
  303. return `${Math.floor(diffVal / 60)}小时${diffVal % 60 || 0}分钟`;
  304. },
  305. // 已预约会议列表
  306. async meetingList() {
  307. let params = {
  308. roomCode: this.roomCode,
  309. };
  310. let res = await meetingList(params);
  311. let { code, data, msg } = res || {};
  312. if (code === 0) {
  313. this.meetingData = data;
  314. } else {
  315. this.meetingData = [];
  316. }
  317. },
  318. // 查询当前待签到的会议信息
  319. async waitSign() {
  320. let params = {
  321. roomCode: this.roomCode,
  322. };
  323. let res = await waitSign(params);
  324. let { code, data, msg } = res || {};
  325. if (code === 0) {
  326. this.waitSignData = data;
  327. this.isActive = this.waitSignData.checkStatus;
  328. this.memberFlag = this.waitSignData.memberFlag;
  329. if (this.waitSignData.checkStatus === 0) {
  330. this.isActiveTxt = '会议室签到';
  331. } else {
  332. this.isActiveTxt = '会议室签退';
  333. }
  334. } else {
  335. this.$toast.fail(msg);
  336. this.waitSignData = {};
  337. this.isActive = !this.isActive;
  338. // this.handleClick();
  339. }
  340. },
  341. initScroll() {
  342. let vm = this;
  343. this.$nextTick(() => {
  344. let bs = new BScroll('.scroll-wrapper', {
  345. startX: vm.translateX,
  346. click: true,
  347. scrollX: true,
  348. scrollY: false, // 忽略竖直方向的滚动
  349. eventPassthrough: 'vertical',
  350. bounce: {
  351. left: false,
  352. right: false,
  353. },
  354. });
  355. });
  356. },
  357. initYZScroll() {
  358. let vm = this;
  359. this.$nextTick(() => {
  360. this.scroll = new BScroll('.scroll-box', {
  361. probeType: 3,
  362. click: true,
  363. scrollX: false,
  364. scrollY: true,
  365. bounce: {
  366. top: false,
  367. bottom: false,
  368. },
  369. });
  370. });
  371. },
  372. handleClick() {
  373. this.btnFlag = !this.btnFlag;
  374. if (this.btnFlag) {
  375. if (this.$refs.signContent && this.$refs.contentWrap) {
  376. this.$refs.signContent.style.top = '44%';
  377. this.$refs.contentWrap.style.height = '360px';
  378. }
  379. } else {
  380. if (this.$refs.signContent && this.$refs.contentWrap) {
  381. this.$refs.signContent.style.top = '13%';
  382. this.$refs.contentWrap.style.height = '570px';
  383. }
  384. }
  385. },
  386. jump() {
  387. this.$router.push({ name: 'screenGuide' });
  388. },
  389. // 会议签到或签退
  390. async signClick() {
  391. if (!this.isActive) {
  392. let res = await meetingSign({
  393. roomCode: this.roomCode,
  394. id: this.waitSignData.id || '',
  395. sign: true,
  396. });
  397. let { code, data, msg } = res || {};
  398. if (code === 0) {
  399. this.isActive = !this.isActive;
  400. this.isActiveTxt = '会议室签退';
  401. this.$toast.success('已签到!');
  402. } else if (code === 12058) {
  403. // 未认证
  404. this.$toast.fail(msg);
  405. } else {
  406. this.$toast.fail(msg);
  407. this.meetingList();
  408. this.waitSign();
  409. }
  410. } else {
  411. this.$dialog
  412. .confirm({
  413. title: '',
  414. message: '是否确定释放本会议室?',
  415. })
  416. .then(async () => {
  417. let res = await meetingSign({
  418. roomCode: this.roomCode,
  419. id: this.waitSignData.id || '',
  420. sign: false,
  421. });
  422. let { code, data, msg } = res || {};
  423. if (code === 0) {
  424. this.waitSignData = {};
  425. // this.signOut = true;
  426. this.isActive = !this.isActive;
  427. this.isActiveTxt = '会议室签到';
  428. this.$toast.success('已签退!');
  429. // this.handleClick();
  430. } else if (code === 12058) {
  431. // 未认证
  432. this.$toast.fail(msg);
  433. } else {
  434. this.$toast.fail(msg);
  435. this.meetingList();
  436. this.waitSign();
  437. }
  438. })
  439. .catch(() => {});
  440. }
  441. },
  442. //左翻右翻操作
  443. translateHandle(type, e) {
  444. //内层宽度
  445. const INNER_WIDTH = this.maxWidth;
  446. //外层宽度
  447. const OUTER_WIDTH = e.target.parentNode.offsetWidth;
  448. // 步长
  449. const STEP = this.itemWidth * 4;
  450. //内外宽度差,最大可移动距离
  451. const MAX = INNER_WIDTH - OUTER_WIDTH;
  452. if (type == 1) {
  453. if (this.translateX < 0) {
  454. this.translateX +=
  455. this.translateX + STEP + this.leftPadding < 0 ? STEP : 0 - this.translateX;
  456. }
  457. } else {
  458. if (MAX + this.translateX > 0) {
  459. this.translateX -=
  460. MAX + this.translateX > STEP + this.leftPadding ? STEP : MAX + this.translateX;
  461. }
  462. }
  463. },
  464. init() {
  465. const outerWidth = document.querySelector('.m-s-header-container').offsetWidth;
  466. const innerWidth = document.querySelector(
  467. '.m-s-header-container .transform-element',
  468. ).offsetWidth;
  469. this.max_translateX = innerWidth > outerWidth ? innerWidth - outerWidth : 0;
  470. if (this.isToday) {
  471. let hour = new Date().getHours();
  472. let posit;
  473. if (hour <= 2) {
  474. this.translateX = 0;
  475. } else {
  476. posit = (hour - 2) * 4 * this.itemWidth;
  477. this.translateX = 0 - (this.max_translateX > posit ? posit : this.max_translateX);
  478. }
  479. } else {
  480. this.translateX =
  481. 0 -
  482. (this.max_translateX > this.itemWidth * 36 ? this.itemWidth * 36 : this.max_translateX);
  483. }
  484. },
  485. // 当前时间分割标记
  486. getCurrentTime() {
  487. const D = new Date();
  488. const NOW_HOURS = D.getHours();
  489. const NOW_MINUTES = D.getMinutes();
  490. this.currentTime = `${NOW_HOURS}:${NOW_MINUTES > 9 ? NOW_MINUTES : '0' + NOW_MINUTES}`;
  491. // 当前时间/15分钟所得数
  492. this.currentTimeValue = NOW_HOURS * 4 + Math.floor(NOW_MINUTES / 15);
  493. // 当前时间/15分钟*每一列的宽度
  494. this.currentTimeLeftValue = this.itemWidth * (NOW_HOURS * 4 + NOW_MINUTES / 15);
  495. },
  496. timeToPosition(time) {
  497. if (time) {
  498. const [H, M] = time.split(':');
  499. return (
  500. parseInt(H) * 4 * this.itemWidth + (parseInt(M) / 15) * this.itemWidth
  501. );
  502. }
  503. },
  504. positionWidth(item) {
  505. let diffVal = moment(item.endTime).diff(moment(item.beginTime), 'minute');
  506. let m = diffVal / 15 * this.itemWidth;
  507. return m;
  508. }
  509. },
  510. };
  511. </script>
  512. <style scoped lang="scss">
  513. .van-pull-refresh {
  514. height: 100%;
  515. }
  516. .sign-wrap {
  517. height: 100%;
  518. background: #ffffff;
  519. .meeting-sign-wraper {
  520. position: relative;
  521. height: 100%;
  522. padding: 0px 30px;
  523. padding-top: 35px;
  524. background: url('../img/蓝.svg') no-repeat;
  525. // background-size: 375px;
  526. background-size: contain;
  527. &.isMember {
  528. background: url('../img/灰.svg') no-repeat;
  529. background-size: contain;
  530. }
  531. .close_box {
  532. width: 40px;
  533. height: 26px;
  534. opacity: 0.6;
  535. background: rgba(255, 255, 255, 0);
  536. border: 1px solid #ffffff;
  537. border-radius: 14px;
  538. color: #ffffff;
  539. display: flex;
  540. align-items: center;
  541. justify-content: center;
  542. line-height: 26px;
  543. position: fixed;
  544. top: 10px;
  545. right: 10px;
  546. img {
  547. width: 9px;
  548. height: 9px;
  549. }
  550. }
  551. .screen-guide {
  552. width: 84px;
  553. height: 31px;
  554. background: #ff7d00;
  555. border-radius: 16px 0px 0px 16px;
  556. box-shadow: 0px 1px 6px 0px #e5b07e;
  557. position: fixed;
  558. top: 44%;
  559. right: -1px;
  560. z-index: 1000;
  561. display: flex;
  562. align-items: center;
  563. justify-content: center;
  564. cursor: pointer;
  565. span {
  566. font-size: 13px;
  567. font-family: PingFangSC, PingFangSC-Regular;
  568. font-weight: 400;
  569. color: #ffffff;
  570. line-height: 17px;
  571. margin-right: 5px;
  572. }
  573. img {
  574. width: 9px;
  575. height: 9px;
  576. }
  577. }
  578. .sign-top {
  579. .meeting-name {
  580. font-size: 19px;
  581. font-family: PingFangSC, PingFangSC-Semibold;
  582. font-weight: 600;
  583. color: #ffffff;
  584. line-height: 27px;
  585. margin-bottom: 12px;
  586. overflow: hidden;
  587. text-overflow: ellipsis;
  588. white-space: nowrap;
  589. }
  590. .meeting-time {
  591. display: flex;
  592. align-items: center;
  593. justify-content: space-between;
  594. .time {
  595. > div {
  596. font-size: 25px;
  597. font-family: DINAlternate, DINAlternate-Bold;
  598. font-weight: 700;
  599. color: #ffffff;
  600. line-height: 29px;
  601. }
  602. > p {
  603. opacity: 0.7;
  604. font-size: 12px;
  605. font-family: PingFangSC, PingFangSC-Regular;
  606. font-weight: 400;
  607. color: #ffffff;
  608. line-height: 17px;
  609. }
  610. &.left {
  611. margin-right: 17px;
  612. }
  613. &.right {
  614. margin-left: 17px;
  615. }
  616. }
  617. .center {
  618. display: flex;
  619. align-items: center;
  620. justify-content: center;
  621. }
  622. .line {
  623. width: 30px;
  624. height: 1px;
  625. background: #b0c5ff;
  626. margin: 0px 5px;
  627. }
  628. .middle {
  629. width: 80px;
  630. height: 23px;
  631. opacity: 0.6;
  632. background: #4273f6;
  633. border-radius: 3px;
  634. font-size: 12px;
  635. font-family: PingFangSC, PingFangSC-Regular;
  636. font-weight: 400;
  637. color: #ffffff;
  638. line-height: 17px;
  639. display: flex;
  640. align-items: center;
  641. justify-content: center;
  642. }
  643. }
  644. .meeting-users {
  645. font-size: 14px;
  646. font-family: PingFangSC, PingFangSC-Regular;
  647. font-weight: 400;
  648. color: #ffffff;
  649. line-height: 17px;
  650. margin-top: 12px;
  651. }
  652. .meeting-id {
  653. font-size: 14px;
  654. font-family: PingFangSC, PingFangSC-Regular;
  655. font-weight: 400;
  656. color: #ffffff;
  657. line-height: 17px;
  658. margin-top: 8px;
  659. }
  660. .btn-box {
  661. display: flex;
  662. align-items: center;
  663. justify-content: center;
  664. // margin-top: 15px;
  665. position: fixed;
  666. left: 50%;
  667. top: 30%;
  668. transform: translateX(-50%);
  669. .btn {
  670. width: 208px;
  671. height: 40px;
  672. background: #4273f6;
  673. border-radius: 22px;
  674. box-shadow: 0px 3px 5px 0px #0347e6;
  675. font-size: 16px;
  676. font-family: PingFangSC, PingFangSC-Regular;
  677. font-weight: 400;
  678. color: #ffffff;
  679. line-height: 16px;
  680. display: flex;
  681. align-items: center;
  682. justify-content: center;
  683. &.active {
  684. background: #ff7d00;
  685. box-shadow: 0px 3px 5px 0px #e5b07e;
  686. }
  687. }
  688. .no-sign {
  689. width: 268px;
  690. height: 32px;
  691. background: #ffffff;
  692. border-radius: 4px;
  693. font-size: 14px;
  694. font-family: PingFangSC, PingFangSC-Regular;
  695. font-weight: 400;
  696. color: #ff7d00;
  697. display: flex;
  698. align-items: center;
  699. justify-content: center;
  700. > img {
  701. width: 17px;
  702. margin-right: 7px;
  703. }
  704. }
  705. }
  706. }
  707. .no-waitSign {
  708. display: flex;
  709. align-items: center;
  710. justify-content: center;
  711. position: fixed;
  712. left: 50%;
  713. top: 20%;
  714. transform: translateX(-50%);
  715. > img {
  716. width: 17px;
  717. margin-right: 7px;
  718. }
  719. > span {
  720. font-size: 14px;
  721. font-family: PingFangSC, PingFangSC-Regular;
  722. font-weight: 400;
  723. color: #ffffff;
  724. }
  725. }
  726. .sign-content {
  727. position: fixed;
  728. top: 44%;
  729. left: 50%;
  730. transform: translateX(-50%);
  731. width: 343px;
  732. background: #ffffff;
  733. border-radius: 8px;
  734. box-shadow: 0px 2px 5px 0px #e6e6e6;
  735. transition: all 0.3s;
  736. > div {
  737. padding: 12px 20px;
  738. overflow: hidden;
  739. max-height: 586px;
  740. height: 360px;
  741. &::-webkit-scrollbar {
  742. display: none;
  743. }
  744. }
  745. > img {
  746. position: absolute;
  747. top: -8%;
  748. left: 50%;
  749. transform: translateX(-50%);
  750. z-index: 999;
  751. &.img-line {
  752. width: 28px;
  753. }
  754. &.img-down {
  755. width: 22px;
  756. }
  757. }
  758. ul {
  759. overflow: hidden;
  760. height: 100%;
  761. li {
  762. padding-bottom: 30px;
  763. .date {
  764. font-size: 15px;
  765. font-family: PingFangSC, PingFangSC-Medium;
  766. font-weight: 500;
  767. color: #5f6368;
  768. line-height: 20px;
  769. margin-bottom: 6px;
  770. }
  771. .time-kedu-box {
  772. display: flex;
  773. align-items: center;
  774. margin-bottom: 20px;
  775. overflow-x: auto;
  776. overflow-y: hidden;
  777. position: relative;
  778. height: 35px;
  779. &::-webkit-scrollbar {
  780. display: none;
  781. }
  782. .kedu-wrap {
  783. width: 29px;
  784. flex: 0 0 29px;
  785. margin-right: 2px;
  786. }
  787. }
  788. .time-content {
  789. .content-box {
  790. border-bottom: 1px solid #dedede;
  791. padding: 8px 10px;
  792. &:last-child {
  793. border-bottom: 0px;
  794. }
  795. .content-top {
  796. display: flex;
  797. align-items: center;
  798. justify-content: center;
  799. .time {
  800. font-size: 22px;
  801. font-family: DINAlternate, DINAlternate-Bold;
  802. font-weight: 700;
  803. color: #202124;
  804. line-height: 26px;
  805. &.left {
  806. margin-right: 17px;
  807. }
  808. &.right {
  809. margin-left: 10px;
  810. }
  811. }
  812. .line {
  813. width: 30px;
  814. height: 1px;
  815. background: #f0f0f0;
  816. margin: 0px 5px;
  817. }
  818. .middle {
  819. width: 82px;
  820. height: 23px;
  821. background: #f7f7f7;
  822. border-radius: 3px;
  823. font-size: 12px;
  824. font-family: PingFangSC, PingFangSC-Regular;
  825. font-weight: 400;
  826. color: #5f6368;
  827. line-height: 17px;
  828. display: flex;
  829. align-items: center;
  830. justify-content: center;
  831. }
  832. }
  833. .content-bottom {
  834. font-size: 12px;
  835. font-family: PingFangSC, PingFangSC-Regular;
  836. font-weight: 400;
  837. color: #9a9a9a;
  838. line-height: 17px;
  839. margin-top: 7px;
  840. span {
  841. color: #202124;
  842. }
  843. }
  844. }
  845. }
  846. }
  847. }
  848. }
  849. }
  850. }
  851. .transform-element {
  852. transition: transform 0.5s;
  853. }
  854. table {
  855. width: 100%;
  856. table-layout: fixed;
  857. border-collapse: collapse;
  858. }
  859. .m-s-header-container,
  860. .m-s-body-container {
  861. width: 100%;
  862. }
  863. .m-s-header-container {
  864. touch-action: none;
  865. height: 100%;
  866. position: relative;
  867. z-index: 10;
  868. white-space: nowrap;
  869. overflow: hidden;
  870. .translate-handle {
  871. position: absolute;
  872. top: 3px;
  873. z-index: 10;
  874. display: block;
  875. width: 20px;
  876. height: 20px;
  877. color: #4273f6;
  878. background-color: #fff;
  879. border-radius: 50%;
  880. border: none;
  881. box-shadow: 0px 0px 8px 0px #edeff1;
  882. * {
  883. pointer-events: none;
  884. }
  885. }
  886. .translate-left {
  887. left: 0;
  888. }
  889. .translate-right {
  890. right: 0;
  891. }
  892. tr {
  893. .header-item {
  894. position: absolute;
  895. bottom: -20px;
  896. left: 0;
  897. float: left;
  898. color: #90959d;
  899. font-weight: 400;
  900. font-size: 10px;
  901. // line-height: 35px;
  902. text-align: center;
  903. transform: translateX(-50%);
  904. // transform: scale(0.8);
  905. }
  906. th {
  907. position: relative;
  908. height: 18px;
  909. border: none;
  910. background: #f7f7f7;
  911. }
  912. th:not(:nth-child(4n + 2)) {
  913. .header-item {
  914. display: none;
  915. }
  916. }
  917. th:nth-child(4n + 2) {
  918. border-left: 2px solid #ffffff;
  919. }
  920. th:last-child {
  921. border-right: 2px solid #ffffff;
  922. }
  923. }
  924. }
  925. .scroll-wrapper {
  926. .scroll-content {
  927. display: inline-block;
  928. }
  929. }
  930. .current-time-line {
  931. position: absolute;
  932. top: 0px;
  933. left: 0px;
  934. z-index: 100;
  935. // width: 1px;
  936. height: 18px;
  937. border-left: 1px dotted #f35b4e;
  938. }
  939. .m-s-activity {
  940. position: absolute;
  941. top: 0;
  942. display: flex;
  943. align-items: center;
  944. height: 100%;
  945. color: #6d88d0;
  946. z-index: 200;
  947. background: rgba(107,147,255,0.80);
  948. width: 100%;
  949. }
  950. </style>
  951. <style>
  952. .van-icon {
  953. font: normal normal normal 36px 'vant-icon' !important;
  954. }
  955. </style>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/99171
推荐阅读
相关标签