| /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding |
| copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a |
| copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS |
| IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ |
| |
| <template> |
| <div class="standTable"> |
| <div class="border_table"> |
| <el-table |
| :data="tableDatas.list" |
| style="width: 100%" |
| :height="Height" |
| :max-height="maxHeight" |
| tooltip-effect="light" |
| :cell-style="{ |
| padding: `${celineHeight ? celineHeight : 0}px ${celineWidth ? celineWidth : 0}px !important`, |
| }" |
| :header-cell-style="{ |
| color: 'black', |
| overflow: 'hidden', |
| background: '#F9FAFC', |
| padding: `${lineHeight ? lineHeight : 0}px ${lineWidth ? lineWidth : 0}px !important`, |
| }" |
| @selection-change="handleSelectionChange" |
| > |
| <el-table-column fixed="left" v-if="selectData" type="selection" width="50" align="center"> </el-table-column> |
| <el-table-column :key="item.prop" v-for="item of columns.list" min-width="180px" :width="item.width + 'px'" :align="item.align" :fixed="item.fixed" show-overflow-tooltip> |
| <template #header> |
| <span :class="{ spanbox: item.required }"></span> |
| <svg v-if="iconArr.icon[item.icon]" :class="['icon', { 'icon-time': item.icon === 'TIME' }]" @click="sqlClick" aria-hidden="true"> |
| <use :xlink:href="`#icon-${iconArr.icon[item.icon]}`"></use> |
| </svg> |
| <span :style="{ 'margin-left': iconArr.icon[item.icon] ? '5px' : '' }">{{ $t(item.label) }}</span> |
| <i :class="item.icon" style="margin-left: 4px" @click="iconEvent(item.iconNum)"></i> |
| </template> |
| <template #default="scope"> |
| <el-input |
| v-if="item.type === 'INPUT' && (!scope.row[item.prop] || scope.row.display || item.canEdit)" |
| v-model="scope.row[item.prop]" |
| :size="item.size" |
| :class="{ borderRed: (scope.row.namecopy || !scope.row[item.prop]) && scope.row.border && item.border }" |
| :placeholder="$t('device.inputTip') + $t(item.label)" |
| @blur="item.event(scope, scope.row, scope.row[item.prop], $event)" |
| > |
| </el-input> |
| <el-input |
| v-if="item.type === 'TEXT'" |
| v-model="scope.row[item.prop]" |
| :maxlength="item.maxlength" |
| :size="item.size" |
| :placeholder="$t('device.inputTip') + $t(item.label)" |
| @blur="checkInput(scope.row[item.prop], item.required)" |
| > |
| </el-input> |
| <el-select |
| v-model="scope.row[item.prop]" |
| :class="{ borderRed: !scope.row[item.prop] && scope.row.seBorder }" |
| :placeholder="$t(item.label)" |
| v-if="item.type === 'SELECT' && (!scope.row[item.prop] || scope.row.display)" |
| :size="item.size" |
| @change="item.event(scope, scope.row)" |
| > |
| <el-option v-for="item in item.options" :key="item.value" :label="item.label" :value="item.value" @click="selectEncoding(item.value, scope.row)"> |
| <span style="float: left">{{ item.label }}</span> |
| </el-option> |
| </el-select> |
| <el-select |
| v-model="scope.row[item.prop]" |
| :class="{ borderRed: !scope.row[item.prop] && scope.row.seBorder }" |
| :placeholder="$t('device.selectTip')" |
| v-if="item.type === 'SELECTCH' && (!scope.row[item.prop] || scope.row.display)" |
| :size="item.size" |
| > |
| <el-option v-for="item in scope.row.options" :key="item.value" :label="item.label" :value="item.value"> |
| <span style="float: left">{{ item.label }}</span> |
| </el-option> |
| </el-select> |
| <!-- <div v-if="item.type === 'TAGS'"> |
| <span v-for="(item, index) in scope.row[item.prop]" :key="index"> {{ item }}={{ item[1] }}, </span> |
| </div> --> |
| <div v-if="item.type === 'ATTRIBUTES' || item.type === 'TAG'"> |
| <i v-if="!item.onlyShow" class="el-icon-edit editF" @click="editTag(scope.row[item.prop], scope.row.timeseries, item.prop, scope.$index)"></i> |
| <span v-for="(item, index) in scope.row[item.prop]" :key="index">{{ item[0] }} = {{ item[1] }}, </span> |
| </div> |
| <span |
| :class="item.type" |
| v-if="item.type && scope.row[item.prop] && !scope.row.display && item.type !== 'TEXT' && item.type !== 'ATTRIBUTES' && item.type !== 'TAG' && item.prop !== 'alias'" |
| >{{ scope.row[item.prop] }}</span |
| > |
| <span class="item.type" v-if="!item.type">{{ scope.row[item.prop] || item.value }}</span> |
| </template> |
| </el-table-column> |
| <el-table-column fixed="right" v-if="actionO" :label="$t(actionO.label)" min-width="150px"> |
| <template #default="scope"> |
| <slot :scope="scope"></slot> |
| </template> |
| </el-table-column> |
| </el-table> |
| </div> |
| <div class="paination" v-if="paginations || deleteArry"> |
| <el-button v-if="deleteArry" type="primary" @click="deleteArrys">{{ $t('standTable.deleteArry') }}</el-button> |
| <div></div> |
| <el-pagination |
| v-if="paginations" |
| @size-change="handleSizeChange" |
| @current-change="getList" |
| v-model:currentPage="paginations.pageNum" |
| :page-size="paginations.pageSize" |
| layout="total, prev, pager, next" |
| :total="total" |
| :hide-on-single-page="true" |
| > |
| </el-pagination> |
| </div> |
| <el-dialog :title="`${edData.label}编辑`" v-model="dialogFormVisible.flag" width="500px" class="dialog_tag"> |
| <div class="tag_content"> |
| <div> |
| <span>物理量名称:</span><span>{{ edData.name }}</span> |
| </div> |
| <div> |
| <span>物理量{{ edData.label }}:</span> |
| <svg class="icon" aria-hidden="true" @click="addData(edData.data)"> |
| <use xlink:href="#icon-add1"></use> |
| </svg> |
| </div> |
| <div class="content"> |
| <div v-for="(item, index) in edData.data" :key="index"> |
| <el-input v-model="item[0]" size="small" maxlength="30" :placeholder="`${edData.label}名`" /> = |
| <el-input v-model="item[1]" size="small" maxlength="30" :placeholder="`${edData.label}值`" /><el-button type="text" |
| ><i class="el-icon-delete" @click="deleTag(edData.data, index)" |
| /></el-button> |
| </div> |
| </div> |
| </div> |
| <template #footer> |
| <span class="dialog-footer"> |
| <el-button @click="dialogFormVisible.flag = false">取 消</el-button> |
| <el-button type="primary" @click="confirmTag">确 定</el-button> |
| </span> |
| </template> |
| </el-dialog> |
| </div> |
| </template> |
| |
| <script> |
| import { ElTable, ElTableColumn, ElInput, ElSelect, ElOption, ElMessage, ElButton, ElPagination, ElDialog } from 'element-plus'; |
| import { onActivated, reactive } from 'vue'; |
| export default { |
| name: 'StandTable', |
| props: { |
| column: Array, |
| tableData: Array, |
| selectData: Function, |
| maxHeight: Number, |
| Height: Number, |
| lineHeight: Number, |
| lineWidth: Number, |
| pagination: Object, |
| deleteArry: Function, |
| encoding: Object, |
| total: Number, |
| getList: Function, |
| celineWidth: Number, |
| celineHeight: Number, |
| backColor: String, |
| }, |
| setup(props, { emit }) { |
| let dialogFormVisible = reactive({ |
| flag: false, |
| }); |
| const iconArr = reactive({ |
| icon: { |
| INT64: 'int64', |
| BOOLEAN: 'buer', |
| INT32: 'int32', |
| TEXT: 'TEXT', |
| DOUBLE: 'DOUBLE', |
| FLOAT: 'FLOAT', |
| TIME: 'time', |
| }, |
| }); |
| let edData = reactive({ |
| data: [], |
| name: '', |
| label: '', |
| }); |
| const columns = reactive({ |
| list: {}, |
| }); |
| const actionA = props.column.list.filter((item) => item.prop === 'action'); |
| columns.list = props.column.list.filter((item) => item.prop !== 'action'); |
| const actionO = actionA.length > 0 ? reactive(actionA[0]) : ''; |
| const paginations = reactive(props.pagination); |
| const tableDatas = reactive(props.tableData); |
| const encodings = reactive(props.encoding); |
| function handleSelectionChange(val) { |
| props.selectData(val); |
| } |
| function deleteArrys() { |
| props.deleteArry(); |
| } |
| function checkInput(val, flag) { |
| if (!val && flag) { |
| ElMessage({ |
| showClose: true, |
| message: '该项值不能为空,请填写', |
| type: 'error', |
| }); |
| } |
| } |
| function getlist(val) { |
| console.log(11111); |
| console.log(val); |
| } |
| function handleCurrentChange(val) { |
| console.log(val); |
| emit('getPagintions', val); |
| } |
| function getColumn(data) { |
| columns.list = data.filter((item) => item.prop !== 'action'); |
| } |
| function selectEncoding(val, row) { |
| row.options = encodings[val]; |
| if (!row.options) { |
| row.options = encodings.DEFAULT; |
| } |
| if (val === 'FLOAT' || val === 'DOUBLE') { |
| row.encoding = row.options[row.options.length - 1].value; |
| } else { |
| row.encoding = row.options[0].value; |
| } |
| } |
| function iconEvent(iconNum) { |
| emit('iconEvent', iconNum); |
| } |
| function editTag(arr, name, str, index) { |
| let obj = { |
| tags: '标签', |
| attributes: '属性', |
| }; |
| edData.data = [...arr]; |
| edData.name = name; |
| edData.label = obj[str]; |
| edData.index = index; |
| dialogFormVisible.flag = true; |
| } |
| function addData(arr) { |
| arr.unshift([null, null]); |
| } |
| function deleTag(arr, index) { |
| arr.splice(index, 1); |
| } |
| const isRepeat = (arr) => { |
| var hash = {}; |
| |
| for (var i in arr) { |
| if (hash[arr[i]]) return true; |
| |
| hash[arr[i]] = true; |
| } |
| |
| return false; |
| }; |
| |
| const confirmTag = () => { |
| let result = isRepeat(edData.data.map((d) => d[0])); |
| let keys = edData.data.map((d) => d[0]); |
| let values = edData.data.map((d) => d[1]); |
| |
| let pattern = /^[0-9]*$/; |
| if (keys.every((d) => pattern.test(d)) || values.every((d) => pattern.test(d))) { |
| ElMessage.error(`${edData.label}不能完全为数值`); |
| return; |
| } |
| if (edData.data.length && (!keys.every((d) => d !== null) || !values.find((d) => d !== null))) { |
| ElMessage.error(`请填写完整`); |
| return; |
| } |
| if (result) { |
| ElMessage.error(`${edData.label}名不能重复`); |
| return; |
| } |
| if (edData.label === '标签') { |
| tableDatas.list[edData.index].tags = edData.data; |
| } else { |
| tableDatas.list[edData.index].attributes = edData.data; |
| } |
| dialogFormVisible.flag = false; |
| }; |
| onActivated(() => { |
| // |
| }); |
| return { |
| iconArr, |
| deleTag, |
| addData, |
| deleteArrys, |
| edData, |
| columns, |
| actionO, |
| paginations, |
| tableDatas, |
| checkInput, |
| handleSelectionChange, |
| handleCurrentChange, |
| selectEncoding, |
| getlist, |
| iconEvent, |
| getColumn, |
| editTag, |
| dialogFormVisible, |
| confirmTag, |
| }; |
| }, |
| components: { |
| ElTable, |
| ElTableColumn, |
| ElInput, |
| ElSelect, |
| ElOption, |
| ElButton, |
| ElPagination, |
| ElDialog, |
| }, |
| }; |
| </script> |
| |
| <style lang="scss" scoped> |
| .standTable { |
| .icon { |
| cursor: pointer; |
| } |
| .icon-time { |
| color: #4eb5ff; |
| } |
| } |
| .border_table { |
| border-radius: 4px; |
| border: 1px solid #eaecf0; |
| } |
| .editF { |
| cursor: pointer; |
| padding-right: 3px; |
| } |
| .tag_content { |
| div { |
| padding: 8px 0; |
| } |
| .icon_color { |
| cursor: pointer; |
| color: #7a859f; |
| } |
| .content { |
| div { |
| text-align: center; |
| } |
| i { |
| color: red; |
| } |
| .el-input__inner { |
| width: 150px; |
| } |
| } |
| } |
| .spanbox::before { |
| content: '*'; |
| color: #f56c6c; |
| margin-right: 4px; |
| } |
| .paination { |
| display: flex; |
| justify-content: space-between; |
| margin-top: 10px; |
| |
| // padding: 10px 0px; |
| .el-pagination { |
| padding: 4px 5px 0 5px; |
| } |
| } |
| .export_button { |
| height: 30px; |
| line-height: 0px; |
| min-height: 0 !important; |
| } |
| </style> |
| <style lang="scss"> |
| .borderRed { |
| .el-input__inner { |
| border: 1px solid red; |
| } |
| } |
| .tag_content { |
| .content { |
| .el-input { |
| width: 100px; |
| padding: 0 16px; |
| } |
| } |
| } |
| </style> |