You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

857 lines
28 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="app-container">
<el-form ref="basicInfoForm" :model="info" :rules="rules" label-width="150px">
<el-form-item label="通用标识" prop="commonFlag" v-if="false">
<el-input placeholder="请选择通用标识" v-model="info.commonFlag"/>
</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item label="模型名称" prop="deviceModeName">
<el-input placeholder="请输入模型名称" v-model="info.deviceModeName"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属场景" prop="sceneId">
<el-select v-model="info.sceneId" placeholder="请选择" :disabled="disabled">
<el-option
v-for="(scene, index) in scenes"
:key="index"
:label="scene.sceneName"
:value="scene.sceneId"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="定位标识" prop="gpsFlag">
<el-radio-group v-model="info.gpsFlag" @input="gpsFlagRadioChange" :disabled="disabled">
<el-radio
v-for="dict in dict.type.hw_device_mode_gps_flag"
:key="dict.value"
:label="dict.value"
v-model="gps_flag"
>{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="模型分类" prop="modeClassfication">
<el-select v-model="info.modeClassfication" placeholder="请选择数据类型">
<el-option
v-for="dict in dict.type.hw_mode_function_mode_classfication"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="语言" prop="language_code" v-if="false">
<el-select v-model="info.languageCode" placeholder="请选择">
<el-option
v-for="(language, index) in languages"
:key="index"
:label="language.languageName"
:value="language.languageCode"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="设备模型图片" prop="deviceModePic">
<el-upload
single
:action="uploadImgUrl"
list-type="picture-card"
:limit="limit"
:on-success="handleUploadSuccess"
:before-upload="handleBeforeUpload"
:on-error="handleUploadError"
:on-exceed="handleExceed"
ref="imageUpload"
:on-remove="handleDeletePicture"
:show-file-list="true"
:headers="headers"
:file-list="fileList"
:on-preview="handlePictureCardPreview"
:class="{hide: this.fileList.length >= 1}"
>
<i class="el-icon-plus"></i>
</el-upload>
<!-- 上传提示 -->
<div class="el-upload__tip" slot="tip" v-if="showTip">
<template v-if="fileSize"> <b style="color: #f56c6c">{{ fileSize }}MB</b></template>
<template v-if="fileType"> <b style="color: #f56c6c">{{ fileType.join("/") }}</b></template>
的文件
</div>
<el-dialog
:visible.sync="dialogVisible"
title="预览"
width="800"
append-to-body
>
<img
:src="dialogImageUrl"
style="display: block; max-width: 100%; margin: 0 auto"
/>
</el-dialog>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-card>
<el-tabs v-model="activeName">
<el-tab-pane label="属性" name="attributesInfo">
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
</el-row>
<el-table ref="attributesTable" :data="attributesData" row-key="columnId">
<el-table-column label="序号" type="index" min-width="5%" class-name="allowDrag"/>
<el-table-column
label="功能模式"
prop="functionMode"
v-if="false"
/>
<el-table-column
label="定位坐标标识"
prop="coordinate"
v-if="false"
/>
<el-table-column
label="描述"
prop="remark"
v-if="false"
/>
<el-table-column
label="功能类型"
prop="functionType"
min-width="10%">
<template slot-scope="scope">
<dict-tag :options="dict.type.hw_mode_function_function_type" :value="scope.row.functionType"/>
</template>
</el-table-column>
<el-table-column
label="功能名称"
prop="functionName"
min-width="10%"
:show-overflow-tooltip="true"
/>
<el-table-column
label="标识符"
prop="functionIdentifier"
min-width="10%"
:show-overflow-tooltip="true"
/>
<el-table-column prop="dataType" label="数据类型" min-width="10%">
<template slot-scope="scope">
<dict-tag :options="dict.type.hw_mode_function_data_type" :value="scope.row.dataType"/>
</template>
</el-table-column>
<el-table-column
label="数据定义"
prop="dataDefinition"
min-width="10%"
:show-overflow-tooltip="true"
v-if="false"
/>
<el-table-column
label="单位"
prop="propertyUnit"
min-width="10%"
:show-overflow-tooltip="true"
/>
<el-table-column
label="读写权限"
prop="rwFlag"
min-width="10%"
:show-overflow-tooltip="true"
>
<template slot-scope="scope">
<dict-tag :options="dict.type.hw_mode_function_rw_flag" :value="scope.row.rwFlag"/>
</template>
</el-table-column>
<el-table-column
label="显示"
prop="displayFlag"
min-width="10%"
:show-overflow-tooltip="true"
>
<template slot-scope="scope">
<dict-tag :options="dict.type.hw_mode_function_display_flag" :value="scope.row.displayFlag"/>
</template>
</el-table-column>
<el-table-column label="操作" align="center" min-width="10%">
<template slot-scope="scope" v-if="scope.row.roleId !== 1">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
v-if="scope.row.coordinate==null"
@click="handleUpdateAttribute(scope.row)"
>修改
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
v-if="scope.row.coordinate==null"
@click="handleDeleteAttribute(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改设备模型功能对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="modeFunctionForm" :model="form" :rules="modeFunctionRules" label-width="80px">
<el-form-item label="功能模式" prop="functionMode" v-show="false">
<el-input v-model="form.functionMode" placeholder="请输入功能模式"/>
</el-form-item>
<el-form-item label="功能类型" prop="functionType">
<el-select v-model="form.functionType" placeholder="请选择功能类型">
<el-option
v-for="dict in dict.type.hw_mode_function_function_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="功能名称" prop="functionName">
<el-input v-model="form.functionName" placeholder="请输入功能名称"/>
</el-form-item>
<el-form-item label="标识符" prop="functionIdentifier">
<el-input v-model="form.functionIdentifier" placeholder="请输入标识符" maxlength="20"/>
</el-form-item>
<el-form-item label="数据类型" prop="dataType">
<el-select v-model="form.dataType" placeholder="请选择数据类型">
<el-option
v-for="dict in dict.type.hw_mode_function_data_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="取值范围" prop="dataDefinition" v-show="false">
<el-input v-model="form.minValue" placeholder="请输入最小值" style="width:150px;"/>
——
<el-input v-model="form.maxValue" placeholder="请输入最大值" style="width:150px;"/>
</el-form-item>
<el-form-item label="布尔值" prop="dataDefinition" v-show="form.dataType == '8'">
0——
<el-input v-model="form.boolFalse" placeholder="请输入值" style="width:150px;"/>
</el-form-item>
<el-form-item label="" prop="dataDefinition" v-show="form.dataType == '8'">
1——
<el-input v-model="form.boolTrue" placeholder="请输入值" style="width:150px;"/>
</el-form-item>
<el-form-item label="长度" prop="dataDefinition" v-show="form.dataType == '10'">
<el-input-number v-model="form.dataDefinition" placeholder="请输入最大长度" :min="10" :max="1000"
style="width:150px;"/>
</el-form-item>
<el-form-item label="单位" prop="propertyUnit">
<el-input v-model="form.propertyUnit" placeholder="请输入单位"/>
</el-form-item>
<el-form-item label="显示标识" prop="displayFlag">
<el-radio-group v-model="form.displayFlag">
<el-radio
v-for="dict in dict.type.hw_mode_function_display_flag"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="读写标识" prop="rwFlag">
<el-radio-group v-model="form.rwFlag">
<el-radio
v-for="dict in dict.type.hw_mode_function_rw_flag"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="描述" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitDeviceModeFunctionForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</el-tab-pane>
<el-tab-pane label="服务" name="servicesInfo">
<device-mode-service ref="servicesTable" :servicesData="servicesData" :deviceModeId="deviceModeId"/>
</el-tab-pane>
<el-tab-pane label="事件" name="eventsInfo">
<device-mode-event ref="eventInfo" :eventsData="eventsData" :deviceModeId="deviceModeId"/>
</el-tab-pane>
</el-tabs>
<el-form label-width="100px">
<el-form-item style="text-align: center;margin-left:-100px;margin-top:10px;">
<el-button type="primary" @click="submitForm()">提交</el-button>
<el-button @click="close()"></el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
import {addDeviceMode, getDeviceMode, updateDeviceMode,getEditedScenes} from "@/api/business/deviceMode";
import deviceModeService from "./deviceModeService";
import deviceModeEvent from "./deviceModeEvent";
import {
addDeviceModeFunction,
delDeviceModeFunction,
updateDeviceModeFunction
} from "@/api/business/deviceModeFunction";
import {getToken} from "@/utils/auth";
export default {
dicts: ['hw_device_mode_gps_flag', 'hw_mode_function_mode_classfication', 'hw_mode_function_function_type', 'hw_mode_function_function_type', 'hw_mode_function_data_type', 'hw_mode_function_display_flag', 'hw_mode_function_rw_flag'],
components: {
deviceModeService,
deviceModeEvent
},
props: {
value: [String, Object, Array],
// 图片数量限制
limit: {
type: Number,
default: 1,
},
// 大小限制(MB)
fileSize: {
type: Number,
default: 5,
},
// 文件类型, 例如['png', 'jpg', 'jpeg']
fileType: {
type: Array,
default: () => ["png", "jpg", "jpeg"],
},
// 是否显示提示
isShowTip: {
type: Boolean,
default: true
}
},
data() {
return {
info: {},
// 弹出层标题
title: "",
// 表单参数
form: {},
editedForm: {},
gps_flag: '',
// 是否显示弹出层
open: false,
disabled: true,
rules: {
deviceModeName: [{
required: true,
message: '请输入模型名称',
trigger: 'blur'
}],
sceneId: [
{required: true, message: "请选择场景", trigger: "change"}
],
gpsFlag: [
{required: true, message: "请选择定位标识", trigger: "change"}
],
},
modeFunctionRules: {
functionType: [
{required: true, message: "请选择功能类型", trigger: "blur"},
],
functionName: [
{required: true, message: "请输入功能名称", trigger: "blur"}
],
functionIdentifier: [
{required: true, message: "请输入标识符", trigger: "blur"},
{
pattern: /^[a-z][a-z0-9_]+$/,
message: "2-20个字符由小写字母、数字或下划线组成开头必须为小写字母",
trigger: "blur"
}
],
},
// 选中选项卡的 name
activeName: "attributesInfo",
//场景列表
scenes: [],
//语言列表
languages: [],
//经度标识符
IDENTIFIER_LONGITUDE: 'longitude',
//纬度标识符
IDENTIFIER_LATITUDE: 'latitude',
//设备模型ID
deviceModeId: '',
//属性的列表值。数组
attributesData: [],
attributeDataIndex: -1,//待编辑的行的数组index
//服务的列表值。数组
servicesData: [],
//事件的列表值。数组
eventsData: [],
// 表格的高度
tableHeight: document.documentElement.scrollHeight - 245 + "px",
number: 0,
uploadList: [],
dialogImageUrl: "",
dialogVisible: false,
hideUpload: false,
uploadImgUrl: process.env.VUE_APP_BASE_API + "/file/upload", // 上传的图片服务器地址
headers: {
Authorization: "Bearer " + getToken(),
},
fileList: [],
}
},
created() {
this.getConfigKey("hw.gps.longitude").then(response => {//获取经度标识符
this.IDENTIFIER_LONGITUDE = response.msg;
});
this.getConfigKey("hw.gps.latitude").then(response => {//获取纬度标识符
this.IDENTIFIER_LATITUDE = response.msg;
});
// getLanguages().then(response => {
// this.languages = response.data;
// });
getEditedScenes().then(response => {
this.scenes = response.data;
});
const deviceModeId = this.$route.params && this.$route.params.deviceModeId;
if (deviceModeId) {
// 获取表详细信息
getDeviceMode(deviceModeId).then(res => {
this.info = res.data.deviceMode;
this.attributesData = (res.data.deviceModeFunctionMap)['1'];
this.servicesData = (res.data.deviceModeFunctionMap)['2'];
this.eventsData = (res.data.deviceModeFunctionMap)['3'];
this.deviceModeId = deviceModeId;
if (res.data.deviceMode.deviceModePic != null) {
let previewFile = {};
previewFile.url = res.data.deviceMode.deviceModePic
this.fileList.push(previewFile);
}
// this.columns = res.data.rows;
});
/** 查询字典下拉列表 */
// getDictOptionselect().then(response => {
// this.dictOptions = response.data;
// });
} else {
//初始化设备模型的数据
this.info = {
gpsFlag: "0",
commonFlag: "0"
};
this.gps_flag = "0"
this.disabled = false;
this.eventsData = [];
}
},
computed: {},
watch: {},
mounted() {
},
methods: {
// 定位标识单选按钮值变化时
gpsFlagRadioChange(value) {
if (parseInt(value) === 1) {//定位传感器
let attributesData = this.attributesData;
if (attributesData.length > 0) {
this.$modal.confirm('修改定位标识会删除所有属性,确定修改定位标识么?').then(function () {
attributesData.splice(0, attributesData.length);
}).then(() => {
this.addGpsAttribute();
});
} else {
this.addGpsAttribute();
}
} else {
let attributesData = this.attributesData;
if (attributesData.length > 0) {
this.$modal.confirm('修改定位标识会删除所有属性,确定修改定位标识么?').then(function () {
attributesData.splice(0, attributesData.length);
});
}
}
},
addGpsAttribute() {
this.reset();
this.form.coordinate = "1"
this.form.functionIdentifier = this.IDENTIFIER_LONGITUDE;
this.form.functionName = "经度";
this.form.dataType = 5;
this.attributesData.push(this.form);
this.reset();
this.form.coordinate = "2"
this.form.functionIdentifier = this.IDENTIFIER_LATITUDE;
this.form.functionName = "纬度";
this.form.dataType = 5;
this.attributesData.push(this.form);
},
/** 新增属性按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加设备模型属性";
},
// 设备属性表单重置
reset() {
this.form = {
functionMode: '1',
modeFunctionId: null,
deviceModeId: null,
coordinate: null,
functionName: null,
functionIdentifier: null,
functionType: "1",//默认直采变量
dataType: "2",//默认int类型
dataDefinition: null,
functionFormula: null,
propertyUnit: null,
displayFlag: "1",//默认显示
rwFlag: "2",//默认只读
boolFalse: '',
boolTrue: '',
minValue: '',
maxValue: '',
invokeMethod: null,
eventType: null,
remark: null,
};
this.resetForm("modeFunctionForm");
},
handleUpdateAttribute(row) {
// this.reset();
this.attributeDataIndex = this.attributesData.indexOf(row);
this.convertParameterDefinition(row);
this.form = JSON.parse(JSON.stringify(row));//需要深拷贝。如果直接等于,则在编辑时,数组直接变化
this.open = true;
this.title = "添加设备模型属性";
},
convertParameterDefinition(row) {
let dataType = row.dataType;
if (parseInt(dataType) === 8) {
let dataDefinitionJson = JSON.parse(row.dataDefinition)
row.boolFalse = dataDefinitionJson["0"];
row.boolTrue = dataDefinitionJson["1"];
}
row.dataType = dataType.toString();
},
handleDeleteAttribute(row) {
if (row.modeFunctionId !== undefined) {
delDeviceModeFunction(row.modeFunctionId).then(res => {
this.$modal.msgSuccess(res.msg);
if (res.code === 200) {
this.attributesData.splice(this.attributesData.indexOf(row), 1);
}
});
} else {
this.attributesData.splice(this.attributesData.indexOf(row), 1);
}
},
/** 关闭按钮 */
close() {
// alert(this.$route.query.pageNum);
const obj = {path: "/device/deviceMode", query: {t: Date.now(), pageNum: this.$route.query.pageNum}};
this.$tab.closeOpenPage(obj);
},
submitDeviceModeFunctionForm() {
this.$refs['modeFunctionForm'].validate(valid => {
if (valid) {
/** 设备模型添加后在list中添加 */
//alert(this.minValue+"--"+this.maxValue)
if (this.form.dataType === "8") {
let boolFalse = this.form.boolFalse;
let boolTrue = this.form.boolTrue;
if (boolFalse === '' || boolTrue === '') {
this.$modal.msgError("请输入布尔值");
return;
} else {
this.form.dataDefinition = '{"0":"' + boolFalse + '","1":"' + boolTrue + '"}';
}
}
if (this.deviceModeId && this.deviceModeId !== '') {
let modeFunctionId = this.form.modeFunctionId;
this.form.deviceModeId = this.deviceModeId;
if (modeFunctionId !== undefined && modeFunctionId != null) {
let attributeDataIndex = this.attributeDataIndex;
let oldForm = this.attributesData[attributeDataIndex];
if (oldForm.functionIdentifier != this.form.functionIdentifier
|| oldForm.dataType != this.form.dataType) {
this.$modal.confirm('修改标识符或数据类型,之前上报数据会清除,确认要修改么?').then(() => {
return this.doUpdateDeviceModeFunction();
}
)
} else {
this.doUpdateDeviceModeFunction();
}
} else {
addDeviceModeFunction(this.form).then(res => {
this.$modal.msgSuccess(res.msg);
if (res.code === 200) {
this.open = false;
this.form.modeFunctionId = res.data;
this.pushData();
}
});
}
} else {
this.open = false;
this.pushData();
}
}
})
},
doUpdateDeviceModeFunction() {
updateDeviceModeFunction(this.form).then(res => {
this.$modal.msgSuccess(res.msg);
if (res.code === 200) {
this.open = false;
this.pushData();
}
});
},
pushData() {
let attributeDataIndex = this.attributeDataIndex;
if (attributeDataIndex > -1) {
this.attributeDataIndex = -1;
this.attributesData.splice(attributeDataIndex, 1, this.form);
} else {
this.attributesData.push(this.form)
}
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
submitForm() {
this.$refs['basicInfoForm'].validate(valid => {
if (valid) {
if (this.info.deviceModeId != undefined) {
updateDeviceMode(this.info).then(res => {
this.$modal.msgSuccess(res.msg);
if (res.code === 200) {
this.close();
}
});
} else {
if (this.attributesData.length <= 0) {
this.$modal.msgError("请添加属性");
return;
}
let functionData = this.servicesData.concat(this.attributesData);
functionData = functionData.concat(this.eventsData)
this.info.hwDeviceModeFunctionList = functionData;
addDeviceMode(this.info).then(res => {
this.$modal.msgSuccess(res.msg);
if (res.code === 200) {
this.close();
}
});
}
}
})
},
/**上传图片处理*/
// 上传前loading加载
handleBeforeUpload(file) {
let isImg = false;
if (this.fileType.length) {
let fileExtension = "";
if (file.name.lastIndexOf(".") > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
}
isImg = this.fileType.some(type => {
if (file.type.indexOf(type) > -1) return true;
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
return false;
});
} else {
isImg = file.type.indexOf("image") > -1;
}
if (!isImg) {
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`);
return false;
}
if (this.fileSize) {
const isLt = file.size / 1024 / 1024 < this.fileSize;
if (!isLt) {
this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`);
return false;
}
}
this.$modal.loading("正在上传图片,请稍候...");
this.number++;
},
checkPicture(file) {
},
// 文件个数超出
handleExceed() {
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} !`);
},
// 上传成功回调
handleUploadSuccess(res, file) {
if (res.code === 200) {
this.uploadList.push(res.data.url);
this.uploadedSuccessfully();
} else {
this.number--;
this.$modal.closeLoading();
this.$modal.msgError(res.msg);
this.$refs.imageUpload.handleRemove(file);
this.uploadedSuccessfully();
}
},
// 上传结束处理
uploadedSuccessfully() {
if (this.number > 0 && this.uploadList.length === this.number) {
this.fileList = this.fileList.concat(this.uploadList);
this.uploadList = [];
this.number = 0;
this.info.deviceModePic = this.fileList[0];
// this.$emit("input", this.listToString(this.fileList));
this.$modal.closeLoading();
}
},
// 删除图片
handleDeletePicture(file) {
const findex = this.fileList.map(f => f.name).indexOf(file.name);
if (findex > -1) {
this.fileList.splice(findex, 1);
// this.$emit("input", this.listToString(this.fileList));
}
this.info.deviceModePic = '';
},
// 上传失败
handleUploadError() {
this.$modal.msgError("上传图片失败,请重试");
this.$modal.closeLoading();
},
// 预览
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
// 对象转成指定字符串分隔
listToString(list, separator) {
let strs = "";
separator = separator || ",";
for (let i in list) {
if (list[i].url) {
strs += list[i].url.replace(this.baseUrl, "") + separator;
}
}
return strs != '' ? strs.substr(0, strs.length - 1) : '';
},
},
}
</script>