|
|
@@ -47,38 +47,41 @@
|
|
|
|
|
|
<el-date-picker v-model="startDate" type="date" placeholder="选择日期"
|
|
|
value-format="yyyy-MM-dd" size="small" :append-to-body="true"
|
|
|
- :popper-options="{ boundariesPadding: 0, gpuAcceleration: false }"
|
|
|
- class="form-item">
|
|
|
+ :popper-options="{ boundariesPadding: 0, gpuAcceleration: false }">
|
|
|
</el-date-picker>
|
|
|
|
|
|
- <el-time-picker v-model="startTime" placeholder="选择时间" value-format="HH:mm:ss"
|
|
|
- size="small" :append-to-body="true"
|
|
|
- :popper-options="{ boundariesPadding: 0, gpuAcceleration: false }"
|
|
|
- class="form-item">
|
|
|
+ <el-time-picker v-model="startTime" placeholder="选择时间"
|
|
|
+ value-format="HH:mm:ss" size="small" :append-to-body="true"
|
|
|
+ :popper-options="{ boundariesPadding: 0, gpuAcceleration: false }">
|
|
|
</el-time-picker>
|
|
|
|
|
|
<el-date-picker v-model="endDate" type="date" placeholder="选择日期"
|
|
|
value-format="yyyy-MM-dd" size="small" :append-to-body="true"
|
|
|
- :popper-options="{ boundariesPadding: 0, gpuAcceleration: false }"
|
|
|
- class="form-item">
|
|
|
+ :popper-options="{ boundariesPadding: 0, gpuAcceleration: false }">
|
|
|
</el-date-picker>
|
|
|
|
|
|
- <el-time-picker v-model="endTime" placeholder="选择时间" value-format="HH:mm:ss"
|
|
|
- size="small" :append-to-body="true"
|
|
|
- :popper-options="{ boundariesPadding: 0, gpuAcceleration: false }"
|
|
|
- class="form-item">
|
|
|
+ <el-time-picker v-model="endTime" placeholder="选择时间"
|
|
|
+ value-format="HH:mm:ss" size="small" :append-to-body="true"
|
|
|
+ :popper-options="{ boundariesPadding: 0, gpuAcceleration: false }">
|
|
|
</el-time-picker>
|
|
|
|
|
|
- <el-select v-model="duration" placeholder="请选择时长" size="small"
|
|
|
- :popper-append-to-body="true" class="form-item">
|
|
|
- <el-option v-for="d in durationOptions" :key="d" :label="d"
|
|
|
- :value="d"></el-option>
|
|
|
- </el-select>
|
|
|
+ <div class="form-item-labeled">
|
|
|
+ <span class="form-label">时长</span>
|
|
|
+ <el-select v-model="duration" placeholder="请选择时长" size="small"
|
|
|
+ :popper-append-to-body="true">
|
|
|
+ <el-option v-for="d in durationOptions" :key="d" :label="d"
|
|
|
+ :value="d"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
|
|
|
- <el-select v-model="period" placeholder="请选择周期" size="small"
|
|
|
- :popper-append-to-body="true" class="form-item">
|
|
|
- <el-option v-for="p in 8" :key="p" :label="'周期' + p" :value="p"></el-option>
|
|
|
- </el-select>
|
|
|
+ <div class="form-item-labeled">
|
|
|
+ <span class="form-label">周期</span>
|
|
|
+ <el-select v-model="period" placeholder="请选择周期" size="small"
|
|
|
+ :popper-append-to-body="true">
|
|
|
+ <el-option v-for="p in 8" :key="p" :label="'周期' + p"
|
|
|
+ :value="p"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
@@ -88,7 +91,7 @@
|
|
|
<div v-for="(item, index) in currentStageList" :key="index"
|
|
|
class="stage-item-wrapper">
|
|
|
<div class="phase-box" :class="{ 'is-active': item.value === currentStage }"
|
|
|
- @click="currentStage = item.value">
|
|
|
+ @click="onStageClick(item.value)">
|
|
|
<img :src="item.img" alt="stage" class="phase-image" />
|
|
|
</div>
|
|
|
|
|
|
@@ -105,8 +108,8 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 方案圆饼图 -->
|
|
|
- <div class="donut-row" v-if="!showLockTime">
|
|
|
+ <!-- 方案圆饼图:步进模式下不显示 -->
|
|
|
+ <div class="donut-row" v-if="!showLockTime && currentMethod !== 'step'">
|
|
|
<div class="donut-item">
|
|
|
<div class="donut-title">实时方案(执行方案3)</div>
|
|
|
<PlanDonutChart :chartData="realtimeDonutData"
|
|
|
@@ -141,12 +144,18 @@
|
|
|
</label>
|
|
|
</div>
|
|
|
</div>
|
|
|
+ <div class="lock-time-actions" v-if="currentMethod === 'step'">
|
|
|
+ <button type="button" class="btn btn-cancel"
|
|
|
+ @click="onCancel()">取消</button>
|
|
|
+ <button type="button" class="btn btn-confirm"
|
|
|
+ @click="onConfirm()">确认</button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</transition>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <div class="button-group" v-show="isManualMode">
|
|
|
+ <div class="button-group" v-show="isManualMode && currentMethod !== 'step'">
|
|
|
<div>
|
|
|
<button type="button" class="btn btn-cancel" @click="onCancel()">取消</button>
|
|
|
<button type="button" class="btn btn-confirm" @click="onConfirm()">确认</button>
|
|
|
@@ -244,23 +253,14 @@ export default {
|
|
|
watch: {
|
|
|
// 监听控制方式切换
|
|
|
currentMethod(newVal) {
|
|
|
- // 需求4:切换步进方案策略时,出现锁定时间弹窗
|
|
|
+ // 切换到步进时不自动弹出锁定时间,等用户点击阶段再弹
|
|
|
+ this.showLockTime = false;
|
|
|
if (newVal === 'step') {
|
|
|
- this.showLockTime = true;
|
|
|
this.syncLocktimeByStage();
|
|
|
- } else {
|
|
|
- this.showLockTime = false;
|
|
|
}
|
|
|
|
|
|
// 模拟需求1:根据不同模式,切换对应的控制方案数据 (Mock 逻辑)
|
|
|
this.updateSchemeDataByMethod(newVal);
|
|
|
- },
|
|
|
- // 步进模式下切换阶段时,更新锁定时间选项并重新显示面板
|
|
|
- currentStage() {
|
|
|
- if (this.currentMethod === 'step') {
|
|
|
- this.showLockTime = true;
|
|
|
- this.syncLocktimeByStage();
|
|
|
- }
|
|
|
}
|
|
|
},
|
|
|
mounted() {
|
|
|
@@ -275,6 +275,14 @@ export default {
|
|
|
if (this._ro) this._ro.disconnect();
|
|
|
},
|
|
|
methods: {
|
|
|
+ // 点击阶段:切换选中,步进模式下同时弹出锁定时间
|
|
|
+ onStageClick(value) {
|
|
|
+ this.currentStage = value;
|
|
|
+ if (this.currentMethod === 'step') {
|
|
|
+ this.showLockTime = true;
|
|
|
+ this.syncLocktimeByStage();
|
|
|
+ }
|
|
|
+ },
|
|
|
// 根据当前选中阶段同步锁定时间选项
|
|
|
syncLocktimeByStage() {
|
|
|
const stage = this.currentStageList.find(s => s.value === this.currentStage);
|
|
|
@@ -742,6 +750,14 @@ export default {
|
|
|
color: #ffffff;
|
|
|
}
|
|
|
|
|
|
+.lock-time-actions {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ gap: clamp(4px, calc(var(--s) * 8px), 8px);
|
|
|
+ padding: clamp(4px, calc(var(--s) * 8px), 8px) clamp(4px, calc(var(--s) * 10px), 10px);
|
|
|
+ border-top: 1px solid rgba(161, 190, 255, 0.15);
|
|
|
+}
|
|
|
+
|
|
|
.lock-time-option {
|
|
|
font-size: clamp(9px, calc(var(--s) * 14px), 14px);
|
|
|
}
|
|
|
@@ -769,21 +785,21 @@ export default {
|
|
|
width: 100%;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- justify-content: space-around;
|
|
|
- flex-wrap: wrap;
|
|
|
- gap: clamp(4px, calc(var(--s) * 8px), 10px);
|
|
|
- padding: clamp(6px, calc(var(--s) * 12px), 32px);
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ gap: clamp(8px, calc(var(--s) * 18px), 24px);
|
|
|
+ padding: clamp(4px, calc(var(--s) * 8px), 16px);
|
|
|
color: #ffffff;
|
|
|
}
|
|
|
|
|
|
.current-stage-label {
|
|
|
font-size: clamp(9px, calc(var(--s) * 14px), 14px);
|
|
|
- width: auto;
|
|
|
white-space: nowrap;
|
|
|
+ flex-shrink: 0;
|
|
|
}
|
|
|
|
|
|
.stage-input {
|
|
|
- width: clamp(32px, calc(var(--s) * 65px), 65px);
|
|
|
+ width: 100%;
|
|
|
+ min-width: 0;
|
|
|
border: 1px solid rgba(161, 190, 255, 0.7);
|
|
|
background-color: transparent;
|
|
|
padding: clamp(2px, calc(var(--s) * 5px), 5px);
|
|
|
@@ -793,8 +809,8 @@ export default {
|
|
|
|
|
|
.phase-box {
|
|
|
position: relative;
|
|
|
- width: clamp(30px, calc(var(--s) * 90px), 90px);
|
|
|
- height: clamp(30px, calc(var(--s) * 90px), 90px);
|
|
|
+ width: 100%;
|
|
|
+ aspect-ratio: 1 / 1;
|
|
|
background: #E6F0FF;
|
|
|
border-radius: 4px;
|
|
|
display: flex;
|
|
|
@@ -907,6 +923,8 @@ export default {
|
|
|
|
|
|
/* 当前阶段输入框微调 */
|
|
|
.stage-item-wrapper {
|
|
|
+ flex: 1 1 0;
|
|
|
+ min-width: 0;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
align-items: stretch;
|
|
|
@@ -929,7 +947,8 @@ export default {
|
|
|
}
|
|
|
|
|
|
.stage-input {
|
|
|
- width: clamp(32px, calc(var(--s) * 65px), 65px);
|
|
|
+ width: 100%;
|
|
|
+ min-width: 0;
|
|
|
border: 1px solid rgba(161, 190, 255, 0.7);
|
|
|
background-color: transparent;
|
|
|
padding: clamp(2px, calc(var(--s) * 5px), 5px);
|
|
|
@@ -959,13 +978,22 @@ export default {
|
|
|
}
|
|
|
|
|
|
.stage-input {
|
|
|
- width: clamp(32px, calc(var(--s) * 65px), 65px);
|
|
|
+ width: 100%;
|
|
|
+ min-width: 0;
|
|
|
border: 1px solid rgba(161, 190, 255, 0.7);
|
|
|
background-color: transparent;
|
|
|
padding: clamp(2px, calc(var(--s) * 5px), 5px);
|
|
|
+ font-size: clamp(9px, calc(var(--s) * 11px), 11px);
|
|
|
color: #ffffff;
|
|
|
text-align: center;
|
|
|
border-radius: 4px;
|
|
|
+ -moz-appearance: textfield;
|
|
|
+}
|
|
|
+
|
|
|
+.stage-input::-webkit-outer-spin-button,
|
|
|
+.stage-input::-webkit-inner-spin-button {
|
|
|
+ -webkit-appearance: none;
|
|
|
+ margin: 0;
|
|
|
}
|
|
|
|
|
|
.stage-input:disabled {
|
|
|
@@ -1020,20 +1048,35 @@ export default {
|
|
|
|
|
|
/* ===== 时间表单栏布局 ===== */
|
|
|
.time-form-bar {
|
|
|
- display: flex;
|
|
|
- flex-wrap: wrap;
|
|
|
- gap: clamp(4px, calc(var(--s) * 8px), 10px);
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(4, 1fr);
|
|
|
+ gap: clamp(3px, calc(var(--s) * 5px), 6px);
|
|
|
margin-bottom: clamp(4px, calc(var(--s) * 10px), 20px);
|
|
|
}
|
|
|
|
|
|
-.time-form-bar .form-item {
|
|
|
- flex: 1 1 calc(30% - 8px);
|
|
|
- min-width: clamp(80px, calc(var(--s) * 140px), 140px);
|
|
|
+/* 第二行:带标签的项各占 2 列(共 4 列,两项铺满一行) */
|
|
|
+.time-form-bar .form-item-labeled {
|
|
|
+ grid-column: span 2;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: clamp(3px, calc(var(--s) * 6px), 8px);
|
|
|
+}
|
|
|
+
|
|
|
+.time-form-bar .form-label {
|
|
|
+ white-space: nowrap;
|
|
|
+ flex-shrink: 0;
|
|
|
+ color: rgba(200, 220, 255, 0.65);
|
|
|
+ font-size: clamp(9px, calc(var(--s) * 12px), 13px);
|
|
|
+}
|
|
|
+
|
|
|
+.time-form-bar .form-item-labeled .el-select {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 0;
|
|
|
}
|
|
|
|
|
|
/* ===== ElementUI 深色主题适配 ===== */
|
|
|
|
|
|
-/* 覆盖 el-date-editor 固定宽度,让其跟随 flex 布局 */
|
|
|
+/* 覆盖 el-date-editor 固定宽度,让其跟随 grid 布局 */
|
|
|
.time-form-bar>>>.el-date-editor.el-input,
|
|
|
.time-form-bar>>>.el-date-editor.el-input__inner,
|
|
|
.time-form-bar>>>.el-select {
|
|
|
@@ -1045,9 +1088,11 @@ export default {
|
|
|
background-color: rgba(255, 255, 255, 0.06);
|
|
|
border: 1px solid rgba(161, 190, 255, 0.35);
|
|
|
color: #e0e6f1;
|
|
|
- font-size: clamp(9px, calc(var(--s) * 13px), 13px);
|
|
|
- height: clamp(22px, calc(var(--s) * 32px), 32px);
|
|
|
- line-height: clamp(22px, calc(var(--s) * 32px), 32px);
|
|
|
+ font-size: clamp(9px, calc(var(--s) * 11px), 11px);
|
|
|
+ height: clamp(22px, calc(var(--s) * 28px), 28px);
|
|
|
+ line-height: clamp(22px, calc(var(--s) * 28px), 28px);
|
|
|
+ padding-left: clamp(22px, calc(var(--s) * 26px), 26px);
|
|
|
+ padding-right: clamp(4px, calc(var(--s) * 6px), 6px);
|
|
|
}
|
|
|
|
|
|
.time-form-bar>>>.el-input__inner::placeholder {
|
|
|
@@ -1062,15 +1107,15 @@ export default {
|
|
|
border-color: #3b74ff;
|
|
|
}
|
|
|
|
|
|
-/* 图标颜色与大小 */
|
|
|
+/* 图标颜色、尺寸跟随缩放 */
|
|
|
.time-form-bar>>>.el-input__prefix,
|
|
|
.time-form-bar>>>.el-input__suffix {
|
|
|
color: rgba(255, 255, 255, 0.4);
|
|
|
- font-size: clamp(9px, calc(var(--s) * 14px), 14px);
|
|
|
}
|
|
|
|
|
|
.time-form-bar>>>.el-input__icon {
|
|
|
- line-height: clamp(22px, calc(var(--s) * 32px), 32px);
|
|
|
- width: clamp(16px, calc(var(--s) * 25px), 25px);
|
|
|
+ font-size: clamp(9px, calc(var(--s) * 12px), 12px);
|
|
|
+ line-height: clamp(22px, calc(var(--s) * 28px), 28px);
|
|
|
+ width: clamp(18px, calc(var(--s) * 22px), 22px);
|
|
|
}
|
|
|
</style>
|