| | |
| | | <template> |
| | | <div id="map-index"> |
| | | <div class="control"> |
| | | <div class="location icon iconfont" @click="location"></div> |
| | | <div class="zoom-in icon iconfont" @click="zoomIn"></div> |
| | | <div class="zoom-out icon iconfont" @click="zoomOut"></div> |
| | | <a href="#" title="定位" @click="aClick()"> |
| | | <div class="location icon iconfont" @click="location"></div> |
| | | </a> |
| | | <a href="#" title="放大" @click="aClick()"> |
| | | <div class="zoom-in icon iconfont" @click="zoomIn"></div> |
| | | </a> |
| | | |
| | | <a href="#" title="缩小" @click="aClick()"> |
| | | <div class="zoom-out icon iconfont" @click="zoomOut"></div> |
| | | </a> |
| | | </div> |
| | | <div class="range icon iconfont" @click="drawPolygon"></div> |
| | | <a href="#" title="新增/编辑" @click="aClick()"> |
| | | <div class="range icon iconfont" @click="drawPolygon"></div> |
| | | </a> |
| | | <el-input v-model="nodeId" placeholder="请输入内容"></el-input> |
| | | <div class="save" v-if="showBtn" @click="savePoly">保存</div> |
| | | <div class="del" v-if="polygonInfo" @click="delPoly">删除</div> |
| | | <div class="cancel" v-if="showBtn" @click="resetMap">取消</div> |
| | | |
| | | <span id="polygonInfo" v-show="polygonInfo">{{ polygonInfo }}</span> |
| | | |
| | | <img |
| | | v-if="myNode && !isHidden" |
| | | src="/images/map/Group 594.png" |
| | | alt="" |
| | | class="video_icon" |
| | | @click="hiddenVideo()" |
| | | /> |
| | | <a v-else href="#" title="实时监控" @click="aClick()"> |
| | | <img |
| | | src="/images/map/监控.png" |
| | | alt="" |
| | | class="video_icon" |
| | | @click="showVideo()" |
| | | /> |
| | | </a> |
| | | |
| | | <div class="video_box" v-if="myNode" :class="{ hidden: isHidden }"> |
| | | <div class="title"> |
| | | <div class="left"> |
| | | <span class="ball"></span> |
| | | <span class="left_info">实时监控</span> |
| | | </div> |
| | | |
| | | <div class="right">设备编码: {{ myNode.values_.id }}</div> |
| | | </div> |
| | | |
| | | <video controls="controls" loop="loop"> |
| | | <source src="/images/map/video_20210924_101628.mp4" type="video/mp4" /> |
| | | </video> |
| | | </div> |
| | | |
| | | <div class="helmet_box" v-show="myNode"> |
| | | <div class="icon_close iconfont" @click="close"></div> |
| | | <div class="sn" v-if="myNode">{{ myNode.values_.lat.id }}</div> |
| | | <div class="location" v-if="myNode">经度: {{ myNode.values_.lat }}</div> |
| | | <div class="location" v-if="myNode">纬度: {{ myNode.values_.lng }}</div> |
| | | <div class="info" v-if="myNode">电量: {{ myNode.values_.battery }}</div> |
| | | <div class="button"> |
| | | <img |
| | | src="/images/InternetData/视频.png" |
| | | alt="" |
| | | v-if="!isSending" |
| | | @click="sendVoice()" |
| | | /> |
| | | <img src="/images/InternetData/视频_点击.png" alt="" v-if="isSending" /> |
| | | <img |
| | | src="/images/InternetData/语音.png" |
| | | alt="" |
| | | v-if="isTele == false" |
| | | @click="isTele = true" |
| | | /> |
| | | <img |
| | | src="/images/InternetData/语音_点击.png" |
| | | alt="" |
| | | v-if="isTele == true" |
| | | @click="isTele = false" |
| | | /> |
| | | </div> |
| | | </div> |
| | | |
| | | <telephoneBox :tele="myNode" v-if="isTele" @close="isTele = false" /> |
| | | |
| | | <div class="mask" v-if="isTele"></div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getHelemtData, getZones, createZones } from "@/api/helemt"; |
| | | import { |
| | | getHelemtData, |
| | | getZones, |
| | | createZones, |
| | | delZones, |
| | | sendAudio, |
| | | } from "@/api/helemt"; |
| | | import telephoneBox from "../components/telephoneBox.vue"; |
| | | |
| | | import "ol/ol.css"; |
| | | import Feature from "ol/Feature"; |
| | |
| | | import Draw from "ol/interaction/Draw"; |
| | | import { Modify, Snap } from "ol/interaction"; |
| | | import Polygon from "ol/geom/Polygon"; |
| | | import Select from "ol/interaction/Select"; |
| | | import Overlay from "ol/Overlay"; |
| | | import { pointerMove } from "ol/events/condition"; |
| | | |
| | | let myMap = {}; |
| | | let myVectorSource = {}; |
| | |
| | | }); |
| | | let myDraw = {}; |
| | | let myModify = {}; |
| | | let myPolygon = {}; |
| | | let mySelect = {}; |
| | | let overlay = {}; |
| | | let overlay2 = {}; |
| | | let voiceText = ""; |
| | | |
| | | export default { |
| | | created() { |
| | | this.getNodeData(); |
| | | }, |
| | | data() { |
| | | return { |
| | | isSending: false, |
| | | isTele: false, |
| | | isHidden: false, |
| | | showBtn: false, |
| | | nodeArr: [ |
| | | { data: [116.06157, 39.66157], id: 1, color: "绿" }, |
| | | { data: [116.06247, 39.66247], id: 2, color: "绿" }, |
| | | { data: [116.06337, 39.66337], id: 3, color: "绿" }, |
| | | { data: [116.06467, 39.66437], id: 4, color: "绿" }, |
| | | { data: [116.06517, 39.66517], id: 5, color: "红" }, |
| | | { data: [116.06627, 39.66627], id: 6, color: "红" }, |
| | | { data: [116.06787, 39.66787], id: 7, color: "红" }, |
| | | { data: [116.06897, 39.66897], id: 8, color: "红" }, |
| | | ], |
| | | nodeArr: [], |
| | | nodeId: "", |
| | | iconArr: [], |
| | | rangeArr: [], |
| | |
| | | polyFeature: [], |
| | | drawStore: [], |
| | | modifyStore: [], |
| | | polygonInfo: "", |
| | | nodeFeature: [], |
| | | myNode: null, |
| | | commentContent: "", |
| | | }; |
| | | }, |
| | | mounted() { |
| | | this.initMap(); |
| | | }, |
| | | components: { |
| | | telephoneBox, |
| | | }, |
| | | methods: { |
| | | async getNodeData() {}, |
| | | async initMap() { |
| | | const that = this; |
| | | // 获取节点 |
| | | const res = await getHelemtData(); |
| | | this.nodeArr = []; |
| | |
| | | data: [item.lng, item.lat], |
| | | id: item.device_sn, |
| | | color: item.is_out_bound == 0 ? "绿" : "红", |
| | | battery: item.battery, |
| | | }); |
| | | }); |
| | | |
| | |
| | | return obj; |
| | | }); |
| | | } |
| | | console.log(this.polygonArr); |
| | | |
| | | // 设置地图中心 |
| | | this.center = this.nodeArr[0].data; |
| | |
| | | console.log(item); |
| | | }) |
| | | }) */ |
| | | |
| | | window.addEventListener("resize", function () { |
| | | map.updateSize(); |
| | | }); |
| | | |
| | | const select = new Select({ |
| | | filter: (feature, layer) => { |
| | | if (feature.values_ && feature.values_.type == "node") { |
| | | this.myNode = feature; |
| | | return true; |
| | | } else if (feature.type && feature.type == "polygon") { |
| | | myPolygon = feature; |
| | | this.myNode = null; |
| | | |
| | | return true; |
| | | } else { |
| | | this.myNode = null; |
| | | return false; |
| | | } |
| | | }, |
| | | style: (feature) => { |
| | | if (feature.values_ && feature.values_.type == "node") { |
| | | return new Style({ |
| | | image: new Icon({ |
| | | size: [32, 32], |
| | | src: `/images/map/安全帽-${feature.values_.color}.png`, |
| | | }), |
| | | zIndex: 1, |
| | | }); |
| | | } else if (feature.type && feature.type == "polygon") { |
| | | return new Style({ |
| | | fill: new Fill({ |
| | | color: "rgba(0, 0, 255, 0.1)", |
| | | }), |
| | | stroke: new Stroke({ |
| | | color: "skyblue", |
| | | width: 3, |
| | | }), |
| | | }); |
| | | } |
| | | }, |
| | | }); |
| | | |
| | | const select2 = new Select({ |
| | | condition: pointerMove, |
| | | filter: (feature, layer) => { |
| | | if (feature.values_ && feature.values_.type == "node") { |
| | | return true; |
| | | } else { |
| | | return false; |
| | | } |
| | | }, |
| | | style: (feature) => { |
| | | if (feature.values_ && feature.values_.type == "node") { |
| | | return new Style({ |
| | | image: new Icon({ |
| | | size: [32, 32], |
| | | src: `/images/map/安全帽-${feature.values_.color}.png`, |
| | | }), |
| | | zIndex: 1, |
| | | }); |
| | | } |
| | | }, |
| | | }); |
| | | |
| | | const info = document.querySelector("#polygonInfo"); |
| | | |
| | | map.addInteraction(select); |
| | | map.addInteraction(select2); |
| | | mySelect = select; |
| | | select.on("select", function (e) { |
| | | e.stopPropagation(); |
| | | overlay2.setPosition(undefined); |
| | | |
| | | if (e.selected.length == 0) { |
| | | that.polygonInfo = ""; |
| | | that.nodeId = ""; |
| | | that.myNode = null; |
| | | return false; |
| | | } |
| | | |
| | | if (e.selected[0].values_.type == "node") { |
| | | that.isHidden = false; |
| | | that.polygonInfo = ""; |
| | | that.nodeId = e.selected[0].values_.id; |
| | | return false; |
| | | } |
| | | |
| | | if (myPolygon.polygonName) { |
| | | that.polygonInfo = myPolygon.polygonName; |
| | | } else { |
| | | that.polygonInfo = "新区域"; |
| | | } |
| | | overlay.setPosition(e.mapBrowserEvent.coordinate); |
| | | return false; |
| | | }); |
| | | |
| | | select2.on("select", function (e) { |
| | | if ( |
| | | e.selected.length && |
| | | e.selected[0].values_.type == "node" && |
| | | that.myNode && |
| | | that.myNode.values_.id == e.selected[0].values_.id |
| | | ) { |
| | | overlay2.setPosition(e.mapBrowserEvent.coordinate); |
| | | } else { |
| | | } |
| | | }); |
| | | }, |
| | | initNode([x, y], color) { |
| | | const iconFeature = new Feature({ |
| | |
| | | |
| | | iconFeature.setStyle(iconStyle); |
| | | this.iconArr.push(iconFeature); |
| | | iconFeature.set("color", `${color}`); |
| | | iconFeature.set("lat", `${x}`); |
| | | iconFeature.set("lng", `${y}`); |
| | | |
| | | return iconFeature; |
| | | }, |
| | | initAllNode() { |
| | | this.nodeArr.forEach((item) => { |
| | | const node = this.initNode(item.data, item.color); |
| | | node.set("id", item.id); |
| | | node.set("type", "node"); |
| | | node.set("battery", item.battery); |
| | | this.nodeFeature.push(node); |
| | | myVectorSource.addFeature(node); |
| | | }); |
| | | }, |
| | |
| | | this.polygonArr.forEach((item) => { |
| | | const feature = new Feature({ geometry: new Polygon([item.data]) }); |
| | | feature.id = item.id; |
| | | feature.type = "polygon"; |
| | | feature.polygonName = item.name; |
| | | this.polyFeature.push(feature); |
| | | }); |
| | | }, |
| | |
| | | }); |
| | | }, |
| | | initBottomMap(vectorLayer) { |
| | | const info = document.querySelector("#polygonInfo"); |
| | | const helmet_box = document.querySelector(".helmet_box"); |
| | | overlay2 = new Overlay({ |
| | | element: helmet_box, |
| | | autoPan: true, |
| | | autoPanAnimation: { |
| | | duration: 250, |
| | | }, |
| | | }); |
| | | |
| | | overlay = new Overlay({ |
| | | element: info, |
| | | }); |
| | | return new Map({ |
| | | target: "map-index", |
| | | layers: [baseLayer, vectorLayer], |
| | |
| | | center: transform(this.center, "EPSG:4326", "EPSG:3857"), |
| | | zoom: this.zoom, |
| | | }), |
| | | overlays: [overlay, overlay2], |
| | | }); |
| | | }, |
| | | zoomIn() { |
| | |
| | | view.setCenter(transform(this.center, "EPSG:4326", "EPSG:3857")); |
| | | }, |
| | | drawPolygon() { |
| | | this.resetMap(); |
| | | mySelect.setActive(false); |
| | | this.showBtn = true; |
| | | const draw = new Draw({ |
| | | source: myVectorSource, |
| | |
| | | } |
| | | |
| | | event.feature.id = id; |
| | | event.feature.type = "polygon"; |
| | | this.drawStore.push({ |
| | | id, |
| | | data: event.feature.getGeometry().getCoordinates()[0], |
| | |
| | | |
| | | const modify = new Modify({ source: myVectorSource }); |
| | | modify.addEventListener("modifyend", (event) => { |
| | | console.log(event.features); |
| | | const id = event.features.array_[0].id; |
| | | const data = event.features.array_[0].getGeometry().getCoordinates()[0]; |
| | | this.modifyStore.push({ id, data }); |
| | |
| | | myMap.addInteraction(draw); |
| | | }, |
| | | resetMap() { |
| | | this.polygonInfo = ""; |
| | | mySelect.setActive(true); |
| | | this.initPolygonArr(); |
| | | console.log(this.polyFeature); |
| | | const vectorSource = new VectorSource({ |
| | | features: this.polyFeature, |
| | | }); |
| | | /* if(this.polygonArr.length>0){ |
| | | this.initPolygonArr() |
| | | console.log(this.polyFeature); |
| | | vectorSource.addFeature(this.polyFeature[0]) |
| | | } */ |
| | | myVectorSource = vectorSource; |
| | |
| | | this.modifyStore = []; |
| | | }, |
| | | async savePoly() { |
| | | mySelect.setActive(true); |
| | | myMap.removeInteraction(myDraw); |
| | | myMap.removeInteraction(myModify); |
| | | this.showBtn = false; |
| | |
| | | } |
| | | const arrData = this.polygonArr.map((item) => { |
| | | let name = item.name ? item.name : ""; |
| | | console.log(item); |
| | | let data = item.data.map((arr) => { |
| | | arr = transform([arr[0], arr[1]], "EPSG:3857", "EPSG:4326"); |
| | | return arr.join(","); |
| | |
| | | id: +item.id, |
| | | }; |
| | | }); |
| | | const res = await createZones({ dots_arr: arrData }); |
| | | console.log(res); |
| | | await createZones({ dots_arr: arrData }); |
| | | const res = await getHelemtData(); |
| | | this.nodeArr = []; |
| | | res.data.items.forEach((item) => { |
| | | this.nodeArr.push({ |
| | | data: [item.lng, item.lat], |
| | | id: item.device_sn, |
| | | color: item.is_out_bound == 0 ? "绿" : "红", |
| | | }); |
| | | }); |
| | | this.nodeFeature.forEach((item) => { |
| | | myVectorSource.removeFeature(item); |
| | | }); |
| | | this.initNode(); |
| | | this.initAllNode(); |
| | | }, |
| | | delPoly() { |
| | | this.$confirm("此操作将删除该区域, 是否继续?", "提示", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }) |
| | | .then(async () => { |
| | | myVectorSource.removeFeature(myPolygon); |
| | | const res = await delZones({ id: myPolygon.id }); |
| | | if (res.status == 200) { |
| | | this.$message({ |
| | | type: "success", |
| | | message: "删除成功!", |
| | | }); |
| | | this.polygonInfo = ""; |
| | | const res2 = await getZones(); |
| | | if (res2.data && res2.data.items && res2.data.items.length > 0) { |
| | | this.polygonArr = res2.data.items.map((obj) => { |
| | | obj.data = obj.dots.map((item) => { |
| | | return transform( |
| | | [item[0], item[1]], |
| | | "EPSG:4326", |
| | | "EPSG:3857" |
| | | ); |
| | | }); |
| | | return obj; |
| | | }); |
| | | } |
| | | } else { |
| | | this.$message({ |
| | | type: "info", |
| | | message: "删除失败", |
| | | }); |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | this.$message({ |
| | | type: "info", |
| | | message: "已取消删除", |
| | | }); |
| | | }); |
| | | }, |
| | | showVideo() { |
| | | if (!this.myNode) { |
| | | return false; |
| | | } |
| | | |
| | | this.isHidden = false; |
| | | }, |
| | | hiddenVideo() { |
| | | document.querySelector("video").pause(); |
| | | this.isHidden = true; |
| | | }, |
| | | close() { |
| | | overlay2.setPosition(undefined); |
| | | }, |
| | | onCommentInputChange() { |
| | | let value = document.querySelector("#commentContent").value; |
| | | voiceText = value; |
| | | let cont = 20 - value.length; |
| | | document.querySelector( |
| | | "#comment_info" |
| | | ).innerHTML = `还可输入${cont}个字符`; |
| | | }, |
| | | sendVoice() { |
| | | const _this = this; |
| | | this.isSending = true; |
| | | |
| | | const h = this.$createElement; |
| | | this.$msgbox({ |
| | | message: h( |
| | | "div", |
| | | { |
| | | attrs: { |
| | | class: "el-textarea", |
| | | }, |
| | | }, |
| | | [ |
| | | h( |
| | | "div", |
| | | { |
| | | attrs: { |
| | | class: "el-title", |
| | | }, |
| | | }, |
| | | [ |
| | | h( |
| | | "span", |
| | | { |
| | | attrs: { |
| | | class: "icon iconfont", |
| | | }, |
| | | }, |
| | | "\ue7cc" |
| | | ), |
| | | h("span", null, "发送语音"), |
| | | ] |
| | | ), |
| | | h("textarea", { |
| | | attrs: { |
| | | placeholder: "请输入语音命令", |
| | | maxlength: "20", |
| | | class: "el-textarea__inner", |
| | | autocomplete: "off", |
| | | rows: 3, |
| | | id: "commentContent", |
| | | }, |
| | | value: this.commentContent, |
| | | on: { input: this.onCommentInputChange }, |
| | | }), |
| | | h( |
| | | "div", |
| | | { attrs: { class: "info", id: "comment_info" } }, |
| | | "还可输入20个字符" |
| | | ), |
| | | ] |
| | | ), |
| | | showCancelButton: true, |
| | | confirmButtonText: "确定", |
| | | confirmButtonClass: "hele_btn_save", |
| | | cancelButtonClass: "hele_btn_cancel", |
| | | cancelButtonText: "取消", |
| | | beforeClose: (action, instance, done) => { |
| | | document.querySelector("#commentContent").value = ""; |
| | | document.querySelector( |
| | | "#comment_info" |
| | | ).innerHTML = `还可输入20个字符`; |
| | | _this.isSending = false; |
| | | done(); |
| | | }, |
| | | }) |
| | | .then((action) => { |
| | | if (action == "confirm") { |
| | | if (!voiceText) { |
| | | this.$message({ |
| | | message: "指令不能为空", |
| | | type: "warning", |
| | | }); |
| | | _this.isSending = false; |
| | | return; |
| | | } |
| | | sendAudio(_this.myNode.values_.id, voiceText).then((res) => { |
| | | this.$message({ |
| | | message: "指令发送成功", |
| | | type: "success", |
| | | }); |
| | | _this.isSending = false; |
| | | }); |
| | | _this.isSending = false; |
| | | } else { |
| | | _this.isSending = false; |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | _this.isSending = false; |
| | | }); |
| | | }, |
| | | aClick() { |
| | | return false; |
| | | }, |
| | | }, |
| | | watch: { |
| | |
| | | if (res.data.items && res.data.items.length > 0) { |
| | | res.data.items.forEach((obj) => { |
| | | this.nodeArr.forEach((item) => { |
| | | if ((item.id = obj.device_sn)) { |
| | | if (item.id == obj.device_sn) { |
| | | arr.push(item); |
| | | } |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | console.log(this.rangeArr); |
| | | |
| | | if (this.rangeArr.length > 0) { |
| | | this.rangeArr.forEach((item) => { |
| | |
| | | |
| | | rangeFeature.setStyle(iconStyle); |
| | | myVectorSource.addFeature(rangeFeature); |
| | | rangeFeature.set("type", "range"); |
| | | this.rangeArr.push(rangeFeature); |
| | | }); |
| | | } |
| | |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | a { |
| | | background-color: transparent; |
| | | color: #337ab7; |
| | | text-decoration: none; |
| | | } |
| | | a:active a:hover { |
| | | outline: 0; |
| | | } |
| | | |
| | | #map-index { |
| | | position: relative; |
| | | margin: 20px 0; |
| | | width: 1170px; |
| | | width: 100%; |
| | | height: 396px; |
| | | border-radius: 15px; |
| | | |
| | | .helmet_box { |
| | | width: 205px; |
| | | height: 172px; |
| | | padding: 10px 10px 20px 15px; |
| | | font-size: 12px; |
| | | background: rgba(255, 255, 255, 0.7); |
| | | backdrop-filter: blur(4px); |
| | | border-radius: 15px; |
| | | text-align: left; |
| | | |
| | | .icon_close { |
| | | text-align: right; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .sn { |
| | | color: #f54336; |
| | | } |
| | | .location { |
| | | margin: 10px 0; |
| | | } |
| | | .button { |
| | | margin-top: 10px; |
| | | text-align: center; |
| | | img { |
| | | cursor: pointer; |
| | | width: 22px; |
| | | &:first-child { |
| | | margin-right: 48px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .video_box { |
| | | box-sizing: border-box; |
| | | overflow: hidden; |
| | | position: absolute; |
| | | z-index: 2; |
| | | top: 45px; |
| | | right: 25px; |
| | | width: 483px; |
| | | height: 306px; |
| | | background: rgba(241, 250, 246, 0.6); |
| | | backdrop-filter: blur(4px); |
| | | /* Note: backdrop-filter has minimal browser support */ |
| | | border-radius: 15px; |
| | | border: 1px solid rgb(17, 170, 102); |
| | | transition: all linear 0.5s; |
| | | |
| | | &.hidden { |
| | | width: 0; |
| | | border: none; |
| | | } |
| | | |
| | | .title { |
| | | margin: 15px 40px 0 20px; |
| | | width: 420px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | color: #4f4f4f; |
| | | font-size: 12px; |
| | | |
| | | .left { |
| | | .ball { |
| | | display: inline-block; |
| | | width: 0; |
| | | height: 0; |
| | | border: 4px solid #f54336; |
| | | border-radius: 2px; |
| | | margin-right: 10px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | video { |
| | | margin: 8px 40px 0 20px; |
| | | width: 424px; |
| | | height: 246px; |
| | | object-fit: fill; |
| | | } |
| | | } |
| | | |
| | | .control { |
| | | position: absolute; |
| | | display: flex; |
| | |
| | | line-height: 36px; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .del { |
| | | position: absolute; |
| | | z-index: 3; |
| | | top: 15px; |
| | | right: 113px; |
| | | width: 87px; |
| | | height: 35px; |
| | | background: rgb(245, 108, 108); |
| | | border: 1px solid rgb(245, 108, 108); |
| | | border-radius: 8px; |
| | | color: #fff; |
| | | font-size: 12px; |
| | | line-height: 36px; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .video_icon { |
| | | position: absolute; |
| | | z-index: 3; |
| | | top: 179px; |
| | | right: 10px; |
| | | width: 37px; |
| | | } |
| | | |
| | | #polygonInfo { |
| | | padding: 10px; |
| | | border: 1px solid; |
| | | color: black; |
| | | background-color: #fff; |
| | | z-index: 3; |
| | | width: 100px; |
| | | } |
| | | |
| | | .mask { |
| | | position: fixed; |
| | | top: 0; |
| | | bottom: 0; |
| | | left: 0; |
| | | right: 0; |
| | | text-align: center; |
| | | z-index: 4; |
| | | background-color: black; |
| | | opacity: 0.5; |
| | | } |
| | | } |
| | | |
| | | .el-textarea { |
| | | height: 150px; |
| | | padding: 0 15px; |
| | | |
| | | .el-title { |
| | | margin-top: 20px; |
| | | margin-bottom: 15px; |
| | | color: #4f4f4f; |
| | | font-size: 16px; |
| | | font-weight: 700; |
| | | |
| | | .icon { |
| | | font-weight: normal; |
| | | font-size: 19px; |
| | | } |
| | | } |
| | | |
| | | .el-textarea__inner { |
| | | width: 357px; |
| | | |
| | | &:focus { |
| | | border: 1px solid #11aa66; |
| | | } |
| | | } |
| | | |
| | | .info { |
| | | font-size: 12px; |
| | | color: #828282; |
| | | text-align: right; |
| | | padding-right: 38px; |
| | | } |
| | | } |
| | | </style> |
| | | |