E6/IE7下:inline-block解决方案

本文探讨了IE6/IE7浏览器对于display:inline-block属性的支持情况,并提供了两种实现方法。一种是通过先触发块元素的display:inline-block,再将其设置为display:inline来实现。另一种则是直接将块元素设置为内联对象并触发layout。

IE6/IE7下对display:inline-block的支持性不好。

1、inline元素的display属性设置为inline-block时,所有的浏览器都支持;

2、block元素的display属性设置为inline-block时,IE6/IE7浏览器是不支持的;

      对象呈递为内联对象,但是对象的内容作为块对象呈递。旁边的内联对象会被呈递在同一行,允许空格。(准确地说,应用此特性的元素现为内联对象,周围元素保持在同一行,但可以设置宽度和高度等块元素的属性)

     IE中对内联元素使用display:inline-block,IE是不识别的,但使用display:inline-block在IE下会触发layout,从而使内联元素拥有了display:inline-block属性的表征。从上面的这个分析,也不难理解为什么IE下,对块元素设置display:inline-block属性无法实现inline-block的效果。这时块元素仅仅是被display:inline-block触发了layout,而它本身就是行布局,所以触发后,块元素依然还是行布局,而不会如Opera中块元素呈递为内联对象。

 

IE6下块元素如何实现display:inline-block的效果?


有两种方法:
1、 先使用display:inline-block属性触发块元素,然后再定义display:inline,让块元素呈递为内联对象(两个display 要先后放在两个CSS声明中才有效果,这是IE的一个经典bug,如果先定义了display:inline-block,然后再将display设回 inline或block,layout不会消失)。代码如下(...为省略的其他属性内容): 

div {display:inline-block;...} 
div {display:inline;}

2、直接让块元素设置为内联对象呈递(设置属性display:inline),然后触发块元素的layout(如:zoom:1 或float属性等)。代码如下:

div { display:inline-block; _zoom:1;_display:inline;} /*推荐*/
div { display:inline-block; _zoom:1;*display:inline;} /*推荐:IE67*/

 

触发haslayout的情况有很多
display: inline-block
* height: (任何值除了auto)
* float: (left 或 right)
* position: absolute
* width: (任何值除了auto)
* writing-mode: tb-rl
* zoom: (除 normal 外任意值)
Internet Explorer 7 还有一些额外的属性(不完全列表):
* min-height: (任意值)
* max-height: (除 none 外任意值)
* min-width: (任意值)
* max-width: (除 none 外任意值)
* overflow: (除 visible 外任意值)
* overflow-x: (除 visible 外任意值)
* overflow-y: (除 visible 外任意值)
* position: fixed
都会触发

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DingTalkLogin.aspx.cs" Inherits="biaoyang_DingTalkLogin" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <title>标样管理</title> <script src='https://g.alicdn.com/code/npm/@ali/dingtalk-h5-remote-debug/0.1.3/index.js'></script> <script src="https://g.alicdn.com/dingding/dingtalk-jsapi/2.10.3/dingtalk.open.js"></script> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif; } body { background: linear-gradient(135deg, #1e5799 0%, #207cca 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 20px; position: relative; } /* 全屏容器样式 */ .fullscreen-container { position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: flex; flex-direction: column; overflow: auto; } .container { background: white; border-radius: 16px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); width: 100%; max-width: 500px; margin: auto; overflow: hidden; text-align: center; position: relative; display: flex; flex-direction: column; min-height: calc(100vh - 40px); } .header { background: #06922a; color: white; padding: 10px 15px; position: relative; } .company-logo { width: 60px; height: 60px; background: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10px; } .logo-text { color: #0086F6; font-weight: bold; font-size: 24px; } .header h1 { font-size: 22px; font-weight: 500; margin-bottom: 5px; } .subtitle { font-size: 24px; opacity: 0.9; letter-spacing: 1px; } .content { padding: 15px 15px; flex: 1; display: flex; flex-direction: column; justify-content: center; } .user-info { background: #f8fafc; border-radius: 12px; padding: 15px; margin: 10px 0; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); } .user-details { display: grid; grid-template-columns: auto 1fr; gap: 15px; text-align: left; margin-top: 20px; } .detail-label { font-weight: 600; color: #06922a; text-align: right; } .detail-value { color: #1e293b; font-weight: 500; } .user-avatar { width: 80px; height: 80px; border-radius: 50%; object-fit: cover; border: 3px solid #0086F6; margin: 0 auto 15px; background-color: #e0e7ff; display: flex; align-items: center; justify-content: center; font-size: 32px; color: #4f46e5; } .loading-container { padding: 30px 0; } .loading-spinner { width: 50px; height: 50px; border: 5px solid rgba(0, 134, 246, 0.2); border-top: 5px solid #0086F6; border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto 20px; } .loading-text { color: #64748b; font-size: 16px; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .error-message { color: #ef4444; background: #fef2f2; padding: 15px; border-radius: 8px; margin: 20px 0; text-align: center; } /* 底部版权信息样式 - 固定在底部 */ .footer { padding: 15px; color: #64748b; font-size: 12px; background: rgba(255, 255, 255, 0.9); border-top: 1px solid #e2e8f0; position: sticky; bottom: 0; z-index: 10; text-align: center; box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05); } /* 按钮美化 */ .btn { background: linear-gradient(135deg, #0086F6 0%, #0066cc 100%); color: white; border: none; border-radius: 10px; padding: 14px 25px; font-size: 17px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; display: inline-block; margin: 20px 0 15px; width: 100%; max-width: 220px; box-shadow: 0 5px 15px rgba(0, 134, 246, 0.3); position: relative; overflow: hidden; } .btn:hover { background: linear-gradient(135deg, #0099ff 0%, #0077e6 100%); transform: translateY(-3px); box-shadow: 0 8px 20px rgba(0, 134, 246, 0.4); } .btn:active { transform: translateY(0); box-shadow: 0 4px 10px rgba(0, 134, 246, 0.3); } .btn::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.2); transform: translateX(-100%); transition: transform 0.5s ease; } .btn:hover::after { transform: translateX(100%); } .btn-icon { display: inline-flex; align-items: center; justify-content: center; gap: 8px; } .btn-icon svg { width: 18px; height: 18px; fill: white; } .success-message { background: #f0fdf4; color: #15803d; padding: 15px; border-radius: 8px; margin: 20px 0; text-align: center; border: 1px solid #bbf7d0; } .info-box { background: #f0f9ff; border: 1px solid #bae6fd; border-radius: 8px; padding: 15px; margin: 15px 0; text-align: left; } .info-box h3 { color: #0369a1; margin-bottom: 10px; font-size: 16px; } .info-box p { color: #0c4a6e; font-size: 14px; line-height: 1.5; } @media (max-width: 480px) { .container { border-radius: 0; max-width: 100%; height: 100%; } body { padding: 0; } .content { padding: 10px 15px; } .user-details { grid-template-columns: 1fr; gap: 8px; } .detail-label { text-align: left; } .btn { padding: 12px 20px; font-size: 16px; max-width: 100%; } } </style> </head> <body> <form id="form1" runat="server"> <div class="fullscreen-container"> <div class="container"> <div class="header"> <div class="subtitle">标样借用</div> </div> <div class="content"> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> </ContentTemplate> </asp:UpdatePanel> <div id="pnlLoading" class="loading-container"> <div class="loading-spinner"></div> <div class="loading-text">正在获取用户信息...</div> </div> <asp:HiddenField ID="hfDingTalkId" runat="server" /> <div id="pnlUserInfo" class="user-info" style="display:none;"> <div class="user-details"> <div class="detail-label" style="display:none">借用人:</div> <div class="detail-value" style="display:none"><asp:Label ID="userneme" runat="server" Text=""></asp:Label></div> <div class="detail-label">标样ID:</div> <div class="detail-value"><asp:Label ID="byid" runat="server" Text=""></asp:Label></div> <div class="detail-label">标样名称:</div> <div class="detail-value"><asp:Label ID="bymc" runat="server" Text=""></asp:Label></div> <div class="detail-label" style="display:none">钉钉ID:</div> <div class="detail-value" style="display:none" ><span id="userId"></span></div><%----%> <div class="detail-label">状态:</div> <div class="detail-value" runat="server"> <span class="success-message" style="display: inline-block; padding: 4px 0px; font-size: 13px; "> <asp:Label ID="sjjyr" runat="server" Text="Label"></asp:Label> <input id="uid" type="hidden" runat="server"/><%-- --%> </span> </div> </div> <!-- 美化后的按钮 --> <asp:Button ID="Button1" runat="server" Text="我要借用" OnClick="Button1_Click" CssClass="btn btn-icon" /> <asp:Button ID="Button2" runat="server" Text="归还" CssClass="btn btn-icon" OnClick="Button1_Click"/> </div> </div> <div id="pnlError" class="error-message" style="display:none;"></div> <button id="btnRefresh" class="btn btn-icon" style="display:none;"> <svg viewBox="0 0 24 24"> <path d="M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z"/> </svg> 重新获取 </button> </div> <!-- 固定在底部的版权信息 --> <div class="footer"> © 2025 标样管理 | 河北龙大包装制品有限公司 </div> </div> </div> </form> <script> // 初始化钉钉JSAPI const button1Id = '<%= Button1.ClientID %>'; const uidInputId = '<%= uid.ClientID %>'; dd.ready(function() { console.log('钉钉JSAPI已准备就绪'); // 获取免登授权码 dd.runtime.permission.requestAuthCode({ corpId: '<%= GetCorpId() %>', onSuccess: function(result) { console.log('获取到免登授权码:', result.code); getUserInfo(result.code); }, onFail: function(err) { showError('获取授权码失败: ' + JSON.stringify(err)); } }); }); dd.error(function(error) { console.error('钉钉JSAPI错误:', error); showError('钉钉环境初始化失败: ' + JSON.stringify(error)); }); // 获取用户信息 function getUserInfo(authCode) { fetch('<%= ResolveUrl("DingTalkLogin.aspx/GetUserInfo") %>', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code: authCode }) }) .then(response => { if (!response.ok) { throw new Error('网络响应异常: ' + response.status); } return response.json(); }) .then(data => { if (data.d && data.d.success) { displayUserInfo(data.d.userInfo); updateUserDetails(data.d.userInfo); } else { showError(data.d.error || '获取用户信息失败'); } }) .catch(error => { showError('请求失败: ' + error); }); } // 显示用户信息 function displayUserInfo(userInfo) { document.getElementById('pnlLoading').style.display = 'none'; document.getElementById('pnlUserInfo').style.display = 'block'; document.getElementById('userneme').innerText = userInfo.name; document.getElementById('userId').innerText = userInfo.userid || userInfo.unionid; //// 显示用户头像首字母 //if (document.getElementById('userId').innerText == document.getElementById('uid').innerText) { //document.getElementById('Button1').style.display = 'none'; // } // 模拟标样ID(实际项目中应从后端获取) // document.getElementById('Label2').innerText = 'BY' + Math.floor(1000 + Math.random() * 9000); document.getElementById('<%= hfDingTalkId.ClientID %>').value = userInfo.userid || userInfo.unionid; const currentUserId = (userInfo.userid || userInfo.unionid || "").toString().trim(); const storedUid = document.getElementById(uidInputId).value.trim(); console.log("Comparing IDs:", currentUserId, "vs", storedUid); if (currentUserId === storedUid) { document.getElementById(button1Id).style.display = 'none'; console.log("Button hidden"); } else { document.getElementById(button1Id).style.display = 'block'; } } // 更新用户详细信息 function updateUserDetails(userInfo) { // 在实际应用中,这里可以添加更多用户信息的处理 console.log('用户详细信息:', userInfo); } // 显示错误信息 function showError(message) { document.getElementById('pnlLoading').style.display = 'none'; const errorPanel = document.getElementById('pnlError'); errorPanel.style.display = 'block'; errorPanel.innerText = message; // 显示刷新按钮 document.getElementById('btnRefresh').style.display = 'inline-block'; } // 刷新页面 document.getElementById('btnRefresh').addEventListener('click', function() { location.reload(); }); // 检测是否在钉钉环境中 function isInDingTalk() { return navigator.userAgent.toLowerCase().indexOf('dingtalk') !== -1; } // 如果不在钉钉环境中显示提示 if (!isInDingTalk()) { document.addEventListener('DOMContentLoaded', function() { showError('请在钉钉客户端内打开此页面'); }); } // 添加响应式调整 window.addEventListener('resize', function() { const container = document.querySelector('.container'); if (window.innerWidth < 480) { container.style.borderRadius = '0'; container.style.maxWidth = '100%'; } else { container.style.borderRadius = '16px'; container.style.maxWidth = '500px'; } }); </script> </body> </html> 手机端显示出现了右侧滑块,请设置全屏,不要滑块
11-24
<template> <div> <div class="video-box" :style="isTabsBoxOpen ? 'width: 70%':'width: 100%'"> <video :src="cTwoVideoUlr" ref="myvideo1" class="isVideo" :style="myStyle" @canplay="getTotal" @timeupdate="timeupdate" v-if="cTwoVideoUlr" playsinline playsinline="" ></video> <video :src="cVideoUlr" @mouseover="handleMouseOver()" @mousemove.self="handleMouseMove()" @dblclick="toggleFullScreen()" ref="myvideo" @click="play" @canplay="getTotal" @timeupdate="timeupdate" :class=" ['object-fit: cover']" playsinline v-if="cVideoUlr" :style="videoItem" playsinline="" ></video> <transition name="fade"> <div @mouseover="ctrlMouseOver" v-show="isShowOperate"> <div class="progress"> <el-slider v-model="currentTimeVal" :max="durationProgress" :show-tooltip="false" @change="getNewTime" > </el-slider> <div v-for="(marker, index) in markers" :key="index" class="marker" :style="{ left: `${marker.time}%` }" > <div class="marker-dot" @click="getNewTime(marker.times)"></div> <div class="marker-name">{{ marker.text }}</div> </div> </div> <div class="control"> <div class="flex-center"> <i class="iconfonts" :class=" isPaused ? 'iconzanting1 el-icon-video-pause' : 'iconicon_play el-icon-video-play' " @click="play()" ></i> <span class="time">{{ currentTime }} / {{ totalTime }}</span> </div> <div class="flex"> <div class="line" @click="isLine('none')"> <div class="flex"> <i class="el-icon-connection"></i> </div> <div>{{display ? '隐藏':'显示'}}</div> </div> <div class="line" @click="isLine('is_video')"> <div class="flex"> <i class="el-icon-sort"></i> </div> <div>交换</div> </div> <div class="line" @click="isLine('leftTop')" :style="{ color: leftTop ? 'orange' : '' }" > <div class="flex"> <i class="el-icon-top-left"></i> </div> <div>左上</div> </div> <div class="line" @click="isLine('leftBottom')" :style="{ color: leftBottom ? 'orange' : '' }" > <div class="flex"> <i class="el-icon-bottom-left"></i> </div> <div>左下</div> </div> <div class="line" @click="isLine('rightTop')" :style="{ color: rightTop ? 'orange' : '' }" > <div class="flex"> <i class="el-icon-top-right"></i> </div> <div>右上</div> </div> <div class="line" @click="isLine('rightBottom')" :style="{ color: rightBottom ? 'orange' : '' }" > <div class="flex"> <i class="el-icon-bottom-right"></i> </div> <div>右下</div> </div> <div class="line" @click="isLine('leftright')" :style="{ color: leftright ? 'orange' : '' }" > <div class="flex"> <i class="el-icon-rank"></i> </div> <div>左右</div> </div> <div class="line" @click="isLine(1)"> <div class="flex"> <img src="../../assets/image/line.png" v-if="is_line" alt="" /> <img src="../../assets/image/is_line.png" v-else alt="" /> </div> <div>线路1</div> </div> <div class="line" @click="isLine(2)"> <div class="flex"> <img src="../../assets/image/line.png" v-if="is_line2" alt="" /> <img src="../../assets/image/is_line.png" v-else alt="" /> </div> <div>线路2</div> </div> <i class="iconfont el-icon-help" @click="toggleFullScreen"></i> </div> </div> </div> </transition> </div> <video ref="myvideo2" class="video-js vjs-default-skin vjs-big-play-centered" style="width: 100%" v-if="cVideoUlr" @seeked="onSeeked" @pause='handlePause' @play="onPlay" playsinline > <source id="source" :src="cVideoUlr" /> </video> <el-dialog title="修改" :visible.sync="isUpdataCourseEvaluation" width="50%"> <el-input type="textarea" :rows="12" placeholder="请修改课评" v-model="courseEvaluation"> </el-input> <span slot="footer" class="dialog-footer"> <el-button @click="isUpdataCourseEvaluation = false">取 消</el-button> <el-button type="primary" @click="UpdataCourseEvaluation">确 定</el-button> </span> </el-dialog> <el-dialog title="修改" :visible.sync="isUpdataCourseEvaluationSections" width="50%"> <el-input type="textarea" :rows="4" placeholder="请修改" v-model="sectionsTitle"> </el-input> <span slot="footer" class="dialog-footer"> <el-button @click="isUpdataCourseEvaluationSections = false">取 消</el-button> <el-button type="primary" @click="submitSections">确 定</el-button> </span> </el-dialog> <el-dialog title="修改" :visible.sync="isUpdataTree" width="50%"> <el-input type="textarea" :rows="4" placeholder="请修改" v-model="treeName"> </el-input> <span slot="footer" class="dialog-footer"> <el-button @click="isUpdataTree = false">取 消</el-button> <el-button type="primary" @click="submitTree">确 定</el-button> </span> </el-dialog> <el-dialog title="历史记录" :visible.sync="isRecords" width="50%"> <el-select v-model="isType" placeholder="类型" clearable size="small" @change="records" style="width: 150px;margin-bottom:20px" > <el-option v-for="dict in recordsList" :key="dict.value" :label="dict.name" :value="dict.value" ></el-option> </el-select> <el-table :data="courseList" width="100%" border > <el-table-column prop="nickName" label="修改人" align="left" show-overflow-tooltip width="100" > </el-table-column> <el-table-column prop="content" label="修改内容" align="left" show-overflow-tooltip > <template slot-scope="{row}"> <div v-html="row.content"></div> </template> </el-table-column> <el-table-column prop="createTime" label="修改时间" align="left" show-overflow-tooltip width="120" > </el-table-column> </el-table> <span slot="footer" class="dialog-footer"> <el-button @click="isRecords = false">取 消</el-button> </span> </el-dialog> <el-dialog title="生成ppt" :visible.sync="visible" width="80%"> <iframe :src='getUrlParams()' width="100%" height="800px" v-if="visible" frameborder="0" seamless ></iframe> <span slot="footer" class="dialog-footer"> <el-button @click="cancel">取消</el-button> </span> </el-dialog> </div> </template> <script> import videojs from "video.js"; import "video.js/dist/video-js.css"; import "videojs-contrib-hls"; import { getVideo, getCheckVideo, getStrongVideo, fabulousCourse, getVodVideoEnd, getUserCourseNote, addCourseNote, updateCourseEvaluation, getCourseEvaluationHistory, courseEvaluationAnalysis } from "@/api/course/course"; import * as echarts from "echarts"; import getTreeConfig from '../coursemanage/course/config/getTreeConfig' export default { name: "error", data() { return { subArray: { tableContents:{ structureList:[] } }, visible:false, isRecords:false, recordsList:[ { name:'Ai评课', value:0, }, { name:'课程导读', value:1, }, { name:'思维脑图', value:2, }, ], isTabsBoxOpen: true, activeName: 'courseEvaluation', courseEvaluation:'', textarea:'', isUpdataCourseEvaluation:false, isUpdataCourseEvaluationSections:false, sectionsTitle:'', timePoint:null, treeName:null, treeNameCopy:null, mindMap:null, display:true, bodyStyle:{ background: '#F3F2FF', cursor: 'pointer', }, isUpdataTree:false, volume: 30, // 音量 videochannalList: [], // 全部视频 timeout1: null, // 定时器 fullFlag: false, // 是否全屏(默认否) isShowOperate: false, // 是否显示播放控件(默认否) val:'rightBottom', // 选集列表 videoinglist: [ { url: "https://www.yy.com/ftpurl/medical-record/video/2020/07/01/1593596146146382.mp4", channelDesc: "导播", }, { url: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4", channelDesc: "导播", }, ], cVideoUlr: "", // "https://cdn-nas.eduzhida.com/2023/09/22/198415ea-6d6f-4c2a-9a9a-690c73e6d159.mp4", // 正在播放视频地址 cTwoVideoUlr: "", videoItem:{}, myvideo: "", myvideo1: "", isPaused: false, //标记当前的播放状态 currentTime: "00:00", //当前播放时间 totalTime: "00:00", //总时长 currentTimeVal: 0, // 进度条当前播放时间,必须是number类型 durationProgress: 0, // 进度条的最大值,必须是number类型 currentIndex: "", leftTop: false, leftBottom: false, rightTop: false, rightBottom: true, leftright:false, is_line: true, is_line2: false, player: "", markers: [], courseKnowledgeList:[], isType:0, courseList:[], myStyle: { bottom: "90px", right: "30%", }, }; }, beforeDestroy() { // 恢复浏览器滚动 this.enableScroll(); document.removeEventListener( "fullscreenchange", this.handleFullScreenChange ); }, watch:{ durationProgress:function(newValue, oldValue){ if(this.courseKnowledgeList.length){ this.markers = this.courseKnowledgeList.map((ele) => { let percentage = (ele.time / newValue) * 100; let roundedPercentage = Number(percentage) - 2; return { time: roundedPercentage.toFixed(0), text: ele.text, times: ele.time, }; }); } } }, mounted() { //获取播放器元素 this.disableScroll(); document.addEventListener("fullscreenchange", this.handleFullScreenChange); this.getVVideo(this.$route.query.id); }, methods: { cancel(){ this.visible = false }, DownLoadPPT(row){ this.visible = true }, handleCourseEvaluationAnalysis(){ courseEvaluationAnalysis(this.$route.query.id,this.$route.query.iscType == 0 ? 0 :1) this.msgSuccess(`课评已在分析,请稍后刷新页面查看`) }, handleCourseEvaluationAnalysis(){ courseEvaluationAnalysis(this.$route.query.id,this.$route.query.iscType == 0 ? 0 :1) this.msgSuccess(`课评已在分析,请稍后刷新页面查看`) }, getUrlParams () { let htmlTagRegex = /<\/?[a-zA-Z][^>]*>/g; const test = this.subArray.courseEvaluation.replace(htmlTagRegex, '') let test1 = test.replace(/"/g, '') console.log(test1); return `https://ppt.bsyxedu.com?userId=${this.$route.query.id}_couser&test=${test1}` // return `http://192.168.8.182:5173?userId=${this.$route.query.id}_couser&test=${test1}` }, records(type){ if(!type && type !=0){ this.isType = 0 switch (this.activeName){ case 'courseEvaluation': this.isType = 0 break; case 'first': this.isType = 1 break; case 'second': this.isType = 2 break; } } let param = { courseId:this.$route.query.id, type:type ? type :this.isType } this.isRecords = true this.$forceUpdate() getCourseEvaluationHistory(param).then(res=>{ this.courseList = res.data }) }, handelsections(item){ this.isUpdataCourseEvaluationSections = true this.sectionsTitle = item.title this.timePoint = item.timePoint console.log(item); }, submitSections(){ let name = '' this.subArray.tableContents.structureList.forEach((ele)=>{ ele.sections.find(row=>{ if(row.timePoint == this.timePoint){ name = row.title row.title = this.sectionsTitle } }) }) let param = { cId:this.$route.query.id, tableContents:JSON.stringify(this.subArray.tableContents), historyContent:`${name}---> ${this.sectionsTitle}` } updateCourseEvaluation(param).then(res=>{ if(res.code == 200){ this.msgSuccess(res.msg) this.isUpdataCourseEvaluationSections = false } }) }, UpdataCourseEvaluation(){ let param = { cId:this.$route.query.id, courseEvaluation:this.courseEvaluation, historyContent:this.courseEvaluation, } updateCourseEvaluation(param).then(res=>{ if(res.code == 200){ this.msgSuccess(res.msg) this.isUpdataCourseEvaluation = false this.subArray.courseEvaluation = this.courseEvaluation.replace(/\n/g, '<br>') } }) }, toggleTabsBox() { this.isTabsBoxOpen = !this.isTabsBoxOpen; console.log(this.val,'val'); console.log(this.myStyle,'myStyle'); if(this.val == "rightTop" ){ if(this.isTabsBoxOpen){ this.myStyle = { top: "0", right: "30%" }; }else{ this.myStyle = { top: "0", right: "0" }; } } else if(this.val == "rightBottom" ){ if(this.isTabsBoxOpen){ this.myStyle = { bottom: "90px", right: "30%" }; }else{ this.myStyle = { bottom: "90px", right: "0" }; } this.videoItem = { width: `100%`, } }else if(this.val == "leftright" ){ const videoBox = document.querySelector('.video-box'); const isVideo = document.querySelector('.isVideo'); const top = `${Math.max(0, (videoBox.offsetHeight - isVideo.offsetHeight) / 2 -90)}px` if(this.isTabsBoxOpen){ this.videoItem = { width: videoBox.offsetWidth/2 +'px', height: 'auto', marginTop: top } this.myStyle = { width: videoBox.offsetWidth/2 +'px !important', height: 'auto !important', right:'30%' ,marginTop: top }; }else{ this.videoItem = { width: videoBox.offsetWidth/2 +'px', height: 'auto', marginTop: '15%' } this.myStyle = { width: videoBox.offsetWidth/2 +'px !important', height: 'auto !important', right:'0' ,marginTop: '15%' }; } } else if(this.val == 'none'){ if(this.isTabsBoxOpen){ if(this.myStyle?.right){ this.myStyle.right = "30%" } }else{ if(this.myStyle?.right){ this.myStyle.right = "0" } } } }, handleResize() { this.$nextTick(() => { if (this.points) { this.points.resize(); } }); }, submitTree(){ console.log(this.treeName); const findNodeByName = this.findNodeByName(this.mindMap,this.treeNameCopy) console.log(findNodeByName); findNodeByName.name = this.treeName let param = { cId:this.$route.query.id, mindMap:JSON.stringify(this.mindMap), historyContent:`${this.treeNameCopy}---> ${this.treeName}` } updateCourseEvaluation(param).then(res=>{ if(res.code == 200){ this.isUpdataTree = false this.msgSuccess(res.msg) this.points.setOption(getTreeConfig(this.mindMap)); } }) }, initChart(data) { this.$nextTick(() => { console.log(data,'data'); this.points = echarts.init(this.$refs.points, "macarons"); this.points.setOption(getTreeConfig(data)); this.points.on('click',(params)=>{ this.treeName = params.name this.treeNameCopy = params.name if(this.permissions.includes('*:*:*') || this.permissions.includes('course:knowledge:evaluation')){ this.isUpdataTree = true } }) }); }, findNodeByName(root, targetName) { // 1. 检查当前节点的name是否匹配目标 if (root.name === targetName) { return root; // 找到目标节点,返回 } // 2. 递归遍历子节点(如果有children) if (root.children && Array.isArray(root.children)) { for (const child of root.children) { // 递归查找子节点 const found = this.findNodeByName(child, targetName); if (found) { // 子节点中找到目标,提前返回 return found; } } } // 3. 未找到目标节点 return null; }, cardClick(item){ const timePoint = item.timePoint.split('-')[0]; // 将时间字符串分割成小时、分钟和秒 const time = this.timeToSeconds(timePoint) // const player = videojs(document.querySelector("video")) // player.currentTime(time || 0) this.getNewTime(time) }, timeToSeconds(timeStr) { const parts = timeStr.split(':').map(Number); let seconds = 0; if (parts.length === 3) { // 完整格式 HH:mm:ss seconds = parts[0] * 3600 + parts[1] * 60 + parts[2]; } else if (parts.length === 2) { // 省略小时格式 mm:ss seconds = parts[0] * 60 + parts[1]; } else if (parts.length === 1) { // 仅秒数格式 ss seconds = parts[0]; } return seconds; }, handleSubmit(){ if(!this.textarea) return else{ addCourseNote({courseId:this.$route.query.id,content:this.textarea,type:this.$route.query.iscType == 0 ? 0 :1}).then(res=>{ if(res.code == 200) this.msgSuccess('保存成功') }) } }, handleClick(tab, event) { console.log(tab); if(tab.name == "third"){ getUserCourseNote({courseId:this.$route.query.id,type:this.$route.query.iscType == 0 ? 0 :1}).then(res=>{ this.textarea = res.data ? res.data.content :'' // this.subArray = data }) }else if(tab.name =="second"){ this.initChart(JSON.parse(this.subArray.mindMap)) } }, onPlay() { console.log('Video is playing...'); const customElement = document.querySelector('.overlay-module'); customElement.play() }, handlePause(event) { // 处理视频暂停的逻辑 console.log('Video paused at time:', event.target.currentTime); const customElement = document.querySelector('.overlay-module'); customElement.pause() }, onSeeked(event){ const video = event.target; const currentTime = video.currentTime; console.log('用户点击进度条,当前时间:', currentTime); const customElement = document.querySelector('.overlay-module'); customElement.currentTime = currentTime }, getUrl(id, name) { console.log(name, "namee"); if (name == "getVideo") { this.getVVideo(id); } else if (name == "getCheckVideo") { this.getEVideo(id); } else if (name == "getStrongVideo") { this.getSVideo(id); } else { this.getBoutiqueVideo(id); } }, //播放课程视频 getVVideo(id) { getVideo(id).then((res) => { const { cVideoUlr, cTwoVideoUlr } = res.data; this.cTwoVideoUlr = cTwoVideoUlr; this.cVideoUlr = cVideoUlr; this.subArray = res.data; if(this.subArray.tableContents){ this.subArray.tableContents = JSON.parse(this.subArray.tableContents) } this.courseEvaluation = res.data.courseEvaluation if(this.subArray.courseEvaluation){ this.subArray.courseEvaluation = res.data.courseEvaluation.replace(/\n/g, '<br>') } this.mindMap = JSON.parse(this.subArray.mindMap) // this.$route.query.id; this.$nextTick(() => { this.myvideo = this.$refs.myvideo; this.myvideo1 = this.$refs.myvideo1; this.myvideo1.volume = 0 let arr = [], result = []; if (res.data?.courseKnowledgeList) { arr = res.data.courseKnowledgeList.map((ele) => { return { time: ele.payDateSeconds, text: ele.knowledgeName }; }); this.courseKnowledgeList = arr } console.log(this.courseKnowledgeList,'courseKnowledgeList'); const player1 = videojs(this.$refs.myvideo); player1.on("play", () => { if (player1.userActive()) { this.$nextTick(() => { console.log('demo'); this.demo(result); }); // 执行其他操作... } }); this.$nextTick(() => { const player = videojs( this.$refs.myvideo2, { controls: true, }, () => { player.pause(); } ); if (arr.length) { result = arr.map((item) => item.text); } console.log(arr,'arr'); player.markers({ markerTip: { display: true, text: function (marker) { return `${marker.text}`; }, }, markerStyle: { // 标记点样式 width: "1em", height: "1em", bottom: "-0.20em", "border-radius": "50%", "background-color": "rgb(194,158,206)", position: "absolute", "font-size": "16px", }, markers: arr, }); }); }); // if(res.data.isXy == 1) url =res.data.cPlaybackUlr // else url = res.data.cVideoUlr; }); }, disableScroll() { document.body.style.overflow = "hidden"; window.addEventListener("touchmove", this.preventDefault, { passive: false, }); }, enableScroll() { document.body.style.overflow = ""; window.removeEventListener("touchmove", this.preventDefault); }, preventDefault(event) { event.preventDefault(); }, // 鼠标在控件内 ctrlMouseOver() { clearTimeout(this.timeout1); this.isShowOperate = true; }, handleMouseOver() { this.isShowOperate = true; }, handleMouseMove() { this.isShowOperate = true; clearTimeout(this.timeout1); // 使用定时器前先清除定时器 this.timeout1 = setTimeout(() => { this.isShowOperate = false; }, 1000); }, isLine(val) { console.log(this.isTabsBoxOpen,'isTabsBoxOpen'); this.val = val let isVideos = document.querySelector('.isVideo'); switch (val) { case "none": console.log(isVideos.style.display); this.display = !this.display isVideos.style.display = this.display ? 'block' :'none' break ; case "is_video": let currentTime = this.$refs.myvideo.currentTime let currentTime1 = this.$refs.myvideo1.currentTime let cTwoVideoUlr = this.cTwoVideoUlr; let cVideoUlr = this.cVideoUlr; this.cVideoUlr = cTwoVideoUlr; this.cTwoVideoUlr = cVideoUlr; this.$nextTick(() => { this.$refs.myvideo.currentTime = currentTime this.$refs.myvideo1.currentTime = currentTime1 if(this.isPaused){ this.$refs.myvideo.play(); this.$refs.myvideo1.play(); } }) break; case 1: this.is_line = !this.is_line; console.log(this.is_line,'this.is_line'); this.myvideo.volume = this.is_line ? 1 : 0; //赋值 break; case 2: this.is_line2 = !this.is_line2; this.myvideo1.volume = this.is_line2 ? 1 : 0; //赋值 break; case "leftTop": this.leftTop = true; (this.leftBottom = false), (this.rightTop = false), (this.rightBottom = false); this.leftright = false this.myStyle = { top: "0", left: "0" }; this.videoItem = { width: `100%`, } break; case "leftBottom": this.leftTop = false; (this.leftBottom = true), (this.rightTop = false), (this.rightBottom = false); this.leftright = false this.myStyle = { bottom: "90px", left: "0" }; this.videoItem = { width: `100%`, } break; case "rightTop": this.leftTop = false; (this.leftBottom = false), (this.rightTop = true), (this.rightBottom = false); this.leftright = false if(this.isTabsBoxOpen){ this.myStyle = { top: "0", right: "30%" }; }else{ this.myStyle = { top: "0", right: "0" }; } this.videoItem = { width: `100%`, } break; case "rightBottom": this.leftTop = false; (this.leftBottom = false), (this.rightTop = false), (this.rightBottom = true); this.leftright = false if(this.isTabsBoxOpen){ this.myStyle = { bottom: "90px", right: "30%" }; }else{ this.myStyle = { bottom: "90px", right: "0" }; } this.videoItem = { width: `100%`, } break; case "leftright": this.leftTop = false; (this.leftBottom = false), (this.rightTop = false), (this.rightBottom = false); this.leftright = true const videoBox = document.querySelector('.video-box'); const isVideo = document.querySelector('.isVideo'); const top = `${Math.max(0, (videoBox.offsetHeight - isVideo.offsetHeight) / 2 -90)}px` if(this.isTabsBoxOpen){ this.videoItem = { width: videoBox.offsetWidth/2 +'px', height: 'auto', marginTop: top } this.myStyle = { width: videoBox.offsetWidth/2 +'px !important', height: 'auto !important', right:'30%' ,marginTop: top }; }else{ this.videoItem = { width: videoBox.offsetWidth/2 +'px', height: 'auto', marginTop: '15%' } this.myStyle = { width: videoBox.offsetWidth/2 +'px !important', height: 'auto !important', right:'0' ,marginTop: '15%' }; } break; } }, //获取课程详情 demo(list) { const arr = list ?? []; const transparentElements = document.querySelectorAll(".vjs-marker"); transparentElements.forEach(function (element, index) { // 在这里对每个透明元素进行进一步的操作 const textNode = document.createElement("div"); textNode.textContent = arr[index]; var textLength = textNode.innerHTML.length; var width = textLength * 10; // 假设每个字符宽度为 10px textNode.style.whiteSpace = "nowrap"; textNode.style.position = "absolute"; textNode.style.bottom = "10px"; // textNode.style.color = 'orange' // textNode.style.left = `-${width}px` textNode.style.fontSize = "14px"; textNode.style.background = "rgba(0,0,0,0.5)"; textNode.style.padding = "10px"; textNode.classList.add("is_element"); element.insertBefore(textNode, element.firstChild); }); }, // 选集 changevideo(val) { console.log(val); if (this.cVideoUlr == val) { this.isPaused = false; this.myvideo.pause(); } }, play() { //修改当前的播放状态 this.isPaused = !this.isPaused; if (this.isPaused) { this.myvideo.play(); this.myvideo1.play(); } else { this.myvideo.pause(); this.myvideo1.pause(); } }, // 进度条拖动时间 getNewTime(val) { console.log(val); this.myvideo.currentTime = val; this.myvideo1.currentTime = val; }, // 音量控制 getNewVoice(val) { this.volume = val; let newVc = val / 100; //h5规定,volume的值必须再0-1之间,比如0.5就是50%的音量,但是进度条的值为100,因此这里做个除法 this.myvideo.volume = newVc; //赋值 }, //时间格式化处理 timeFormat(time) { let minute = Math.floor((time % 3600) / 60); let second = Math.floor(time % 60); minute = minute < 10 ? "0" + minute : minute; second = second < 10 ? "0" + second : second; return `${minute}:${second}`; }, //获取总时长 getTotal() { this.totalTime = this.timeFormat(this.myvideo.duration); this.durationProgress = this.myvideo.duration; // if(res.customKpointList.length){ // arr = res.customKpointList.map(ele=>{ // return {time:ele.nodeSeconds,text:ele.kpointName} // }) // } }, //获取当前视频播放到的时间 timeupdate() { if (this.myvideo.currentTime == this.myvideo.duration) { this.isPaused = !this.isPaused; this.myvideo.pause(); this.myvideo1.pause(); } this.currentTime = this.timeFormat(this.myvideo.currentTime); this.currentTimeVal = this.myvideo.currentTime; }, handleFullScreenChange() { const playerVideo = this.$refs.myvideo2; const that = this; if (!document.fullscreenElement) { that.myvideo.currentTime = playerVideo.currentTime; that.myvideo1.currentTime = playerVideo.currentTime; // that.isOpacity = false this.$nextTick(()=>{ console.log(document.querySelectorAll('video')[2].style,'document.querySelectorAll("video")'); document.querySelectorAll('video')[2].style.width = 0 }) that.myvideo.play(); that.myvideo1.play(); this.myvideo1.volume = this.is_line2 ? 1 : 0; //赋值 this.myvideo.volume = this.is_line ? 1 : 0; //赋值 playerVideo.pause(); const customElement = document.querySelector('.overlay-module'); customElement.pause(); customElement.remove(); this.isPaused = true // 执行退出全屏后的逻辑 }else{ this.$refs.myvideo.pause(); this.$refs.myvideo1.pause(); const playerVideo = this.$refs.myvideo; // console.log(playerVideo.currentTime,'playerVideo.currentTime'); // // const isVideo = document.querySelector(".isVideo"); const newElement = document.createElement("video"); // 创建新的 div 元素 newElement.classList.add('overlay-module') newElement.style.position = `absolute`; newElement.style.objectFit = `cover`; // newElement.style.right = `0`; newElement.src = this.cTwoVideoUlr; // newElement.controls = true; // newElement.autoplay = true; const video2 = document.querySelectorAll('.vjs-tech')[1] console.log(this.myStyle,'this.myStyle'); console.log(video2,'this.video2'); console.log(newElement,'this.newElement'); if(this.myStyle?.height){ newElement.style.width = '50%'; newElement.style.height = 'auto'; newElement.style.top = '25%'; video2.style.width = '50%'; video2.style.top = '25%'; video2.style.height = 'auto'; }else{ newElement.style.width = '30%'; newElement.style.height = '30%'; video2.style.width = '100%'; video2.style.top = '0'; video2.style.height = '100%'; } newElement.volume = 0 newElement.currentTime = playerVideo.currentTime if(this.myStyle?.bottom){ console.log('bottom'); newElement.style.bottom = this.myStyle.bottom } if(this.myStyle?.right){ newElement.style.right = 0 } if(this.myStyle?.top){ newElement.style.top = this.myStyle.top console.log('top'); } if(this.myStyle?.bottom){ newElement.style.left = this.myStyle.left console.log('left'); } newElement.autoplay = true const videoJsContainer = document.querySelector(".video-js"); if(this.display){ videoJsContainer.appendChild(newElement); } } }, //全屏切换 toggleFullScreen(event) { this.$nextTick(() => { this.$refs.myvideo.pause(); this.$refs.myvideo1.pause(); const player = videojs(this.$refs.myvideo2); if (player) { player.src({ src: this.cVideoUlr, // type: 'video/mp4', // 根据你的视频格式来设置 }); // this.$refs.myvideo1.pause(); // 如果你想要在新的视频加载后立即播放,可以调用 player.play() // 但是请注意浏览器对自动播放的限制 // this.player.play(); player.play() player.volume = 0 } player.currentTime(this.myvideo.currentTime); //如果当前是全屏状态,就退出全屏,否则进入全屏状态 //获取当前的全屏状态 let isFullscreen = document.webkitIsFullScreen || document.fullscreen; if (!isFullscreen) { const inFun = player.requestFullscreen || player.webkitRequestFullScreen; //让当前播放器进入全屏状态 inFun.call(player); console.log(1); } else { const exitFun = document.exitFullscreen || document.webkitExitFullScreen; //退出全屏状态要使用document exitFun.call(document); console.log(2); // this.$refs.myvideo2.style.width='100px' // this.$refs.myvideo2.style.height='100px' } // if (player.requestFullscreen) { // player.requestFullscreen(); // } else if (player.mozRequestFullScreen) { // player.mozRequestFullScreen(); // Firefox // } else if (player.webkitRequestFullscreen) { // player.webkitRequestFullscreen(); // Chrome, Safari and Opera // } else if (player.msRequestFullscreen) { // player.msRequestFullscreen(); // IE/Edge // } }); }, }, }; </script> <style lang="scss" scoped> .video-box, .info-box { // float: left; background: #fff; height: 100%; box-sizing: border-box; } .iconfonts { display: flex; justify-content: center; align-items: center; font-size: 30px; } .iconfont { display: flex; justify-content: center; align-items: center; font-size: 30px; cursor: pointer; } .courseEvaluation{ font-size: 14px; color: #585a73; line-height: 24px; padding: 0 20px 0 10px; } .coures-icon{ font-size: 18px; padding: 10px 20px 0 10px; cursor: pointer; } .chapter{ font-size: 15px; color: rgb(64, 64, 64); margin: 20px 0; } .isOpen{ position: fixed; // right: 0; top: 50%; z-index: 99; cursor: pointer; transition: right 0.3s ease; color: #585a73; .isOpen-icon{ font-size: 40px } } .tabs-box.collapsed { right: -30%; } .records{ position: absolute; right: 30px; top: 0px; cursor: pointer; z-index: 999; } .tabs-box{ width: 30%; padding: 20px 30px; height: 100%; overflow-y: scroll; position: fixed; right: 0; top: 0; background-color: white; transition: right 0.3s ease; /deep/.el-tabs__item { font-size: 16px; } .points { width: 26vw; height: 80vh; display: flex; align-items: center; justify-content: center; } } .primary-submit{ color: #FFFFFF; background-color: #7F1083; border-color: #7F1083; text-align: center; width: 80px; cursor: pointer; height: 30px; border-radius: 4px; font-size: 14px; line-height: 30px; margin: 0 auto; margin-top: 20px; } .video-box { width: 100%; box-sizing: border-box; position: relative; height: 100vh; overflow: hidden; .isVideo { width: 30% !important; height: 30% !important; position: fixed; z-index: 99; } video { width: 100%; height: 100vh; object-fit: cover; cursor: pointer; } .control { width: 100%; height: 90px; padding-top: 18px; padding-right: 20px; position: absolute; bottom: 0; left: 0; background-color: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: space-between; color: #fff; .iconicon_play { cursor: pointer; width: 50px; height: 50px; } .iconzanting1 { cursor: pointer; width: 50px; height: 50px; } .line:hover { color: orange; } .line { display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: 14px; margin-right: 15px; cursor: pointer; img { width: 25px; height: 25px; } i { font-size: 25px; } } /deep/.el-select .el-input .el-select__caret { color: #fff; } /deep/.el-input__inner { color: #fff; &::placeholder { color: #fff; } &::-webkit-input-placeholder { /* WebKit browsers 适配谷歌 */ color: #fff; } &:-moz-placeholder { /* Mozilla Firefox 4 to 18 适配火狐 */ color: #fff; } &::-moz-placeholder { /* Mozilla Firefox 19+ 适配火狐 */ color: #fff; } &:-ms-input-placeholder { /* Internet Explorer 10+ 适配ie*/ color: #fff; } } .time { margin-left: 0.22rem; color: #f5f5fa; } .iconyinliang-gao { margin-left: 2.68rem; } /deep/.el-input, div.el-select { width: 1.1rem !important; background-color: transparent; .el-input__inner { background-color: transparent; } } .anthology { margin: 0 0.2rem 0 0.24rem; } .iconquanping-video, .iconquanping { margin-left: 0.44rem; cursor: pointer; } } /deep/ .el-slider { width: 0.88rem; margin-left: 0.1rem; .el-slider__runway, .el-slider__bar { height: 6px !important; } // .el-slider__button { // width: 0.13rem; // height: 0.13rem; // } .el-slider__button-wrapper { top: -16px; } } .progress { width: 100%; position: absolute; bottom: 44px; left: 0; // overflow: hidden; z-index: 999; padding: 0 1%; .el-slider { width: 100%; // margin-left: 0; } } .operating-room-video::-webkit-scrollbar { // height: 4px; // background:#bababa; } .operating-room-video { width: 100%; height: 100px; border: 1px solid; white-space: nowrap; overflow-x: auto; overflow-y: hidden; > div.lunb { width: max-content; height: 1.2rem; > div.sing { width: 2.07rem; display: block; height: 1.2rem; float: left; position: relative; cursor: pointer; > img { width: 2.08rem; height: 1.2rem; } .name { width: 100%; position: absolute; bottom: 0; left: 0; background-color: rgba(0, 0, 0, 0.1); text-align: center; color: #fff; } } } } } .video-info-height { height: 6.3rem; } .info-box { width: 3.92rem; /deep/ .el-tabs__nav-scroll { display: flex; justify-content: space-around; .el-tabs__item { font-size: 0.18rem; padding: 0 0.5rem; color: #999; } .el-tabs__active-bar { width: 0.75rem !important; background-color: red; } .is-active { color: #333; } } .video-info { padding: 0.1rem 0.4rem; > div { line-height: 0.34rem; display: flex; > div:first-child { color: red; margin-right: 0.1rem; min-width: 0.7rem; } > div { display: inline-block; } } } .patient-info { > div { > div:first-child { min-width: 0.9rem; } } } } .fade-enter-active, .fade-leave-active { transition: opacity 1s; } .fade-enter, .fade-leave-to { opacity: 0; } .marker { position: absolute; top: -30px; /* 根据需要调整与滑块的距离 */ text-align: center; pointer-events: none; } .marker-dot { display: inline-block; width: 15px; height: 15px; background-color: rgb(127, 16, 131); border-radius: 50%; margin-bottom: -38px; /* 与名称之间的间距 */ cursor: pointer; } .marker-name { font-size: 12px; color: #fff; } /deep/.vjs_video_3-dimensions{ width: 100%; } </style>视频没问题 为什么我在移动端就播放不起了
09-04
ftl文件 <!DOCTYPE html> <html lang="en"> <#include "/common/taglibs.ftl"> <head> <meta charset="UTF-8"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <title>农村居住区</title> <link rel="stylesheet" href="${ctx}/plugins/layui/css/layui.css"> <link rel="stylesheet" href="${ctx}/infoSys/css/style.css"> <script src="${ctx}/plugins/jquery-3.3.1.min.js"></script> <script src="${ctx}/plugins/vue/vue.js"></script> <script src="${ctx}/plugins/layui/layui.js"></script> <script src="${ctx}/plugins/common/custom_layui.js"></script> <script src="${ctx}/plugins/nightMap/api.js"></script> <script src="${ctx}/plugins/nightMap/heatmap_min.js"></script> <script src="${ctx}/plugins/nightMap/mapv.js"></script> <script src="${ctx}/plugins/nightMap/haidian.js"></script> <script src="${ctx}/aiplatform/js/verifyList.js"></script> <style> .left-nav-ul .streetManage { border-left: 2px #2080E7 solid; } .left-nav-ul .streetManage a { color: #2080E7; background-image: url(${ctx}/othersSys/images/icon-lajilou2.svg); } .layui-table-box th, .layui-table-box td { text-align: center; } .layui-table-cell { height: auto; line-height: auto; } #addMap { width: 100%; } .administrativeNumber{ width: 100%; height: 50px; line-height: 50px; background-color: #e6f7ff; border: 1px solid #c3e0eb; padding-left: 10px; } </style> </head> <body class="body"> <div class="padding-body" id="app" v-cloak> <iframe src="${ctx}/service/allNav" style="position: fixed;left: 0;top: 0;width: 18rem;height: 100%;" allowfullscreen allow="autoplay; fullscreen"></iframe> <!-- left --> <#-- <#include "/infoSys/nav2.ftl">--> <!-- header --> <#include "/infoSys/header.ftl"> <!-- main --> <section class="main"> <div class="header-title white-bg clearfix"> <h1>{{config.title}}</h1> </div> <div class="main-content white-bg"> <form class="layui-form search-form" onkeypress="return event.keyCode != 13;"> <div class="layui-inline" v-for="(item,index) in config.searchForm"> <label class="layui-form-label first-label">{{item.title}}:</label> <div class="layui-input-inline" v-if="item.type == 'select'"> <select :name="item.prop" :id="item.prop" v-model="searchData[item.prop]" style="width:150px;height:30px" :lay-filter="'form_'+item.prop"> <option v-for="sItem in item.option" :value="sItem.value" >{{sItem.label}}</option> </select> </div> <div class="layui-input-inline" v-else> <input type="text" :id="item.prop" :name="item.prop" v-model="searchData[item.prop]" :placeholder="`请输入`+item.title" autocomplete="off" class="layui-input"/> </div> </div> <#--阻止回车触发提交--> <div class="layui-input-inline" style="width: 200px;display: none;"> <select lay-verify="" type="hidden"> </select> </div> <div class="layui-inline margin-left15" style="float: right;margin-right: 20px;"> <#-- <button type="button" class="layui-btn layui-btn-normal" id="taste_button" lay-submit="record"--> <#-- lay-filter="record">语音--> <#-- </button>--> <#-- <button type="button" class="layui-btn layui-btn-normal" id="start_button" class="start-button"--> <#-- style="display: none">停止--> <#-- </button>--> <button type="button" class="layui-btn layui-btn-normal" lay-submit="" lay-filter="formSearch">查询 </button> <button type="reset" lay-submit lay-filter="formReset" class="layui-btn layui-btn-primary">重置</button> </div> </form> <#-- <div class="administrativeNumber">行政村总数:{{ count }}</div>--> <div> <a class="layui-btn layui-btn-normal layui-btn-sm" v-if="btnJson.add" @click="alertFun('','add')">新建</a> <#-- <a class="layui-btn layui-btn-normal layui-btn-sm" v-if="btnJson.moreUpload" id="moreUpload"--> <#-- class="moreUpload">导入</a>--> <a class="layui-btn layui-btn-normal layui-btn-sm" v-if="btnJson.moreUpload" id="moreUpload" class="moreUpload" @click="uploads">导入</a> <#-- <a class="layui-btn layui-btn-normal layui-btn-sm" v-if="btnJson.download"--> <#-- href="../../../excel/model_street_export.xlsx" download="街镇模板">模板下载</a>--> <a class="layui-btn layui-btn-normal layui-btn-sm" lay-submit="" v-if="btnJson.export" lay-filter="export">导出</a> <#-- <a class="layui-btn layui-btn-normal layui-btn-sm" v-if="btnJson.print" @click="prints()">打印</a>--> <#-- <a class="layui-btn layui-btn-normal layui-btn-sm">新建</a>--> <#-- <a class="layui-btn layui-btn-normal layui-btn-sm" id="moreUpload" class="moreUpload">导入</a>--> <#-- <a class="layui-btn layui-btn-normal layui-btn-sm" href="../../../excel/model_street_export.xlsx" download="街镇模板">模板下载</a>--> <#-- <a class="layui-btn layui-btn-normal layui-btn-sm" lay-submit="" lay-filter="export">导出</a>--> <#-- <a class="layui-btn layui-btn-normal layui-btn-sm" @click="prints()">打印</a>--> </div> <div style="clear:both;"></div> <table id="allTable" lay-filter="allTable" lay-skin="line"></table> </div> </section> <!-- 添加和编辑查看弹窗 --> <form class="layui-form" lay-filter="information" id="information" style="display:none;padding:35px 30px"> <div class="layui-form-item" v-for="(item,index) in config.form"> <div class="layui-inline"> <label class="layui-form-label"><span class="red">*</span> {{item.title}}</label> <div class="layui-input-inline" v-if="item.type == 'select'"> <select :name="item.prop" :id="item.prop" style="width:150px;height:30px"> <option v-for="sItem in item.option" :value="sItem.value">{{sItem.label}}</option> </select> </div> <div class="layui-input-inline" v-else-if="item.type == 'custom-text'"> 自定义内容 </div> <div class="layui-input-inline" v-else> <input type="text" :name="item.prop" autocomplete="off" :lay-verify="item.rule" class="layui-input"/> </div> </div> </div> <div class="layui-form-item"> <div class="layui-input-block"> <button type="button" v-show="type!=='look'" class="layui-btn layui-btn-lg layui-btn-normal" lay-submit="" lay-filter="up">提交 </button> <button type="button" class="layui-btn layui-btn-lg layui-btn-normal" onclick="layer.closeAll()">取消 </button> </div> </div> </form> <div id="UploadFile" class="UploadFileWrapper" style="width: 100%;height: 100%;padding: 1rem;box-sizing: border-box;display: none"> <div class="layui-btn-container" id="upload-btn-warp"> <span id="choiceWrapper"><button type="button" class="layui-btn layui-btn-normal" id="choice">选择文件</button></span> <span id="checkFileWrapper"><button type="button" class="layui-btn" id="checkFile">校验</button></span> <button type="button" class="layui-btn" id="startUpload" @click="fnUploadFile">开始上传</button> </div> <div style="margin: 1rem 0"> <div>操作步骤:</div> <div>1.选择需要上传的文件</div> <div>2.选择完成后点击“校验”按钮</div> <div>3.校验通过后点击“确认上传”</div> </div> </div> </div> <script> var menusButtonList = '${Session.buttonList?default("")}'; menusButtonList = menusButtonList ? JSON.parse(menusButtonList) : [] $(document).on("keypress", "form", function (event) { return event.keyCode != 13; }) </script> <script src="${ctx}/infoSys/js/public.js"></script> <script src="${ctx}/infoSys/js/countryPlanning/list.js"></script> <script src="${ctx}/infoSys/js/add-map.js"></script> <script src="${ctx}/plugins/rtasr/hmac-sha256.js"></script> <script src="${ctx}/plugins/rtasr/HmacSHA1.js"></script> <script src="${ctx}/plugins/rtasr/md5.js"></script> <script src="${ctx}/plugins/rtasr/enc-base64-min.js"></script> <script src="${ctx}/plugins/rtasr/index.js"></script> <script src="${ctx}/infoSys/js/navPublic.js"></script> </body> </html> js文件 const script = document.createElement('script'); script.src = `${ctx}/infoSys/js/commonJs/formConfig.js`; // 替换为实际的JavaScript文件路径 document.head.appendChild(script); script.onload = function() { // 此处可以执行其他操作 const config = countryPlanningCfg var vues = new Vue({ el: '#app', // mixins: [myMixins], // components:{ // upload // }, watch:{ 'searchData.streetName':function (n,o){ this.loadCommunityData(n) } }, computed:{ config:()=>{ return config } }, data: { navList:[],//nav模块 paramList:{},//nav模块-url tableHead: config.tableHead, streetList: [], communityList: [], menuBtn: [], btnJson: config.btnJson, isHaveHandle: false, searchListFlag: false, searchLi: [], printQuery: '', cheakliat: "", // searchData:{}, name: '', imgShow: false, type: '', url: '', uploadFile: new FormData(), uploadsVar: '', count:0, searchData: { name: '', commName: '', streetName: '', }, }, mounted: function () { // this.getNav() this.menuListBtn() this.table(); this.loadStreetData() // 绑定街道下拉框 change 事件 const streetSelect = document.getElementById('streetName'); if (streetSelect) { streetSelect.addEventListener('change', this.onStreetChange); } layui.use('form', () => { const form = layui.form form.render('select') // 页面加载时初始化所有下拉框 }) const self = this layui.use(['form'], function () { layui.form.on('select(form_streetName)', function (data) { self.searchData.streetName = data.value }) }) // this.selcetInit(); }, methods: { selectChange(prop){ console.log(prop,'prop') }, // 加载街道数据 loadStreetData() { const self = this $.ajax({ url: ctx + '/service/region/list', type: 'GET', data: { grade: 3 // 街道等级为3 }, success: function (res) { console.log(res,'resss') if (res.code === 0) { const streetOptions = res.data.map(item => ({ label: item.name, value: item.coding, coding: item.coding })) console.log('街道数据加载完成:', streetOptions) // 更新街道下拉选项 const streetItem = self.config.searchForm.find(i => i.prop === 'streetName'); if (streetItem) streetItem.option = streetOptions; // 更新搜索表单和编辑表单中的街道下拉选项 self.$set( self.config.searchForm.find(item => item.prop === 'streetName'), 'option', streetOptions ) console.log(self.config.searchForm,'self.config.searchForm') self.$set( self.config.form.find(item => item.prop === 'streetName'), 'option', streetOptions ) self.$forceUpdate() self.$nextTick(() => { setTimeout(() => { layui.form.render('select') }, 100) }) } else { console.error('加载街道数据失败:', res.msg) } }, error: function (xhr, status, error) { console.error('请求失败:', error) } }) }, // 根据街道编码加载社区数据 loadCommunityData(streetCoding) { const self = this; $.ajax({ url: ctx + '/service/region/list', type: 'GET', data: { grade: 4, // 社区等级为4 coding: streetCoding // 传入街道编码 }, success: function (res) { if (res.code === 0) { const commOptions = res.data.map(item => ({ label: item.name, value: item.id })); // 更新社区下拉选项 const commItem = self.config.searchForm.find(i => i.prop === 'commName'); if (commItem) { commItem.option = commOptions; } // 更新搜索表单和编辑表单中的社区下拉选项 const searchCommItem = self.config.searchForm.find(item => item.prop === 'commName'); const formCommItem = self.config.form.find(item => item.prop === 'commName'); if (searchCommItem) { searchCommItem.option.splice(0); // 清空旧数据 searchCommItem.option.push(...commOptions); } if (formCommItem) { formCommItem.option.splice(0); formCommItem.option.push(...commOptions); } self.$forceUpdate() self.$nextTick(() => { layui.form.render('select'); // 重新渲染下拉框 }); } }, error: function (xhr, status, error) { console.error('请求失败:', error); } }); }, // 监听街道选择变化 onStreetChange(event) { console.log('111',event) const streetValue = event.target.value; // 获取选中的街道值 const selectedStreet = this.config.searchForm .find(item => item.prop === 'streetName')?.option .find(item => item.value === streetValue); if (selectedStreet && selectedStreet.coding) { this.loadCommunityData(selectedStreet.coding); // 加载社区数据 } else { // 清空社区下拉框 const communityItem = this.config.searchForm.find(item => item.prop === 'commName'); if (communityItem) communityItem.option = []; const communityFormItem = this.config.form.find(item => item.prop === 'commName'); if (communityFormItem) communityFormItem.option = []; } self.$forceUpdate() this.$nextTick(() => { layui.form.render('select'); // 重新渲染下拉框 }); }, menuListBtn() { this.$nextTick(() => { let arr = [] menusButtonList.forEach((e) => { if (e.menuId == menusIds) { this.menuBtn.push(e) if (e.attrType == 1) { arr.push(e) } } }) console.log(this.menuBtn) this.menuBtn.forEach((e) => { if (e.buttonClass == 'add') { vues.btnJson.add = true } else if (e.buttonClass == 'moreUpload') { vues.btnJson.moreUpload = true } else if (e.buttonClass == 'download') { vues.btnJson.download = true } else if (e.buttonClass == 'export') { vues.btnJson.export = true } else if (e.buttonClass == 'print') { vues.btnJson.print = true } }) if (arr.length == 0) { this.isHaveHandle = true; this.tableHead[0].pop(); } }) }, //显示大图片 showBigImage(e) { layer.open({ type: 1, title: false, closeBtn: 0, shadeClose: true, //点击阴影关闭 area: [$(e).width + 'px', $(e).height + 'px'], //宽高 content: "<img src=" + $(e).attr('src') + " />" }); }, //打印 prints() { var v = document.createElement("div"); let self = this; $.ajax({ url: ctx + config.list, data: {limit: 999999, page: 1, ...self.searchData}, success: function (res) { if (res.code == 0) { if (res.data.length) { // <head><link rel="stylesheet" href="'+ctx+'/plugins/layui/css/layui.css"></head> let str = '<html><body><head><style>tr,td{padding:3px}.layui-table {width: 100%;background-color: #fff;color: #666;margin: 10px 0;}.layui-table-cell {height: 28px;line-height: 28px;padding: 0 15px;position: relative;box-sizing: border-box}.layui-table-cell{top: -1px;padding: 0}.layui-table-cell .layui-table-link {color: #01AAED}</style></head><table border style="width: 100%;border-collapse: collapse;border-spacing: 0;" class="layui-table">'; str += '<thead style="background-color: #f2f2f2;width: 100%">'; str += '<tr class=" layui-table-col-special layui-table-cell laytable-cell-1-0-5" style="background-color: #f2f2f2;font-weight: 700">'; config.tableHead[0].forEach(item=>{ str += `<td style="background: #f2f2f2;width: ${item.width}">${item.title}</td>` }) str += '</tr>'; str += '</thead>'; str += '<tbody style="width: 100%">'; for (var i = 0; i < res.data.length; i++) { str += '<tr class="layui-table" >'; config.tableHead[0].forEach(item=>{ if(item.type == 'numbers'){ str += `<td style="width: ${item.width}">${i+1}</td>`; } str += `<td style="background: #f2f2f2;width: ${item.width}">${res.data[i][item.prop] ? res.data[i][item.prop]:'-'}</td>` }) str += '</tr>'; } str += '</tbody>'; str += '</table></body></html>'; var h = window.open("打印窗口", "_blank"); h.document.write(str + $(v).prop("outerHTML")); h.document.close(); console.log(h) h.print(); h.close(); } else { layerObj.failMsg("该条件下暂无数据,无法打印!"); } } ; } }); }, //list table: function () { var self = this; //默认list var dataUrl = ctx + config.url.list; const tableHeadArr = self.tableHead[0].map(item=>{ let templet = null if(item.templet){ templet = item.templet }else if(item.title=='操作'){ templet =function (res){ var btn = ""; btn += '<a target="_blank" class="layui-btn layui-btn-xs" lay-event="look">详情</a >'; return btn; } }else{ templet =function (res) { return !res[item.prop] ? '-' : res[item.prop]; } } return { ...item, templet:templet } }) layerObj.tableList([tableHeadArr], 'allTable', dataUrl, 'tool(allTable)', function (res, curr, count) { self.count = count }, function (e) { let id = e.data.id; //查看 if (e.event === "look") { self.alertFun(id, 'look',e.data) } //编辑 if (e.event === "edit") { self.alertFun(id, 'edit') } // 删除 if (e.event === 'delete') { layer.confirm('是否删除?', { btn: ['确定', '取消'] //可以无限个按钮 }, function (index, layero) { layerObj.ajaxSend( 'get', ctx + `${config.url.delete}?id=` + id, 'json', {}, function (data) { if (data.code === 1) { layer.alert(data.msg); } else { self.table(); } } ); layer.close(index); }, function (index) { layer.close(index); }); } }, "allTable"); //搜索 layui.use(['form', 'table', 'upload'], function () { var form = layui.form; var table = layui.table; var upload = layui.upload; form.on("submit(formSearch)", function (data) { table.reload("allTable", { headers: self.tableHead, url: dataUrl, page: {curr: 1}, where: data.field, done: function () { } }, 'data'); }); // 重置 form.on("submit(formReset)", function (data) { self.condition = null table.reload("allTable", { headers: self.tableHead, url: dataUrl, page: {curr: 1}, where: self.condition, done: function () { } }, 'data'); }); //导出 form.on("submit(export)", function (data) { var name = $('input[name="name"]').val(); var cs = ctx + `${config.url.export}?name=` + name; window.open(cs); }); //上传附件 var uploadInst = upload.render({ elem: '#uploadBtn' , url: ctx + '/service/upload/minio/uploadAttach' , accept: 'file' //普通文件 , choose: function (obj) { obj.preview(function (index, file, result) { self.fileName = file.name; $('#attachUrl').html(file.name); }) } , done: function (res) { if (res.code > 0) { self.filePath = res.data.filePath self.imgShow = true $('#attachUrl').on('click', function () { window.location.href = ctx + '/service/upload/minio/downloadReplaceFileName?filename=' + $('#attachUrl').text() + '&fileUrlName=' + res.data.fileName }) layer.msg('上传成功'); }else { layer.msg(res.msg); } } }); }); }, //添加和编辑弹窗 alertFun(myid, type,data) { var self = this; self.type = type document.getElementById("information").reset(); self.imgShow = false $('#image').val(""); $("#roleIds,#roleNames").val(""); var titleName; var postUrl = ''; if (type == 'edit') { titleName = "编辑"; postUrl = ctx + config.url.edit } else if (type == 'add'){ titleName = "新建"; postUrl = ctx + config.url.add }else{ titleName = "查看"; } $('#imageWrapper').html('<input type="hidden" name="image" id="image" />') layui.use(['form', 'layer', 'upload', 'laydate'], function () { let form = layui.form; let layer = layui.layer; let upload = layui.upload; let laydate = layui.laydate; var myLayer = layer.open({ title: titleName + "菜单", type: 1, area: ["900px", "700px"], content: $("#information"), success: function () { if (myid && config.url.detail) { //回显 $.ajax({ url: ctx + `${config.url.detail}?id=` + myid, success: function (res) { const obj = {} config.form.forEach((item,index)=>{ obj[item.prop] = res.data[item.prop] ? res.data[item.prop] : '' }) form.val("information",obj); //文件 var image = res.data.image; self.filePath = image if (image && image != "") { self.imgShow = image ? true : false; $('#attachUrl').html(image.split('_')[image.split('_').length - 1]); $('#attachUrl').on('click', function () { window.location.href = ctx + '/service/upload/minio/downloadReplaceFileName?filename=' + $('#attachUrl').text() + '&fileUrlName=' + image }) } self.$nextTick(() => { form.render() }) } }); }else if(!config.url.detail){ const obj = {} config.form.forEach((item,index)=>{ obj[item.prop] = data[item.prop] ? data[item.prop] : '' }) form.val("information",obj); } else { form.val("information", {}); $('#attachUrl').html(''); self.imgShow = false; self.$nextTick(() => { form.render() }) } form.on('submit(up)', function (data) { let paramObj = data.field; paramObj.pid = self.pid; paramObj.imageUrl = self.filePath; if (myid) { paramObj.id = myid; } layerObj.commonAjax('POST', postUrl, "json", paramObj, function (data) { if (data.code == 0) { layer.closeAll(); layerObj.successMsg("保存成功!"); self.table(); } else { layerObj.failMsg(data.msg); } }); }); // 校验 form.verify(config.formVerify) } }); }); }, //点击搜索列表 queryBtn: function () { var self = this; self.searchListFlag = true; $.ajax({ url: ctx + '/service/baiduMap/get/suggestion', type: 'post', data: { "keyword": self.printQuery, "region": "北京市", "pageSize": 20, "pageNum": 1 }, success: function (res) { if (res.data.results) { self.searchLi = res.data.results; } } }); }, //确认选择li chooseLi: function (item) { var self = this; self.searchListFlag = false; var lng = item.location.longitude, lat = item.location.latitude; addPointFun(lng, lat); $(".longitudeLatitude").val(lng + "," + lat); $(".longitude").val(lng); $(".latitude").val(lat); self.printQuery = item.address; $(".detailAddress").val(item.address); bm.centerAndZoom(new BMap.Point(lng, lat), 14); }, // 页面初始化 pageInit() { var self = this; layui.use(['form', 'upload', 'layer'], function () { var upload = layui.upload; self.uploadsVar = upload.render({ elem: '#choice', accept: 'file', acceptMime: 'application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', exts: 'xlsx|xls', //只允许上传excel文件, auto: false, bindAction: '#checkFile' }); }) }, // 上传弹框 uploads() { $('#choiceWrapper').html('<button type="button" class="layui-btn layui-btn-normal" id="choice">选择文件</button>'); this.uploadsVar = ''; $('.layui-upload-choose').html(''); $('#checkFileWrapper').html('<span id="checkFileWrapper"><button type="button" class="layui-btn" id="checkFile">校验</button></span>'); this.pageInit() this.$nextTick(() => { $('#startUpload').css('display', 'none') }) let self = this layui.use(['form', 'upload', 'layer'], function () { let form = layui.form; let layer = layui.layer; var upload = layui.upload; var checkurl = '' var myLayer = layer.open({ title: '上传文件', type: 1, area: ["680px", "250px"], content: $("#UploadFile"), success: function (res) { // 校验接口 checkurl = ctx + '/service/base/street/checkExcelUpload' self.uploadsVar.reload({ elem: '#choice', accept: 'file', acceptMime: 'application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', exts: 'xlsx|xls', //只允许上传excel文件, url: checkurl, auto: false, bindAction: '#checkFile', choose: (obj) => { $('#startUpload').css('display', 'none') self.uploadFile = new FormData(); var files = obj.pushFile(); var firstProp; var count = 0; // 获取第一个属性 for (var key in files) { if (files.hasOwnProperty(key)) { firstProp = key; break; } } // 统计文件数 for (var k in files) { count++; } if (count > 1) { delete files[firstProp]; } //预读本地文件,如果是多文件,则会遍历。(不支持ie8/9) obj.preview(function (index, file, result) { self.uploadFile.append('file', file); }); }, done: function (res, index) { if (res.code == 0) { layer.msg(res.msg); $('#startUpload').css('display', 'inline-block') } else { layer.alert(res.msg); $('#startUpload').css('display', 'none') } } }); } , end: () => { $('#startUpload').css('display', 'none') } }) }) }, // 上传 fnUploadFile() { var self = this layui.use(['layer'], function () { var layer = layui.layer; // 上传接口 var url = '' url = ctx + config.url.import let key = self.uploadFile.getAll('file')[0]; $.ajax({ url: url, method: 'post', data: self.uploadFile, contentType: false, processData: false, dataType: "json", async: false, success: (res) => { if (res.code == 0) { layer.msg(res.msg); setTimeout(() => { layer.closeAll(); self.table(); }, 2500); } else { layer.alert(res.msg); } }, fail: (res) => { layer.alert(res.msg); } }) }) }, //nav-获取列表 getNav(){ let self = this let url = document.location.toString() let urlObj = url.split('?') let paramObj let paramList = {}//url参数集合 if(urlObj.length >0){ paramObj = urlObj[1].split('&') paramObj.forEach((val,index)=>{ let arrList = val.split('=') Object.defineProperty(paramList,arrList[0],{value:arrList[1]}) // paramList.arrList[0] = arrList[1] }) } self.paramList = paramList //获取菜单列表并渲染 $.ajax({ url:ctx + "/service/authorityMenu/listByMenuId?menuId="+paramList.pid, type:"get", success:function (res) { console.log('菜单请求返回值',res) if(res.code == 0){ //修改数据内容 渲染nav选中项 res.data.forEach((val,index)=>{ if(val.childMenus.length>0){ val.childMenus.forEach((value)=>{ value.select = false; if(value.id == self.paramList.cid||value.id == self.paramList.cPid){ value.select = true; } value.childMenus }) } }) self.navList = res.data } } }) }, //nav-页面跳转 toUrl(items){ console.log(items) if(items.url.indexOf('?') != -1){ window.location.href = ctx + items.url+'&pid='+this.paramList.pid+'&cid='+items.id+'&cPid='+items.pid }else{ window.location.href = ctx + items.url+'?pid='+this.paramList.pid+'&cid='+items.id+'&cPid='+items.pid } }, //nav-渲染nav选中项 changeNavState(items){ items.select = !items.select }, //时间戳转日期函数 DateFormat(sjc) { var date = new Date(sjc); var y = date.getFullYear(); var m = date.getMonth() + 1; m = m < 10 ? '0' + m : m; var d = date.getDate(); d = d < 10 ? ("0" + d) : d; var h = date.getHours(); h = h < 10 ? ("0" + h) : h; var min = date.getMinutes(); min = min < 10 ? ("0" + min) : min; var s = date.getSeconds(); s = s < 10 ? ("0" + s) : s; var str = y + "-" + m + "-" + d + " " + h + ":" + min + ":" + s; return str; }, }, }) }; 点击街镇和社区的下拉点击查询按钮可以查询
09-04
本指南详细阐述基于Python编程语言结合OpenCV计算机视觉库构建实时眼部状态分析系统的技术流程。该系统能够准确识别眼部区域,并对眨眼动作与持续闭眼状态进行判别。OpenCV作为功能强大的图像处理工具库,配合Python简洁的语法特性与丰富的第三方模块支持,为开发此类视觉应用提供了理想环境。 在环境配置阶段,除基础Python运行环境外,还需安装OpenCV核心模块与dlib机器学习库。dlib库内置的HOG(方向梯度直方图)特征检测算法在面部特征定位方面表现卓越。 技术实现包含以下关键环节: - 面部区域检测:采用预训练的Haar级联分类器或HOG特征检测器完成初始人脸定位,为后续眼部分析建立基础坐标系 - 眼部精确定位:基于已识别的人脸区域,运用dlib提供的面部特征点预测模型准确标定双眼位置坐标 - 眼睑轮廓分析:通过OpenCV的轮廓提取算法精确勾勒眼睑边缘形态,为状态判别提供几何特征依据 - 眨眼动作识别:通过连续帧序列分析眼睑开合度变化,建立动态阈值模型判断瞬时闭合动作 - 持续闭眼检测:设定更严格的状态持续时间与闭合程度双重标准,准确识别长时间闭眼行为 - 实时处理架构:构建视频流处理管线,通过帧捕获、特征分析、状态判断的循环流程实现实时监控 完整的技术文档应包含模块化代码实现、依赖库安装指引、参数调优指南及常见问题解决方案。示例代码需具备完整的错误处理机制与性能优化建议,涵盖图像预处理、光照补偿等实际应用中的关键技术点。 掌握该技术体系不仅有助于深入理解计算机视觉原理,更为疲劳驾驶预警、医疗监护等实际应用场景提供了可靠的技术基础。后续优化方向可包括多模态特征融合、深度学习模型集成等进阶研究领域。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值