345 lines
12 KiB
Vue
345 lines
12 KiB
Vue
<template>
|
||
<div class="energy-link-page">
|
||
<!-- 查询条件 -->
|
||
<el-card class="search-card">
|
||
<el-form :model="queryParams" label-width="120px" size="small">
|
||
<el-row :gutter="20">
|
||
<el-col :xs="24" :sm="12" :md="6">
|
||
<el-form-item label="能源类型:">
|
||
<el-select v-model="queryParams.energyTypeId" placeholder="请选择能源类型" clearable @change="handleQuery">
|
||
<el-option v-for="item in energyTypeList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="6">
|
||
<el-form-item label="库区:">
|
||
<el-select v-model="queryParams.warehouseId" placeholder="请选择库区" clearable @change="handleQuery">
|
||
<el-option v-for="item in warehouseList" :key="item.warehouseId" :label="item.warehouseName" :value="item.warehouseId"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="6">
|
||
<el-form-item label="状态:">
|
||
<el-select v-model="queryParams.isEnabled" placeholder="请选择状态" clearable @change="handleQuery">
|
||
<el-option label="启用" :value="1"></el-option>
|
||
<el-option label="禁用" :value="0"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="6">
|
||
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">查询</el-button>
|
||
<el-button icon="el-icon-refresh" size="small" @click="resetQuery">重置</el-button>
|
||
<el-button type="success" icon="el-icon-plus" size="small" @click="openAddDialog">新增</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
</el-card>
|
||
|
||
<!-- 统计信息 -->
|
||
<el-row :gutter="20" class="statistics-row">
|
||
<el-col :xs="24" :sm="12" :md="6">
|
||
<div class="stat-card">
|
||
<div class="stat-label">总映射数</div>
|
||
<div class="stat-value">{{ statistics.totalLinks }}</div>
|
||
</div>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="6">
|
||
<div class="stat-card">
|
||
<div class="stat-label">库区数</div>
|
||
<div class="stat-value">{{ statistics.totalWarehouses }}</div>
|
||
</div>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="6">
|
||
<div class="stat-card">
|
||
<div class="stat-label">仪表数</div>
|
||
<div class="stat-value">{{ statistics.totalMeters }}</div>
|
||
</div>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="6">
|
||
<div class="stat-card">
|
||
<div class="stat-label">能源类型数</div>
|
||
<div class="stat-value">{{ statistics.totalEnergyTypes }}</div>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 映射列表 -->
|
||
<el-card class="list-card" v-loading="loading">
|
||
<div slot="header" class="clearfix">
|
||
<span class="card-title">能源-库区映射列表</span>
|
||
</div>
|
||
|
||
<el-table :data="linkList" stripe border>
|
||
<el-table-column prop="linkId" label="映射ID" width="100"></el-table-column>
|
||
<el-table-column prop="energyTypeName" label="能源类型" width="100"></el-table-column>
|
||
<el-table-column prop="meterCode" label="仪表编号" width="150"></el-table-column>
|
||
<el-table-column prop="warehouseName" label="逻辑库区" width="150"></el-table-column>
|
||
<el-table-column prop="allocationMode" label="分摊方式" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag v-if="scope.row.allocationMode === 'count'" type="success">按数量</el-tag>
|
||
<el-tag v-else-if="scope.row.allocationMode === 'weight'" type="warning">按重量</el-tag>
|
||
<el-tag v-else type="info">按重量×时间</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="weightRatio" label="权重比例" width="100">
|
||
<template slot-scope="scope">
|
||
{{ formatNumber(scope.row.weightRatio, 4) }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="isEnabled" label="状态" width="80">
|
||
<template slot-scope="scope">
|
||
<el-tag v-if="scope.row.isEnabled === 1" type="success">启用</el-tag>
|
||
<el-tag v-else type="danger">禁用</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="150" fixed="right">
|
||
<template slot-scope="scope">
|
||
<el-button type="primary" size="mini" @click="openEditDialog(scope.row)">编辑</el-button>
|
||
<el-button type="danger" size="mini" @click="deleteLink(scope.row)">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<!-- 分页 -->
|
||
<el-pagination
|
||
:current-page="queryParams.pageNum"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="queryParams.pageSize"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="total"
|
||
@size-change="handlePageSizeChange"
|
||
@current-change="handlePageChange"
|
||
style="margin-top: 20px; text-align: right;"
|
||
></el-pagination>
|
||
</el-card>
|
||
|
||
<!-- 编辑对话框 -->
|
||
<el-dialog :title="editDialogTitle" :visible.sync="editDialogVisible" width="600px" @close="closeEditDialog">
|
||
<el-form :model="editForm" label-width="120px" size="small" ref="editFormRef">
|
||
<el-form-item label="能源类型:" prop="energyTypeId">
|
||
<el-select v-model="editForm.energyTypeId" placeholder="请选择能源类型">
|
||
<el-option v-for="item in energyTypeList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="库区:" prop="warehouseId">
|
||
<el-select v-model="editForm.warehouseId" placeholder="请选择库区">
|
||
<el-option v-for="item in warehouseList" :key="item.warehouseId" :label="item.warehouseName" :value="item.warehouseId"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="仪表:" prop="meterId">
|
||
<el-select v-model="editForm.meterId" placeholder="请选择仪表">
|
||
<el-option v-for="item in meterList" :key="item.id" :label="item.meterCode" :value="item.id"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="分摊方式:" prop="allocationMode">
|
||
<el-select v-model="editForm.allocationMode" placeholder="请选择分摊方式">
|
||
<el-option label="按数量" value="count"></el-option>
|
||
<el-option label="按重量" value="weight"></el-option>
|
||
<el-option label="按重量×时间" value="weight_time"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="权重比例:" prop="weightRatio">
|
||
<el-input-number v-model="editForm.weightRatio" :min="0" :max="1" :step="0.01" :precision="4"></el-input-number>
|
||
</el-form-item>
|
||
<el-form-item label="状态:" prop="isEnabled">
|
||
<el-radio-group v-model="editForm.isEnabled">
|
||
<el-radio :label="1">启用</el-radio>
|
||
<el-radio :label="0">禁用</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
</el-form>
|
||
<span slot="footer" class="dialog-footer">
|
||
<el-button @click="closeEditDialog">取消</el-button>
|
||
<el-button type="primary" @click="saveLink">保存</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { listEnergyLink } from '@/api/ems/energyAllocation'
|
||
|
||
export default {
|
||
name: 'EnergyLink',
|
||
data() {
|
||
return {
|
||
loading: false,
|
||
total: 0,
|
||
queryParams: {
|
||
energyTypeId: null,
|
||
warehouseId: null,
|
||
isEnabled: null,
|
||
pageNum: 1,
|
||
pageSize: 20
|
||
},
|
||
linkList: [],
|
||
energyTypeList: [
|
||
{ id: 1, name: '电' },
|
||
{ id: 2, name: '水' },
|
||
{ id: 3, name: '气' }
|
||
],
|
||
warehouseList: [],
|
||
meterList: [],
|
||
statistics: {
|
||
totalLinks: 0,
|
||
totalWarehouses: 0,
|
||
totalMeters: 0,
|
||
totalEnergyTypes: 0
|
||
},
|
||
editDialogVisible: false,
|
||
editDialogTitle: '新增映射',
|
||
editForm: {
|
||
linkId: null,
|
||
energyTypeId: null,
|
||
warehouseId: null,
|
||
meterId: null,
|
||
allocationMode: 'weight_time',
|
||
weightRatio: 1,
|
||
isEnabled: 1
|
||
}
|
||
};
|
||
},
|
||
mounted() {
|
||
this.loadWarehouseList();
|
||
this.loadMeterList();
|
||
this.handleQuery();
|
||
},
|
||
methods: {
|
||
handleQuery() {
|
||
this.loading = true;
|
||
listEnergyLink(this.queryParams).then(response => {
|
||
this.linkList = response.rows || [];
|
||
this.total = response.total || 0;
|
||
}).catch(() => {
|
||
this.$message.error('加载映射列表失败');
|
||
}).finally(() => {
|
||
this.loading = false;
|
||
});
|
||
},
|
||
resetQuery() {
|
||
this.queryParams = {
|
||
energyTypeId: null,
|
||
warehouseId: null,
|
||
isEnabled: null,
|
||
pageNum: 1,
|
||
pageSize: 20
|
||
};
|
||
this.handleQuery();
|
||
},
|
||
handlePageChange(page) {
|
||
this.queryParams.pageNum = page;
|
||
this.handleQuery();
|
||
},
|
||
handlePageSizeChange(size) {
|
||
this.queryParams.pageSize = size;
|
||
this.handleQuery();
|
||
},
|
||
loadWarehouseList() {
|
||
// TODO: 从后端加载库区列表
|
||
this.warehouseList = [
|
||
{ id: 1, name: '库区A' },
|
||
{ id: 2, name: '库区B' },
|
||
{ id: 3, name: '库区C' }
|
||
];
|
||
},
|
||
loadMeterList() {
|
||
// TODO: 从后端加载仪表列表
|
||
this.meterList = [
|
||
{ id: 1, meterCode: 'METER-001' },
|
||
{ id: 2, meterCode: 'METER-002' },
|
||
{ id: 3, meterCode: 'METER-003' }
|
||
];
|
||
},
|
||
openAddDialog() {
|
||
this.editDialogTitle = '新增映射';
|
||
this.editForm = {
|
||
linkId: null,
|
||
energyTypeId: null,
|
||
warehouseId: null,
|
||
meterId: null,
|
||
allocationMode: 'weight_time',
|
||
weightRatio: 1,
|
||
isEnabled: 1
|
||
};
|
||
this.editDialogVisible = true;
|
||
},
|
||
openEditDialog(row) {
|
||
this.editDialogTitle = '编辑映射';
|
||
this.editForm = { ...row };
|
||
this.editDialogVisible = true;
|
||
},
|
||
closeEditDialog() {
|
||
this.editDialogVisible = false;
|
||
this.$refs.editFormRef && this.$refs.editFormRef.clearValidate();
|
||
},
|
||
saveLink() {
|
||
// TODO: 调用后端API保存映射
|
||
this.$message.success('保存成功');
|
||
this.closeEditDialog();
|
||
this.handleQuery();
|
||
},
|
||
deleteLink(row) {
|
||
this.$confirm('确定删除该映射吗?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
// TODO: 调用后端API删除映射
|
||
this.$message.success('删除成功');
|
||
this.handleQuery();
|
||
}).catch(() => {});
|
||
},
|
||
formatNumber(value, decimals = 2) {
|
||
if (value === null || value === undefined) return '0.00';
|
||
return parseFloat(value).toFixed(decimals);
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped>
|
||
.energy-link-page {
|
||
padding: 20px;
|
||
}
|
||
|
||
.search-card {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.statistics-row {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.stat-card {
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
color: white;
|
||
padding: 20px;
|
||
border-radius: 4px;
|
||
text-align: center;
|
||
}
|
||
|
||
.stat-card .stat-label {
|
||
font-size: 12px;
|
||
opacity: 0.8;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.stat-card .stat-value {
|
||
font-size: 28px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.list-card {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.card-title {
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.dialog-footer {
|
||
text-align: right;
|
||
}
|
||
</style>
|