快乐的昕的电脑
2025-10-31 f0007b357d982060aefbd1271b7c49ab4156eea3
components/mold.vue
@@ -4,26 +4,30 @@
        <view class="top-section-grid">
            <view class="form-cell">
                <label class="form-label">刀具编号:</label>
                <input class="input" v-model="selectedToolNo" placeholder="请通过刀具目录选择" disabled />
                <input class="input small-font" v-model="selectedToolNo" placeholder="请通过刀具目录选择" disabled />
                <button class="btn-blue" @click="openToolDialog" :disabled="loadingTools">刀具目录</button>
            </view>
            <view class="form-cell">
                <label class="form-label">设置使用上限:</label>
                <input class="input" type="number" v-model="useLimitInput" placeholder="每次换刀后手填" :disabled="!selectedToolNo || loadingForm" />
                <input class="input small-font" type="number" v-model="useLimitInput" placeholder="每次换刀后手填" :disabled="!selectedToolNo || loadingForm" />
            </view>
            <!-- 新增:寿命比预警值输入框 -->
            <view class="form-cell">
                <label class="form-label">寿命比预警值:</label>
                <input class="input"
                       v-model="lifeWarnInput"
                       placeholder="如0.9或90(%)"
                       :disabled="!selectedToolNo || loadingForm" />
                <view class="input-with-suffix">
                    <input class="input small-font"
                           v-model="lifeWarnInput"
                           placeholder="如0.9或90"
                           :disabled="!selectedToolNo || loadingForm" />
                </view>
                <span class="input-suffix">%</span>
            </view>
            <view class="form-cell">
                <label class="form-label">刀具名称:</label>
                <input class="input" v-model="toolName" placeholder="刀具带出" disabled />
                <input class="input small-font" v-model="toolName" placeholder="刀具带出" disabled />
                <label class="form-label" style="margin-left: 16px;">规格型号:</label>
                <input class="input" v-model="toolModel" placeholder="刀具带出" disabled />
                <input class="input small-font" v-model="toolModel" placeholder="刀具带出" disabled />
            </view>
        </view>
@@ -107,9 +111,10 @@
        </view>
        <!-- 说明 -->
        <view class="tool-desc">
        <!--<view class="tool-desc">
            <p style="color:red;">'使用上限'以下刀时的'使用上限'为计算标准</p>
        </view>
            <p style="color:red;">寿命比预警值默认为90%</p>
        </view>-->
    </view>
</template>
@@ -137,7 +142,14 @@
                loadingForm: false,
                submitting: false,
                _searchTimer: null,
                workOrderCurrentCjNum: null // 工单当前数采
                workOrderCurrentCjNum: null, // 工单当前数采
                // 自动保存相关
                autoSaveTimer: null,
                isDirty: false, // 表单是否有未保存变更
                autoSaveIntervalMs: 5 * 60 * 1000, // 默认 5 分钟
                autoSaveEnabled: true,
                autoSaveActionName: 'handleUpTool' // 自动触发的方法名,可改为自定义保存方法
            };
        },
        computed: {
@@ -145,7 +157,56 @@
                return Math.max(1, Math.ceil(this.total / this.pageSize) || 1);
            }
        },
        watch: {
            // 标记脏数据:按需监听字段变化
            selectedToolNo() { this.isDirty = true; },
            useLimitInput() { this.isDirty = true; },
            lifeWarnInput() { this.isDirty = true; },
            toolName() { this.isDirty = true; },
            toolModel() { this.isDirty = true; }
        },
        methods: {
            // 自动保存:启动
            startAutoSave() {
                if (!this.autoSaveEnabled) return;
                this.stopAutoSave();
                this.autoSaveTimer = setInterval(() => {
                    this.autoSaveTick();
                }, this.autoSaveIntervalMs);
            },
            // 自动保存:停止
            stopAutoSave() {
                if (this.autoSaveTimer) {
                    clearInterval(this.autoSaveTimer);
                    this.autoSaveTimer = null;
                }
            },
            // 自动保存:每次定时执行时的逻辑
            async autoSaveTick() {
                if (!this.autoSaveEnabled) return;
                if (!this.isDirty) return;
                if (this.submitting || this.loadingForm) return;
                const fn = this.autoSaveActionName && typeof this[this.autoSaveActionName] === 'function'
                    ? this[this.autoSaveActionName]
                    : null;
                if (!fn) {
                    console.warn('自动保存:未找到方法', this.autoSaveActionName);
                    return;
                }
                try {
                    this.submitting = true;
                    await fn.call(this); // 调用保存方法(例如 handleUpTool)
                    // 如果保存成功,清脏标记(保存方法内部若失败没有抛出可保持此方式)
                    this.isDirty = false;
                } catch (e) {
                    console.error('自动保存失败:', e);
                } finally {
                    this.submitting = false;
                }
            },
            // 新增:寿命比预警值归一化 (返回 0~1 或 null)
            normalizeLifeWarn(v) {
                if (v == null) return null;
@@ -246,7 +307,7 @@
                if (tool.lifeWarn !== undefined && tool.lifeWarn !== null) {
                    // 格式化为百分比字符串
                    const warn = Number(tool.lifeWarn);
                    this.lifeWarnInput = warn <= 1 ? `${(warn * 100).toFixed(0)}%` : `${warn.toFixed(0)}%`;
                    this.lifeWarnInput = warn <= 1 ? (warn * 100).toFixed(0) : warn.toFixed(0);
                } else {
                    this.lifeWarnInput = '';
                }
@@ -321,6 +382,7 @@
                } catch (err) {
                    console.error(err);
                    this.$showMessage('上刀提交失败,请检查网络');
                    throw err; // 抛出以便自动保存逻辑捕获并保留 isDirty
                } finally {
                    this.submitting = false;
                }
@@ -372,6 +434,7 @@
                } catch (err) {
                    console.error(err);
                    this.$showMessage('下刀提交失败,请检查网络');
                    throw err;
                } finally {
                    this.submitting = false;
                }
@@ -382,6 +445,7 @@
                this.toolModel = '';
                this.useLimitInput = '';
                this.lifeWarnInput = ''; // 新增:清空
                this.isDirty = false;
            },
            async fetchFormData() {
                if (!this.workOrderNo || !this.machineNo) {
@@ -466,7 +530,7 @@
                        };
                    });
                    // 新增:按上刀时间升序排序(越早的越上面)
                    // 新增:按上刀时间降序排序(越晚的越上面)
                    mapped.sort((a, b) => {
                        // 时间格式如 "10-24 16:03",转为 Date 对象比较
                        const parse = s => {
@@ -475,7 +539,7 @@
                            const year = new Date().getFullYear();
                            return new Date(`${year}-${s.replace(/-/g, '-')}:00`).getTime();
                        };
                        return parse(a.upTime) - parse(b.upTime);
                        return parse(b.upTime) - parse(a.upTime); // 注意这里顺序反过来
                    });
                    this.toolRecords = mapped;
@@ -510,7 +574,7 @@
                        // 新增:自动填充寿命比预警值
                        if (order.modlLifeWorning !== undefined && order.modlLifeWorning !== null) {
                            const warn = Number(order.modlLifeWorning);
                            this.lifeWarnInput = warn <= 1 ? `${(warn * 100).toFixed(0)}%` : `${warn.toFixed(0)}%`;
                            this.lifeWarnInput = warn <= 1 ? (warn * 100).toFixed(0) : warn.toFixed(0);
                        } else {
                            this.lifeWarnInput = '';
                        }
@@ -559,6 +623,13 @@
            } else {
                console.warn('机台号或工单号为空,无法获取表单数据');
            }
            // 启动自动保存定时器
            this.startAutoSave();
        },
        beforeDestroy() {
            // 清理定时器,防止内存泄漏
            this.stopAutoSave();
        }
    };
</script>
@@ -596,6 +667,11 @@
        border-radius: 6px;
        background: #f8f8f8;
    }
        /* 新增:小字体样式 */
        .input.small-font {
            font-size: 1vw; /* 调小字体 */
        }
    .form-select {
        width: 12vw;
@@ -862,4 +938,24 @@
    .tool-desc {
        margin-top: 2vh;
    }
    .input-with-suffix {
        position: relative;
        display: flex;
        align-items: center;
    }
        .input-with-suffix .input {
            width: 10vw;
            margin-right: 8px;
            padding-right: 24px; /* 为后缀留出空间 */
        }
    .input-suffix {
        position: absolute;
        right: 16px; /* 调整到输入框内右侧 */
        color: #666;
        font-size: 0.9vw;
        pointer-events: none; /* 防止干扰输入 */
    }
</style>