doum
7 天以前 074bcb8394fab66ce531c219e1e7de7c142ff2d5
admin/src/views/business/components/YwElectricalRemote.vue
@@ -1,6 +1,6 @@
<template>
  <GlobalWindow title="电表远程控制" :visible.sync="visible" width="780px" :show-confirm="false">
    <el-tabs v-model="activeTab">
    <el-tabs v-model="activeTab" @tab-click="onTabClick">
      <el-tab-pane label="基本操作" name="basic">
        <div class="info-block">
          <p>采集器号:{{ info.collectorId }} <span :class="info.online === 1 ? 'green' : 'red'">{{ info.online === 1 ? '在线' : '离线' }}</span></p>
@@ -9,11 +9,23 @@
          <p>电表类型:{{ info.type }}</p>
          <p>关联房间:{{ info.roomNames }}</p>
        </div>
        <div class="meter-data-block" v-loading="infoLoading">
          <div class="meter-data-block__title">最新抄表数据</div>
          <p>当前总电量:{{ totalPower }}</p>
          <p>电量同步时间:{{ latest && latest.addTime ? latest.addTime : '-' }}</p>
          <p>当前剩余金额(元):{{ latest && latest.ye != null ? latest.ye : (info.balance != null ? info.balance : '0.0000') }}</p>
          <p>余额同步时间:{{ balanceSyncTime }}</p>
        </div>
        <div class="btn-row">
          <el-button type="primary" :loading="isOperating" @click="doOperate('resetPrepay', '确认清零并切换到预付费模式吗?')">清零并切换到预付费模式</el-button>
          <el-button type="primary" :loading="isOperating" @click="doOperate('resetPostpay', '确认清零并切换到后付费模式吗?')">清零并切换到后付费模式</el-button>
          <el-button type="primary" :loading="isOperating" @click="doOperate('trip', '确认拉闸吗?')">拉闸</el-button>
          <el-button type="primary" :loading="isOperating" @click="doOperate('close', '确认合闸吗?')">合闸</el-button>
        </div>
        <div class="btn-row btn-row--relay">
          <span class="btn-row__label">拉合闸操作</span>
          <el-button type="danger" :loading="isOperating" @click="doRelayOperate('trip')">拉闸</el-button>
          <el-button type="primary" :loading="isOperating" @click="doRelayOperate('close')">合闸</el-button>
          <el-button type="warning" :loading="isOperating" @click="doRelayOperate('powerProtect')">保电</el-button>
          <el-button type="danger" plain :loading="isOperating" @click="doRelayOperate('powerProtectRelease')">解除保电</el-button>
        </div>
      </el-tab-pane>
      <el-tab-pane label="开户" name="open">
@@ -39,18 +51,86 @@
          @confirm="doOperate('recharge', '确认充值吗?')"
        />
      </el-tab-pane>
      <el-tab-pane label="控制记录" name="records">
        <el-table v-loading="recordsLoading" :data="recordsList" stripe size="small" class="records-table">
          <el-table-column label="操作类型" min-width="100" align="center">
            <template slot-scope="{ row }">{{ formatActionType(row.actionType) }}</template>
          </el-table-column>
          <el-table-column prop="oprId" label="操作ID" min-width="150" align="center" show-overflow-tooltip />
          <el-table-column label="状态" min-width="80" align="center">
            <template slot-scope="{ row }">
              <span :class="statusClass(row.status)">{{ formatStatus(row.status) }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="resultMsg" label="执行结果" min-width="140" align="center" show-overflow-tooltip>
            <template slot-scope="{ row }">{{ row.resultMsg || '-' }}</template>
          </el-table-column>
          <el-table-column prop="createDate" label="操作时间" min-width="150" align="center" />
          <el-table-column label="报文" min-width="120" align="center">
            <template slot-scope="{ row }">
              <el-button type="text" :disabled="!row.requestBody" @click="openJson('请求报文', row.requestBody)">请求</el-button>
              <el-button type="text" :disabled="!row.responseBody" @click="openJson('响应报文', row.responseBody)">响应</el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作" min-width="100" align="center" fixed="right">
            <template slot-scope="{ row }">
              <el-button
                v-if="row.status === 0 && row.oprId"
                type="text"
                :loading="queryLoadingId === row.id"
                v-permissions="['business:ywelectricalactions:queryResult']"
                @click="handleQueryResult(row)"
              >查询结果</el-button>
            </template>
          </el-table-column>
        </el-table>
        <pagination
          small
          @size-change="handleRecordsSizeChange"
          @current-change="loadActionRecords"
          :pagination="recordsPagination"
        />
      </el-tab-pane>
    </el-tabs>
    <OperaInterfaceLogWindow ref="jsonWindow" />
    <template slot="footer">
      <el-button type="primary" icon="el-icon-refresh" :loading="isRefreshing" @click="refreshMeterData">刷新电表数据</el-button>
      <el-button @click="visible = false">返回</el-button>
    </template>
  </GlobalWindow>
</template>
<script>
import GlobalWindow from '@/components/common/GlobalWindow'
import Pagination from '@/components/common/Pagination'
import OperaInterfaceLogWindow from '@/components/business/OperaInterfaceLogWindow'
import { getRemoteInfo, operate } from '@/api/business/ywelectrical'
import * as actionsApi from '@/api/business/ywelectricalactions'
import AccountRechargePanel from './AccountRechargePanel'
const RELAY_ACTIONS = {
  trip: { label: '拉闸', message: '确认对该电表执行拉闸操作吗?' },
  close: { label: '合闸', message: '确认对该电表执行合闸操作吗?' },
  powerProtect: { label: '保电', message: '确认对该电表执行保电操作吗?' },
  powerProtectRelease: { label: '解除保电', message: '确认对该电表执行解除保电操作吗?' }
}
const ACTION_TYPE_MAP = {
  1: '预付费清零',
  2: '后付费清零',
  3: '远程销户',
  4: '拉闸',
  5: '合闸',
  6: '开户',
  7: '充值',
  8: '抄表',
  9: '保电',
  10: '解除保电'
}
export default {
  name: 'YwElectricalRemote',
  components: { GlobalWindow, AccountRechargePanel },
  components: { GlobalWindow, AccountRechargePanel, Pagination, OperaInterfaceLogWindow },
  data () {
    return {
      visible: false,
@@ -60,7 +140,23 @@
      latest: null,
      purchaseCount: '0',
      form: { money: 0, remark: '' },
      isOperating: false
      isOperating: false,
      isRefreshing: false,
      infoLoading: false,
      recordsLoading: false,
      recordsList: [],
      recordsPagination: { pageIndex: 1, pageSize: 10, total: 0 },
      queryLoadingId: null
    }
  },
  computed: {
    totalPower () {
      if (!this.latest) return '0.00kWh'
      const v = this.latest.zhygzdl || '0'
      return String(v).toLowerCase().indexOf('kwh') >= 0 ? v : v + 'kWh'
    },
    balanceSyncTime () {
      return (this.latest && this.latest.addTime) ? this.latest.addTime : (this.info.balanceTime || '-')
    }
  },
  methods: {
@@ -68,21 +164,86 @@
      this.electricalId = row.id
      this.activeTab = tab || 'basic'
      this.form = { money: 0, remark: '' }
      this.recordsPagination.pageIndex = 1
      this.recordsList = []
      this.visible = true
      this.loadInfo()
      if (this.activeTab === 'records') {
        this.loadActionRecords(1)
      }
    },
    onTabClick (tab) {
      if (tab.name === 'records' && this.recordsList.length === 0) {
        this.loadActionRecords(1)
      }
    },
    loadInfo () {
      if (!this.electricalId) return
      this.infoLoading = true
      getRemoteInfo(this.electricalId).then(res => {
        this.info = res.electrical || {}
        this.latest = res.latestData
        this.purchaseCount = res.purchaseCount || '0'
      }).catch(e => this.$tip.apiFailed(e))
      }).catch(e => this.$tip.apiFailed(e)).finally(() => { this.infoLoading = false })
    },
    refreshMeterData () {
      if (!this.electricalId) return
      this.isRefreshing = true
      operate({
        electricalId: this.electricalId,
        action: 'readMeter'
      })
        .then(res => {
          this.$tip.apiSuccess(res || '抄表请求已提交,正在刷新数据')
          this.loadInfo()
          this.$emit('success')
          if (this.activeTab === 'records') {
            this.loadActionRecords(this.recordsPagination.pageIndex)
          }
        })
        .catch(e => this.$tip.apiFailed(e))
        .finally(() => { this.isRefreshing = false })
    },
    loadActionRecords (page) {
      if (!this.electricalId) return
      if (page) {
        this.recordsPagination.pageIndex = page
      }
      this.recordsLoading = true
      actionsApi.fetchList({
        page: this.recordsPagination.pageIndex,
        capacity: this.recordsPagination.pageSize,
        model: { electricalId: this.electricalId }
      })
        .then(data => {
          this.recordsList = data.records || []
          this.recordsPagination.total = data.total || 0
        })
        .catch(e => this.$tip.apiFailed(e))
        .finally(() => { this.recordsLoading = false })
    },
    handleRecordsSizeChange (size) {
      this.recordsPagination.pageSize = size
      this.loadActionRecords(1)
    },
    readMeter () {
      this.submitOperate('readMeter', true)
    },
    doOperate (action, msg) {
      this.$dialog.actionConfirm(msg, '操作确认')
        .then(() => this.submitOperate(action, false))
        .catch(() => {})
    },
    relayMeterTip () {
      const name = this.info.name || '-'
      const address = this.info.address || '-'
      return `表名称:${name},表地址:${address}`
    },
    doRelayOperate (action) {
      const cfg = RELAY_ACTIONS[action]
      if (!cfg) return
      const meterTip = this.relayMeterTip()
      this.$dialog.actionConfirm(`${cfg.message}(${meterTip})`, '操作确认')
        .then(() => this.submitOperate(action, false))
        .catch(() => {})
    },
@@ -98,15 +259,79 @@
          this.$tip.apiSuccess(res || (silent ? '抄表请求已提交' : '提交成功,请在【日常用电管理-充值记录】中查看充值结果'))
          this.loadInfo()
          this.$emit('success')
          if (this.activeTab === 'records') {
            this.loadActionRecords(this.recordsPagination.pageIndex)
          }
        })
        .catch(e => this.$tip.apiFailed(e))
        .finally(() => { this.isOperating = false })
    },
    formatActionType (val) {
      return ACTION_TYPE_MAP[val] || val || '-'
    },
    formatStatus (val) {
      if (val === 0 || val === '0') return '处理中'
      if (val === 1 || val === '1') return '成功'
      if (val === 2 || val === '2') return '失败'
      return val == null || val === '' ? '-' : String(val)
    },
    statusClass (val) {
      if (val === 1 || val === '1') return 'green'
      if (val === 2 || val === '2') return 'red'
      if (val === 0 || val === '0') return 'orange'
      return ''
    },
    openJson (title, content) {
      if (!content) return
      this.$refs.jsonWindow.open(title, { content })
    },
    handleQueryResult (row) {
      this.queryLoadingId = row.id
      actionsApi.queryResult(row.id)
        .then(msg => {
          this.$tip.success(msg || '查询完成')
          this.loadActionRecords(this.recordsPagination.pageIndex)
        })
        .catch(e => this.$tip.apiFailed(e))
        .finally(() => { this.queryLoadingId = null })
    }
  }
}
</script>
<style scoped>
.info-block { margin-bottom: 16px; line-height: 28px; color: #303133; }
.info-block { margin-bottom: 12px; line-height: 28px; color: #303133; }
.meter-data-block {
  margin-bottom: 16px;
  padding: 12px 14px;
  background: #fafbfe;
  border: 1px solid #eef2f8;
  border-radius: 8px;
  line-height: 26px;
  color: #303133;
}
.meter-data-block__title {
  font-weight: 600;
  font-size: 14px;
  margin-bottom: 6px;
  color: #222;
}
.meter-data-block p { margin: 0; }
.btn-row .el-button { margin: 0 8px 8px 0; }
.btn-row--relay {
  margin-top: 4px;
  padding-top: 12px;
  border-top: 1px dashed #ebeef5;
}
.btn-row__label {
  display: block;
  width: 100%;
  margin-bottom: 8px;
  font-size: 13px;
  color: #909399;
}
.records-table { width: 100%; margin-top: 4px; }
.green { color: #67c23a; }
.red { color: #f56c6c; }
.orange { color: #e6a23c; }
</style>