英文版本配置,二并一(配置)不弹窗BUG修改

This commit is contained in:
huangjp
2025-10-17 14:14:48 +08:00
parent 09d927a800
commit d5c01162f6
29 changed files with 240 additions and 128 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -202,20 +202,20 @@ export function kgFormat(num, digits) {
export function moneyUnitFormat(num) { export function moneyUnitFormat(num) {
if (sessionStorage.getItem('language') === 'en') { if (sessionStorage.getItem('language') === 'en') {
if (!num) { if (!num) {
return 'RMB' return 'EUR'
} }
if (Number(num) >= 1E4) { if (Number(num) >= 1E4) {
return 'CNY10K' return 'EUR10K'
} }
return 'RMB' return 'EUR'
} else { } else {
if (!num) { if (!num) {
return '' return 'EUR'
} }
if (Number(num) >= 1E4) { if (Number(num) >= 1E4) {
return '万元' return 'EUR10K'
} }
return '' return 'EUR'
} }
} }
/** /**

View File

@ -32,13 +32,13 @@ export default {
stationRunPlan: 'The actual operation plan curve of the power station', stationRunPlan: 'The actual operation plan curve of the power station',
runEarning: 'Actual operating earnings', runEarning: 'Actual operating earnings',
recommend: 'Referral strategy earnings', recommend: 'Referral strategy earnings',
valley: '谷(0.1kWh/)', valley: '谷(0.1kWh/EUR)',
flat: '平(0.3kWh/)', flat: '平(0.3kWh/EUR)',
peak: '峰(0.6kWh/)', peak: '峰(0.6kWh/EUR)',
earningForecast: 'Revenue forecasts', earningForecast: 'Revenue forecasts',
defaultEarning: 'Default policy earnings', defaultEarning: 'Default policy earnings',
estimateEarning: 'Estimated earnings increase', estimateEarning: 'Estimated earnings increase',
rmb: 'RMB', rmb: 'EUR',
stts: 'Earnings budgeting', stts: 'Earnings budgeting',
sjsyje: 'Amount of actual earnings', sjsyje: 'Amount of actual earnings',
mrjhqx: 'Default plan curve earnings', mrjhqx: 'Default plan curve earnings',

View File

@ -32,13 +32,13 @@ export default {
stationRunPlan: '电站实际运行计划曲线', stationRunPlan: '电站实际运行计划曲线',
runEarning: '实际运行收益', runEarning: '实际运行收益',
recommend: '推荐策略收益', recommend: '推荐策略收益',
valley: '谷(0.1kWh/)', valley: '谷(0.1kWh/EUR)',
flat: '平(0.3kWh/)', flat: '平(0.3kWh/EUR)',
peak: '峰(0.6kWh/)', peak: '峰(0.6kWh/EUR)',
earningForecast: '收益预测', earningForecast: '收益预测',
defaultEarning: '默认策略收益', defaultEarning: '默认策略收益',
estimateEarning: '预估收益提升', estimateEarning: '预估收益提升',
rmb: '', rmb: 'EUR',
stts: '收益预算', stts: '收益预算',
sjsyje: '实际收益金额', sjsyje: '实际收益金额',
mrjhqx: '默认计划曲线收益', mrjhqx: '默认计划曲线收益',

View File

@ -80,9 +80,11 @@ export function getLanguage() {
// if has not choose language // if has not choose language
const language = (navigator.language || navigator.browserLanguage).toLowerCase() const language = (navigator.language || navigator.browserLanguage).toLowerCase()
const locales = Object.keys(messages) const locales = Object.keys(messages)
console.log(JSON.stringify('语言:' + language, locales))
for (const locale of locales) { for (const locale of locales) {
if (language.indexOf(locale) > -1) { if (language.indexOf(locale) > -1) {
return locale return locale !== 'en' ? 'en' : locale
} }
} }
return 'en' return 'en'

View File

@ -34,7 +34,7 @@ export default {
selectTemValid: 'Please select template validity', selectTemValid: 'Please select template validity',
type: 'Type', type: 'Type',
selectType: 'Please select type', selectType: 'Please select type',
electrovalency: 'Electricity(RMB)', electrovalency: 'Electricity(EUR)',
sure: 'Sure', sure: 'Sure',
cancel: 'Cancel', cancel: 'Cancel',
noSelectData: 'No data is selected', noSelectData: 'No data is selected',
@ -121,7 +121,7 @@ export default {
img: 'Image', img: 'Image',
eleLevel: 'Electricity Price Level', eleLevel: 'Electricity Price Level',
fsdd: 'The price of time-of-use electricity', fsdd: 'The price of time-of-use electricity',
dietailUnit: 'RMB/kWh', dietailUnit: 'EUR/kWh',
eleprice: 'The price of electricity and electricity', eleprice: 'The price of electricity and electricity',
historytrend: 'Historical trends', historytrend: 'Historical trends',
curve: 'Curve', curve: 'Curve',
@ -154,11 +154,11 @@ export default {
charge: 'Charge', charge: 'Charge',
time: 'Time', time: 'Time',
ele: 'Electricity(kWh)', ele: 'Electricity(kWh)',
expend: 'expenditures(RMB)', expend: 'expenditures(EUR)',
disCharge: 'Discharge', disCharge: 'Discharge',
projectRevenue: 'Project Revenue', projectRevenue: 'Project Revenue',
monthTotalChargePrice: 'Total Charging Price Monthly', monthTotalChargePrice: 'Total Charging Price Monthly',
rmb: 'RMB', rmb: 'EUR',
monthTotalDisChargePrice: 'Total Discharging Price Monthly', monthTotalDisChargePrice: 'Total Discharging Price Monthly',
earnings: 'Revenue', earnings: 'Revenue',
earningsRecalculation: 'Revenue Recalculation', earningsRecalculation: 'Revenue Recalculation',
@ -204,7 +204,7 @@ export default {
}, },
glance: { glance: {
day: 'day', day: 'day',
wRMB: 'Million RMB', wRMB: 'EUR10K',
safeDays: 'Safe Operation Days', safeDays: 'Safe Operation Days',
totalCapacity: 'Total Installed Capacity', totalCapacity: 'Total Installed Capacity',
totalCharge: 'Total Charging Volume', totalCharge: 'Total Charging Volume',
@ -232,7 +232,7 @@ export default {
setRevenue: 'Settlement Revenue', setRevenue: 'Settlement Revenue',
chargeCost: 'Charging Cost', chargeCost: 'Charging Cost',
dischargeRev: 'Discharge Revenue', dischargeRev: 'Discharge Revenue',
rmb: 'RMB', rmb: 'EUR',
setRatio: 'Settlement Ratio', setRatio: 'Settlement Ratio',
selectSetRatio: 'Please select settlement ratio', selectSetRatio: 'Please select settlement ratio',
priceCurve: 'Real-Time Electricity Price Curve', priceCurve: 'Real-Time Electricity Price Curve',
@ -243,9 +243,9 @@ export default {
noData: 'No Data', noData: 'No Data',
inputNumber: 'Please input a number from 0-100', inputNumber: 'Please input a number from 0-100',
earningGlance: 'Revenue Glance', earningGlance: 'Revenue Glance',
unit: 'Unit:RMB/kWh', unit: 'Unit:EUR/kWh',
unitKw: 'Unit:kW', unitKw: 'Unit:kW',
planCurve: 'Plan Curve', planCurve: 'Plan Curve',
unitRMB: 'Unit:RMB' unitRMB: 'Unit:EUR'
} }
} }

View File

@ -34,7 +34,7 @@ export default {
selectTemValid: '请选择模板有效期', selectTemValid: '请选择模板有效期',
type: '类型', type: '类型',
selectType: '请选择类型', selectType: '请选择类型',
electrovalency: '电价()', electrovalency: '电价(EUR)',
sure: '确认', sure: '确认',
cancel: '取消', cancel: '取消',
noSelectData: '未选择数据', noSelectData: '未选择数据',
@ -123,7 +123,7 @@ export default {
img: '图片', img: '图片',
eleLevel: '电价水平', eleLevel: '电价水平',
fsdd: '分时电度用电价格', fsdd: '分时电度用电价格',
dietailUnit: '/千瓦时', dietailUnit: 'EUR/千瓦时',
eleprice: '电度用电价格', eleprice: '电度用电价格',
historytrend: '历史趋势', historytrend: '历史趋势',
curve: '曲线', curve: '曲线',
@ -153,11 +153,11 @@ export default {
charge: '充电', charge: '充电',
time: '时段', time: '时段',
ele: '电量(kWh)', ele: '电量(kWh)',
expend: '支出()', expend: '支出(EUR)',
disCharge: '放电', disCharge: '放电',
projectRevenue: '项目收益情况', projectRevenue: '项目收益情况',
monthTotalChargePrice: '本月总充电量总价', monthTotalChargePrice: '本月总充电量总价',
rmb: '', rmb: 'EUR',
monthTotalDisChargePrice: '本月总放电量总价', monthTotalDisChargePrice: '本月总放电量总价',
earnings: '收益', earnings: '收益',
earningsRecalculation: '收益重算', earningsRecalculation: '收益重算',
@ -203,7 +203,7 @@ export default {
}, },
glance: { glance: {
day: '天', day: '天',
wRMB: '万元', wRMB: 'EUR10K',
safeDays: '安全运行天数', safeDays: '安全运行天数',
totalCapacity: '装机总容量', totalCapacity: '装机总容量',
totalCharge: '总充电量', totalCharge: '总充电量',
@ -231,7 +231,7 @@ export default {
setRevenue: '结算收益', setRevenue: '结算收益',
chargeCost: '充电成本', chargeCost: '充电成本',
dischargeRev: '放电收益', dischargeRev: '放电收益',
rmb: '', rmb: 'EUR',
setRatio: '计算比例', setRatio: '计算比例',
selectSetRatio: '请选择结算比例', selectSetRatio: '请选择结算比例',
priceCurve: '实时电价曲线', priceCurve: '实时电价曲线',
@ -242,9 +242,9 @@ export default {
noData: '暂无数据', noData: '暂无数据',
inputNumber: '请输入0-100的数字', inputNumber: '请输入0-100的数字',
earningGlance: '收益概览', earningGlance: '收益概览',
unit: '单位:/kWh', unit: '单位:EUR/kWh',
unitKw: '单位:kW', unitKw: '单位:kW',
planCurve: '计划曲线', planCurve: '计划曲线',
unitRMB: '单位:' unitRMB: '单位:EUR'
} }
} }

View File

@ -21,7 +21,7 @@ export default {
annualEarning: 'Annual Income', annualEarning: 'Annual Income',
totalEarning: 'Total Revenue', totalEarning: 'Total Revenue',
groupEarning: 'Group Income', groupEarning: 'Group Income',
mRMB: 'CNY10K', mRMB: 'EUR10K',
high: 'High', high: 'High',
low: 'Low', low: 'Low',
comTime: 'Commission Time', comTime: 'Commission Time',

View File

@ -21,7 +21,7 @@ export default {
annualEarning: '年收益', annualEarning: '年收益',
totalEarning: '总收益', totalEarning: '总收益',
groupEarning: '集团收益', groupEarning: '集团收益',
mRMB: '万元', mRMB: 'EUR10K',
high: '高', high: '高',
low: '低', low: '低',
comTime: '投运时间', comTime: '投运时间',

View File

@ -280,7 +280,7 @@ export default {
safeLowerError: 'The minimum security capacity cannot be greater than the maximum security capacity', safeLowerError: 'The minimum security capacity cannot be greater than the maximum security capacity',
saveSuccess: 'Save succeeded', saveSuccess: 'Save succeeded',
buildSuccess: 'Generate succeeded', buildSuccess: 'Generate succeeded',
unit: 'Unit: RMB/kWh', unit: 'Unit: EUR/kWh',
loadCurve: 'Load curve', loadCurve: 'Load curve',
importSuccess: 'Import succeeded', importSuccess: 'Import succeeded',
newUnit: 'Unit:kWh' newUnit: 'Unit:kWh'

View File

@ -277,7 +277,7 @@ export default {
safeLowerError: '安全容量下限不能大于安全容量上限', safeLowerError: '安全容量下限不能大于安全容量上限',
saveSuccess: '保存成功', saveSuccess: '保存成功',
buildSuccess: '生成成功', buildSuccess: '生成成功',
unit: '单位:/kWh', unit: '单位:EUR/kWh',
loadCurve: '负荷曲线', loadCurve: '负荷曲线',
importSuccess: '导入成功', importSuccess: '导入成功',
newUnit: '单位:kW' newUnit: '单位:kW'

View File

@ -889,7 +889,7 @@ export default {
day: '日', day: '日',
power: '发电量', power: '发电量',
benefit: '收益', benefit: '收益',
wanji: '万元' wanji: 'EUR10K'
}, },
sophCharging: { // 智慧充电 sophCharging: { // 智慧充电
station: '电站', station: '电站',
@ -905,7 +905,7 @@ export default {
online: '在线', online: '在线',
offline: '离线', offline: '离线',
accruedIncome: '累计收益', accruedIncome: '累计收益',
tenThousand: '万元', tenThousand: 'EUR10K',
faultNum: '故障个数', faultNum: '故障个数',
acAuto: '交流汽车', acAuto: '交流汽车',
chargeBenefit: '充电桩日充电量/收益', chargeBenefit: '充电桩日充电量/收益',
@ -920,9 +920,9 @@ export default {
peak: '峰', peak: '峰',
currentPos: '当前位置', currentPos: '当前位置',
chargeFees: '充电收费', chargeFees: '充电收费',
chargeFeesUnit: '/kWh', chargeFeesUnit: 'EUR/kWh',
serviceFee: '服务费', serviceFee: '服务费',
servecrFeeUnit: '/次', servecrFeeUnit: 'EUR/次',
pileType: '充电桩类型', pileType: '充电桩类型',
chargeNum: '今日充电次数', chargeNum: '今日充电次数',
free: '空闲', free: '空闲',

View File

@ -1044,7 +1044,7 @@ export default {
flex-shrink: 0; flex-shrink: 0;
font-size: 18px !important; font-size: 18px !important;
cursor: pointer; cursor: pointer;
min-width: 100px; // min-width: 100px;
i { i {
font-size: 28px; font-size: 28px;

View File

@ -13,7 +13,7 @@ const service = axios.create({
// request interceptor // request interceptor
service.interceptors.request.use( service.interceptors.request.use(
config => { config => {
config.headers['lang'] = sessionStorage.getItem('language') === 'en' ? 'en_US' : 'zh_CN' config.headers['lang'] = sessionStorage.getItem('language') === 'zh' ? 'zh_CN' : 'en_US'
// do something before request is sent // do something before request is sent
if (config.headers.isScreen) { if (config.headers.isScreen) {
config.headers['authorization'] = getScreenToken() config.headers['authorization'] = getScreenToken()

View File

@ -586,12 +586,12 @@
</svg> </svg>
</div> </div>
</div> </div>
<dispositionPointDialog <DispositionPointData
is-topology is-topology
:show-div-location="true" :show-div-location="true"
:max-length="12" :max-length="12"
:page-location="pageLocation" :page-location="pageLocation"
:visible="show_point_dispostion" :disposition-show="show_point_dispostion"
@close="closePoint" @close="closePoint"
@getData="getDynamicPointData" @getData="getDynamicPointData"
/> />

View File

@ -534,7 +534,7 @@
</svg> </svg>
</div> </div>
</div> </div>
<dispositionPointDialog :visible="show_point_dispostion" :page-location="pageLocation" @close="closePoint" @getData="getDynamicPointData" /> <DispositionPointData :disposition-show="show_point_dispostion" :page-location="pageLocation" @close="closePoint" @getData="getDynamicPointData" />
</ItemBox> </ItemBox>
</template> </template>

View File

@ -377,52 +377,49 @@
<text x="520" :y="105 + ( 20 * index)" fill="#ffffff" font-size="14"> <text x="520" :y="105 + ( 20 * index)" fill="#ffffff" font-size="14">
{{ item.name }} {{ item.name }}
</text> </text>
<text :x="countChineseAndEnglishCharacters(item.name,510)" :y="105 + ( 20 * index)" fill="#FFB800" font-size="14"> <text :x="countChineseAndEnglishCharacters(item.name,lang === 'zh'?510:470)" :y="105 + ( 20 * index)" fill="#FFB800" font-size="14">
{{ item.value }} {{ item.value }}
</text> </text>
</g> </g>
<!-- STS -->
<!-- <g v-for="(item,index) in stsCenterData" :key="item.id">
<text x="415" :y="153 + ( 20 * index)" fill="#ffffff" font-size="14">
{{ item.name }}
</text>
<text :x="countChineseAndEnglishCharacters(item.name,415)" :y="153 + ( 20 * index)" fill="#FFB800" font-size="14">
{{ item.value }}
</text>
</g> -->
<!-- ACDC --> <!-- ACDC -->
<g v-for="(item,index) in acdcCenterData" :key="item.id"> <g v-for="(item,index) in acdcCenterData" :key="item.id">
<text x="415" :y="213 + ( 20 * index)" fill="#ffffff" font-size="14"> <text x="415" :y="213 + ( 20 * index)" fill="#ffffff" font-size="14">
{{ item.name }} {{ item.name }}
</text> </text>
<text :x="countChineseAndEnglishCharacters(item.name,415)" :y="213 + ( 20 * index)" fill="#FFB800" font-size="14"> <text :x="countChineseAndEnglishCharacters(item.name,lang === 'zh'?415:375)" :y="213 + ( 20 * index)" fill="#FFB800" font-size="14">
{{ item.value }} {{ item.value }}
</text> </text>
</g> </g>
<!-- 左侧 1PV --> <!-- 左侧 1PV -->
<g v-for="(item,index) in pcsLeftData" :key="item.id"> <g v-for="(item,index) in pcsLeftData" :key="item.id">
<text x="200" :y="450 + ( 20 * index)" fill="#ffffff" font-size="14"> <foreignObject
{{ item.name }} :x="200"
</text> :y="450 + (20 * index) - 14"
<text :x="countChineseAndEnglishCharacters(item.name,190)" :y="450 + ( 20 * index)" fill="#FFB800" font-size="14"> width="150"
height="20"
style="overflow: visible;"
>
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: center;">
<el-tooltip
:content="item.name"
placement="top"
:open-delay="400"
effect="dark"
popper-class="svg-tooltip"
>
<span style="font-size: 14px;font-family: sans-serif;color: #ffffff;max-width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis">
{{ truncateText(item.name, 120) }}
</span>
</el-tooltip>
</div>
</foreignObject>
<text :x="calculateValueX(item.name, 200)" :y="450 + ( 20 * index)" fill="#FFB800" font-size="14">
{{ item.value }} {{ item.value }}
</text> </text>
</g> </g>
<!-- 中间 2PV -->
<!-- <g v-for="(item,index) in pcsCenterData" :key="item.id">
<text x="410" :y="450 + ( 20 * index)" fill="#ffffff" font-size="14">
{{ item.name }}
</text>
<text :x="countChineseAndEnglishCharacters(item.name,390)" :y="450 + ( 20 * index)" fill="#FFB800" font-size="14">
{{ item.value }}
</text>
</g> -->
<!-- 右侧 3PCS --> <!-- 右侧 3PCS -->
<g v-for="(item,index) in pcsRightData" :key="item.id"> <g v-for="(item,index) in pcsRightData" :key="item.id">
<text x="622" :y="450 + ( 20 * index)" fill="#ffffff" font-size="14"> <text x="622" :y="450 + ( 20 * index)" fill="#ffffff" font-size="14">
@ -514,7 +511,11 @@ export default {
} }
}, },
computed: {}, computed: {
lang() {
return this.$store.getters.language
}
},
watch: {}, watch: {},
created() { created() {
const result = changeTheme() const result = changeTheme()
@ -531,6 +532,34 @@ export default {
}, },
mounted() {}, mounted() {},
methods: { methods: {
truncateText(text, maxWidth) {
if (!text) return ''
const width = this.measureTextWidth(text)
if (width <= maxWidth) return text
let truncated = text
while (this.measureTextWidth(truncated + '...') > maxWidth && truncated.length > 0) {
truncated = truncated.slice(0, -1)
}
return truncated + (truncated.length < text.length ? '...' : '')
},
// 精确测量文本渲染宽度(像素)
measureTextWidth(text, font = '14px sans-serif') {
// 创建或复用一个 canvas避免重复创建
if (!this._textMeasurementCanvas) {
this._textMeasurementCanvas = document.createElement('canvas')
}
const ctx = this._textMeasurementCanvas.getContext('2d')
ctx.font = font
return ctx.measureText(text).width
},
// 计算 value 的 x 坐标baseX + name 的实际宽度 + 一点间距
calculateValueX(name, baseX = 200) {
const truncatedName = this.truncateText(name, 120) // 限制 name 最大宽度
const width = this.measureTextWidth(truncatedName)
return baseX + width + 6 // +6 是 name 和 value 之间的小空隙
},
countChineseAndEnglishCharacters(str, x) { countChineseAndEnglishCharacters(str, x) {
var chineseCount = str.match(/[\u4e00-\u9fa5]/g) ? str.match(/[\u4e00-\u9fa5]/g).length : 0 var chineseCount = str.match(/[\u4e00-\u9fa5]/g) ? str.match(/[\u4e00-\u9fa5]/g).length : 0
var englishCount = str.match(/[a-zA-Z]/g) ? str.match(/[a-zA-Z]/g).length : 0 var englishCount = str.match(/[a-zA-Z]/g) ? str.match(/[a-zA-Z]/g).length : 0

View File

@ -370,7 +370,7 @@
<text x="520" :y="105 + ( 20 * index)" fill="#ffffff" font-size="14"> <text x="520" :y="105 + ( 20 * index)" fill="#ffffff" font-size="14">
{{ item.name }} {{ item.name }}
</text> </text>
<text :x="countChineseAndEnglishCharacters(item.name,510)" :y="105 + ( 20 * index)" fill="#FFB800" font-size="14"> <text :x="countChineseAndEnglishCharacters(item.name,lang === 'zh'?510:465)" :y="105 + ( 20 * index)" fill="#FFB800" font-size="14">
{{ item.value }} {{ item.value }}
</text> </text>
</g> </g>
@ -381,7 +381,7 @@
<text x="415" :y="153 + ( 20 * index)" fill="#ffffff" font-size="14"> <text x="415" :y="153 + ( 20 * index)" fill="#ffffff" font-size="14">
{{ item.name }} {{ item.name }}
</text> </text>
<text :x="countChineseAndEnglishCharacters(item.name,415)" :y="153 + ( 20 * index)" fill="#FFB800" font-size="14"> <text :x="countChineseAndEnglishCharacters(item.name,lang === 'zh'?415:360)" :y="153 + ( 20 * index)" fill="#FFB800" font-size="14">
{{ item.value }} {{ item.value }}
</text> </text>
</g> </g>
@ -392,26 +392,68 @@
<text x="415" :y="213 + ( 20 * index)" fill="#ffffff" font-size="14"> <text x="415" :y="213 + ( 20 * index)" fill="#ffffff" font-size="14">
{{ item.name }} {{ item.name }}
</text> </text>
<text :x="countChineseAndEnglishCharacters(item.name,415)" :y="213 + ( 20 * index)" fill="#FFB800" font-size="14"> <text :x="countChineseAndEnglishCharacters(item.name,lang === 'zh'?415:360)" :y="213 + ( 20 * index)" fill="#FFB800" font-size="14">
{{ item.value }} {{ item.value }}
</text> </text>
</g> </g>
<!-- 左侧 1PV --> <!-- 左侧 1PV -->
<g v-for="(item,index) in pcsLeftData" :key="item.id"> <g v-for="(item,index) in pcsLeftData" :key="item.id">
<text x="200" :y="450 + ( 20 * index)" fill="#ffffff" font-size="14"> <foreignObject
:x="200"
:y="450 + (20 * index) - 14"
width="150"
height="20"
style="overflow: visible;"
>
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: center;">
<el-tooltip
:content="item.name"
placement="top"
:open-delay="400"
effect="dark"
popper-class="svg-tooltip"
>
<span style="font-size: 14px;font-family: sans-serif;color: #ffffff;max-width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis">
{{ truncateText(item.name, 100) }}
</span>
</el-tooltip>
</div>
</foreignObject>
<!-- <text x="200" :y="450 + ( 20 * index)" fill="#ffffff" font-size="14">
{{ item.name }} {{ item.name }}
</text> </text> -->
<text :x="countChineseAndEnglishCharacters(item.name,180)" :y="450 + ( 20 * index)" fill="#FFB800" font-size="14"> <text :x="calculateValueX(item.name, 185)" :y="450 + ( 20 * index)" fill="#FFB800" font-size="14">
{{ item.value }} {{ item.value }}
</text> </text>
</g> </g>
<!-- 中间 2PV --> <!-- 中间 2PV -->
<g v-for="(item,index) in pcsCenterData" :key="item.id"> <g v-for="(item,index) in pcsCenterData" :key="item.id">
<text x="410" :y="450 + ( 20 * index)" fill="#ffffff" font-size="14"> <foreignObject
:x="410"
:y="450 + (20 * index) - 14"
width="150"
height="20"
style="overflow: visible;"
>
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: center;">
<el-tooltip
:content="item.name"
placement="top"
:open-delay="400"
effect="dark"
popper-class="svg-tooltip"
>
<span style="font-size: 14px;font-family: sans-serif;color: #ffffff;max-width: 120px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis">
{{ truncateText(item.name, 100) }}
</span>
</el-tooltip>
</div>
</foreignObject>
<!-- <text x="410" :y="450 + ( 20 * index)" fill="#ffffff" font-size="14">
{{ item.name }} {{ item.name }}
</text> </text> -->
<text :x="countChineseAndEnglishCharacters(item.name,390)" :y="450 + ( 20 * index)" fill="#FFB800" font-size="14"> <text :x="calculateValueX(item.name, 395)" :y="450 + ( 20 * index)" fill="#FFB800" font-size="14">
{{ item.value }} {{ item.value }}
</text> </text>
</g> </g>
@ -507,7 +549,11 @@ export default {
} }
}, },
computed: {}, computed: {
lang() {
return this.$store.getters.language
}
},
watch: {}, watch: {},
created() { created() {
const result = changeTheme() const result = changeTheme()
@ -524,6 +570,34 @@ export default {
}, },
mounted() {}, mounted() {},
methods: { methods: {
truncateText(text, maxWidth) {
if (!text) return ''
const width = this.measureTextWidth(text)
if (width <= maxWidth) return text
let truncated = text
while (this.measureTextWidth(truncated + '...') > maxWidth && truncated.length > 0) {
truncated = truncated.slice(0, -1)
}
return truncated + (truncated.length < text.length ? '...' : '')
},
// 精确测量文本渲染宽度(像素)
measureTextWidth(text, font = '14px sans-serif') {
// 创建或复用一个 canvas避免重复创建
if (!this._textMeasurementCanvas) {
this._textMeasurementCanvas = document.createElement('canvas')
}
const ctx = this._textMeasurementCanvas.getContext('2d')
ctx.font = font
return ctx.measureText(text).width
},
// 计算 value 的 x 坐标baseX + name 的实际宽度 + 一点间距
calculateValueX(name, baseX = 200) {
const truncatedName = this.truncateText(name, 120) // 限制 name 最大宽度
const width = this.measureTextWidth(truncatedName)
return baseX + width + 6 // +6 是 name 和 value 之间的小空隙
},
countChineseAndEnglishCharacters(str, x) { countChineseAndEnglishCharacters(str, x) {
var chineseCount = str.match(/[\u4e00-\u9fa5]/g) ? str.match(/[\u4e00-\u9fa5]/g).length : 0 var chineseCount = str.match(/[\u4e00-\u9fa5]/g) ? str.match(/[\u4e00-\u9fa5]/g).length : 0
var englishCount = str.match(/[a-zA-Z]/g) ? str.match(/[a-zA-Z]/g).length : 0 var englishCount = str.match(/[a-zA-Z]/g) ? str.match(/[a-zA-Z]/g).length : 0

View File

@ -343,7 +343,7 @@
</svg> </svg>
</div> </div>
</div> </div>
<dispositionPointDialog :visible="show_point_dispostion" :max="4" :page-location="pageLocation" @close="closePoint" @getData="getDynamicPointData" /> <DispositionPointData :disposition-show="show_point_dispostion" :max="4" :page-location="pageLocation" @close="closePoint" @getData="getDynamicPointData" />
</ItemBox> </ItemBox>
</template> </template>

View File

@ -460,7 +460,7 @@
</svg> </svg>
</div> </div>
</div> </div>
<dispositionPointDialog :visible="show_point_dispostion" :page-location="pageLocation" @close="closePoint" @getData="getDynamicPointData" /> <DispositionPointData :disposition-show="show_point_dispostion" :page-location="pageLocation" @close="closePoint" @getData="getDynamicPointData" />
</ItemBox> </ItemBox>
</template> </template>

View File

@ -81,14 +81,14 @@ export default {
const province = [] const province = []
if (data.length) { if (data.length) {
data.forEach((el) => { data.forEach((el) => {
el.value = [el.latitude, el.longitude] el.value = [el.longitude, el.latitude]
el.symbol = 'image://' + blue el.symbol = 'image://' + blue
el.cityCode = 1000 el.cityCode = 1000
province.push(el) province.push(el)
}) })
this.pointData = province this.pointData = province
} else { } else {
this.pointData = [{ symbol: 'image://' + blue, cityCode: 1000, value: [118.8062, 31.9208], name: '江苏' }] this.pointData = [{ symbol: 'image://' + blue, cityCode: 1000, value: [30.787045, 103.923008], name: 'Sichuan' }]
} }
} finally { } finally {
this.loading = false this.loading = false
@ -97,21 +97,12 @@ export default {
}, },
getInitMap() { getInitMap() {
this.$echarts.registerMap('world', worldJson) this.$echarts.registerMap('world', worldJson)
// this.$echarts.registerMap('china', chinaMap)
// this.$echarts.registerMap('chinaMapOutline', chinaMapOutline)
this.pointData = [
{ name: 'Beijing', value: [116.4074, 39.9042] }, // 北京
{ name: 'New York', value: [-74.0060, 40.7128] }, // 纽约
{ name: 'London', value: [-0.1278, 51.5074] } // 伦敦
]
var series = [ var series = [
{ {
// map: 'china',
name: '国家', name: '国家',
map: 'world', map: 'world',
type: 'map', type: 'map',
roam: false, roam: false,
// zoom: 1.65,
zoom: 1.1, zoom: 1.1,
label: { label: {
normal: { normal: {
@ -126,7 +117,6 @@ export default {
} }
} }
}, },
// top: '29%',
top: '10%', top: '10%',
tooltip: { tooltip: {
show: false show: false
@ -144,8 +134,7 @@ export default {
} }
} }
}, },
// data: this.mapData data: this.mapData
data: [{ name: 'China', value: 100 }]
}, },
{ {
@ -164,10 +153,11 @@ export default {
shadowColor: '#333' shadowColor: '#333'
} }
}, },
symbolSize: 10, symbolSize: 24,
data: [this.pointData[this.pointIndex]] symbolOffset: [0, '-50%'], // 或 [0, -12] 更精确
data: [this.pointData[this.pointIndex]],
// showEffectOn: 'render' // 加载完毕显示特效 showEffectOn: 'render' // 加载完毕显示特效
} }
] ]
@ -197,25 +187,25 @@ export default {
trigger: 'item', trigger: 'item',
alwaysShowContent: true, alwaysShowContent: true,
backgroundColor: 'transparent', backgroundColor: 'transparent',
position: 'top', position: 'bottom',
triggerOn: 'click', triggerOn: 'click',
enterable: true, enterable: true,
formatter: params => { formatter: params => {
// 获取xAxis data中的数据 // 获取xAxis data中的数据
let dataStr = `<div></div>` let dataStr = `<div></div>`
dataStr += `<div> dataStr += `<div>
<span style="padding-left:10px;font-weight:bold;margin-left:20px;margin-top:5px;font-size="14px">${params.name}</span> <span style="padding-left:20px;font-weight:bold;margin-left:20px;margin-top:5px;font-size="14px">${params.name}</span>
</div>` </div>`
dataStr += `<div style="margin-top:15px"> dataStr += `<div style="margin-top:15px">
<span style="padding-left:10px;">投运时间</span> <span style="padding-left:10px;">${this.$t('screen.comTime')}</span>
<span style="margin-left:5px;margin-right:10px;color:rgba(245, 221, 0, 1);font-family:DIN;">${params.data.createTime}</span> <span style="margin-left:5px;margin-right:10px;color:rgba(245, 221, 0, 1);font-family:DIN;">${params.data.createTime}</span>
</div>` </div>`
dataStr += `<div style="margin-top:2px;"> dataStr += `<div style="margin-top:2px;">
<span style="padding-left:10px;">装机容量</span> <span style="padding-left:10px;">${this.$t('screen.capacity')}</span>
<span style="margin-left:5px;margin-right:5px;color:rgba(245, 221, 0, 1);font-family:DIN;">${params.data.capacity}</span> <span style="margin-left:5px;margin-right:5px;color:rgba(245, 221, 0, 1);font-family:DIN;">${params.data.capacity}</span>
<span style="color:rgba(245, 221, 0, 1);">kWh</span> <span style="color:rgba(245, 221, 0, 1);">kWh</span>
</div>` </div>`
const div = `<div style='max-width:220px;height:85px; const div = `<div style='height:85px;
background-image:url(${require('../../../assets/new-screen/tooltip-bg.png')});background-repeat: no-repeat;background-size:100% 100%;' >${dataStr}</div>` background-image:url(${require('../../../assets/new-screen/tooltip-bg.png')});background-repeat: no-repeat;background-size:100% 100%;' >${dataStr}</div>`
return div return div
} }
@ -224,11 +214,8 @@ export default {
geo: [ geo: [
{ {
silent: true, silent: true,
// map: 'chinaMapOutline',
map: 'world', map: 'world',
zoom: 1.1, zoom: 1.1,
// top: '10%',
label: { label: {
normal: { normal: {
show: false, show: false,
@ -266,7 +253,6 @@ export default {
{ {
silent: true, silent: true,
map: 'chinaMapOutline', map: 'chinaMapOutline',
// zoom: 1.1,
zoom: 1.2, zoom: 1.2,
top: '7%', top: '7%',
label: { label: {

View File

@ -6,7 +6,7 @@
<!-- 头部 s --> <!-- 头部 s -->
<div class="title_wrap"> <div class="title_wrap">
<div class="title"> <div class="title">
<span class="left-title" /> <span :class="lang === 'zh'? 'left-title' : 'left-title-en'" />
<span :class="lang === 'zh'? 'title-text' : 'en-eitle-text'">{{ $t('screen.ztscreenTitle') }}</span> <span :class="lang === 'zh'? 'title-text' : 'en-eitle-text'">{{ $t('screen.ztscreenTitle') }}</span>
<div class="right-title"> <div class="right-title">
<span>{{ time }}</span> <span>{{ time }}</span>
@ -339,7 +339,17 @@ $margin: 16px;
left: $margin; left: $margin;
top: 30px; top: 30px;
} }
.left-title-en {
width: 200px;
height: 52px;
background: url(../../assets/new-screen/zhongzien.png) no-repeat;
background-size: 100% 100%;
color: #fff;
font-size: 16px;
position: absolute;
left: $margin;
top: 30px;
}
.right-title { .right-title {
font-family: LCD; font-family: LCD;
color: #fff; color: #fff;

View File

@ -77,7 +77,7 @@
</el-table-column> </el-table-column>
<el-table-column width="150" :label="$t('remote.yhxgz')"> <el-table-column width="150" :label="$t('remote.yhxgz')">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model="scope.row.modifyValue" type="number" placeholder="请输入" /> <el-input v-model="scope.row.modifyValue" type="number" :placeholder="$t('remote.pleaseInput')" />
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column width="180" label="站内接入点"> <!-- <el-table-column width="180" label="站内接入点">

View File

@ -1901,12 +1901,12 @@ box-shadow: inset 0px 2px 16px 0px rgba(0, 148, 255, 0.4);' >${dataStr}</div>`
} }
.label { .label {
width: 110px; flex: 1;
color: rgba(255, 255, 255, 1); color: rgba(255, 255, 255, 1);
} }
.value { .value {
flex: 1; flex: 0.5;
margin-left: 5px; margin-left: 5px;
text-align: right; text-align: right;
color: rgba(0, 148, 255, 1); color: rgba(0, 148, 255, 1);

View File

@ -205,7 +205,7 @@ import {
GetPageSelectAll, GetPageSelectAll,
DeleteTemplate DeleteTemplate
} from '@/api/surveillance/battery-analysis' } from '@/api/surveillance/battery-analysis'
import { GetQueryPointList } from '@/api/surveillance/battery-analysis' import { GetQueryPoint } from '@/api/surveillance/battery-analysis'
import ModelKuang from '@/components/ModelKuang/index.vue' import ModelKuang from '@/components/ModelKuang/index.vue'
import { pageSize, pageSizes } from '@/config' import { pageSize, pageSizes } from '@/config'
import Pagingbar from '@/components/Pagingbar' import Pagingbar from '@/components/Pagingbar'
@ -663,7 +663,7 @@ export default {
stationId: this.filters.stationId stationId: this.filters.stationId
} }
try { try {
const res = await GetQueryPointList(params) const res = await GetQueryPoint(params)
const option = res.data const option = res.data
// 将指标的数据处理成树 // 将指标的数据处理成树
if (option.length > 0) { if (option.length > 0) {

View File

@ -41,8 +41,8 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="6"> <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="6">
<el-form-item :label="$t('surveillance.chargeType') + ':'" label-width="100px"> <el-form-item :label="$t('surveillance.chargeType') + ':'">
<el-select v-model="filter.segmentType" style="width: 100%;" placeholder="请选择" @change="changeType"> <el-select v-model="filter.segmentType" placeholder="请选择" @change="changeType">
<el-option <el-option
v-for="item in dateTypeList" v-for="item in dateTypeList"
:key="item.value" :key="item.value"

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="realtime-wrapper"> <div class="realtime-wrapper">
<el-row :gutter="10"> <el-row class="card-total-box" :gutter="10">
<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6"> <el-col class="card-box" :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
<div class="card-total station"> <div class="card-total station">
<div class="station-name">{{ panel_data.stationName }}</div> <div class="station-name">{{ panel_data.stationName }}</div>
<div class="content"> <div class="content">
@ -25,7 +25,7 @@
</div> </div>
</el-col> </el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6"> <el-col class="card-box" :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
<div class="card-total charge"> <div class="card-total charge">
<div class="content"> <div class="content">
<div class="name"> <div class="name">
@ -39,7 +39,7 @@
</div> </div>
</div> </div>
</el-col> </el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6"> <el-col class="card-box" :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
<div class="card-total discharge"> <div class="card-total discharge">
<div class="content"> <div class="content">
<div class="name"> <div class="name">
@ -53,7 +53,7 @@
</div> </div>
</div> </div>
</el-col> </el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6"> <el-col class="card-box" :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
<div class="card-total earnings"> <div class="card-total earnings">
<div class="content"> <div class="content">
<div class="name"> <div class="name">
@ -1055,15 +1055,25 @@ box-shadow: inset 0px 2px 16px 0px rgba(0, 148, 255, 0.4);' >${dataStr}</div>`
.search-row { .search-row {
margin-top: 10px margin-top: 10px
} }
/* 父容器 el-row 改为 flex 布局,确保列等高 */
.card-total-box {
display: flex;
align-items: stretch; /* 关键:让所有列拉伸至相同高度 */
}
/* 确保每个 el-col 占满行高 */
.card-box {
display: flex;
}
.card-total { .card-total {
width: 100%; width: 100%;
height: 138px; min-height: 138px;
margin-top: 10px; margin-top: 10px;
padding: 10px; padding: 10px;
display: flex; display: flex;
position: relative; position: relative;
/* 确保卡片内容撑满高度 */
flex-direction: column;
.content { .content {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View File

@ -28,7 +28,8 @@ const topCenterList = [
{ label: '七合一(配置)', value: 'seventhTopCenter' }, { label: '七合一(配置)', value: 'seventhTopCenter' },
{ label: '八合一(配置)', value: 'eighthTopCenter' }, { label: '八合一(配置)', value: 'eighthTopCenter' },
{ label: '九合一(配置)', value: 'ninthTopCenter' }, { label: '九合一(配置)', value: 'ninthTopCenter' },
{ label: '十合一(配置)', value: 'tenthTopCenter' } { label: '十合一(配置)', value: 'tenthTopCenter' },
{ label: '一百二十合一(配置)', value: 'zzhbTopCenter' }
] ]
const rightTopList = [ const rightTopList = [
{ label: '实时告警', value: 'topRight' }, { label: '实时告警', value: 'topRight' },

View File

@ -6,7 +6,7 @@ function resolve(dir) {
return path.join(__dirname, dir) return path.join(__dirname, dir)
} }
const name = defaultSettings.title || '弘正新能源' // page title const name = defaultSettings.title || '中自新能源' // page title
// If your port is set to 80, // If your port is set to 80,
// use administrator privileges to execute the command line. // use administrator privileges to execute the command line.