Files
smart_storage_web/src/views/remote-control/issue-order/index.vue
2025-06-30 10:17:15 +08:00

636 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<section class="realtime-wrapper">
<el-form id="searchForm" :model="filters" label-width="80px">
<el-row :gutter="5" class="search-row">
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6">
<el-form-item :label="$t('remote.eqpt') + ''">
<el-input v-model="devAllName" readonly :placeholder="$t('remote.pleaseInput')" class="input-with-select">
<el-button slot="append" icon="el-icon-search" :loading="dev_loading" @click="openTreeDialog" />
</el-input>
</el-form-item>
</el-col>
<el-col :xs="12" :sm="9" :md="9" :lg="9" :xl="9">
<el-button
:loading="load_data"
type="primary"
icon="el-icon-search"
@click="on_refresh"
>{{ $t('remote.query') }}</el-button>
</el-col>
<el-col :xs="12" :sm="9" :md="9" :lg="9" :xl="9" class="btn-box">
<el-button
v-permission="['remoteControl:command:batchDistribution']"
type="primary"
icon="el-icon-bottom"
:loading="isMoreLoading"
class="reset-btn"
@click="handleMoreOrder"
>{{ $t('remote.batchdelivery') }}</el-button>
<el-button
v-permission="['remoteControl:command:export']"
type="primary"
icon="el-icon-upload2"
class="reset-btn"
:loading="export_loading"
@click="handleExport"
>{{ $t('remote.export') }}</el-button>
</el-col>
</el-row>
</el-form>
<div class="table-wrapper">
<el-table
ref="alarmtable"
v-loading="load_data"
:row-style="getRowStyle"
header-align="center"
:height="$setAutoTableHeight(46,searchHeight)"
:data="table_data"
:element-loading-text="loadingText"
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="50"
align="center"
/>
<el-table-column
type="index"
:index="tableRowClassName"
:label="$t('remote.ordinal')"
width="65"
align="center"
/>
<el-table-column prop="deviceName" width="100" :label="$t('remote.eqpt')" />
<el-table-column prop="colName" width="300" :label="$t('remote.chineseName')" show-overflow-tooltip />
<el-table-column prop="col" width="100" :label="$t('remote.englishName')" show-overflow-tooltip />
<el-table-column prop="maxValue" :label="$t('remote.maxValue')" />
<el-table-column prop="minValue" :label="$t('remote.minValue')" />
<el-table-column prop="updateTime" :label="$t('remote.upDate')" width="150" />
<el-table-column prop="value" :label="$t('remote.nowValue')">
<template slot-scope="scope">
{{ scope.row.value }}{{ scope.row.unit ? scope.row.unit : '' }}
</template>
</el-table-column>
<el-table-column width="150" :label="$t('remote.yhxgz')">
<template slot-scope="scope">
<el-input v-model="scope.row.modifyValue" type="number" placeholder="请输入" />
</template>
</el-table-column>
<!-- <el-table-column width="180" label="站内接入点">
<template slot-scope="scope">
<el-select v-model="scope.row.sn" placeholder="请输入" style="width:100%" @change="getHeartbeat(scope.row.sn)">
<el-option
v-for="item in snList"
:key="item.id"
:label="item.sn"
:value="item.sn"
/>
</el-select>
</template>
</el-table-column> -->
<el-table-column :label="$t('remote.operate')" width="120">
<template slot-scope="scope">
<el-button
v-permission="['remoteControl:command:singleDistribution']"
type="text"
icon="el-icon-bottom"
@click="handleOrder(scope.row,scope.$index)"
>{{ $t('remote.issued') }}</el-button>
<el-button
type="text"
icon="el-icon-refresh"
@click="handleRefresh(scope.row,scope.$index)"
>{{ $t('remote.refresh') }}</el-button>
</template>
</el-table-column>
</el-table>
<Pagingbar>
<div slot="page">
<el-pagination
:current-page="currentPage"
:page-size="pageSize"
:page-sizes="pageSizes"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
/>
</div>
</Pagingbar>
<TreeDialog ref="treeDialog" :visible="treeVisible" :tree-changedata="srcId" :tree-props="treeProps" check-strictly :title="$t('remote.eqptType')" @confirm="getTreeId" @close="closeTreeDialog" />
</div>
</section>
</template>
<script>
import { pageSize, pageSizes } from '@/config'
import Pagingbar from '@/components/Pagingbar'
import TreeDialog from '@/components/TreeDialog'
import { handleDownExcel } from '@/utils'
import { GetTreeVirtualDevices } from '@/api/surveillance/energy-storage/index'
import { GetPointList, GetSNBystationId, GetObjById, SetOrderIssued, GetOrderProgressBar, GetHeartbeat, beforeOrderSend } from '@/api/monitor/integrated-cabinet'
export default {
components: { Pagingbar, TreeDialog },
props: {},
data() {
return {
filters: {
stationId: '',
srcId: null
},
srcId: [],
snList: [],
multipleSelection: [],
table_data: [],
// 当前页码
currentPage: 1,
// 数据总条目
total: 0,
// 每页显示多少条数据
pageSize: pageSize,
pageSizes: pageSizes,
// 请求时的loading效果
load_data: false,
isMoreLoading: false,
interval: null,
moreInterval: null,
orderError: [],
loadingText: 'Loading...',
cascaderKey: 0,
props: { label: 'name', value: 'srcId', children: 'children', emitPath: false },
stationNormalizer(node) {
return {
id: node.srcId,
label: node.name,
children:
node.children && node.children.length > 0
? node.children
: undefined
}
},
treeProps: {
id: 'srcId',
label: 'name',
children: 'children',
disabled: (data, node) => {
if (data.category === 1 || data.category === 2) {
return true
}
}
},
devAllName: '',
treeVisible: false,
dev_loading: false,
export_loading: false
}
},
computed: {
stations: function() {
return this.$store.getters.stations || []
},
currentStation() {
return this.$store.getters.currentStation || undefined
},
searchHeight() {
return this.$store.getters.searchHeight
}
},
watch: {
// stations: {
// handler: function(stations) {
// if (stations.length > 0) {
// this.filters.stationId = this.stations[0].id
// this.get_table_data()
// this.getFindIntegratedCabinets()
// }
// }
// },
currentStation: {
async handler(val) {
if (val && val.id) {
this.filters.stationId = val.id
this.currentPage = 1
await this.getFindIntegratedCabinets()
this.get_table_data()
}
},
deep: true
}
},
async created() {
if (this.currentStation.id) {
this.filters.stationId = this.currentStation.id
await this.getFindIntegratedCabinets()
this.beforeOrderSend()
// const isOffLine = await this.getHeartbeat()
// if (isOffLine) {
// this.get_table_data()
// }
}
},
destroyed() {
clearInterval(self.interval)
clearInterval(self.moreInterval)
},
methods: {
findItem(tree, srcId) {
if (tree.srcId === srcId) {
return tree
}
if (tree.children && tree.children.length > 0) {
for (const child of tree.children) {
const result = this.findItem(child, srcId)
if (result) {
return result
}
}
}
return null
},
getTreeId(val, name) {
// console.log(val, name)
this.devAllName = name
this.filters.srcId = val
},
closeTreeDialog() {
this.treeVisible = false
},
openTreeDialog() {
this.treeVisible = true
},
async beforeOrderSend() {
const params = {
stationId: this.filters.stationId
}
const res = await beforeOrderSend(params)
this.filters.srcId = res.data.srcId
const r = this.findItem(this.srcId[0], this.filters.srcId)
this.$nextTick(() => {
this.$refs.treeDialog.currentNode = this.filters.srcId
})
this.devAllName = r.name
this.get_table_data()
},
tableRowClassName(index) {
return (this.currentPage - 1) * this.pageSize + index + 1
},
getRowStyle(row) {
const ishas = this.orderError.includes(row.row.col)
if (ishas) {
return {
color: 'red'
}
} else {
return {
color: '#ffffff'
}
}
},
async getHeartbeat() {
this.$forceUpdate()
const params = {
stationId: this.filters.stationId,
srcId: this.filters.srcId
}
const res = await GetHeartbeat(params)
if (res.data.heartbeatStatus === 0) {
this.$message.warning(res.data.msg)
return false
} else {
return true
}
},
handleExport() {
this.export_loading = true
const params = {
isSave: 1,
stationId: this.filters.stationId,
srcId: this.filters.srcId,
title: this.$t('remote.mlxf')
}
handleDownExcel('/business/point/exportExcel', params, (callback) => {
this.export_loading = false
})
},
handleSizeChange(val) {
this.currentPage = 1
this.pageSize = val
this.get_table_data()
},
// 页码选择
handleCurrentChange(val) {
this.currentPage = val
this.get_table_data()
},
// 切换电站
handleChangeStation() {
this.getFindIntegratedCabinets()
// this.getSNBystationId()
},
// 刷新
on_refresh() {
this.currentPage = 1
this.get_table_data()
},
// 清空查询条件
handleSearchClear() {
this.filters = {}
this.filters.stationId = this.stations[0].id
this.filters.srcId = ''
this.handleChangeStation()
},
// 多选
handleSelectionChange(val) {
this.multipleSelection = val
},
// 下发
async handleOrder(row, index) {
const self = this
this.orderError = []
row.modifyValue = Number(row.modifyValue)
if (row.modifyValue > row.maxValue || row.modifyValue < row.minValue) {
return this.$message.warning(this.$t('remote.issuedError'))
}
this.load_data = true
this.loadingText = this.$t('remote.Delivering')
const params = {
list: [{ ...row, stationId: self.filters.stationId }]
}
const res = await SetOrderIssued(params)
if (res.data.heartbeatStatus === 0) {
this.load_data = false
this.$message.warning(res.data.msg)
} else {
this.interval = setInterval(() => {
self.getOrderProgressBar(row, index)
}, 500)
}
},
// 下发进度
async getOrderProgressBar(row, index) {
const self = this
const params = {
stationId: this.filters.stationId,
srcId: this.filters.srcId
}
const res = await GetOrderProgressBar(params)
if (res.data.isEnd === 1) {
clearInterval(self.interval)
this.load_data = false
this.handleRefresh(row, index, true)
self.$message.success(res.data.msg)
} else if (res.data.isEnd === 2) {
clearInterval(self.interval)
this.load_data = false
if (res.data.processList.length > 0) {
res.data.processList.forEach(item => {
if (!self.orderError.includes(item.col)) {
self.orderError.push(item.col)
}
})
}
self.$message.error(res.data.msg)
}
},
// 批量下发进度
async getMoreOrderProgressBar() {
const self = this
const params = {
stationId: this.filters.stationId,
srcId: this.filters.srcId
}
const res = await GetOrderProgressBar(params)
if (res.data.isEnd === 1) {
clearInterval(self.moreInterval)
self.isMoreLoading = false
self.load_data = false
// self.get_table_data()
if (self.multipleSelection.length > 0) {
self.multipleSelection.forEach(item => {
const index = self.table_data.findIndex(v => {
return v.col === item.col
})
self.handleRefresh(item, index, true)
})
} else {
self.orderError = []
}
self.$message.success(res.data.msg)
} else if (res.data.isEnd === 2) {
clearInterval(self.moreInterval)
self.load_data = false
self.isMoreLoading = false
if (res.data.processList.length > 0) {
res.data.processList.forEach(item => {
if (!self.orderError.includes(item.col)) {
self.orderError.push(item.col)
}
})
}
this.refershSuccessOreder()
self.$message.error(res.data.msg)
}
},
refershSuccessOreder() {
const self = this
const successList = this.multipleSelection.filter(item => {
return !self.orderError.includes(item.col)
})
successList.forEach(item => {
const index = self.table_data.findIndex(v => {
return v.col === item.col
})
self.handleRefresh(item, index, true)
})
},
async handleMoreOrder() {
const self = this
this.orderError = []
if (this.multipleSelection.length > 0) {
this.isMoreLoading = true
this.multipleSelection.forEach(function(item) {
item.stationId = self.filters.stationId
})
const params = {
list: this.multipleSelection
}
const res = await SetOrderIssued(params)
if (res.data.heartbeatStatus === 0) {
this.load_data = false
this.isMoreLoading = false
this.$message.warning(res.data.msg)
} else {
this.moreInterval = setInterval(() => {
self.getMoreOrderProgressBar()
}, 500)
}
} else {
this.$message.warning(this.$t('remote.pleaseSelectData'))
}
},
// 查询设备
async getFindIntegratedCabinets() {
this.dev_loading = true
const params = {
stationId: this.filters.stationId
}
try {
const res = await GetTreeVirtualDevices(params)
this.srcId = res.data
if (this.srcId.length > 0) {
this.filters.srcId = this.srcId[0].srcId
this.getHeartbeat()
} else {
this.filters.srcId = ''
}
} catch (error) {
// console.log(error);
} finally {
this.dev_loading = false
}
},
// 查询SN
async getSNBystationId() {
const params = {
stationId: this.filters.stationId
}
const res = await GetSNBystationId(params)
this.snList = res.data
if (this.snList.length > 0) {
this.getHeartbeat()
}
},
// 查询
async handleRefresh(row, index, isRefresh) {
const params = {
...row,
stationId: this.filters.stationId
}
const res = await GetObjById(params)
res.data.modifyValue = res.data.value
this.$set(this.table_data, index, res.data)
if (!isRefresh) {
this.orderError = []
}
},
// 获取电站数据
async get_table_data() {
const self = this
this.load_data = true
const params = {
pageNum: self.currentPage,
pageSize: self.pageSize,
isSave: 1,
stationId: self.filters.stationId,
srcId: self.filters.srcId
}
const res = await GetPointList(params)
res.data.list.forEach(row => {
row.modifyValue = row.value
})
self.table_data = res.data.list
self.total = res.data.totalRows
self.load_data = false
self.orderError = []
}
}
}
</script>
<style lang="scss" scoped>
.realtime-wrapper {
width: 100%;
height: 100%;
background: rgba(4, 48, 80, 0.6);
padding: 10px;
box-shadow: inset 0px 2px 16px 0px rgba(0, 148, 255, 0.15);
::v-deep .el-loading-spinner .path {
-webkit-animation: loading-dash 1.5s ease-in-out infinite;
animation: loading-dash 1.5s ease-in-out infinite;
stroke-dasharray: 90, 150;
stroke-dashoffset: 0;
stroke-width: 4;
stroke: #59C5DC;
stroke-linecap: round;
}
.el-loading-spinner .el-loading-text {
color: #59C5DC;
margin: 3px 0;
font-size: 14px;
}
.search-first-row {
margin-bottom: 10px;
}
::v-deep .el-form-item__content {
display: flex;
.el-checkbox {
margin-right: 20px;
.el-checkbox__label {
color: #fff;
font-size: 15px;
}
}
}
.btn-box{
text-align: right;
}
.reset-btn{
background: rgba(0, 148, 255, 0.15);
border-color: rgba(0, 148, 255, 0.15);
}
.shigu {
padding-left: 6px;
color: red;
}
.yichang {
padding-left: 6px;
color: #f4c304;
}
.yuexian {
padding-left: 6px;
color: #d7e707;
}
.bianwei {
padding-left: 6px;
color: #45eef5;
}
.gaozhi {
padding-left: 6px;
color: #538ff1;
}
.total {
padding-left: 6px;
color: #fff;
}
.trans-order {
background: #de6822;
border: 1px solid #de6822;
}
.table-wrapper {
.main-btns {
width: 100%;
text-align: right;
padding: 10px 20px;
button {
color: #fff;
}
}
}
}
</style>