快乐的昕的电脑
2025-10-25 8665f6ea328877d28bff1750155fdfe70c9ee4d9
components/mold.vue
@@ -11,6 +11,14 @@
                <label class="form-label">设置使用上限:</label>
                <input class="input" 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>
            <view class="form-cell">
                <label class="form-label">刀具名称:</label>
                <input class="input" v-model="toolName" placeholder="刀具带出" disabled />
@@ -100,9 +108,8 @@
        <!-- 说明 -->
        <view class="tool-desc">
            <p style="color:red;">当前工单中,换了几次刀,就会产生几条数据。上刀时间、下刀时间在表中能看到。</p>
            <p style="color:red;">上刀时间和对应时间用生产计数器匹配,查出当时的生产数(累计计数)。</p>
            <p style="color:red;">寿命比预警值在刀具上,默认统一。</p>
            <p style="color:red;">'使用上限'以下刀时的'使用上限'为计算标准</p>
            <p style="color:red;">寿命比预警值默认为90%</p>
        </view>
    </view>
</template>
@@ -125,6 +132,7 @@
                searchKey: '',
                filteredTools: [],
                useLimitInput: '',
                lifeWarnInput: '', // 新增:寿命比预警值原始输入
                toolRecords: [],
                loadingTools: false,
                loadingForm: false,
@@ -139,6 +147,15 @@
            }
        },
        methods: {
            // 新增:寿命比预警值归一化 (返回 0~1 或 null)
            normalizeLifeWarn(v) {
                if (v == null) return null;
                const raw = String(v).trim().replace(/[%%]/g, '');
                if (raw === '') return null;
                const num = Number(raw);
                if (!isFinite(num) || num <= 0) return null;
                return num > 1 ? (num / 100) : num;
            },
            openToolDialog() {
                this.showToolDialog = true;
                this.pageIndex = 1;
@@ -171,10 +188,12 @@
                            return null;
                        };
                        // 这里需要把 lifeWarn 字段也带出来
                        const mapped = (payload || []).map(t => ({
                            no: getField(t, 'cutterId', 'CUTTER_ID', 'cutteR_ID', 'daA001', 'no'),
                            name: getField(t, 'cutterName', 'CUTTER_NAME', 'cutteR_NAME', 'name'),
                            model: getField(t, 'cutterModel', 'CUTTER_MODEL', 'cutteR_MODEL', 'model')
                            model: getField(t, 'cutterModel', 'CUTTER_MODEL', 'cutteR_MODEL', 'model'),
                            lifeWarn: getField(t, 'modlLifeWorning', 'lifeWarn', 'LIFE_WARN', 'lifE_WARN')
                        }));
                        this.filteredTools = mapped;
@@ -224,6 +243,14 @@
                this.toolName = tool.name;
                this.toolModel = tool.model;
                this.activeToolNo = tool.no;
                // 新增:带出寿命比预警值
                if (tool.lifeWarn !== undefined && tool.lifeWarn !== null) {
                    // 格式化为百分比字符串
                    const warn = Number(tool.lifeWarn);
                    this.lifeWarnInput = warn <= 1 ? `${(warn * 100).toFixed(0)}%` : `${warn.toFixed(0)}%`;
                } else {
                    this.lifeWarnInput = '';
                }
            },
            confirmTool() {
                this.showToolDialog = false;
@@ -252,20 +279,22 @@
                if (!this.workOrderNo) { this.$showMessage('工单号不能为空'); return; }
                if (!this.machineNo) { this.$showMessage('机台号不能为空'); return; }
                if (!this.selectedToolNo) { this.$showMessage('刀具编号不能为空'); return; }
                if (!this.useLimitInput) { this.$showMessage('使用上限不能为空'); return; }
                //上刀不强制录入使用上限
                //if (!this.useLimitInput) { this.$showMessage('使用上限不能为空'); return; }
                const useLimit = Number(this.useLimitInput);
                if (isNaN(useLimit) || useLimit <= 0) { this.$showMessage('请输入有效的使用上限'); return; }
                //if (isNaN(useLimit) || useLimit <= 0) { this.$showMessage('请输入有效的使用上限'); return; }
                // sdjs 使用工单 currentCjNum
                const sdjs = this.workOrderCurrentCjNum != null ? Number(this.workOrderCurrentCjNum) : null;
                const lifeWarnRatio = this.normalizeLifeWarn(this.lifeWarnInput);
                const payload = {
                    workOrderNo: this.workOrderNo,
                    machineNo: this.machineNo,
                    toolNo: this.selectedToolNo,
                    type: '上机',
                    useLimit,
                    sdjs // 上刀计数(工单当前数采)
                    sdjs,// 上刀计数(工单当前数采)
                    modlLifeWorning: lifeWarnRatio // 新增
                };
                try {
                    this.submitting = true;
@@ -308,14 +337,15 @@
                // 下刀计数同样取工单最新采集数
                const xdjs = this.workOrderCurrentCjNum != null ? Number(this.workOrderCurrentCjNum) : null;
                const lifeWarnRatio = this.normalizeLifeWarn(this.lifeWarnInput);
                const payload = {
                    workOrderNo: this.workOrderNo,
                    machineNo: this.machineNo,
                    toolNo: this.selectedToolNo,
                    type: '下机',
                    useLimit,
                    xdjs // 下刀计数
                    xdjs,// 下刀计数
                    modlLifeWorning: lifeWarnRatio // 新增
                };
                try {
                    this.submitting = true;
@@ -352,6 +382,7 @@
                this.toolName = '';
                this.toolModel = '';
                this.useLimitInput = '';
                this.lifeWarnInput = ''; // 新增:清空
            },
            async fetchFormData() {
                if (!this.workOrderNo || !this.machineNo) {
@@ -384,19 +415,6 @@
                        return null;
                    };
                    const parseNumber = v => {
                        if (v === null || v === undefined || v === '') return null;
                        const s = String(v).replace(/[,%%]/g, '').trim();
                        const n = parseFloat(s);
                        return Number.isFinite(n) ? n : null;
                    };
                    const formatPercent = n => {
                        if (n === null || n === undefined || isNaN(n)) return '';
                        if (n <= 1) return `${(n * 100).toFixed(0)}%`;
                        return `${Number(n).toFixed(0)}%`;
                    };
                    const mapped = (list || []).map(t => {
                        const upTimeRaw = getField(t, 'uP_TIME', 'UP_TIME', 'uPTime', 'UPTIME', 'UpTime');
                        const downTimeRaw = getField(t, 'dowN_TIME', 'DOWN_TIME', 'downTime', 'DOWNTIME');
@@ -407,11 +425,7 @@
                        const useLimit = getField(t, 'usE_LIMIT', 'USE_LIMIT', 'useLimit');
                        let percent = '';
                        if (
                            useCount != null && useLimit != null &&
                            !isNaN(useCount) && !isNaN(useLimit) &&
                            Number(useLimit) > 0
                        ) {
                        if (useCount != null && useLimit != null && !isNaN(useCount) && !isNaN(useLimit) && Number(useLimit) > 0) {
                            percent = ((Number(useCount) / Number(useLimit)) * 100).toFixed(0) + '%';
                        }
@@ -453,6 +467,18 @@
                        };
                    });
                    // 新增:按上刀时间降序排序(越晚的越上面)
                    mapped.sort((a, b) => {
                        // 时间格式如 "10-24 16:03",转为 Date 对象比较
                        const parse = s => {
                            if (!s) return 0;
                            // 补年份,假设都是今年
                            const year = new Date().getFullYear();
                            return new Date(`${year}-${s.replace(/-/g, '-')}:00`).getTime();
                        };
                        return parse(b.upTime) - parse(a.upTime); // 注意这里顺序反过来
                    });
                    this.toolRecords = mapped;
                    const totalFromRes = Number(
                        res.data?.total ?? res.data?.totalCount ?? res.total ?? res.totalCount ?? mapped.length
@@ -482,6 +508,13 @@
                        this.toolModel = order.cutterModel || order.cutteR_MODEL || '';
                        // 关键:获取工单最新采集数
                        this.workOrderCurrentCjNum = order.CurrentCjNum ?? order.currentCjNum ?? null;
                        // 新增:自动填充寿命比预警值
                        if (order.modlLifeWorning !== undefined && order.modlLifeWorning !== null) {
                            const warn = Number(order.modlLifeWorning);
                            this.lifeWarnInput = warn <= 1 ? `${(warn * 100).toFixed(0)}%` : `${warn.toFixed(0)}%`;
                        } else {
                            this.lifeWarnInput = '';
                        }
                    } else {
                        this.workOrderCurrentCjNum = null;
                    }
@@ -518,9 +551,8 @@
            this.fetchTools('');
            this.machineNo = uni.getStorageSync('machineNo') || '';
            this.workOrderNo = uni.getStorageSync('daa001') || '';
            console.log('机台号:', this.machineNo);
            console.log('工单号:', this.workOrderNo);
            // 去除默认预警值 (90% -> 0.9)
            //this.lifeWarnInput = '90';
            if (this.machineNo && this.workOrderNo) {
                this.fetchFormData();
@@ -533,16 +565,17 @@
</script>
<style scoped>
    /* 原样保持,未改动样式,只插入了一个输入框 */
    .top-section-grid {
        display: flex;
        justify-content: center;
        align-items: flex-end;
        gap: 32px;
        margin-bottom: 2vh;
        width: 95vw; /* 新增,和表格宽度一致 */
        max-width: 1600px; /* 新增,和表格一致 */
        margin-left: auto; /* 新增,居中 */
        margin-right: auto; /* 新增,居中 */
        width: 95vw;
        max-width: 1600px;
        margin-left: auto;
        margin-right: auto;
    }
    .form-cell {
@@ -665,7 +698,7 @@
    }
    .tool-btn {
        flex: 0 0 24%; /* 每行4个按钮 */
        flex: 0 0 24%;
        box-sizing: border-box;
        margin: 5px 1% 5px 0;
        padding: 12px 18px;
@@ -721,7 +754,6 @@
        box-shadow: none;
    }
    /* 表格整体居中,宽度限制,内容居中 */
    .table-section {
        display: flex;
        justify-content: center;
@@ -730,8 +762,8 @@
    }
    table.styled-table {
        max-width: 1600px; /* 原为1400px,调宽 */
        width: 95vw; /* 原为90vw,调宽 */
        max-width: 1600px;
        width: 95vw;
        margin: 0 auto;
        border-collapse: separate;
        border-spacing: 0;
@@ -759,13 +791,11 @@
            text-align: center;
        }
    .table-section table th:first-child,
    .table-section table td:first-child {
    .table-section table th:first-child, .table-section table td:first-child {
        border-left: 2px solid #bfbfbf;
    }
    .table-section table th:last-child,
    .table-section table td:last-child {
    .table-section table th:last-child, .table-section table td:last-child {
        border-right: 2px solid #bfbfbf;
    }