ll
liukangdong
2024-11-01 064128dfb784d9780aa4ac5dbd897c29d46a2666
ll
已修改5个文件
288 ■■■■ 文件已修改
admin/src/components/business/OperaHiddenDangerParamWindow.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaMemberWindow.vue 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/platform/LogisticsRecord/waybill.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/src/views/EnergyConsum.vue 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
screen/vite.config.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaHiddenDangerParamWindow.vue
@@ -4,11 +4,11 @@
      <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">
@@ -103,8 +103,10 @@
          }
        })
    },
    loadMember() {
      this.$set(this.form, 'memberIdList', [])
    loadMember(flag) {
      if(flag && flag == 1){
        this.$set(this.form, 'memberIdList', null)
      }
      allList({
        type: 2,
        companyType: 1,
admin/src/components/business/OperaMemberWindow.vue
@@ -54,7 +54,37 @@
          </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>
@@ -63,14 +93,26 @@
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'
      },
@@ -119,6 +161,122 @@
    })
  },
  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]
admin/src/views/platform/LogisticsRecord/waybill.vue
@@ -142,7 +142,6 @@
  },
  created() {
    this.changeRadio('0')
    this.getList()
  },
  methods: {
    changeRadio(day) {
@@ -215,7 +214,7 @@
        selDate: [],
        fastdate: 0
      }
      this.getList()
      this.changeRadio('0')
    },
    handleDetail(row) {
      this.isShowDetail = true
screen/src/views/EnergyConsum.vue
@@ -1,5 +1,5 @@
<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">
@@ -48,11 +48,11 @@
                <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>
@@ -193,13 +193,13 @@
              <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>
@@ -276,7 +276,13 @@
    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',
@@ -295,7 +301,7 @@
      }
    },
    grid: {
      top: '16%',
      top: '26%',
      left: '4%',
      right: '2%',
      bottom: '2%',
@@ -303,12 +309,7 @@
    },
    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: {
@@ -344,7 +345,7 @@
          width: 2, // 线条粗细
        },
        symbol: 'circle',
        symbolSize: 10,
        symbolSize: 6,
        itemStyle: {
          normal: {
            color: '#F3BD00', //折线点的颜色
@@ -364,7 +365,11 @@
  var myChart = echarts.init(document.querySelector('.loadRef'))
  // 绘制图表
  myChart.setOption({
    // tooltip: {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'line'
      },
    //   trigger: 'axis',
    //   axisPointer: {
    //     type: 'line'
@@ -384,7 +389,7 @@
    //       </div>
    //     `
    //   }
    // },
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
@@ -407,7 +412,7 @@
      }
    },
    grid: {
      top: '16%',
      top: '26%',
      left: '4%',
      right: '2%',
      bottom: '2%',
@@ -426,7 +431,7 @@
              y2: 1,
              colorStops: [{
                offset: 0,
                color: "rgba(192, 156, 53,.7)" // 0% 处的颜色
                color: "#2e6ab5" // 0% 处的颜色
              }, {
                offset: 1,
                color: "#1b1b12" // 100% 处的颜色
@@ -443,18 +448,18 @@
            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
@@ -466,14 +471,12 @@
    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%',
@@ -487,7 +490,7 @@
    },
    xAxis: {
      type: 'category',
      data: [1, 2, 3, 4, 4, 5]
      data: data2.value.map(i => i.timeData)
    },
    yAxis: {
      type: 'value',
@@ -505,7 +508,7 @@
    },
    series: [
      {
        data: [1, 2, 3, 4, 5],
        data: data2.value.map(i => i.energy),
        type: 'bar',
        barWidth: 10,
        itemStyle: {
@@ -513,8 +516,8 @@
            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]
@@ -532,20 +535,32 @@
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([])
@@ -557,11 +572,21 @@
  })
}
const data5 = ref([])
const getData5 = () => {
  zxenergyDataList({type: 3}).then(res => {
    const result = res.data
    data5.value = result
    initOperation()
  })
}
onMounted(() => {
  getData1()
  getData2()
  getData3()
  getData4()
  getData5()
})
@@ -606,9 +631,7 @@
      .load_wrap {
        width: 100%;
        height: 210px;
        padding: 12px 12px;
        height: 250px;
        .loadRef {
          width: 100%;
          height: 100%;
@@ -619,7 +642,7 @@
    .left_box_three {
      .energy_wrap {
        width: 100%;
        height: 200px;
        height: 250px;
        .energyRef {
          width: 100%;
@@ -890,11 +913,9 @@
    .right_box_three {
      .wrap {
        padding: 8px;
        .analyseRef {
          width: 100%;
          height: 210px;
          height: 250px;
        }
      }
    }
@@ -934,7 +955,9 @@
    align-items: center;
    font-size: 14px;
    color: #d2e0ff;
    .tab{
      cursor: pointer;
    }
    .separate {
      width: 1px;
      height: 14px;
screen/vite.config.js
@@ -25,9 +25,9 @@
  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/, ""),
      },