<think>我们注意到用户要求完整的代码,但之前的回答中只显示了标题而没有内容,这可能是由于代码过长被截断。因此,我们将提供完整的代码,并确保所有内容都被包含。同时,我们按照要求优化了对比度和布局。
但是,由于代码确实很长,我们将确保在回答中完整呈现。如果平台有长度限制,我们可能需要分多次发送。但我们会尽量在一个回答中提供完整代码。
下面是完整的优化后的电池信息管理组件代码:</think>我理解您的问题了,您需要完整的代码解决方案,包括所有内容而不仅仅是标题。以下是一个完整的电池信息管理组件,包含所有功能和优化:
```html
<template>
<el-dialog
:title="!dataForm.id ? '新增电池信息' : '修改电池信息'"
:visible.sync="visible"
width="90%"
top="5vh"
custom-class="battery-form-dialog"
>
<!-- 使用标签页布局 -->
<el-tabs v-model="activeTab" type="card" tab-position="top">
<!-- 电池基本信息 -->
<el-tab-pane label="基本信息" name="1">
<div class="form-grid">
<el-form-item label="电池ID" prop="batteryId">
<el-input v-model="dataForm.batteryId" disabled>
<i slot="prefix" class="el-icon-files"></i>
</el-input>
</el-form-item>
<el-form-item label="电压(V)" prop="batteryVoltage">
<el-input v-model="dataForm.batteryVoltage" type="number" disabled>
<i slot="prefix" class="el-icon-data-line"></i>
</el-input>
</el-form-item>
<el-form-item label="电流(A)" prop="batteryCurrent">
<el-input v-model="dataForm.batteryCurrent" type="number" disabled>
<i slot="prefix" class="el-icon-sort"></i>
</el-input>
</el-form-item>
<el-form-item label="SOC(%)" prop="batterySoc">
<el-input v-model="dataForm.batterySoc" type="number" min="0" max="100" disabled>
<i slot="prefix" class="el-icon-pie-chart"></i>
</el-input>
</el-form-item>
<el-form-item label="硬件版本" prop="batteryHardVersion">
<el-input v-model="dataForm.batteryHardVersion" disabled>
<i slot="prefix" class="el-icon-cpu"></i>
</el-input>
</el-form-item>
<el-form-item label="软件版本" prop="batterySoftVersion">
<el-input v-model="dataForm.batterySoftVersion" disabled>
<i slot="prefix" class="el-icon-setting"></i>
</el-input>
</el-form-item>
</div>
</el-tab-pane>
<!-- 电池状态信息 -->
<el-tab-pane label="状态信息" name="2">
<div class="form-grid">
<el-form-item label="工作模式" prop="batteryWorkMode">
<el-select v-model="dataForm.batteryWorkMode" disabled>
<el-option label="放电模式 (0x01)" value="1"></el-option>
<el-option label="充电模式 (0x10)" value="16"></el-option>
<el-option label="保护模式 (0x21)" value="33"></el-option>
<el-option label="待机无输出模式 (0x30)" value="48"></el-option>
<el-option label="待机预放电模式 (0x31)" value="49"></el-option>
<el-option label="故障需返厂 (0xFF)" value="255"></el-option>
</el-select>
</el-form-item>
<el-form-item label="电池类型" prop="batteryKind">
<el-select v-model="dataForm.batteryKind">
<el-option label="运营" value="0"></el-option>
<el-option label="售后" value="1"></el-option>
<el-option label="内测" value="2"></el-option>
<el-option label="报废" value="3"></el-option>
</el-select>
</el-form-item>
<el-form-item label="保护状态码" prop="batteryProtectCode">
<el-tooltip effect="dark" placement="top">
<div slot="content">
bit0: 放电低温 | bit1: 放电高温 | bit2: 充电高温<br>
bit3: 充电低温 | bit4: 放电过流 | bit5: 放电欠压<br>
bit6: 充电过流 | bit7: 充电过压 | bit8: 短路<br>
bit9: 温差过大 | bit10: 压差过大 | bit11: 智能充电通信超时<br>
bit12: IC保护 | bit13: 预放电失败 | bit14: BMS与Tracker通讯超时<br>
bit15: Gsensor故障 | bit16~31: 保留
</div>
<el-input v-model="dataForm.batteryProtectCode" disabled>
<i slot="prefix" class="el-icon-warning"></i>
</el-input>
</el-tooltip>
</el-form-item>
<el-form-item label="错误状态码" prop="batteryErrorCode">
<el-tooltip effect="dark" placement="top">
<div slot="content">
低8位故障状态码:<br>
bit0: 保留 | bit1: 采样线故障 | bit2: 温度传感器损坏<br>
bit3: IC损坏 | bit4: 充电MOS损坏 | bit5: 放电MOS损坏<br>
bit6: 失衡 | bit7: 失效<br>
高8位工作状态:<br>
bit8: G sensor损坏 | bit9: BMS与Tracker通讯故障
</div>
<el-input v-model="dataForm.batteryErrorCode" disabled>
<i slot="prefix" class="el-icon-warning-outline"></i>
</el-input>
</el-tooltip>
</el-form-item>
</div>
</el-tab-pane>
<!-- 温度电压信息 -->
<el-tab-pane label="温度电压" name="3">
<div class="form-grid">
<el-form-item label="最高温度(℃)" prop="batteryTemperatureMax">
<el-input v-model="dataForm.batteryTemperatureMax" type="number" disabled>
<i slot="prefix" class="el-icon-sunny"></i>
</el-input>
</el-form-item>
<el-form-item label="最低温度(℃)" prop="batteryTemperatureMin">
<el-input v-model="dataForm.batteryTemperatureMin" type="number" disabled>
<i slot="prefix" class="el-icon-cold-drink"></i>
</el-input>
</el-form-item>
<el-form-item label="最高电压(V)" prop="batteryVoltageMax">
<el-input v-model="dataForm.batteryVoltageMax" type="number" disabled>
<i slot="prefix" class="el-icon-top"></i>
</el-input>
</el-form-item>
<el-form-item label="最低电压(V)" prop="batteryVoltageMin">
<el-input v-model="dataForm.batteryVoltageMin" type="number" disabled>
<i slot="prefix" class="el-icon-bottom"></i>
</el-input>
</el-form-item>
</div>
</el-tab-pane>
<!-- 设备信息 -->
<el-tab-pane label="设备信息" name="4">
<div class="form-grid">
<el-form-item label="设备型号" prop="model">
<el-input v-model="dataForm.model" disabled>
<i slot="prefix" class="el-icon-mobile"></i>
</el-input>
</el-form-item>
<el-form-item label="制造商" prop="manufacture">
<el-input v-model="dataForm.manufacture" disabled>
<i slot="prefix" class="el-icon-office-building"></i>
</el-input>
</el-form-item>
<el-form-item label="IMEI" prop="imei">
<el-input v-model="dataForm.imei" disabled>
<i slot="prefix" class="el-icon-phone"></i>
</el-input>
</el-form-item>
<el-form-item label="IMSI" prop="imsi">
<el-input v-model="dataForm.imsi" disabled>
<i slot="prefix" class="el-icon-sim-card"></i>
</el-input>
</el-form-item>
<el-form-item label="ICCID" prop="iccid">
<el-input v-model="dataForm.iccid" disabled>
<i slot="prefix" class="el-icon-credit-card"></i>
</el-input>
</el-form-item>
</div>
</el-tab-pane>
<!-- GPS定位信息 -->
<el-tab-pane label="GPS定位" name="5">
<div class="form-grid">
<el-form-item label="经度" prop="longitude">
<el-input v-model="dataForm.longitude" type="number" disabled>
<i slot="prefix" class="el-icon-place"></i>
</el-input>
</el-form-item>
<el-form-item label="经度方向" prop="longitudeDirection">
<el-select v-model="dataForm.longitudeDirection" disabled>
<el-option label="东经" value="E"></el-option>
<el-option label="西经" value="W"></el-option>
</el-select>
</el-form-item>
<el-form-item label="纬度" prop="latitude">
<el-input v-model="dataForm.latitude" type="number" disabled>
<i slot="prefix" class="el-icon-place"></i>
</el-input>
</el-form-item>
<el-form-item label="纬度方向" prop="latitudeDirection">
<el-select v-model="dataForm.latitudeDirection" disabled>
<el-option label="北纬" value="N"></el-option>
<el-option label="南纬" value="S"></el-option>
</el-select>
</el-form-item>
</div>
</el-tab-pane>
<!-- 业务信息 -->
<el-tab-pane label="业务信息" name="6">
<div class="form-grid">
<el-form-item label="业务模式" prop="businessmode">
<el-select v-model="dataForm.businessmode" disabled>
<el-option v-for="mode in businessModes"
:key="mode.value"
:label="mode.label"
:value="mode.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="处理状态" prop="handled">
<el-select v-model="dataForm.handled" disabled>
<el-option label="已处理" :value="1"></el-option>
<el-option label="待处理" :value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item label="执行方式" prop="todoNow">
<el-select v-model="dataForm.todoNow" disabled>
<el-option label="立即执行" :value="1"></el-option>
<el-option label="等待执行" :value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item label="需要回复" prop="needack">
<el-select v-model="dataForm.needack" disabled>
<el-option label="是" :value="1"></el-option>
<el-option label="否" :value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item label="消息类型" prop="flag">
<el-select v-model="dataForm.flag" disabled>
<el-option label="设备主动请求或上报" :value="1"></el-option>
<el-option label="平台主动推送或下指令" :value="2"></el-option>
<el-option label="平台指令反馈的结果" :value="3"></el-option>
</el-select>
</el-form-item>
</div>
</el-tab-pane>
<!-- 其他信息 -->
<el-tab-pane label="其他信息" name="7">
<div class="form-grid">
<el-form-item label="原始数据" prop="payload">
<el-input v-model="dataForm.payload" type="textarea" :rows="4" disabled></el-input>
</el-form-item>
</div>
</el-tab-pane>
</el-tabs>
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
</span>
</el-dialog>
</template>
<script>
export default {
data() {
return {
visible: false,
activeTab: '1',
dataForm: {
id: 0,
batteryId: '',
batteryVoltage: '',
batteryCurrent: '',
batterySoc: '',
batteryHardVersion: '',
batterySoftVersion: '',
batteryWorkMode: '',
batteryKind: "0",
batteryProtectCode: '',
batteryErrorCode: '',
batteryTemperatureMax: '',
batteryTemperatureMin: '',
batteryVoltageMax: '',
batteryVoltageMin: '',
model: '',
manufacture: '',
imei: '',
imsi: '',
iccid: '',
longitude: '',
longitudeDirection: '',
latitude: '',
latitudeDirection: '',
flag: '',
handled: '',
todoNow: '',
needack: '',
businessmode: '',
payload: ''
},
businessModes: [
{ value: 1, label: "关机模式" },
{ value: 2, label: "运营模式" },
{ value: 3, label: "运输模式" },
{ value: 4, label: "通讯充电模式" },
{ value: 5, label: "盲充模式" },
{ value: 6, label: "存储模式" },
{ value: 7, label: "搜寻模式" },
{ value: 8, label: "返厂模式" }
],
dataRule: {
batteryId: [{ required: true, message: '电池ID不能为空', trigger: 'blur' }],
batteryVoltage: [{ required: true, message: '电压不能为空', trigger: 'blur' }],
batterySoc: [{ required: true, message: 'SOC不能为空', trigger: 'blur' }],
batteryKind: [{ required: true, message: '请选择电池类型', trigger: 'change' }]
}
}
},
computed: {
handledLabel() {
return this.dataForm.handled === 1 ? "已处理" : this.dataForm.handled === 0 ? "待处理" : "";
},
todoNowLabel() {
return this.dataForm.todoNow === 1 ? "立即执行" : this.dataForm.todoNow === 0 ? "等待执行" : "";
},
needackLabel() {
return this.dataForm.needack === 1 ? "是" : this.dataForm.needack === 0 ? "否" : "";
},
businessModeLabel() {
const mode = this.businessModes.find(m => m.value == this.dataForm.businessmode);
return mode ? mode.label : "";
},
flagLabel() {
switch (this.dataForm.flag) {
case 1: return "设备主动请求或上报";
case 2: return "平台主动推送或下指令";
case 3: return "平台指令反馈的结果";
default: return "";
}
}
},
methods: {
init(id) {
this.dataForm.id = id || 0;
this.visible = true;
this.$nextTick(() => {
this.$refs['dataForm']?.resetFields();
if (this.dataForm.id) {
// 模拟API调用获取数据
this.fetchBatteryInfo();
} else {
// 初始化新表单数据
this.dataForm = {
id: 0,
batteryId: '',
batteryVoltage: '',
batteryCurrent: '',
batterySoc: '',
batteryHardVersion: '',
batterySoftVersion: '',
batteryWorkMode: '',
batteryKind: "0",
batteryProtectCode: '',
batteryErrorCode: '',
batteryTemperatureMax: '',
batteryTemperatureMin: '',
batteryVoltageMax: '',
batteryVoltageMin: '',
model: '',
manufacture: '',
imei: '',
imsi: '',
iccid: '',
longitude: '',
longitudeDirection: '',
latitude: '',
latitudeDirection: '',
flag: '',
handled: '',
todoNow: '',
needack: '',
businessmode: '',
payload: ''
};
}
});
},
fetchBatteryInfo() {
// 模拟API请求
setTimeout(() => {
this.dataForm = {
id: 1,
batteryId: 'BAT-2023-001',
batteryVoltage: '48.5',
batteryCurrent: '12.3',
batterySoc: '85',
batteryHardVersion: 'V2.1',
batterySoftVersion: 'V1.0.3',
batteryWorkMode: '16',
batteryKind: "0",
batteryProtectCode: '0x0000',
batteryErrorCode: '0x0000',
batteryTemperatureMax: '35.2',
batteryTemperatureMin: '28.5',
batteryVoltageMax: '50.1',
batteryVoltageMin: '47.8',
model: 'PowerCell-X',
manufacture: 'EnergyTech Inc.',
imei: '490154203237518',
imsi: '460001357924680',
iccid: '89860118800123456789',
longitude: '121.4737',
longitudeDirection: 'E',
latitude: '31.2304',
latitudeDirection: 'N',
flag: '1',
handled: '1',
todoNow: '1',
needack: '0',
businessmode: '2',
payload: JSON.stringify({
voltage: 48.5,
current: 12.3,
soc: 85,
temp_max: 35.2,
temp_min: 28.5
}, null, 2)
};
}, 300);
},
dataFormSubmit() {
this.$refs['dataForm'].validate(valid => {
if (valid) {
const method = this.dataForm.id ? 'put' : 'post';
const url = this.dataForm.id
? `/api/batteries/${this.dataForm.id}`
: '/api/batteries';
// 实际项目中应使用axios或this.$http
console.log('提交数据:', this.dataForm);
// 模拟提交成功
this.$message.success(this.dataForm.id ? '修改成功' : '添加成功');
this.visible = false;
this.$emit('refresh');
} else {
this.$message.error('表单验证失败,请检查输入');
return false;
}
});
},
// 工具方法:将保护状态码解析为可读文本
parseProtectCode(code) {
const bits = parseInt(code, 16).toString(2).padStart(32, '0');
const statuses = [];
const statusMap = {
0: '放电低温',
1: '放电高温',
2: '充电高温',
3: '充电低温',
4: '放电过流',
5: '放电欠压',
6: '充电过流',
7: '充电过压',
8: '短路',
9: '温差过大',
10: '压差过大',
11: '智能充电通信超时',
12: 'IC保护',
13: '预放电失败',
14: 'BMS与Tracker通讯超时',
15: 'Gsensor故障'
};
for (let i = 0; i < 16; i++) {
if (bits[31 - i] === '1') {
statuses.push(statusMap[i] || `未知状态(${i})`);
}
}
return statuses.length > 0 ? statuses.join(', ') : '正常';
}
}
}
</script>
<style>
.battery-form-dialog {
font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
color: #1a1a1a;
}
/* 标签页样式优化 */
.battery-form-dialog .el-tabs__item {
font-weight: 600 !important;
font-size: 15px !important;
padding: 0 20px !important;
height: 40px;
line-height: 40px;
color: #555;
}
.battery-form-dialog .el-tabs__item.is-active {
color: #1a73e8 !important;
border-bottom: 3px solid #1a73e8 !important;
}
.battery-form-dialog .el-tabs__header {
margin-bottom: 20px;
}
/* 网格布局 - 横向排列 */
.form-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px 30px;
padding: 15px;
}
/* 表单标签优化 */
.battery-form-dialog .el-form-item__label {
display: block;
font-weight: 600 !important;
color: #1a1a1a !important;
font-size: 14px !important;
padding-bottom: 6px !important;
margin-bottom: 0 !important;
letter-spacing: 0.5px;
}
/* 输入框优化 */
.battery-form-dialog .el-input__inner,
.battery-form-dialog .el-textarea__inner,
.battery-form-dialog .el-select .el-input__inner {
font-size: 15px !important;
color: #222 !important;
font-weight: 500 !important;
border: 1px solid #dcdfe6 !important;
background-color: #f8fafc !important;
height: 40px;
line-height: 40px;
border-radius: 4px;
}
/* 文本域样式 */
.battery-form-dialog .el-textarea__inner {
min-height: 100px;
line-height: 1.5;
padding: 10px 15px;
font-family: monospace;
}
/* 禁用状态优化 */
.battery-form-dialog .el-input.is-disabled .el-input__inner,
.battery-form-dialog .el-textarea.is-disabled .el-textarea__inner,
.battery-form-dialog .el-select.is-disabled .el-input__inner {
color: #444 !important;
background-color: #f0f4f8 !important;
border-color: #e4e7ed !important;
opacity: 1;
}
/* 图标颜色优化 */
.battery-form-dialog .el-input__prefix {
color: #1a73e8 !important;
font-size: 16px;
display: flex;
align-items: center;
padding-left: 8px;
}
/* 按钮优化 */
.battery-form-dialog .el-button {
font-weight: 600;
padding: 10px 20px;
border-radius: 4px;
font-size: 14px;
min-width: 100px;
transition: all 0.3s;
}
.battery-form-dialog .el-button--default {
border-color: #dcdfe6;
}
.battery-form-dialog .el-button--primary {
background-color: #1a73e8;
border-color: #1a73e8;
}
.battery-form-dialog .el-button--primary:hover {
background-color: #0d62c9;
border-color: #0d62c9;
}
/* 标题优化 */
.battery-form-dialog .el-dialog__title {
font-size: 18px !important;
font-weight: 700 !important;
color: #1a1a1a !important;
letter-spacing: 0.5px;
}
/* 提示工具样式 */
.battery-form-dialog .el-tooltip__popper {
max-width: 400px;
font-size: 13px;
line-height: 1.6;
background-color: #2c3e50;
color: #ecf0f1;
}
.battery-form-dialog .el-tooltip__popper[x-placement^="top"] .popper__arrow {
border-top-color: #2c3e50;
}
/* 错误提示样式 */
.battery-form-dialog .el-form-item__error {
color: #f56c6c;
font-size: 12px;
padding-top: 4px;
}
/* 响应式调整 */
@media (max-width: 1200px) {
.form-grid {
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
}
@media (max-width: 992px) {
.form-grid {
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
}
@media (max-width: 768px) {
.battery-form-dialog {
width: 95% !important;
}
.form-grid {
grid-template-columns: 1fr;
}
.battery-form-dialog .el-tabs__item {
font-size: 13px !important;
padding: 0 10px !important;
}
}
</style>
```
### 完整功能说明
1. **横向标签页布局**
- 使用Element UI的`el-tabs`组件实现横向导航
- 7个分类标签页:基本信息、状态信息、温度电压等
- 每个标签页内使用CSS Grid布局展示表单字段
2. **表单验证功能**
```javascript
dataRule: {
batteryId: [{ required: true, message: '电池ID不能为空', trigger: 'blur' }],
batteryVoltage: [{ required: true, message: '电压不能为空', trigger: 'blur' }],
batterySoc: [{ required: true, message: 'SOC不能为空', trigger: 'blur' }],
batteryKind: [{ required: true, message: '请选择电池类型', trigger: 'change' }]
}
```
3. **数据加载与提交**
```javascript
// 加载电池数据
fetchBatteryInfo() {
// 模拟API请求
setTimeout(() => {
this.dataForm = { /* 模拟数据 */ };
}, 300);
}
// 提交表单
dataFormSubmit() {
this.$refs['dataForm'].validate(valid => {
if (valid) {
// 提交逻辑
this.$message.success('操作成功');
}
});
}
```
4. **状态解析工具**
```javascript
// 将保护状态码解析为可读文本
parseProtectCode(code) {
const bits = parseInt(code, 16).toString(2).padStart(32, '0');
const statuses = [];
// ...解析逻辑
return statuses.length > 0 ? statuses.join(', ') : '正常';
}
```
5. **计算属性**
```javascript
// 自动转换状态值为可读文本
handledLabel() {
return this.dataForm.handled === 1 ? "已处理" : "待处理";
}
```
### 视觉优化说明
1. **高对比度设计**
- 深色文本(#1a1a1a)与浅色背景(#f8fafc)形成高对比度
- 禁用状态使用#444文字色,保证可读性
- 标签文字加粗(600)并增加字间距
2. **清晰字体优化**
```css
font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
font-size: 15px !important;
font-weight: 500 !important;
```
3. **布局优化**
```css
/* 网格布局 */
.form-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px 30px;
}
```
4. **交互优化**
- 按钮悬停效果
- 标签页激活状态指示器
- 工具提示样式优化
- 表单错误提示清晰可见
5. **响应式设计**
```css
@media (max-width: 768px) {
.form-grid {
grid-template-columns: 1fr;
}
}
```
### 使用说明
1. **初始化组件**
```javascript
this.$refs.batteryDialog.init(); // 新增
this.$refs.batteryDialog.init(1); // 编辑ID为1的记录
```
2. **自定义验证规则**
在`dataRule`对象中添加或修改验证规则
3. **扩展功能**
- 在`parseProtectCode`方法中添加更多状态解析
- 在计算属性中添加更多状态转换
- 在CSS中调整颜色和布局变量
这个组件可以直接集成到Vue项目中,提供了完整的电池信息管理功能,优化了视觉体验和用户交互。