Newer
Older
laserPTZFrontV2.0 / src / views / line / editLine.vue
bairujie on 7 Jun 2023 11 KB bug修改
<script lang="ts" setup name="EditLine">
import type { Ref } from 'vue'
import { nextTick, reactive } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import type { LineListInfo, PointInfo } from './line-interface'
import { isInRange, isInRangeNum, isIp, isPort } from '@/utils/validate'
import { HCPreset, getLineList, ToPosition } from '@/api/ptz/line'
const emits = defineEmits(['closeRefresh'])

// 对话框类型:create,update
const dialogStatus = ref('create')
const dialogVisible = ref(false)
const disabledBtn = ref(true)
const presetName = ref('')
// 显示标题
const textMap: { [key: string]: string } = {
  detail: '详情',
  update: '编辑',
  create: '新增',
  insert: '插入',
}
// 表单数据对象
const formData: Ref<PointInfo> = ref({
  deviceIp: '',
  command: '',
  presetIndex: '',
  cruiseRoute: '',
  presetName: '',
  cruiseName: '',
  direction: '',
  pitch: '',
  speed: '',
  stopTime: '',
  alarmValue: '',
})

// 保存按钮加载状态
const btnLoading = ref(false)

// ---------------表单提交--------------------------------

const isInRangeV = function (min: number, max: number) {
  return function (rule: any, value: any, callback: any) {
    if (value === '' || !isInRange(value, min, max)) {
      callback(new Error(`请输入${min.toString()}-${max.toString()}整数`))
    }
    else {
      callback()
    }
    callback()
  }
}

const isInRangeNumV = function (min: number, max: number, length: number) {
  return function (rule: any, value: any, callback: any) {
    if (isNaN(value) || value === '') {
      callback(new Error(`请输入${min.toString()}-${max.toString()}范围${length}位小数`))
    }
    else if (isInRangeNum(Number(value), min, max)) {
      if (value.toString().includes('.') && value.toString().split('.')[1].length > length) {
        callback(new Error(`请输入${min.toString()}-${max.toString()}范围${length}位小数`))
      }
      callback()
    }
    else {
      callback(new Error(`请输入${min.toString()}-${max.toString()}范围${length}位小数`))
    }
    callback()
  }
}

// 表单对象
const dataFormRef = ref<FormInstance>()
// 校验规则
const rules = reactive<FormRules>({
  presetName: [{ required: true, message: '预置点名不能为空', trigger: ['blur', 'change'] }],
  cruiseRoute: [{ required: true, message: '巡航路径不能为空', trigger: ['blur', 'change'] }],
  direction: [{ required: true, message: '请输入合法方向角(0~360整数/一位小数)', trigger: ['blur', 'change'], validator: isInRangeNumV(0, 360, 1) }],
  pitch: [{ required: true, message: '请输入合法方向角(-90~90整数/一位小数)', trigger: ['blur', 'change'], validator: isInRangeNumV(-90, 90, 1) }],
  speed: [{ type: 'number', required: true, message: '请输入合法巡航速度(1~63整数)', trigger: ['blur', 'change'], validator: isInRangeV(1, 63) }],
  stopTime: [{ type: 'number', required: true, message: '请输入合法停留时间(0~255整数)', trigger: ['blur', 'change'], validator: isInRangeV(0, 255) }],
  alarmValue: [{ type: 'number', required: true, message: '请输入合法报警阈值(0~10000整数)', trigger: ['blur', 'change'], validator: isInRangeV(0, 10000) }],
})

const lineList: Ref<LineListInfo[]> = ref([])
function getLine(id: string) {
  getLineList('', id).then((res) => {
    lineList.value = res.data
  })
}

// 获取场站列表
const stationList: Ref<StationListInfo[]> = ref([])
function fetchStationList() {
  getStationList().then((res) => {
    stationList.value = res.data
  })
}

// 表单提交
function submitForm() {
  if (dataFormRef) {
    dataFormRef.value?.validate((valid: boolean) => {
      if (valid) {
        ElMessageBox.confirm(
          '确认设备已定位至输入视角?',
          '确认保存',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
          },
        ).then(() => {
          if (dialogStatus.value === 'create') {
            createData()
          }
          else if (dialogStatus.value === 'update') {
            updateData()
          }
          else if (dialogStatus.value === 'insert') {
            insertData()
          }
        })

      }
    })
  }
}

// 定位视图
function posView() {
  if(formData.value.direction && formData.value.pitch) {
    setTimeout(()=>{
      disabledBtn.value = false;
      const params = {
        deviceIp:formData.value.deviceIp,
        horizontalAngle:formData.value.direction,
        verticalAngle:formData.value.pitch,
      }
      ToPosition(params).then(res =>{
        console.log(res)
      })
    },2000)
  } else {
    ElMessage.warning('请输入合法方向角度!')
  }
}

// 新增数据
function createData() {
  formData.value.cruiseName = lineList.value.filter(item => item.id === formData.value.cruiseRoute)[0].lineName
  HCPreset(formData.value).then((res) => {
    ElMessage.success('新增成功')
    btnLoading.value = false
    closeRefresh()
  }).catch((_) => { // 异常情况,loading置为false
    btnLoading.value = false
  })
}

// 更新数据
function updateData() {
  HCPreset(formData.value).then((res) => {
    ElMessage.success('修改成功')
    btnLoading.value = false
    closeRefresh()
  }).catch((_) => { // 异常情况,loading置为false
    btnLoading.value = false
  })
}

// 更新数据
function insertData() {
  console.log(formData.value)
  HCPreset(formData.value).then((res) => {
    ElMessage.success('插入成功')
    btnLoading.value = false
    closeRefresh()
  }).catch((_) => { // 异常情况,loading置为false
    btnLoading.value = false
  })
}

// 重置表单
function resetForm() {
  formData.value = {
    deviceIp: '',
    command: '',
    presetIndex: '',
    cruiseRoute: '',
    presetName: '',
    cruiseName: '',
    direction: '',
    pitch: '',
    speed: '',
    stopTime: '',
    alarmValue: '',
  }
}

// ----------初始化、关闭对话框相关-----------------
function initDialog(dialogstatus: string, row: any) {
  disabledBtn.value = true
  dialogStatus.value = dialogstatus
  dialogVisible.value = true
  btnLoading.value = false
  resetForm()
  if (dialogstatus === 'create') {
    getLine(row.id)
    formData.value.command = 'presetAdd'
    formData.value.deviceIp = row.ip
    nextTick(() => {
      dataFormRef.value?.clearValidate()
    })
  }
  else if (dialogstatus === 'update' || dialogstatus === 'detail' || dialogstatus === 'insert') {
    nextTick(() => {
      dataFormRef.value?.clearValidate()
    })
    presetName.value = row.serialName
    formData.value = {
      deviceIp: row.ip,
      command: dialogstatus === 'insert' ? 'presetInsert' : 'presetEdit',
      presetIndex: dialogstatus === 'insert' ? '' : row.serialNum,
      presetName: dialogstatus === 'insert' ? '' : row.serialName,
      cruiseRoute: row.lineNum,
      cruiseName: row.lineName,
      direction: dialogstatus === 'insert' ? '' : row.direction,
      pitch: dialogstatus === 'insert' ? '' : row.pitch,
      speed: dialogstatus === 'insert' ? '' : row.speed,
      stopTime: dialogstatus === 'insert' ? '' : row.stopTime,
      alarmValue: dialogstatus === 'insert' ? '' : row.alarmValue,
    }
  }
}

// 关闭并刷新
function closeRefresh() {
  dialogVisible.value = false
  resetForm()
  emits('closeRefresh')
}
// 关闭弹窗
function dialogClose() {
  dialogVisible.value = false
  resetForm()
  closeRefresh()
}

onMounted(() => {
})
// ----------------------- 以下是暴露的方法内容 ----------------------------
defineExpose({ initDialog })
</script>

<template>
  <el-dialog
    v-model="dialogVisible"
    :title="textMap[dialogStatus]"
    width="50%"
    :before-close="dialogClose"
    append-to-body
    :open-delay="0"
    :close-on-click-modal="false"
  >
    <el-form
      ref="dataFormRef" :model="formData" :rules="rules" label-position="left" label-width="150px" class="form-container"
      size="default" @submit.prevent
    >
      <el-row :gutter="10">
        <el-col :span="18" :offset="2" class="grid-cell">
          <el-form-item label="巡航路径" prop="cruiseRoute" class="required">
            <el-select v-model="formData.cruiseRoute" :disabled="dialogStatus !== 'create'" placeholder="必选" style="width: 100%;">
              <el-option
                v-for="item in lineList"
                :key="item.id"
                :label="item.lineName"
                :value="item.id"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col v-if="dialogStatus === 'insert'" :span="18" :offset="2" class="grid-cell">
          <el-form-item label="* 原预置点名" class="required">
            <el-input v-model="presetName" disabled type="text" placeholder="必填" />
          </el-form-item>
        </el-col>
        <el-col :span="18" :offset="2" class="grid-cell">
          <el-form-item label="预置点名" prop="presetName" class="required">
            <el-input v-model="formData.presetName" :disabled="dialogStatus === 'detail' || dialogStatus === 'update'" type="text" placeholder="必填" />
          </el-form-item>
        </el-col>
        <el-col :span="18" :offset="2" class="grid-cell">
          <el-form-item label="方位角(°)" prop="direction" class="required">
            <el-input v-model="formData.direction" :disabled="dialogStatus === 'detail'" type="text" placeholder="必填" @input="disabledBtn = true"/>
          </el-form-item>
        </el-col>
        <el-col :span="18" :offset="2" class="grid-cell">
          <el-form-item label="俯仰角(°)" prop="pitch" class="required">
            <el-input v-model="formData.pitch" :disabled="dialogStatus === 'detail'" type="text" placeholder="必填" @input="disabledBtn = true"/>
          </el-form-item>
        </el-col>
        <el-col :span="18" :offset="2" class="grid-cell">
          <el-form-item label="默认巡航速度(m/s)" prop="speed" class="required">
            <el-input v-model="formData.speed" :disabled="dialogStatus === 'detail'" type="text" placeholder="例如:30" />
          </el-form-item>
        </el-col>
        <el-col :span="18" :offset="2" class="grid-cell">
          <el-form-item label="默认停留时间(s)" prop="stopTime" class="required">
            <el-input v-model="formData.stopTime" :disabled="dialogStatus === 'detail'" type="text" placeholder="例如:3" />
          </el-form-item>
        </el-col>
        <el-col :span="18" :offset="2" class="grid-cell">
          <el-form-item label="默认报警值(ppm·m)" prop="alarmValue" class="required">
            <el-input v-model="formData.alarmValue" :disabled="dialogStatus === 'detail'" type="text" placeholder="例如:5000" />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <div v-show="dialogStatus !== 'detail'" class="dialog-footer">
        <el-button :loading="btnLoading" type="primary" @click="posView">
          定位视角
        </el-button>
        <el-button :loading="btnLoading" type="primary" @click="submitForm" :disabled="disabledBtn">
          保存
        </el-button>
        <el-button @click="dialogClose">
          取消
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.form-container {
  width: 100%;

  .full-width-input {
    width: 100%;
  }

  .dict-detail {
    padding: 10px;

    .title {
      font-size: 16px;
      font-weight: bold;
      margin-bottom: 15px;
    }
  }
}
</style>