Files
app-govern/pages/index/comp/monitoringPoint.vue

813 lines
25 KiB
Vue
Raw Normal View History

2026-05-27 10:10:19 +08:00
<template>
2026-05-29 16:23:56 +08:00
<view class="itic2-page">
2026-06-01 20:36:04 +08:00
<view class="itic2-content">
2026-05-29 16:23:56 +08:00
<view class="project-header card">
<view class="project-title-row">
<view class="project-title-left">
<uni-icons custom-prefix="iconfont" type="icon-gongcheng" size="22" color="#376cf3" />
<text class="project-name">{{ engineeringName }}</text>
</view>
<view class="switch-btn" @click="switchEngineering">
<uni-icons type="loop" size="14" color="#376cf3" />
<text>切换工程</text>
</view>
2026-05-27 10:10:19 +08:00
</view>
2026-05-29 16:23:56 +08:00
<view class="stats-row">
<view class="stats-item" v-for="(item, idx) in summaryStats" :key="idx">
<text class="stats-num">{{ item.value }}</text>
<text class="stats-label">{{ item.label }}</text>
</view>
2026-05-27 10:10:19 +08:00
</view>
</view>
2026-05-29 16:23:56 +08:00
<view class="monitor-section-header">
<view class="section-title-row section-title-row--no-mb">
<uni-icons type="settings" size="18" color="#376cf3" />
<text class="section-title">已选展示指标</text>
</view>
</view>
<view class="indicators-card card">
<view class="indicator-tags">
2026-06-01 20:36:04 +08:00
<view v-for="(tag, idx) in selectedIndicators" :key="tag"
class="indicator-tag indicator-tag--active" @click="removeIndicator(idx)">
2026-05-29 16:23:56 +08:00
<text class="indicator-tag-text">{{ formatIndicatorTag(tag) }}</text>
<uni-icons type="closeempty" size="12" color="#376cf3" />
</view>
<view class="indicator-tag indicator-tag--add" @click="openIndicatorPopup">
<text>+添加指标</text>
</view>
</view>
</view>
2026-05-27 10:10:19 +08:00
2026-05-29 16:23:56 +08:00
<view class="monitor-section">
<view class="monitor-section-header">
<view class="section-title-row section-title-row--no-mb">
<uni-icons type="map-pin-ellipse" size="20" color="#376cf3" />
<text class="section-title">监测点信息</text>
</view>
<view class="legend-row">
<view class="legend-item" v-for="phase in phaseColors" :key="phase.name">
<view class="legend-dot" :style="{ background: phase.color }" />
<text class="legend-text">{{ phase.name }}</text>
2026-05-27 10:10:19 +08:00
</view>
2026-05-29 16:23:56 +08:00
</view>
</view>
<view class="monitor-list">
<view class="monitor-card card" v-for="(point, idx) in monitoringPoints" :key="idx">
<view class="card-header">
<view class="event-icon">
<Cn-icon-transient name="监测点" />
2026-05-27 10:10:19 +08:00
</view>
2026-05-29 16:23:56 +08:00
<view class="card-header-info">
<text class="point-name ellipsis">{{ point.pointName }}</text>
<view class="meta-row">
<text class="meta-item ellipsis">项目{{ point.projectName }}</text>
<text class="meta-item ellipsis">设备{{ point.deviceName }}</text>
</view>
<text class="meta-time ellipsis">最新数据时间{{ point.dataTime || '-' }}</text>
2026-05-27 10:10:19 +08:00
</view>
</view>
2026-05-29 16:23:56 +08:00
<view class="params-section">
2026-06-01 20:36:04 +08:00
<view v-for="(rowItems, rowIdx) in chunkedChildren(getDisplayChildren(point))" :key="rowIdx"
class="double-row">
2026-05-29 16:23:56 +08:00
<view v-for="(child, childIdx) in rowItems" :key="childIdx" class="param-group">
<view class="param-title">
2026-06-01 20:36:04 +08:00
<text>{{ child.name }} {{ child.unit ? `(${child.unit})` : '' }}</text>
2026-05-27 10:10:19 +08:00
</view>
2026-06-01 20:36:04 +08:00
<view v-if="hasTPhaseData(child)" class="phase-single">
<text class="phase-value-vertical phase-value-vertical--neutral">{{ child.T
}}</text>
</view>
<view v-else class="phase-vertical">
2026-05-29 16:23:56 +08:00
<view class="phase-item-vertical">
2026-06-01 20:36:04 +08:00
<text class="phase-value-vertical"
:style="{ color: phaseColors[0].color }">{{ child.A }}</text>
2026-05-29 16:23:56 +08:00
</view>
<view class="phase-divider" />
<view class="phase-item-vertical">
2026-06-01 20:36:04 +08:00
<text class="phase-value-vertical"
:style="{ color: phaseColors[1].color }">{{ child.B }}</text>
2026-05-29 16:23:56 +08:00
</view>
<view class="phase-divider" />
<view class="phase-item-vertical">
2026-06-01 20:36:04 +08:00
<text class="phase-value-vertical"
:style="{ color: phaseColors[2].color }">{{ child.C }}</text>
2026-05-29 16:23:56 +08:00
</view>
2026-05-27 10:10:19 +08:00
</view>
</view>
</view>
</view>
2026-05-29 16:23:56 +08:00
<view class="more-btn" @click="onMoreIndicators(point)">
<uni-icons type="list" size="16" color="#376cf3" />
<text>更多指标</text>
</view>
2026-05-27 10:10:19 +08:00
</view>
2026-06-01 20:36:04 +08:00
<uni-load-more v-if="listStatus == 'loading' || monitoringPoints.length > 0"
:status="listStatus"></uni-load-more>
<Cn-empty v-else style="top: 35%"></Cn-empty>
2026-05-27 10:10:19 +08:00
</view>
</view>
2026-06-01 20:36:04 +08:00
</view>
<view class="back-top boxClick" v-show="showBackTop" @click="backToTop">
<uni-icons type="arrow-up" size="22" color="#fff"></uni-icons>
</view>
2026-05-29 16:23:56 +08:00
<uni-popup ref="indicatorPopup" type="bottom">
<view class="indicator-popup">
<view class="indicator-popup-header">
<text class="indicator-popup-cancel" @click="closeIndicatorPopup">取消</text>
<text class="indicator-popup-confirm" @click="confirmIndicatorPopup">确定</text>
</view>
2026-06-01 20:36:04 +08:00
<view class="indicator-popup-list" scroll-y>
2026-05-29 16:23:56 +08:00
<view v-if="targetLists.length === 0" class="indicator-popup-empty">
<text>暂无指标数据</text>
</view>
2026-06-01 20:36:04 +08:00
<view v-for="item in targetLists" :key="item.id || item.name" class="indicator-popup-item"
2026-05-29 16:23:56 +08:00
:class="{ 'indicator-popup-item--active': popupSelectedIndicators.includes(item.name) }"
2026-06-01 20:36:04 +08:00
@click="togglePopupIndicator(item.name)">
2026-05-29 16:23:56 +08:00
<text>{{ item.name }}</text>
2026-06-01 20:36:04 +08:00
<uni-icons v-if="popupSelectedIndicators.includes(item.name)" type="checkmarkempty" size="18"
color="#376cf3" />
2026-05-29 16:23:56 +08:00
</view>
2026-06-01 20:36:04 +08:00
</view>
2026-05-29 16:23:56 +08:00
</view>
</uni-popup>
2026-05-27 10:10:19 +08:00
</view>
</template>
<script>
2026-05-29 16:23:56 +08:00
import { queryByCode, queryCsDictTree } from '@/common/api/dictionary'
2026-06-01 20:36:04 +08:00
import { getLineDataByEngineer } from '@/common/api/harmonic'
import { getDevCount } from '@/common/api/device.js'
2026-05-29 16:23:56 +08:00
const DEFAULT_INDICATOR_CODES = ['Key_Power_Quality_V', 'Key_Power_Quality_I']
2026-05-27 10:10:19 +08:00
export default {
data() {
return {
2026-05-29 16:23:56 +08:00
targetLists: [],
popupSelectedIndicators: [],
engineeringName: '',
2026-06-01 20:36:04 +08:00
engineeringId: '',
2026-05-29 16:23:56 +08:00
summaryStats: [
2026-06-01 20:36:04 +08:00
{ label: '项目总数', value: 0 },
{ label: '设备总数', value: 0 },
{ label: '监测点总数', value: 0 },
2026-05-29 16:23:56 +08:00
],
selectedIndicators: [],
phaseColors: [
{ name: 'A相', color: '#F1B22E' },
{ name: 'B相', color: '#2BA471' },
{ name: 'C相', color: '#D54941' },
],
2026-06-01 20:36:04 +08:00
monitoringPoints: [],
listStatus: 'noMore',
lineDataRequestId: 0,
showBackTop: false,
2026-05-27 10:10:19 +08:00
}
},
2026-06-01 20:36:04 +08:00
onPageScroll(e) {
this.showBackTop = e.scrollTop > 200
},
2026-05-29 16:23:56 +08:00
// 页面显示时同步工程名称
onShow() {
const engineering = uni.getStorageSync('engineering')
2026-06-01 20:36:04 +08:00
if (engineering?.id) {
this.engineeringName = engineering.name || ''
this.engineeringId = engineering.id
this.info()
}
if (this.targetLists.length) {
this.loadSelectedIndicators()
2026-05-29 16:23:56 +08:00
}
},
// 加载电能质量指标字典
created() {
queryByCode('Key_Power_Quality').then((res) => {
queryCsDictTree(res.data.id).then((resp) => {
this.targetLists = (resp.data || []).slice().reverse()
2026-06-01 20:36:04 +08:00
this.loadSelectedIndicators()
2026-05-29 16:23:56 +08:00
})
})
},
2026-06-01 20:36:04 +08:00
// 下拉刷新
onPullDownRefresh() {
this.info()
},
2026-05-27 10:10:19 +08:00
methods: {
2026-06-01 20:36:04 +08:00
// 查询接口
info() {
if (!this.engineeringId) {
uni.stopPullDownRefresh()
return
}
this.loadDevCount()
this.loadLineData()
},
loadDevCount() {
getDevCount(this.engineeringId).then((res) => {
if (res.code == 'A0000') {
this.updateSummaryStats(res.data)
}
})
},
loadLineData() {
this.listStatus = 'loading'
this.monitoringPoints = []
const requestId = ++this.lineDataRequestId
const engineerId = this.engineeringId
getLineDataByEngineer({ id: engineerId })
.then((res) => {
if (requestId !== this.lineDataRequestId) return
if (res.code == 'A0000') {
this.monitoringPoints = this.parseMonitoringPoints(res.data)
} else if (res.message) {
this.$util.toast(res.message)
}
})
.catch(() => {
if (requestId !== this.lineDataRequestId) return
this.$util.toast('加载失败,请稍后重试')
})
.finally(() => {
if (requestId !== this.lineDataRequestId) return
this.listStatus = 'noMore'
uni.stopPullDownRefresh()
})
},
// 接口 data 转为页面 monitoringPoints
parseMonitoringPoints(data = []) {
const list = Array.isArray(data) ? data : []
return list.map((point) => ({
projectName: point.projectName || '',
deviceName: point.deviceName || '',
pointName: point.pointName || '',
dataTime: point.dataTime || '',
children: this.groupChildren(point.children || []),
}))
},
// 将按相别拆分的指标合并为 A/B/C 结构
groupChildren(children = []) {
const map = {}
const order = []
children.forEach((item) => {
const key = item.targetId || item.name
if (!map[key]) {
map[key] = {
targetId: item.targetId,
name: item.name,
unit: item.unit,
A: '-',
B: '-',
C: '-',
T: '-',
}
order.push(key)
}
const phase = item.phase
if (phase === 'A' || phase === 'B' || phase === 'C' || phase === 'T') {
map[key][phase] = this.formatPhaseValue(item.data)
}
})
return order.map((key) => map[key])
},
formatPhaseValue(value) {
if (value === null || value === undefined || value === '') return '-'
return String(value)
},
hasTPhaseData(child) {
return child.T !== undefined && child.T !== null && child.T !== '-'
},
updateSummaryStats(devCount = {}) {
const deviceTotal =
(devCount.currentOnLineDevCount || 0) + (devCount.currentOffLineDevCount || 0)
this.summaryStats = [
{ label: '项目总数', value: devCount.currentProjectCount || 0 },
{ label: '设备总数', value: deviceTotal },
{ label: '监测点总数', value: devCount.lineCount || 0 },
]
},
2026-05-29 16:23:56 +08:00
// 指标名称超过6个字截断显示
formatIndicatorTag(name) {
if (!name || name.length <= 6) return name
2026-06-01 20:36:04 +08:00
return `${name.slice(0, 5)}...`
2026-05-29 16:23:56 +08:00
},
// 判断指标名称是否匹配(兼容括号后缀)
matchIndicator(name, selected) {
2026-06-01 20:36:04 +08:00
if (!name || !selected) return false
const base = (name || '').replace(/\(.*\)/, '').trim()
const selectedBase = (selected || '').replace(/\(.*\)/, '').trim()
return base === selectedBase
},
// 从缓存读取已选指标,无缓存时使用默认电压/电流指标
loadSelectedIndicators() {
const cached = uni.getStorageSync(this.$cacheKey.monitorSelectedIndicators)
if (Array.isArray(cached) && cached.length) {
const valid = cached.filter((name) =>
this.targetLists.some((item) => this.matchIndicator(item.name, name)),
)
if (valid.length) {
this.selectedIndicators = valid
return
}
}
this.selectedIndicators = this.getDefaultIndicatorsByCode()
this.saveSelectedIndicators()
2026-05-29 16:23:56 +08:00
},
2026-06-01 20:36:04 +08:00
getDefaultIndicatorsByCode() {
return this.targetLists
2026-05-29 16:23:56 +08:00
.filter((item) => DEFAULT_INDICATOR_CODES.includes(item.code) && item.name)
.map((item) => item.name)
},
2026-06-01 20:36:04 +08:00
saveSelectedIndicators() {
uni.setStorageSync(this.$cacheKey.monitorSelectedIndicators, this.selectedIndicators)
},
2026-05-29 16:23:56 +08:00
// 跳转切换工程
switchEngineering() {
uni.navigateTo({ url: '/pages/home/selectEngineering' })
},
// 移除已选指标
removeIndicator(idx) {
if (this.selectedIndicators.length <= 1) {
uni.showToast({ title: '至少保留一个指标', icon: 'none' })
return
}
this.selectedIndicators.splice(idx, 1)
2026-06-01 20:36:04 +08:00
this.saveSelectedIndicators()
2026-05-29 16:23:56 +08:00
},
// 打开指标选择弹窗
openIndicatorPopup() {
if (!this.targetLists.length) {
uni.showToast({ title: '暂无指标数据', icon: 'none' })
return
}
this.popupSelectedIndicators = this.targetLists
.filter((item) => this.selectedIndicators.some((name) => this.matchIndicator(item.name, name)))
.map((item) => item.name)
this.$refs.indicatorPopup.open()
},
// 关闭指标选择弹窗
closeIndicatorPopup() {
this.$refs.indicatorPopup.close()
this.popupSelectedIndicators = []
},
// 切换弹窗内指标勾选状态
togglePopupIndicator(name) {
const idx = this.popupSelectedIndicators.indexOf(name)
if (idx > -1) {
this.popupSelectedIndicators.splice(idx, 1)
} else {
this.popupSelectedIndicators.push(name)
}
},
// 确认指标选择
confirmIndicatorPopup() {
if (!this.popupSelectedIndicators.length) {
uni.showToast({ title: '至少保留一个指标', icon: 'none' })
return
}
this.selectedIndicators = [...this.popupSelectedIndicators]
2026-06-01 20:36:04 +08:00
this.saveSelectedIndicators()
2026-05-29 16:23:56 +08:00
this.closeIndicatorPopup()
},
// 查看更多指标
onMoreIndicators(point) {
2026-06-01 20:36:04 +08:00
uni.setStorageSync('monitorPointDetail', {
...point,
engineeringName: this.engineeringName,
selectedIndicators: [...this.selectedIndicators],
})
2026-05-29 16:23:56 +08:00
uni.navigateTo({
2026-06-01 20:36:04 +08:00
url: '/pages/index/comp/targetInfo',
2026-05-29 16:23:56 +08:00
})
},
// 获取监测点当前展示的指标数据
getDisplayChildren(point) {
return (point.children || []).filter((child) =>
this.selectedIndicators.some((name) => this.matchIndicator(child.name, name)),
)
},
// 将指标列表按每行两个分组
2026-05-27 10:10:19 +08:00
chunkedChildren(children) {
const result = []
for (let i = 0; i < children.length; i += 2) {
result.push(children.slice(i, i + 2))
}
return result
},
2026-06-01 20:36:04 +08:00
backToTop() {
uni.pageScrollTo({
scrollTop: 0,
duration: 300,
})
this.showBackTop = false
},
2026-05-29 16:23:56 +08:00
},
2026-05-27 10:10:19 +08:00
}
</script>
2026-05-29 16:23:56 +08:00
<style lang="scss" scoped>
.itic2-page {
min-height: 100vh;
background: #f7f8fa;
2026-06-01 20:36:04 +08:00
position: relative;
2026-05-29 16:23:56 +08:00
}
2026-06-01 20:36:04 +08:00
.itic2-content {
padding: 20rpx 0 40rpx;
2026-05-27 10:10:19 +08:00
box-sizing: border-box;
}
2026-06-01 20:36:04 +08:00
.back-top {
position: fixed;
right: 30rpx;
bottom: 60rpx;
width: 80rpx;
height: 80rpx;
border-radius: 50%;
background: #376cf3;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 16rpx rgba(55, 108, 243, 0.35);
z-index: 99;
}
2026-05-29 16:23:56 +08:00
.card {
background: #ffffff;
border-radius: 10px;
2026-06-01 20:36:04 +08:00
box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 3px 1px;
2026-05-29 16:23:56 +08:00
margin: 0 10px 10px;
overflow: hidden;
2026-05-27 10:10:19 +08:00
}
2026-05-29 16:23:56 +08:00
.project-header {
padding: 20rpx;
// margin-top: 20rpx;
}
.project-title-row {
2026-05-27 10:10:19 +08:00
display: flex;
2026-05-29 16:23:56 +08:00
align-items: center;
2026-05-27 10:10:19 +08:00
justify-content: space-between;
2026-05-29 16:23:56 +08:00
margin-bottom: 20rpx;
}
.project-title-left {
display: flex;
2026-05-27 10:10:19 +08:00
align-items: center;
2026-05-29 16:23:56 +08:00
gap: 12rpx;
flex: 1;
min-width: 0;
}
.project-name {
font-size: 32rpx;
font-weight: 700;
color: #333333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.switch-btn {
display: flex;
align-items: center;
gap: 6rpx;
padding: 8rpx 20rpx;
border: 1rpx solid #376cf380;
background-color: #266FFF10;
border-radius: 16rpx;
2026-05-27 10:10:19 +08:00
flex-shrink: 0;
2026-05-29 16:23:56 +08:00
text {
font-size: 24rpx;
color: #376cf3;
}
2026-05-27 10:10:19 +08:00
}
2026-05-29 16:23:56 +08:00
.stats-row {
2026-05-27 10:10:19 +08:00
display: flex;
2026-05-29 16:23:56 +08:00
gap: 20rpx;
2026-05-27 10:10:19 +08:00
}
2026-05-29 16:23:56 +08:00
.stats-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4rpx;
padding: 16rpx 12rpx;
background: #376cf3;
border-radius: 16rpx;
color: #ffffff;
2026-05-27 10:10:19 +08:00
}
2026-05-29 16:23:56 +08:00
.stats-num {
font-size: 44rpx;
2026-05-27 10:10:19 +08:00
font-weight: 700;
2026-05-29 16:23:56 +08:00
line-height: 1.2;
}
.stats-label {
font-size: 26rpx;
}
.indicators-card {
padding: 24rpx;
}
.section-title-row {
display: flex;
align-items: center;
gap: 10rpx;
margin-bottom: 20rpx;
&--no-mb {
margin-bottom: 0;
}
}
.section-title {
font-size: 30rpx;
font-weight: 600;
color: #333333;
}
.indicator-tags {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
}
.indicator-tag {
display: flex;
align-items: center;
2026-06-01 20:36:04 +08:00
gap: 6rpx;
padding: 6rpx 14rpx;
2026-05-29 16:23:56 +08:00
border-radius: 16rpx;
font-size: 26rpx;
max-width: 100%;
.indicator-tag-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&--active {
background: #376cf315;
color: #376cf3;
}
&--add {
background: #f5f5f5;
color: #666666;
border: 1rpx dashed #dcdfe6;
}
}
.monitor-section-header {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 12rpx;
padding: 0 10px 16rpx;
2026-05-27 10:10:19 +08:00
}
.legend-row {
display: flex;
gap: 20rpx;
align-items: center;
}
.legend-item {
display: flex;
align-items: center;
2026-05-29 16:23:56 +08:00
gap: 8rpx;
2026-05-27 10:10:19 +08:00
}
2026-05-29 16:23:56 +08:00
.legend-dot {
width: 16rpx;
height: 16rpx;
2026-05-27 10:10:19 +08:00
border-radius: 50%;
}
.legend-text {
font-size: 24rpx;
2026-05-29 16:23:56 +08:00
color: #666666;
2026-05-27 10:10:19 +08:00
}
2026-05-29 16:23:56 +08:00
.monitor-list {
2026-05-27 10:10:19 +08:00
display: flex;
flex-direction: column;
2026-05-29 16:23:56 +08:00
padding-bottom: 40rpx;
2026-05-27 10:10:19 +08:00
}
.monitor-card {
2026-05-29 16:23:56 +08:00
border: 1rpx solid #eef2f6;
2026-06-01 20:36:04 +08:00
box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 3px 1px;
2026-05-27 10:10:19 +08:00
}
.card-header {
2026-05-29 16:23:56 +08:00
padding: 20rpx 20rpx 12rpx;
display: flex;
align-items: center;
2026-05-27 10:10:19 +08:00
border-bottom: 1rpx solid #eef2f6;
2026-05-29 16:23:56 +08:00
}
.event-icon {
width: 90rpx;
height: 90rpx;
border-radius: 16rpx;
2026-05-27 10:10:19 +08:00
display: flex;
2026-05-29 16:23:56 +08:00
justify-content: center;
2026-05-27 10:10:19 +08:00
align-items: center;
2026-05-29 16:23:56 +08:00
margin-right: 20rpx;
background-color: #376cf320;
flex-shrink: 0;
2026-05-27 10:10:19 +08:00
}
.card-header-info {
flex: 1;
min-width: 0;
}
.point-name {
display: block;
font-size: 30rpx;
font-weight: 700;
color: #333333;
2026-05-29 16:23:56 +08:00
margin-bottom: 8rpx;
2026-05-27 10:10:19 +08:00
}
.meta-row {
display: grid;
grid-template-columns: 1fr 1fr;
2026-05-29 16:23:56 +08:00
gap: 6rpx 12rpx;
2026-05-27 10:10:19 +08:00
}
.meta-item {
2026-06-01 11:32:25 +08:00
font-size: 24rpx;
2026-05-27 10:10:19 +08:00
color: #666666;
2026-06-01 11:32:25 +08:00
line-height: 1.2;
2026-05-27 10:10:19 +08:00
}
2026-05-29 16:23:56 +08:00
.meta-time {
display: block;
margin-top: 8rpx;
2026-06-01 11:32:25 +08:00
font-size: 24rpx;
2026-05-29 16:23:56 +08:00
color: #666666;
2026-06-01 11:32:25 +08:00
line-height: 1.2;
2026-05-27 10:10:19 +08:00
}
.params-section {
2026-05-29 16:23:56 +08:00
padding: 20rpx 16rpx;
2026-05-27 10:10:19 +08:00
}
.double-row {
2026-05-29 16:23:56 +08:00
display: grid;
grid-template-columns: repeat(2, 1fr);
2026-05-27 10:10:19 +08:00
gap: 16rpx;
margin-bottom: 16rpx;
2026-05-29 16:23:56 +08:00
&:last-child {
margin-bottom: 0;
}
2026-05-27 10:10:19 +08:00
}
.param-group {
2026-05-29 16:23:56 +08:00
min-width: 0;
background: #f3f3f3;
border-radius: 16rpx;
padding: 16rpx 8rpx 12rpx;
2026-05-27 10:10:19 +08:00
}
.param-title {
font-size: 24rpx;
color: #666666;
2026-05-29 16:23:56 +08:00
margin-bottom: 8rpx;
2026-05-27 10:10:19 +08:00
padding-left: 4rpx;
}
.phase-vertical {
display: flex;
align-items: stretch;
}
2026-06-01 20:36:04 +08:00
.phase-single {
display: flex;
justify-content: center;
align-items: center;
padding: 4rpx;
}
2026-05-27 10:10:19 +08:00
.phase-item-vertical {
flex: 1;
display: flex;
justify-content: center;
2026-05-29 16:23:56 +08:00
align-items: center;
padding: 4rpx;
2026-05-27 10:10:19 +08:00
}
.phase-value-vertical {
font-size: 28rpx;
font-weight: 700;
2026-06-01 20:36:04 +08:00
&--neutral {
color: #333333;
}
2026-05-27 10:10:19 +08:00
}
.phase-divider {
2026-05-29 16:23:56 +08:00
width: 1px;
background: #d2d2d2;
2026-05-27 10:10:19 +08:00
margin: 8rpx 0;
}
2026-05-29 16:23:56 +08:00
.more-btn {
margin: 0 20rpx 20rpx;
height: 72rpx;
line-height: 72rpx;
text-align: center;
border: 1rpx solid #376cf380;
background-color: #266FFF10;
border-radius: 16rpx;
text {
font-size: 28rpx;
color: #376cf3;
font-weight: 500;
}
}
2026-05-27 10:10:19 +08:00
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
2026-05-29 16:23:56 +08:00
.indicator-popup {
background: #ffffff;
overflow: hidden;
}
.indicator-popup-header {
2026-05-27 10:10:19 +08:00
display: flex;
align-items: center;
2026-05-29 16:23:56 +08:00
justify-content: space-between;
padding: 18rpx 32rpx;
border-bottom: 1rpx solid #eef2f6;
}
.indicator-popup-cancel {
font-size: 27rpx;
color: #666666;
min-width: 80rpx;
}
.indicator-popup-confirm {
font-size: 28rpx;
color: #376cf3;
min-width: 80rpx;
text-align: right;
}
.indicator-popup-list {
max-height: 60vh;
padding: 16rpx 0;
box-sizing: border-box;
}
.indicator-popup-empty {
padding: 80rpx 0;
text-align: center;
font-size: 28rpx;
color: #999999;
}
.indicator-popup-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 28rpx 32rpx;
font-size: 28rpx;
color: #333333;
&--active {
color: #376cf3;
background: #376cf310;
}
2026-05-27 10:10:19 +08:00
}
2026-05-29 16:23:56 +08:00
</style>