|
|
@@ -0,0 +1,532 @@
|
|
|
+<template>
|
|
|
+ <ele-modal
|
|
|
+ :visible.sync="visible"
|
|
|
+ :title="title"
|
|
|
+ width="1100px"
|
|
|
+ append-to-body
|
|
|
+ @close="cancel"
|
|
|
+ >
|
|
|
+ <el-form
|
|
|
+ ref="form"
|
|
|
+ :model="form"
|
|
|
+ :rules="rules"
|
|
|
+ label-width="120px"
|
|
|
+ class="create-form"
|
|
|
+ v-loading="loading"
|
|
|
+ >
|
|
|
+ <!-- <el-row :gutter="15">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="所属场站" prop="stationName">
|
|
|
+ <el-input
|
|
|
+ v-model="form.stationName"
|
|
|
+ placeholder="请输入"
|
|
|
+ :maxlength="20"
|
|
|
+ class="!w-100%"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="所属区域" prop="areaId">
|
|
|
+ <ele-tree-select
|
|
|
+ clearable
|
|
|
+ :data="areaTree"
|
|
|
+ v-model="form.areaId"
|
|
|
+ valueKey="id"
|
|
|
+ labelKey="name"
|
|
|
+ placeholder="请选择"
|
|
|
+ @change="areaIdChange"
|
|
|
+ default-expand-all
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row> -->
|
|
|
+
|
|
|
+ <el-row :gutter="15">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="所属区域" prop="areaId">
|
|
|
+ <area-select
|
|
|
+ v-model="form.areaId"
|
|
|
+ @checkedKeys="getAreaInfo"
|
|
|
+ :data="areaTreeList"
|
|
|
+ ref="areaTree"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="摄像机编号" prop="deviceCode">
|
|
|
+ <el-input
|
|
|
+ v-model="form.deviceCode"
|
|
|
+ placeholder="请输入"
|
|
|
+ :maxlength="50"
|
|
|
+ class="!w-100%"
|
|
|
+ disabled
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="摄像机类型" prop="classifyCode">
|
|
|
+ <DictSelection
|
|
|
+ dictName="摄像机类型"
|
|
|
+ v-model="form.classifyCode"
|
|
|
+ @itemChange="classifyCodeChange"
|
|
|
+ ></DictSelection>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="15">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="摄像机名称" prop="name">
|
|
|
+ <el-input
|
|
|
+ v-model="form.name"
|
|
|
+ placeholder="请输入"
|
|
|
+ :maxlength="20"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="品牌" prop="brandCode">
|
|
|
+ <DictSelection
|
|
|
+ dictName="摄像头品牌"
|
|
|
+ v-model="form.brandCode"
|
|
|
+ @itemChange="brandCodeChange"
|
|
|
+ ></DictSelection>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="型号" prop="modelName">
|
|
|
+ <el-input
|
|
|
+ v-model="form.modelName"
|
|
|
+ placeholder="请输入"
|
|
|
+ :maxlength="20"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="15">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="排序号" prop="deviceSort">
|
|
|
+ <el-input-number
|
|
|
+ v-model="form.deviceSort"
|
|
|
+ :min="1"
|
|
|
+ :max="99999"
|
|
|
+ class="!w-100%"
|
|
|
+ controls-position="right"
|
|
|
+ placeholder="请输入"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="状态" prop="activityStatus">
|
|
|
+ <el-radio-group
|
|
|
+ v-model="form.activityStatus"
|
|
|
+ class="ml-4"
|
|
|
+ style="flex-wrap: nowrap"
|
|
|
+ >
|
|
|
+ <el-radio :label="1">启用</el-radio>
|
|
|
+ <el-radio :label="0">停用</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <div class="tit">连接配置</div>
|
|
|
+ <el-row :gutter="15">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="IP" prop="extraInfo.ip">
|
|
|
+ <el-input
|
|
|
+ v-model="form.extraInfo.ip"
|
|
|
+ placeholder="请输入"
|
|
|
+ :maxlength="20"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="端口" prop="extraInfo.port">
|
|
|
+ <el-input-number
|
|
|
+ v-model="form.extraInfo.port"
|
|
|
+ :min="1"
|
|
|
+ :max="65535"
|
|
|
+ :maxlength="5"
|
|
|
+ controls-position="right"
|
|
|
+ placeholder="请输入"
|
|
|
+ class="!w-100%"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="15">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="账号" prop="extraInfo.account">
|
|
|
+ <el-input
|
|
|
+ v-model="form.extraInfo.account"
|
|
|
+ placeholder="请输入"
|
|
|
+ :maxlength="30"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="密码" prop="extraInfo.password">
|
|
|
+ <el-input
|
|
|
+ v-model="form.extraInfo.password"
|
|
|
+ placeholder="请输入"
|
|
|
+ :maxlength="30"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="15">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="通道号" prop="extraInfo.channel">
|
|
|
+ <el-input v-model="form.extraInfo.channel" placeholder="请输入" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="RTSP流" prop="extraInfo.stream">
|
|
|
+ <el-input v-model="form.extraInfo.stream" placeholder="请输入" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="支持云台控制" prop="extraInfo.ptzControl">
|
|
|
+ <el-radio-group
|
|
|
+ v-model="form.extraInfo.ptzControl"
|
|
|
+ class="ml-4"
|
|
|
+ style="flex-wrap: nowrap"
|
|
|
+ >
|
|
|
+ <el-radio :label="0">支持</el-radio>
|
|
|
+ <el-radio :label="1">不支持</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <!-- <div class="tit">关联配置</div>
|
|
|
+ <el-row :gutter="15">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="关联NVR设备" prop="byNvrCode">
|
|
|
+ <el-select
|
|
|
+ @change="handleNvr"
|
|
|
+ placeholder="请选择"
|
|
|
+ v-model="form.byNvrCode"
|
|
|
+ clearable
|
|
|
+ class="!w-100%"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="(item, index) in loadNvrDeviceList"
|
|
|
+ :key="index"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.deviceCode"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row> -->
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="cancel">取消</el-button>
|
|
|
+ <el-button type="primary" @click="save" :loading="saving">
|
|
|
+ 确定
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </ele-modal>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import dictMixins from '@/mixins/dictMixins';
|
|
|
+ import * as CameraApi from '@/api/ledgerAssets/camera';
|
|
|
+ import * as DeviceApi from '@/api/ledgerAssets/device';
|
|
|
+ import * as AreaApi from '@/api/basic/area';
|
|
|
+ import { basicAreaPageAPI } from '@/api/factoryModel';
|
|
|
+ import { getCode } from '@/api/ruleManagement/matter';
|
|
|
+ import areaSelect from '@/components/area-select.vue';
|
|
|
+ // import { handleTree } from '@/utils/tree'
|
|
|
+ // import { getStationData } from '@/utils/auth'
|
|
|
+
|
|
|
+ const defForm = {
|
|
|
+ name: '',
|
|
|
+ deviceCode: '',
|
|
|
+ classifyCode: '',
|
|
|
+ classifyName: '',
|
|
|
+ modelId: '',
|
|
|
+ modelName: '',
|
|
|
+ brandCode: '',
|
|
|
+ brandName: '',
|
|
|
+ stationName: '',
|
|
|
+ stationId: '',
|
|
|
+ areaId: '',
|
|
|
+ areaCode: '',
|
|
|
+ areaName: '',
|
|
|
+ // byNvrCode: '',
|
|
|
+ // byNvrName: '',
|
|
|
+ deviceSort: 100,
|
|
|
+ activityStatus: 1,
|
|
|
+ relDeviceType: '',
|
|
|
+ relDeviceId: '',
|
|
|
+ delayTime: '',
|
|
|
+ listLoad: [],
|
|
|
+ extInfo: '{}',
|
|
|
+ extraInfo: {
|
|
|
+ ip: '',
|
|
|
+ port: 8000,
|
|
|
+ account: 'admin',
|
|
|
+ password: 'admin',
|
|
|
+ ptzControl: 0,
|
|
|
+ stream: '',
|
|
|
+ channel: ''
|
|
|
+ // nvr: ''
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ export default {
|
|
|
+ name: 'CameraForm',
|
|
|
+ mixins: [dictMixins],
|
|
|
+ components: {
|
|
|
+ areaSelect
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ visible: false,
|
|
|
+ title: '',
|
|
|
+ loading: false,
|
|
|
+ saving: false,
|
|
|
+ type: '',
|
|
|
+ areaTree: [],
|
|
|
+ areaTreeList: [],
|
|
|
+ loadNvrDeviceList: [],
|
|
|
+ loadDeviceList: [],
|
|
|
+ defaultProps: {
|
|
|
+ children: 'children',
|
|
|
+ label: 'name'
|
|
|
+ },
|
|
|
+ form: { ...defForm },
|
|
|
+ rules: {
|
|
|
+ name: [
|
|
|
+ { required: true, message: '摄像机名称不能为空', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ deviceCode: [
|
|
|
+ { required: true, message: '摄像机编号不能为空', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ brandCode: [
|
|
|
+ { required: true, message: '品牌不能为空', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ classifyCode: [
|
|
|
+ { required: true, message: '摄像机类型不能为空', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ deviceSort: [
|
|
|
+ { required: true, message: '排序号不能为空', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ stationName: [
|
|
|
+ { required: true, message: '所属场站不能为空', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ areaId: [
|
|
|
+ { required: true, message: '所属区域不能为空', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ extraInfo: {
|
|
|
+ ip: [{ required: true, message: 'IP不能为空', trigger: 'blur' }],
|
|
|
+ port: [
|
|
|
+ { required: true, message: '端口不能为空', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ account: [
|
|
|
+ { required: true, message: '账号不能为空', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ password: [
|
|
|
+ { required: true, message: '密码不能为空', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ channel: [
|
|
|
+ { required: true, message: '通道号不能为空', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ stream: [
|
|
|
+ { required: true, message: 'RTSP流不能为空', trigger: 'blur' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.requestDict('摄像头品牌');
|
|
|
+ // this.requestDict('NVR设备类型');
|
|
|
+ this.requestDict('摄像机类型');
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ brandCodeChange(e) {
|
|
|
+ console.log('brandCodeChange', e);
|
|
|
+ this.form.brandName = e.dictValue;
|
|
|
+ },
|
|
|
+ classifyCodeChange(e) {
|
|
|
+ console.log('classifyCodeChange', e);
|
|
|
+ this.form.classifyName = e.dictValue;
|
|
|
+ },
|
|
|
+ /** 加载NVR设备列表 */
|
|
|
+ loadNvrDeviceData() {
|
|
|
+ DeviceApi.getDeviceList({ classifyCode: '' }).then((res) => {
|
|
|
+ this.loadNvrDeviceList = res;
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 获得区域树 */
|
|
|
+ getAreaTree(stationId) {
|
|
|
+ AreaApi.getAreaList({ stationId: stationId }).then((res) => {
|
|
|
+ // this.areaTree = handleTree(res)
|
|
|
+ console.log('getAreaTree', res);
|
|
|
+ this.areaTree = this.$util.toTreeData({
|
|
|
+ data: res.list,
|
|
|
+ idField: 'id',
|
|
|
+ parentIdField: 'parentId'
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 获取区域树列表 */
|
|
|
+ getBasicAreaList() {
|
|
|
+ basicAreaPageAPI({
|
|
|
+ pageNum: 1,
|
|
|
+ size: 9999
|
|
|
+ }).then((list) => {
|
|
|
+ this.areaTreeList = this.$util.toTreeData({
|
|
|
+ data: list || [],
|
|
|
+ idField: 'id',
|
|
|
+ parentIdField: 'parentId'
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 区域选择回调 */
|
|
|
+ getAreaInfo(nodeInfo) {
|
|
|
+ if (nodeInfo) {
|
|
|
+ this.form.areaId = nodeInfo.id;
|
|
|
+ this.form.areaName = nodeInfo.name;
|
|
|
+ this.form.areaCode = nodeInfo.areaCode;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 品牌change事件 */
|
|
|
+ brandChange(e) {
|
|
|
+ this.form.brandName = this.getDictValue('摄像头品牌', e + '');
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 设备分类Change事件 */
|
|
|
+ handleClassifyId(e) {
|
|
|
+ this.form.classifyName = this.getDictValue('摄像机类型', e);
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 关联NVR设备Change事件 */
|
|
|
+ handleNvr(val) {
|
|
|
+ const deviceObj = this.loadNvrDeviceList.find(
|
|
|
+ (item) => item.deviceCode == val
|
|
|
+ );
|
|
|
+ if (deviceObj) {
|
|
|
+ this.form.byNvrName = deviceObj.name;
|
|
|
+ } else {
|
|
|
+ this.form.byNvrName = '';
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 区域Change事件 */
|
|
|
+ areaIdChange(e) {
|
|
|
+ this.processingAreaId(e, this.areaTree);
|
|
|
+ },
|
|
|
+
|
|
|
+ processingAreaId(id, data) {
|
|
|
+ for (let i = 0; i < data.length; i++) {
|
|
|
+ if (data[i].id == id) {
|
|
|
+ this.form.areaCode = data[i].areaCode;
|
|
|
+ this.form.areaName = data[i].name;
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ if (data[i].children && data[i].children.length) {
|
|
|
+ this.processingAreaId(id, data[i].children);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 打开弹窗 */
|
|
|
+ open(type, id, areaInfo) {
|
|
|
+ this.type = type;
|
|
|
+ this.title = type === 'create' ? '新增摄像机' : '编辑摄像机';
|
|
|
+
|
|
|
+ // 重置表单
|
|
|
+ this.form = { ...defForm };
|
|
|
+ // this.loadNvrDeviceData()
|
|
|
+
|
|
|
+ // 加载区域树
|
|
|
+ this.getBasicAreaList();
|
|
|
+
|
|
|
+ // 从列表页左侧区域树带入所选区域
|
|
|
+ if (areaInfo && areaInfo.id) {
|
|
|
+ this.form.areaId = areaInfo.id;
|
|
|
+ this.form.areaName = areaInfo.name;
|
|
|
+ this.form.areaCode = areaInfo.areaCode;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 编辑时,加载数据
|
|
|
+ if (id) {
|
|
|
+ this.loading = true;
|
|
|
+ CameraApi.getDevice(id)
|
|
|
+ .then((res) => {
|
|
|
+ this.form = res;
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ this.loading = false;
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // 新增时生成编号
|
|
|
+ getCode('camera_code').then((code) => {
|
|
|
+ this.form.deviceCode = code;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ this.visible = true;
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 取消 */
|
|
|
+ cancel() {
|
|
|
+ this.form = { ...defForm };
|
|
|
+ this.visible = false;
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 保存 */
|
|
|
+ save() {
|
|
|
+ this.$refs.form.validate((valid) => {
|
|
|
+ if (valid) {
|
|
|
+ this.saving = true;
|
|
|
+ const data = { ...this.form };
|
|
|
+ const action =
|
|
|
+ this.type === 'create'
|
|
|
+ ? CameraApi.createDevice(data)
|
|
|
+ : CameraApi.updateDevice(data);
|
|
|
+
|
|
|
+ action
|
|
|
+ .then(() => {
|
|
|
+ this.$message.success(
|
|
|
+ this.type === 'create' ? '新增成功' : '修改成功'
|
|
|
+ );
|
|
|
+ this.cancel();
|
|
|
+ this.$emit('success');
|
|
|
+ })
|
|
|
+ .catch((e) => {
|
|
|
+ this.$message.error(e.message);
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ this.saving = false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .tit {
|
|
|
+ margin-left: 10px;
|
|
|
+ font-weight: bold;
|
|
|
+ border-left: 3px solid #9266f9;
|
|
|
+ padding-left: 10px;
|
|
|
+ margin-bottom: 14px;
|
|
|
+ }
|
|
|
+</style>
|