123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818 |
- <template>
- <div style="width: 100%">
- <div class="page-header">
- <div class="page-title">
- <el-page-header @back="goBack" :content="$t('menu.record')"></el-page-header>
- </div>
- </div>
- <el-container>
- <el-aside width="300px">
- <div class="record-list-box-box">
- <!-- -->
- <el-date-picker size="mini" v-model="chooseDate" type="date" value-format="yyyy-MM-dd" :placeholder="$t('date')"
- @change="dateChange()"></el-date-picker>
- <!-- 格式选择 与日期选择框样式对其-->
- <el-select style="width: 220px" v-model="filterExt" size="mini" @change="filterExtChangeHandle" :placeholder="$t('filter')">
- <el-option
- v-for="item in extList"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- >
- </el-option>
- </el-select>
- <div class="record-list-box" v-loading="recordsLoading" :style="recordListStyle">
- <ul v-if="detailFiles.length >0" class="infinite-list record-list">
- <li v-for="item in detailFiles" class="infinite-list-item record-list-item">
- <el-tag @click="checkedFile(item)" :type="chooseFile == item?'danger':''">
- <i class="el-icon-video-camera"></i>
- <span class="icon" :class="'icon-'+item.extName">{{item.extName}}</span>
- {{ moment(item.startTime).format('HH:mm:ss') }}-{{ moment(item.endTime).format('HH:mm:ss') }}
- </el-tag>
- <i style="color: #409EFF;margin-left: 5px;" class="el-icon-download" @click="downloadRecord(item)"></i>
- </li>
- </ul>
- </div>
- <div size="mini" v-if="detailFiles.length ==0" class="record-list-no-val">{{ $t('noData') }}</div>
- </div>
- </el-aside>
- <el-main style="padding-bottom: 10px;">
- <div class="playBox" :style="playerStyle">
- <player ref="recordVideoPlayer"
- :videoUrl="videoUrl"
- :error="videoError"
- :message="videoError"
- :hasAudio="hasAudio"
- style="max-height: 100%"
- v-if="activePlayer === 'jessibuca'"
- fluent autoplay live></player>
- <rtc-player
- v-if="activePlayer === 'webrtc'"
- ref="webrtc"
- @eventCallback="webrtcPlayEventHandle"
- :videoUrl="videoUrl"
- :error="videoError"
- :message="videoError"
- :hasAudio="hasAudio"
- />
- </div>
- <div class="player-option-box">
- <div>
- <el-radio-group
- v-model="activePlayer"
- size="medium"
- @input="playerChangeHandle"
- >
- <el-radio-button
- v-for="(item,i) in playerList"
- :key="item.key + i"
- :label="$t(`video.play.${item.key}.title`)">
- {{ $t(`video.play.${item.key}.title`) }}
- </el-radio-button>
- </el-radio-group>
- <el-button-group>
- <el-time-picker
- size="mini"
- is-range
- align="left"
- v-model="timeRange"
- value-format="yyyy-MM-dd HH:mm:ss"
- range-separator="-"
- :start-placeholder="$t('video.startTime')"
- :end-placeholder="$t('video.endTime')"
- @change="timePickerChange"
- :placeholder="$t('video.timeRange')">
- </el-time-picker>
- </el-button-group>
- <el-button-group>
- <el-button size="mini" class="iconfont icon-zanting"
- :title="$t('play')"
- @click="gbPause()"></el-button>
- <el-button size="mini" class="iconfont icon-kaishi"
- :title="$t('pause')"
- @click="gbPlay()"></el-button>
- <el-dropdown size="mini" :title="$t('playMultiples')" @command="gbScale">
- <el-button size="mini">
- {{ $t('playMultiples') }} <i class="el-icon-arrow-down el-icon--right"></i>
- </el-button>
- <el-dropdown-menu slot="dropdown">
- <el-dropdown-item command="0.25">0.25</el-dropdown-item>
- <el-dropdown-item command="0.5">0.5</el-dropdown-item>
- <el-dropdown-item command="1.0">1</el-dropdown-item>
- <el-dropdown-item command="2.0">2</el-dropdown-item>
- <el-dropdown-item command="4.0">4</el-dropdown-item>
- </el-dropdown-menu>
- </el-dropdown>
- <el-button size="mini" class="iconfont icon-xiazai1" :title="$t('download')"
- @click="downloadRecord()"></el-button>
- </el-button-group>
- </div>
- <el-slider
- class="playtime-slider"
- v-model="playTime"
- id="playtimeSlider"
- :disabled="detailFiles.length === 0"
- :min="sliderMIn"
- :max="sliderMax"
- :range="true"
- :format-tooltip="playTimeFormat"
- @change="playTimeChange"
- :marks="playTimeSliderMarks">
- </el-slider>
- <div class="slider-val-box">
- <div class="slider-val" v-for="item of detailFiles"
- :style="'width:' + getDataWidth(item) + '%; left:' + getDataLeft(item) + '%'"></div>
- </div>
- </div>
- </el-main>
- </el-container>
- <recordDownload ref="recordDownload"></recordDownload>
- </div>
- </template>
- <script>
- import uiHeader from '../layout/UiHeader.vue'
- import player from './common/jessibuca.vue'
- import moment from 'moment'
- import recordDownload from './dialog/recordDownload.vue'
- import handle from "@/until/handle";
- import RtcPlayer from "@components/dialog/rtcPlayer.vue";
- import mpegTsVideo from "@components/common/mpegtsVideo.vue";
- import h265WebJessibuca from "@components/common/h265webJessibuca.vue";
- import H265WebJs from "@components/common/h265webJs.vue";
- import {webrtcEvent} from "@/map/eventMap";
- import {strFill} from "@/until/str";
- import {checkWebrtcHevcSupport} from "../until/browser";
- const playList = [
- {
- key: "webrtc",
- text: "webrtc 播放器",
- description: "延迟较低的播放器,需要浏览器支持",
- support: checkWebrtcHevcSupport()? ['h264', 'h265'] : ['h264'],
- audioSupport: ['opus', 'pcma', 'pcmu'],
- disable: false
- },
- {
- key: "jessibuca",
- text: "265 jessibuca播放器",
- description: "用于播放265格式视频",
- support: ['h264', 'h265'],
- audioSupport: ['aac'],
- disable: false
- },
- ];
- const playerProtocol = {
- webrtc: ["rtc", "rtcs"],
- jessibuca: ["ws_flv", "wss_flv"],
- };
- let playTimeSliderMarks = {};
- for (let i = 0 ; i < 24 ; i++)
- {
- playTimeSliderMarks[i * 3600] = `${strFill(i, 2)}:00`;
- }
- export default {
- name: 'app',
- components: {
- H265WebJs, h265WebJessibuca, mpegTsVideo,
- RtcPlayer,
- uiHeader, player, recordDownload
- },
- data() {
- return {
- activePlayer: '',
- playerList: playList,
- fps: 15,
- deviceId: this.$route.params.deviceId,
- channelId: this.$route.params.channelId,
- recordsLoading: false,
- streamId: "",
- hasAudio: true,
- allDetailFiles: [],
- // detailFiles: [],
- chooseDate: null,
- videoUrl: null,
- chooseFile: null,
- streamInfo: null,
- app: null,
- mediaServerId: null,
- ssrc: null,
- sliderMIn: 0,
- sliderMax: 86400,
- autoPlay: true,
- taskUpdate: null,
- tabVal: "running",
- recordListStyle: {
- height: this.winHeight + "px",
- overflow: "auto",
- margin: "10px auto 10px auto"
- },
- playerStyle: {
- "margin": "0 auto 20px auto",
- "height": this.winHeight + "px",
- },
- winHeight: window.innerHeight - 240,
- playTime: null,
- timeRange: null,
- startTime: null,
- endTime: null,
- playTimeSliderMarks: playTimeSliderMarks,
- extList: [],
- filterExt: null,
- };
- },
- computed: {
- detailFiles() {
- let ext = this.filterExt;
- if(!ext){
- return this.allDetailFiles;
- }
- if(ext === 'all') {
- return this.allDetailFiles;
- }
- return this.allDetailFiles.filter((item) => {
- return item.extName === ext;
- })
- }
- },
- mounted() {
- this.recordListStyle.height = this.winHeight + "px";
- this.playerStyle["height"] = this.winHeight + "px";
- this.chooseDate = moment().format('YYYY-MM-DD')
- this.dateChange();
- if(!this.activePlayer){
- this.activePlayer = this.playerList[0].key;
- }
- },
- beforeDestroy() {
- console.log('准备销毁页面')
- this.stopPlayRecord();
- this.stopDownloadRecord();
- },
- destroyed() {
- this.$destroy('recordVideoPlayer');
- },
- methods: {
- async dateChange() {
- let err, res;
- let recordList = [];
- if (!this.chooseDate) {
- return;
- }
- this.setTime(this.chooseDate + " 00:00:00", this.chooseDate + " 23:59:59");
- this.recordsLoading = true;
- // this.detailFiles = [];
- let url = '/api/gb_record/query/'
- url += `${this.deviceId}/${this.channelId}`;
- url += `?startTime=${this.startTime}`;
- url += `&endTime=${this.endTime}`;
- [err, res] = await handle(this.$axios.axios({
- method: 'get',
- url: url
- }))
- this.recordsLoading = false;
- if (err) {
- this.$message({
- showClose: true,
- message: err.message,
- type: "error",
- });
- return;
- }
- if (res.data.code !== 0) {
- this.$message({
- showClose: true,
- message: res.data.msg,
- type: "error",
- });
- }
- // 创建一个set集合
- let extSet = new Set();
- recordList = res.data.data.recordList;
- // 遍历获取文件后缀名
- recordList.forEach((item) => {
- // item.name = item.fileName;
- item.extName = this.getExtName(item.name);
- extSet.add(item.extName);
- })
- this.allDetailFiles = recordList;
- // 将set集合转换为数组
- this.extList = Array.from(extSet).map((item) => {
- return {
- label: item,
- value: item
- }
- });
- // 首位添加 所有格式
- this.extList.unshift({
- label: "all",
- value: "all"
- });
- this.filterExt = "all";
- console.log(this.detailFiles);
- },
- getExtName(fileName){
- let tmpSplit = fileName.split(".");
- let extName = tmpSplit[tmpSplit.length - 1];
- return extName;
- },
- moment: function (v) {
- return moment(v)
- },
- setTime: function (startTime, endTime) {
- this.startTime = startTime;
- this.endTime = endTime;
- let start = (new Date(this.startTime).getTime() - new Date(this.chooseDate + " 00:00:00").getTime()) / 1000;
- let end = (new Date(this.endTime).getTime() - new Date(this.chooseDate + " 00:00:00").getTime()) / 1000;
- console.log(start)
- console.log(end)
- this.playTime = [start, end];
- this.timeRange = [startTime, endTime];
- },
- videoError: function (e) {
- console.log("播放器错误:" + JSON.stringify(e));
- },
- checkedFile(file) {
- this.chooseFile = file;
- this.setTime(file.startTime, file.endTime);
- // 开始回放
- this.playRecord()
- },
- playRecord: function () {
- if (this.streamId !== "") {
- this.stopPlayRecord(() => {
- this.streamId = "";
- this.playRecord();
- })
- } else {
- this.$axios.axios({
- method: 'get',
- url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' +
- this.endTime
- }).then(async (res) => {
- if (res.data.code === 0) {
- this.streamInfo = res.data.data;
- await this.queryMediaInfo(true);
- console.log(`streamInfo`);
- console.log(this.streamInfo);
- this.app = this.streamInfo.app;
- this.streamId = this.streamInfo.stream;
- this.mediaServerId = this.streamInfo.mediaServerId;
- this.ssrc = this.streamInfo.ssrc;
- // 根据tracks 选择播放器
- this.videoUrl = this.getUrlByStreamInfo(this.streamInfo);
- } else {
- this.$message({
- showClose: true,
- message: res.data.msg,
- type: "error",
- });
- }
- });
- }
- },
- gbPlay() {
- console.log('前端控制:播放');
- this.$axios.axios({
- method: 'get',
- url: '/api/playback/resume/' + this.streamId
- }).then((res) => {
- this.$refs["recordVideoPlayer"].play(this.videoUrl)
- });
- },
- gbPause() {
- console.log('前端控制:暂停');
- this.$axios.axios({
- method: 'get',
- url: '/api/playback/pause/' + this.streamId
- }).then(function (res) {
- });
- },
- gbScale(command) {
- console.log('前端控制:倍速 ' + command);
- this.$axios.axios({
- method: 'get',
- url: `/api/playback/speed/${this.streamId}/${command}`
- }).then(function (res) {
- });
- },
- downloadRecord: function (row) {
- if (!row) {
- let startTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + this.playTime[0] * 1000).format("YYYY-MM-DD HH:mm:ss");
- let endTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + this.playTime[1] * 1000).format("YYYY-MM-DD HH:mm:ss");
- console.log(startTimeStr);
- console.log(endTimeStr);
- row = {
- startTime: startTimeStr,
- endTime: endTimeStr
- }
- }
- if (this.streamId !== "") {
- this.stopPlayRecord(() => {
- this.streamId = "";
- this.downloadRecord(row);
- })
- } else {
- this.$axios.axios({
- method: 'get',
- url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
- row.endTime + '&downloadSpeed=4'
- }).then((res) => {
- if (res.data.code === 0) {
- let streamInfo = res.data.data;
- this.$refs.recordDownload.openDialog(this.deviceId, this.channelId, streamInfo.app, streamInfo.stream, streamInfo.mediaServerId);
- } else {
- this.$message({
- showClose: true,
- message: res.data.msg,
- type: "error",
- });
- }
- });
- }
- },
- stopDownloadRecord: function (callback) {
- this.$refs["recordVideoPlayer"].pause();
- this.videoUrl = '';
- this.$axios.axios({
- method: 'get',
- url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
- }).then((res) => {
- if (callback) callback(res)
- });
- },
- stopPlayRecord: function (callback) {
- this.$refs["recordVideoPlayer"].pause();
- this.videoUrl = '';
- this.$axios.axios({
- method: 'get',
- url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
- }).then(function (res) {
- if (callback) callback()
- });
- },
- getDataWidth(item) {
- let timeForFile = this.getTimeForFile(item);
- let result = (timeForFile[2]) / ((this.sliderMax - this.sliderMIn) * 1000)
- return result * 100
- },
- getDataLeft(item) {
- let timeForFile = this.getTimeForFile(item);
- let differenceTime = timeForFile[0].getTime() - new Date(this.chooseDate + " 00:00:00").getTime()
- return parseFloat((differenceTime - this.sliderMIn * 1000) / ((this.sliderMax - this.sliderMIn) * 1000)) * 100;
- },
- getUrlByStreamInfo(streamInfo) {
- if (this.enableDebug) {
- console.log("获取基础拉流地址");
- console.log(streamInfo);
- }
- if (!streamInfo) {
- return '';
- }
- if(!this.activePlayer){
- this.activePlayer = this.playerList[0].key;
- }
- let playerData = playerProtocol[this.activePlayer];
- if (location.protocol === "https:") {
- this.videoUrl = streamInfo[playerData[1]]
- } else {
- this.videoUrl = streamInfo[playerData[0]]
- }
- if (this.enableDebug) {
- console.log(`播放url: ${this.videoUrl}`);
- }
- console.log(`播放url: ${this.videoUrl}`);
- console.log(this.videoUrl)
- return this.videoUrl;
- },
- timePickerChange: function (val) {
- this.setTime(val[0], val[1])
- },
- playTimeChange(val) {
- console.log(val)
- let startTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + val[0] * 1000).format("YYYY-MM-DD HH:mm:ss");
- let endTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + val[1] * 1000).format("YYYY-MM-DD HH:mm:ss");
- this.setTime(startTimeStr, endTimeStr)
- this.playRecord();
- },
- setSliderFit() {
- if (this.sliderMIn === 0 && this.sliderMax === 86400) {
- if (this.detailFiles.length > 0) {
- let timeForFile = this.getTimeForFile(this.detailFiles[0]);
- let lastTimeForFile = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1]);
- let timeNum = timeForFile[0].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime()
- let lastTimeNum = lastTimeForFile[1].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime()
- this.playTime = parseInt(timeNum / 1000)
- this.sliderMIn = parseInt(timeNum / 1000 - timeNum / 1000 % (60 * 60))
- this.sliderMax = parseInt(lastTimeNum / 1000 - lastTimeNum / 1000 % (60 * 60)) + 60 * 60
- this.playTime = [this.sliderMIn, this.sliderMax];
- }
- } else {
- this.sliderMIn = 0;
- this.sliderMax = 86400;
- }
- },
- getTimeForFile(file) {
- let startTime = new Date(file.startTime);
- let endTime = new Date(file.endTime);
- return [startTime, endTime, endTime.getTime() - startTime.getTime()];
- },
- playTimeFormat(val) {
- let h = parseInt(val / 3600);
- let m = parseInt((val - h * 3600) / 60);
- let s = parseInt(val - h * 3600 - m * 60);
- let hStr = h;
- let mStr = m;
- let sStr = s;
- if (h < 10) {
- hStr = "0" + hStr;
- }
- if (m < 10) {
- mStr = "0" + mStr;
- s
- }
- if (s < 10) {
- sStr = "0" + sStr;
- }
- return hStr + ":" + mStr + ":" + sStr
- },
- goBack() {
- window.history.go(-1);
- },
- filterExtChangeHandle(){
- let ext = this.filterExt;
- if(!ext){
- return
- }
- if(ext === 'all') {
- this.detailFiles = this.detailFiles;
- }
- },
- findPlayer(videoType, audioType)
- {
- // 先尝试寻找到所有支持对应协议的播放器
- let arr = this.playerList.filter(item => {
- return item.support.includes(videoType)
- })
- console.log(arr);
- console.log(arr);
- console.log(arr);
- console.log(arr);
- // 从中找到同时支持
- let res_player = arr.find(item => {
- // 判断播放器是否同时支持 视频与音频
- return item.audioSupport.includes(audioType);
- })
- if (!res_player)
- {
- res_player = arr[0]
- }
- return res_player;
- },
- async queryMediaInfo(isFirst) {
- let info = this.streamInfo
- let url = `/zlm/${info.mediaServerId}/index/api/getMediaInfo`
- url += `?vhost=__defaultVhost__`
- url += `&schema=rtsp`
- url += `&app=${info.app}`
- url += `&stream=${info.stream}`
- url += this.shareCode ? `&shareCode=${this.shareCode}` : ''
- let [err, res] = await handle(this.$axios.axios({
- method: 'get',
- url: url
- }));
- if (err) {
- console.error(err);
- this.$message.warning("流媒体信息获取失败")
- return;
- }
- console.log(res);
- if (res.data.code !== 0) {
- this.tracksNotLoaded = true;
- this.$message({
- showClose: true,
- message: '获取编码信息失败,',
- type: 'warning'
- });
- return;
- }
- if (res.data.tracks) {
- this.tracks = res.data.tracks;
- if (this.tracks) {
- console.log(`---------tracks----------`)
- // 根据我们摄像头默认fps值来进行配置播放器
- let fps = 15;
- let isH265 = false;
- let isPCMAudio = false;
- for (const tracksElement of this.tracks) {
- console.log(tracksElement);
- if (tracksElement.fps) {
- fps = tracksElement.fps;
- }
- console.log(`${tracksElement.codec_id_name}:code ${tracksElement.codec_id_name ? 'is h265' : 'not h265'}`)
- if (tracksElement.codec_id_name && tracksElement.codec_id_name.includes("265")) {
- isH265 = true;
- }
- if (tracksElement.codec_id_name && tracksElement.codec_id_name.includes("PCM"))
- {
- isPCMAudio = true;
- // console.log("audio")
- }
- }
- this.fps = fps;
- if (isFirst) {
- // g711 264
- // g711 265
- let _Player = this.findPlayer(isH265?'h265':'h264',
- isPCMAudio?'pcma':'aac');
- if (_Player) {
- console.log(`切换为${_Player.key}播放器`);
- this.activePlayer = _Player.key;
- } else {
- console.log("使用默认播放器");
- this.activePlayer = playList[0].key;
- }
- }
- }
- } else {
- console.log('没有编码信息');
- }
- },
- playerChangeHandle() {
- console.log('切换播放器');
- this.$nextTick(() => {
- // todo 切换url
- this.videoUrl = this.getUrlByStreamInfo(this.streamInfo);
- })
- },
- webrtcPlayEventHandle(type, e) {
- // 添加同类型防抖
- if (this.enableDebug) {
- console.log('playEventHandle');
- console.log(type, e);
- }
- if (this.playEventHandleTimer) {
- clearTimeout(this.playEventHandleTimer);
- }
- this.playEventHandleTimer = setTimeout(() => {
- this.webrtcEventExecute(type, e);
- }, 300);
- },
- webrtcEventExecute(type, e) {
- // 防抖,防止多次触发
- if (type === webrtcEvent.apiFail.code) {
- this.$notify.error({
- title: this.$t('notification.noStreamInfo'),
- dangerouslyUseHTMLString: true,
- message: this.$t('notification.zlmFailMsg', {msg: e.message, url: this.videoUrl}),
- duration: 0
- });
- this.videoError = true;
- this.videoUrl = '';
- } else if (type === webrtcEvent.played.code) {
- this.$message.success(this.$t('notification.playSuccess'));
- } else if (type === webrtcEvent.sdpFail.code) {
- console.log(e);
- this.$notify.error({
- title: this.$t('notification.sdpFail'),
- duration: 14500
- })
- }
- },
- }
- };
- </script>
- <style scoped>
- .icon{
- font-size: 12px;
- margin-right: 5px;
- }
- .icon-mp4{
- color: #25cb8e;
- }
- .icon-h265{
- color: #ef7b05;
- }
- .icon-h264{
- color: #407300;
- }
- </style>
- <style>
- .el-slider__runway {
- background-color: rgba(206, 206, 206, 0.47) !important;
- }
- .el-slider__bar {
- background-color: rgba(153, 153, 153, 0) !important;
- }
- .playtime-slider {
- position: relative;
- z-index: 100;
- }
- .data-picker-true {
- }
- .data-picker-true:after {
- content: "";
- position: absolute;
- width: 4px;
- height: 4px;
- background-color: #606060;
- border-radius: 4px;
- left: 45%;
- top: 74%;
- }
- .data-picker-false {
- }
- .slider-val-box {
- height: 6px;
- position: relative;
- top: -22px;
- }
- .slider-val {
- height: 6px;
- background-color: #007CFF;
- position: absolute;
- }
- .record-list-box-box {
- width: 250px;
- float: left;
- }
- .record-list-box {
- overflow: auto;
- width: 220px;
- list-style: none;
- padding: 0;
- margin: 0;
- margin-top: 0px;
- padding: 1rem 0;
- background-color: #FFF;
- margin-top: 10px;
- }
- .record-list {
- list-style: none;
- padding: 0;
- margin: 0;
- background-color: #FFF;
- }
- .record-list-no-val {
- position: absolute;
- color: #9f9f9f;
- top: 50%;
- left: 110px;
- }
- .record-list-item {
- padding: 0;
- margin: 0;
- margin: 0.5rem 0;
- cursor: pointer;
- }
- .record-list-option {
- width: 10px;
- float: left;
- margin-top: 39px;
- }
- .player-option-box {
- padding: 0 20px;
- }
- </style>
|