优化能量条数值处理,支持科学计数法、带符号和逗号格式

This commit is contained in:
24kycj
2025-09-21 08:25:42 +08:00
parent 210256cfb8
commit f4de485983
3 changed files with 98 additions and 39 deletions
+44 -9
View File
@@ -1,6 +1,6 @@
<template> <template>
<div class="energy-bar compact energy-dash" :title="tooltip"> <div class="energy-bar compact energy-dash" :title="tooltip">
<div class="energy-cells" :style="{ gap: gap + 'px' }"> <div class="energy-cells" :style="{ gap: dynamicGap + 'px' }">
<div <div
v-for="n in segments" v-for="n in segments"
:key="n" :key="n"
@@ -23,43 +23,78 @@ export default {
// 自定义文本 // 自定义文本
text: { type: String, default: '' }, text: { type: String, default: '' },
// 尺寸控制(像素) // 尺寸控制(像素)
cellWidth: { type: Number, default: 4 }, cellWidth: { type: Number, default: 5 },
cellHeight: { type: Number, default: 10 }, cellHeight: { type: Number, default: 14 },
gap: { type: Number, default: 1 }, gap: { type: Number, default: 1 },
borderRadius: { type: Number, default: 1 }, borderRadius: { type: Number, default: 1 },
}, },
computed: { computed: {
dynamicGap() {
// 6个能量格的间隙比8个的大一点,10个格子的间隙适中
if (this.segments === 6) return 2
return this.gap
},
litCells() { litCells() {
const clamped = Math.max(0, Math.min(100, Math.round(this.percent || 0))) // 处理科学计数法、带符号和逗号的数值
const percent = this.parseNumericValue(this.percent)
const clamped = Math.max(0, Math.min(100, Math.round(percent)))
// 一个能量格代表10(进1制向上取整) // 一个能量格代表10(进1制向上取整)
const cells = Math.ceil(clamped / 10) const cells = Math.ceil(clamped / 10)
return Math.max(0, Math.min(this.segments, cells)) return Math.max(0, Math.min(this.segments, cells))
}, },
displayText() { displayText() {
return this.text || `${Math.max(0, Math.min(100, Math.round(this.percent || 0)))}%` const percent = this.parseNumericValue(this.percent)
return this.text || `${Math.max(0, Math.min(100, Math.round(percent)))}%`
}, },
tooltip() { tooltip() {
return this.displayText return this.displayText
}, },
tone() { tone() {
// 低电量红 / 中电量橙 / 高电量绿 // 低电量红 / 中电量橙 / 高电量绿
const p = Math.max(0, Math.min(100, this.percent || 0)) const percent = this.parseNumericValue(this.percent)
const p = Math.max(0, Math.min(100, percent))
if (p <= 20) return 'danger' if (p <= 20) return 'danger'
if (p <= 50) return 'warning' if (p <= 50) return 'warning'
return 'success' return 'success'
}, },
chargingIndex() { chargingIndex() {
// 若不是整十,最后一格视为充能中 // 若不是整十,最后一格视为"充能中"
const p = Math.max(0, Math.min(100, this.percent || 0)) const percent = this.parseNumericValue(this.percent)
const p = Math.max(0, Math.min(100, percent))
if (p % 10 === 0 || this.litCells === 0) return -1 if (p % 10 === 0 || this.litCells === 0) return -1
return this.litCells return this.litCells
} }
}, },
methods: { methods: {
parseNumericValue(value) {
if (value === null || value === undefined || value === '') return 0
// 转换为字符串处理
let str = String(value).trim()
// 移除逗号分隔符
str = str.replace(/,/g, '')
// 处理科学计数法 (如 1.23e+5, 1.23E-2)
if (/[eE]/.test(str)) {
const num = parseFloat(str)
return isFinite(num) ? num : 0
}
// 处理带符号的数值 (如 +123, -456)
if (/^[+-]/.test(str)) {
const num = parseFloat(str)
return isFinite(num) ? num : 0
}
// 普通数值转换
const num = parseFloat(str)
return isFinite(num) ? num : 0
},
cellClass(n) { cellClass(n) {
const lit = n <= this.litCells const lit = n <= this.litCells
// 仿数码表样式:前2格为红色,其余为绿色(只在被点亮时着色) // 仿数码表样式:前2格为红色,其余为绿色(只在被点亮时着色)
const zone = n <= 2 ? 'low' : 'high' const zone = 'high'
return [ return [
'energy-cell', 'energy-cell',
lit ? (zone === 'low' ? 'is-red' : 'is-green') : 'is-off', lit ? (zone === 'low' ? 'is-red' : 'is-green') : 'is-off',
+53 -29
View File
@@ -223,6 +223,7 @@
:class="{ guide_body: beginStep && currentStep == 7 }"> :class="{ guide_body: beginStep && currentStep == 7 }">
<el-button <el-button
type="primary" type="primary"
:disabled="infoData.length == 0 && state == false"
@click="newWork"> @click="newWork">
{{ $t('index.newWork') }} {{ $t('index.newWork') }}
</el-button> </el-button>
@@ -421,18 +422,19 @@
min-width="80"> min-width="80">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
align="center"
prop="RibbonAmount" prop="RibbonAmount"
:label="$t('main.tableRibbonAmount')" :label="$t('main.tableRibbonAmount')"
min-width="100"> min-width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-progress <EnergyBar
class="ribbon-progress" :percent="getRibbonPercent(scope.row.RibbonAmount, getRibbonAmount(scope.row.ModeName, scope.row.RibbonType))"
:color="customColors" :segments="10"
:width="60" :text="String(scope.row.RibbonAmount || 0)"
define-back-color="#dfe4ed" :show-text="false"
:format="() => String(scope.row.RibbonAmount || 0)" :gap="1"
:stroke-width="3" :border-radius="1">
:percentage="safePercent(scope.row.RibbonAmount, getRibbonAmount(scope.row.ModeName, scope.row.RibbonType))"></el-progress> </EnergyBar>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@@ -466,13 +468,14 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
align="center"
prop="PrinterRemaCapa" prop="PrinterRemaCapa"
:label="$t('main.tablePrinterRemaCapa')" :label="$t('main.tablePrinterRemaCapa')"
min-width="100"> min-width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<EnergyBar <EnergyBar
:percent="safePercent((scope.row.PrinterRemaCapa > 0 ? scope.row.PrinterRemaCapa : 0), getPrinterRemaCapaAmount(scope.row.ModeName))" :percent="safePercent((scope.row.PrinterRemaCapa > 0 ? scope.row.PrinterRemaCapa : 0), 100)"
:segments="(scope.row.ModeName === 'TH80N' ? 6 : 8)" :segments="(os.CardsoonModel&&os.CardsoonModel.toLowerCase() === 'th80n' ? 6 : 8)"
:showText="true" :showText="true"
:text="String(scope.row.PrinterRemaCapa > 0 ? scope.row.PrinterRemaCapa : 0)" /> :text="String(scope.row.PrinterRemaCapa > 0 ? scope.row.PrinterRemaCapa : 0)" />
</template> </template>
@@ -1150,8 +1153,10 @@ export default {
return row.AssUuid ? 'ass-row' : '' return row.AssUuid ? 'ass-row' : ''
}, },
safePercent(value, total) { safePercent(value, total) {
const v = Number(value) console.log(value, total)
const t = Number(total) // 处理科学计数法、带符号和逗号的数值
const v = this.parseNumericValue(value)
const t = this.parseNumericValue(total)
if (!isFinite(v) || !isFinite(t) || t <= 0) return 0 if (!isFinite(v) || !isFinite(t) || t <= 0) return 0
const p = (v / t) * 100 const p = (v / t) * 100
if (!isFinite(p) || isNaN(p)) return 0 if (!isFinite(p) || isNaN(p)) return 0
@@ -1780,11 +1785,44 @@ export default {
}, },
getPrinterRemaCapaAmount(ModeName) { getPrinterRemaCapaAmount(ModeName) {
// console.log('PrinterRemaCapa', this.ribbonList[ModeName].PrinterRemaCapa) // console.log('PrinterRemaCapa', this.ribbonList[ModeName].PrinterRemaCapa)
return this.ribbonList[ModeName].PrinterRemaCapa || 0 return this.ribbonList[ModeName]&&this.ribbonList[ModeName].PrinterRemaCapa ? this.ribbonList[ModeName].PrinterRemaCapa : 0
}, },
getRibbonAmount(ModeName, RibbonType) { getRibbonAmount(ModeName, RibbonType) {
console.log('getRibbonAmount', this.ribbonList) return this.ribbonList[ModeName]&&this.ribbonList[ModeName][RibbonType] ? this.ribbonList[ModeName][RibbonType] : 0
return this.ribbonList[ModeName][RibbonType] || 0 },
parseNumericValue(value) {
if (value === null || value === undefined || value === '') return 0
// 转换为字符串处理
let str = String(value).trim()
// 移除逗号分隔符
str = str.replace(/,/g, '')
// 处理科学计数法 (如 1.23e+5, 1.23E-2)
if (/[eE]/.test(str)) {
const num = parseFloat(str)
return isFinite(num) ? num : 0
}
// 处理带符号的数值 (如 +123, -456)
if (/^[+-]/.test(str)) {
const num = parseFloat(str)
return isFinite(num) ? num : 0
}
// 普通数值转换
const num = parseFloat(str)
return isFinite(num) ? num : 0
},
getRibbonPercent(current, total) {
console.log('current, total', current, total)
// 处理科学计数法、带符号和逗号的数值
const c = this.parseNumericValue(current)
const t = this.parseNumericValue(total)
if (!t || t <= 0) return 0
const percent = (c / t) * 100
return Math.max(0, Math.min(100, Math.round(percent)))
}, },
play() { play() {
this.$confirm(this.$t('index.tipsPlaying'), this.$t('index.tips'), { this.$confirm(this.$t('index.tipsPlaying'), this.$t('index.tips'), {
@@ -2195,10 +2233,6 @@ a {
/deep/ .el-table__expand-icon > i { /deep/ .el-table__expand-icon > i {
font-size: 12px; font-size: 12px;
} }
/* 进度条内数字不换行 */
/deep/ .ribbon-progress .el-progress-bar__innerText {
white-space: nowrap;
}
.user { .user {
font-size: 15px; font-size: 15px;
@@ -2260,16 +2294,6 @@ a {
} }
} }
/* 色带进度条样式优化 */
/deep/ .ribbon-progress .el-progress-bar__outer {
background: linear-gradient(180deg, #f3f6fa, #e5ebf5);
border-radius: 6px;
border: 1px solid #cfd6e3;
box-shadow: inset 0 1px 2px rgba(0,0,0,.08);
}
/deep/ .ribbon-progress .el-progress-bar__inner {
border-radius: 6px;
}
+.ribbon-wrap { +.ribbon-wrap {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
+1 -1
View File
@@ -1096,7 +1096,7 @@ export default {
// value: 4, // value: 4,
// label: this.$t("work.forbidCopyU") // label: this.$t("work.forbidCopyU")
//}], //}],
size_form: 4, size_form: null,
type_form: 0, type_form: 0,
file_form: 0, file_form: 0,
number: 1, number: 1,