| | |
| | | <el-form-item label="名称" prop="name"> |
| | | <el-input v-model="form.name" placeholder="请输入名称" v-trim /> |
| | | </el-form-item> |
| | | <el-form-item label="责任部门" prop="companyId"> |
| | | <el-select filterable clearable @change="loadMember" v-model="form.companyId"> |
| | | <!-- <el-form-item label="责任部门" prop="companyId"> |
| | | <el-select filterable clearable @change="() => loadMember(1)" v-model="form.companyId"> |
| | | <el-option v-for="op in department" :key="op.id" :label="op.name" :value="op.id"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-form-item> --> |
| | | <el-form-item v-if="form.type == 0" label="选择安全员" prop="memberIdList"> |
| | | <el-select v-model="form.memberIdList" filterable multiple clearable placeholder="请选择"> |
| | | <el-option v-for="item in memberList" :key="item.id" :label="item.name" :value="item.id"> |
| | |
| | | } |
| | | }) |
| | | }, |
| | | loadMember() { |
| | | this.$set(this.form, 'memberIdList', []) |
| | | loadMember(flag) { |
| | | if(flag && flag == 1){ |
| | | this.$set(this.form, 'memberIdList', null) |
| | | } |
| | | allList({ |
| | | type: 2, |
| | | companyType: 1, |
| | |
| | | </div> |
| | | </div> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <div><el-button type="primary" @click="openCamera">采集</el-button></div> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- --> |
| | | <el-dialog title="拍摄" :visible.sync="paisheModal" width="760px" :close-on-click-modal="false" |
| | | :close-on-press-escape="false" append-to-body @close="closeCamera"> |
| | | <video v-show="isShowCamera" id="videoCamera" :width="videoWidth" :height="videoHeight" /> |
| | | <canvas v-show="!isShowCamera" id="canvasCamera" style="display: none" :width="videoWidth" |
| | | :height="videoHeight" /> |
| | | <span slot="footer"> |
| | | <div> |
| | | <el-button @click="closeCamera">取消</el-button> |
| | | <el-button v-show="blobFileCamera" type="primary" @click="resetCamera">重拍</el-button> |
| | | <el-button v-show="blobFileCamera" :loading="cameraLoading" type="primary" |
| | | @click="enterCamera">开始裁剪</el-button> |
| | | <el-button v-show="!blobFileCamera" type="primary" @click="setImage">拍摄</el-button> |
| | | </div> |
| | | </span> |
| | | </el-dialog> |
| | | <!-- --> |
| | | <el-dialog append-to-body :close-on-click-modal="false" title="上传图片" :visible.sync="isShowCropper" width="1000px" |
| | | class="icon-dialog-wrapper dialong-com-style"> |
| | | <ImageCropper ref="iconShot" v-if="isShowCropper" :imgSrc="blobFileCamera"> |
| | | </ImageCropper> |
| | | <span slot="footer" class="dialog-footer"> |
| | | <el-button v-if="loading">取 消</el-button> |
| | | <el-button v-else @click="isShowCropper = false">取 消</el-button> |
| | | <el-button :loading="loading" type="primary" @click="uploadIcon">确 定</el-button> |
| | | </span> |
| | | </el-dialog> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | import UploadAvatarImage from '@/components/common/UploadAvatarImage' |
| | | import UploadFaceImg from '@/components/common/UploadFaceImg' |
| | | import ImageCropper from '@/components/common/ImageCropper' |
| | | import { checkMobile, validIdCardNo, validIdCardNoNew } from '@/utils/form' |
| | | import { allList } from '@/api/business/position' |
| | | import { upload } from '@/api/system/common' |
| | | export default { |
| | | name: 'OperaCompanyWindow', |
| | | extends: BaseOpera, |
| | | components: { GlobalWindow, UploadAvatarImage, UploadFaceImg }, |
| | | components: { GlobalWindow, UploadAvatarImage, UploadFaceImg, ImageCropper }, |
| | | data() { |
| | | return { |
| | | isShowCamera: false, |
| | | paisheModal: false, |
| | | cameraLoading: false, |
| | | videoWidth: 700, |
| | | videoHeight: 525, |
| | | mediaStreamCamera: '', |
| | | blobFileCamera: '', |
| | | isShowCropper: false, |
| | | loading: false, |
| | | // 以上是拍摄 |
| | | uploadData: { |
| | | folder: 'member' |
| | | }, |
| | |
| | | }) |
| | | }, |
| | | methods: { |
| | | openCamera() { |
| | | this.paisheModal = true |
| | | this.isShowCamera = true |
| | | const that = this |
| | | this.$nextTick(() => { |
| | | var mediaOpts = { audio: false, video: true } |
| | | navigator.mediaDevices |
| | | .getUserMedia(mediaOpts) |
| | | .then(function (stream) { |
| | | that.mediaStreamCamera = stream |
| | | const video = document.querySelector('#videoCamera') |
| | | if ('srcObject' in video) { |
| | | video.srcObject = stream |
| | | } else { |
| | | video.src = |
| | | (window.URL && window.URL.createObjectURL(stream)) || stream |
| | | } |
| | | video.play() |
| | | }) |
| | | .catch(function (err) { |
| | | console.log(err) |
| | | }) |
| | | }) |
| | | }, |
| | | // 重拍 |
| | | resetCamera() { |
| | | this.isShowCamera = true |
| | | this.blobFileCamera = '' |
| | | this.openCamera() |
| | | }, |
| | | // 关闭相机 |
| | | closeCamera() { |
| | | this.mediaStreamCamera.getVideoTracks().forEach(function (track) { |
| | | track.stop() |
| | | }) |
| | | this.paisheModal = false |
| | | }, |
| | | // 点击拍摄 |
| | | setImage() { |
| | | const that = this |
| | | that.isShowCamera = false |
| | | const video = document.querySelector('#videoCamera') |
| | | const canvas = document.querySelector('#canvasCamera') |
| | | canvas |
| | | .getContext('2d') |
| | | .drawImage(video, 0, 0, that.videoWidth, that.videoHeight) |
| | | this.mediaStreamCamera.getVideoTracks().forEach(function (track) { |
| | | track.stop() |
| | | }) |
| | | const dataurl = canvas.toDataURL('image/jpg') |
| | | // this.blobFileCamera = that.base64ToFile(dataurl, 'camera') |
| | | this.blobFileCamera = dataurl |
| | | }, |
| | | // 确认拍摄 |
| | | enterCamera() { |
| | | this.isShowCropper = true |
| | | this.paisheModal = false |
| | | this.isShowCamera = true |
| | | }, |
| | | uploadIcon () { |
| | | // 获取裁剪后的图片 |
| | | this.$refs.iconShot.getImagecropper().getCropBlob((fileData) => { // 获取当前裁剪好的数据 |
| | | // 注此时的data是一个Blob数据,部分接口接收的是File转化的FormData数据 |
| | | console.log(fileData) |
| | | const formData = new FormData() |
| | | |
| | | formData.append('folder', 'member') |
| | | formData.append( |
| | | 'file', |
| | | fileData |
| | | ) |
| | | this.loading = true |
| | | upload(formData).then(res => { |
| | | this.loading = false |
| | | console.log(res) |
| | | // this.file.imgurl = res.imgaddr |
| | | // this.file.imgurlfull = res.url |
| | | this.$message.success('上传成功') |
| | | // this.imageSrc = res.url |
| | | // this.updateImg = false |
| | | this.form.faceImg = res.imgaddr |
| | | this.form.faceImgFull = res.url |
| | | // this.$emit('uploadSuccess', { imgurl: res.imgaddr, imgurlfull: res.url, name: res.originname }) |
| | | // this.$emit('uploadEnd') |
| | | }, () => { |
| | | this.loading = false |
| | | }) |
| | | }) |
| | | }, |
| | | base64ToFile(base64, fileName) { |
| | | // 将base64按照 , 进行分割 将前缀 与后续内容分隔开 |
| | | const data = base64.split(',') |
| | | // 利用正则表达式 从前缀中获取图片的类型信息(image/png、image/jpeg、image/webp等) |
| | | const type = data[0].match(/:(.*?);/)[1] |
| | | // 从图片的类型信息中 获取具体的文件格式后缀(png、jpeg、webp) |
| | | const suffix = type.split('/')[1] |
| | | // 使用atob()对base64数据进行解码 结果是一个文件数据流 以字符串的格式输出 |
| | | const bstr = window.atob(data[1]) |
| | | // 获取解码结果字符串的长度 |
| | | let n = bstr.length |
| | | // 根据解码结果字符串的长度创建一个等长的整形数字数组 |
| | | // 但在创建时 所有元素初始值都为 0 |
| | | const u8arr = new Uint8Array(n) |
| | | // 将整形数组的每个元素填充为解码结果字符串对应位置字符的UTF-16 编码单元 |
| | | while (n--) { |
| | | // charCodeAt():获取给定索引处字符对应的 UTF-16 代码单元 |
| | | u8arr[n] = bstr.charCodeAt(n) |
| | | } |
| | | // 利用构造函数创建File文件对象 |
| | | // new File(bits, name, options) |
| | | const file = new File([u8arr], `${fileName}.${suffix}`, { |
| | | type: type |
| | | }) |
| | | // 将File文件对象返回给方法的调用者 |
| | | return file |
| | | }, |
| | | handleChangeCompany(value) { |
| | | if (this.form.company && this.form.company.length > 1) { |
| | | this.form.companyId = this.form.company[this.form.company.length - 1] |
| | |
| | | }, |
| | | created() { |
| | | this.changeRadio('0') |
| | | this.getList() |
| | | }, |
| | | methods: { |
| | | changeRadio(day) { |
| | |
| | | selDate: [], |
| | | fastdate: 0 |
| | | } |
| | | this.getList() |
| | | this.changeRadio('0') |
| | | }, |
| | | handleDetail(row) { |
| | | this.isShowDetail = true |
| | |
| | | <template> |
| | | <v-scale-screen width="1920" height="960" :fullScreen="true"> |
| | | <v-scale-screen width="1920" height="960" > |
| | | <div class="main_app"> |
| | | <img src="@/assets/images/bg_main_app.png" class="main_bg" alt="" /> |
| | | <div class="main_header"> |
| | |
| | | <div>月能耗分析</div> |
| | | </div> |
| | | <div class="tabs"> |
| | | <div class="tab active">用电</div> |
| | | <div class="tab" :class="{ active: activeTab2 == 0 }" @click="tabsClick2(0)">用水</div> |
| | | <div class="separate"></div> |
| | | <div class="tab">用水</div> |
| | | <div class="tab" :class="{ active: activeTab2 == 2 }" @click="tabsClick2(2)">用电</div> |
| | | <div class="separate"></div> |
| | | <div class="tab">用气</div> |
| | | <div class="tab" :class="{ active: activeTab2 == 1 }" @click="tabsClick2(1)">用气</div> |
| | | </div> |
| | | <img src="@/assets/images/title@2x.png" class="bg" alt="" /> |
| | | </div> |
| | |
| | | <img src="@/assets/images/title@2x.png" class="bg" alt="" /> |
| | | </div> |
| | | <div class="list"> |
| | | <div class="line" v-for="item, i in 6"> |
| | | <div class="line" v-for="item, i in data3"> |
| | | <div class="top"><span v-if="i < 3">top</span>{{ i }}</div> |
| | | <div class="id_card">皖A12313</div> |
| | | <div class="id_card">{{ item.carNo }}</div> |
| | | <div class="wrap"> |
| | | <ChargeRate :rate="15" :color /> |
| | | <ChargeRate :rate="item.rate" :color /> |
| | | </div> |
| | | <div class="num">1000</div> |
| | | <div class="num">{{ item.quantity }}</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | xAxis: { |
| | | type: 'category', |
| | | boundaryGap: false, |
| | | data: [1, 2, 3, 4, 5, 5] |
| | | data: data5.value.map(i => i.timeData) |
| | | }, |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { |
| | | type: 'line' |
| | | }, |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | |
| | | } |
| | | }, |
| | | grid: { |
| | | top: '16%', |
| | | top: '26%', |
| | | left: '4%', |
| | | right: '2%', |
| | | bottom: '2%', |
| | |
| | | }, |
| | | series: [ |
| | | { |
| | | data: [1, 2, 3, 4, 4, 5].map(i => { |
| | | return { |
| | | name: i, |
| | | value: i, |
| | | } |
| | | }), |
| | | data: data5.value.map(i => i.energy), |
| | | type: 'line', |
| | | areaStyle: { |
| | | normal: { |
| | |
| | | width: 2, // 线条粗细 |
| | | }, |
| | | symbol: 'circle', |
| | | symbolSize: 10, |
| | | symbolSize: 6, |
| | | itemStyle: { |
| | | normal: { |
| | | color: '#F3BD00', //折线点的颜色 |
| | |
| | | var myChart = echarts.init(document.querySelector('.loadRef')) |
| | | // 绘制图表 |
| | | myChart.setOption({ |
| | | // tooltip: { |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { |
| | | type: 'line' |
| | | }, |
| | | // trigger: 'axis', |
| | | // axisPointer: { |
| | | // type: 'line' |
| | |
| | | // </div> |
| | | // ` |
| | | // } |
| | | // }, |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | boundaryGap: false, |
| | |
| | | } |
| | | }, |
| | | grid: { |
| | | top: '16%', |
| | | top: '26%', |
| | | left: '4%', |
| | | right: '2%', |
| | | bottom: '2%', |
| | |
| | | y2: 1, |
| | | colorStops: [{ |
| | | offset: 0, |
| | | color: "rgba(192, 156, 53,.7)" // 0% 处的颜色 |
| | | color: "#2e6ab5" // 0% 处的颜色 |
| | | }, { |
| | | offset: 1, |
| | | color: "#1b1b12" // 100% 处的颜色 |
| | |
| | | x2: 0, |
| | | y2: 1, |
| | | colorStops: [{ |
| | | offset: 0, color: '#F3BD00' // 0% 处的颜色 |
| | | offset: 0, color: '#2e6ab5' // 0% 处的颜色 |
| | | }, { |
| | | offset: 1, color: '#F3BD00' // 100% 处的颜色 |
| | | offset: 1, color: '#2e6ab5' // 100% 处的颜色 |
| | | }], |
| | | }, |
| | | width: 2, // 线条粗细 |
| | | }, |
| | | symbol: 'circle', |
| | | symbolSize: 10, |
| | | symbolSize: 0, |
| | | itemStyle: { |
| | | normal: { |
| | | color: '#F3BD00', //折线点的颜色 |
| | | color: '#2e6ab5', //折线点的颜色 |
| | | }, |
| | | }, |
| | | smooth: true |
| | |
| | | myChart.resize() |
| | | }) |
| | | } |
| | | const arr = ['#68e2e3', '#50afd3', '#377cdb', '#d5ae3a'] |
| | | const initEnergy = () => { |
| | | var myChart = echarts.init(document.querySelector('.energyRef')) |
| | | // 绘制图表 |
| | | const arr = ['#68e2e3', '#50afd3', '#377cdb', '#d5ae3a'] |
| | | myChart.setOption({ |
| | | grid: { |
| | | top: '20%', |
| | | top: '26%', |
| | | left: '2%', |
| | | right: '2%', |
| | | bottom: '4%', |
| | |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | data: [1, 2, 3, 4, 4, 5] |
| | | data: data2.value.map(i => i.timeData) |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | |
| | | }, |
| | | series: [ |
| | | { |
| | | data: [1, 2, 3, 4, 5], |
| | | data: data2.value.map(i => i.energy), |
| | | type: 'bar', |
| | | barWidth: 10, |
| | | itemStyle: { |
| | |
| | | color: new echarts.graphic.LinearGradient( |
| | | 0, 0, 0, 1, |
| | | [ |
| | | { offset: 0, color: arr[1] }, |
| | | { offset: 1, color: '#080807' } |
| | | { offset: 0, color: '#50afd3' }, |
| | | { offset: 1, color: '#1d4861' } |
| | | ] |
| | | ), |
| | | barBorderRadius: [10, 10, 0, 0] |
| | |
| | | const getData1 = () => { |
| | | zxcenterData().then(res => { |
| | | const result = res.data |
| | | data1.value = result |
| | | }) |
| | | } |
| | | const activeTab2 = ref(0) |
| | | const tabsClick2 = (v) => { |
| | | activeTab2.value = v |
| | | getData2() |
| | | } |
| | | const data2 = ref([]) |
| | | const getData2 = () => { |
| | | zxenergyDataList().then(res => { |
| | | zxenergyDataList({type: activeTab2.value}).then(res => { |
| | | const result = res.data |
| | | data2.value = result |
| | | initEnergy() |
| | | }) |
| | | } |
| | | const data3 = ref([]) |
| | | const getData3 = () => { |
| | | zxlastMonthOil().then(res => { |
| | | const result = res.data |
| | | data3.value = result |
| | | const result = res.data || [] |
| | | data3.value = result.map(i => { |
| | | if(i.quantity && i.maxOil){ |
| | | i.rate = ((i.quantity/i.maxOil) * 25).toFixed(0) |
| | | } |
| | | return i |
| | | }) |
| | | }) |
| | | } |
| | | const data4 = ref([]) |
| | |
| | | }) |
| | | } |
| | | |
| | | const data5 = ref([]) |
| | | const getData5 = () => { |
| | | zxenergyDataList({type: 3}).then(res => { |
| | | const result = res.data |
| | | data5.value = result |
| | | initOperation() |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getData1() |
| | | getData2() |
| | | getData3() |
| | | getData4() |
| | | getData5() |
| | | |
| | | }) |
| | | |
| | |
| | | |
| | | .load_wrap { |
| | | width: 100%; |
| | | height: 210px; |
| | | padding: 12px 12px; |
| | | |
| | | height: 250px; |
| | | .loadRef { |
| | | width: 100%; |
| | | height: 100%; |
| | |
| | | .left_box_three { |
| | | .energy_wrap { |
| | | width: 100%; |
| | | height: 200px; |
| | | height: 250px; |
| | | |
| | | .energyRef { |
| | | width: 100%; |
| | |
| | | |
| | | .right_box_three { |
| | | .wrap { |
| | | padding: 8px; |
| | | |
| | | .analyseRef { |
| | | width: 100%; |
| | | height: 210px; |
| | | height: 250px; |
| | | } |
| | | } |
| | | } |
| | |
| | | align-items: center; |
| | | font-size: 14px; |
| | | color: #d2e0ff; |
| | | |
| | | .tab{ |
| | | cursor: pointer; |
| | | } |
| | | .separate { |
| | | width: 1px; |
| | | height: 14px; |
| | |
| | | server: { |
| | | proxy: { |
| | | "/gateway_interface": { |
| | | target: "http://192.168.0.103:10010", |
| | | // target: "http://192.168.0.103:10010", |
| | | // target: "http://10.50.250.253:8088/gateway_interface", |
| | | // target: "http://192.168.0.173/gateway_interface", |
| | | target: "http://192.168.0.173/gateway_interface", |
| | | changeOrigin: true, |
| | | rewrite: (path) => path.replace(/^\/gateway_interface/, ""), |
| | | }, |