feat(mes/roll): 重构轧辊磨削页面布局并补充备注字段

1.  重构轧辊磨削页面的整体布局,调整为左侧产线Tab+右侧主体的结构
2.  在实体类和BO类中新增remark备注字段
3.  移除运单页面的冗余备注搜索框
4.  优化轧辊列表的检索和展示逻辑,新增厂家筛选选项
5.  补充磨削班组的下拉选择选项,新增字典配置
6.  优化页面样式和交互细节
This commit is contained in:
2026-06-01 11:27:05 +08:00
parent 43f4692a72
commit c5ce33f71a
4 changed files with 417 additions and 285 deletions

View File

@@ -82,6 +82,9 @@ public class MesRollGrind extends BaseEntity {
/** 操作者 */
private String operator;
/** 备注 */
private String remark;
@TableLogic
private Integer delFlag;
}

View File

@@ -37,4 +37,5 @@ public class MesRollGrindBo extends BaseEntity {
private String flawResult;
private BigDecimal hardness;
private String operator;
private String remark;
}

View File

@@ -2,7 +2,7 @@
<div class="app-container grind-page">
<div class="grind-layout">
<!-- 产线 Tab -->
<!-- 左侧产线 Tab -->
<div class="line-tabs">
<div
:class="['lt-item', filterLineId === null ? 'lt-item--active' : '']"
@@ -16,227 +16,320 @@
>{{ l.lineName }}</div>
</div>
<!-- 轧辊列表 -->
<div class="grind-left">
<el-card shadow="never" class="grind-card h-full">
<div slot="header" class="card-header">
<span class="card-title"><i class="el-icon-s-order" /> 轧辊列表</span>
<!-- 右侧主体 -->
<div class="grind-main">
<!-- 顶部检索栏 -->
<div class="search-bar">
<el-input
v-model="filterNo"
size="small"
placeholder="辊号检索"
prefix-icon="el-icon-search"
clearable
style="width:180px"
@input="filterRolls"
/>
<el-radio-group v-model="filterType" size="small" @change="filterRolls">
<el-radio-button label="">全部类型</el-radio-button>
<el-radio-button label="WR">WR</el-radio-button>
<el-radio-button label="BR">BR</el-radio-button>
<el-radio-button label="CR">CR</el-radio-button>
</el-radio-group>
<el-radio-group v-model="filterManufacturer" size="small" @change="filterRolls">
<el-radio-button label="">全部厂家</el-radio-button>
<el-radio-button v-for="mfr in manufacturerOptions" :key="mfr" :label="mfr">{{ mfr }}</el-radio-button>
</el-radio-group>
</div>
<!-- 下方左右布局 -->
<div class="content-area">
<!-- 左侧轧辊列表 -->
<div class="roll-list-panel">
<el-card shadow="never" class="panel-card">
<div slot="header" class="card-header">
<span class="card-title"><i class="el-icon-s-order" /> 轧辊列表</span>
<span class="card-count">{{ filteredRolls.length }}</span>
</div>
<div v-loading="rollLoading" class="roll-list">
<div
v-for="r in filteredRolls"
:key="r.rollId"
:class="['roll-item', selectedRollId === r.rollId ? 'roll-item--active' : '']"
@click="selectRoll(r)"
>
<div class="ri-no">{{ r.rollNo }}</div>
<div class="ri-meta">
<el-tag size="mini" :type="r.rollType === 'WR' ? 'primary' : 'warning'">{{ r.rollType }}</el-tag>
<span :class="['ri-status', 'st-' + r.status]">{{ statusLabel(r.status) }}</span>
<span class="ri-dia">φ{{ r.currentDia != null ? r.currentDia : r.initialDia }}</span>
</div>
<div v-if="r.manufacturer" class="ri-manufacturer">{{ r.manufacturer }}</div>
<div v-if="filterLineId === null && r.lineName" class="ri-line">{{ r.lineName }}</div>
</div>
<div v-if="!rollLoading && filteredRolls.length === 0" class="roll-empty">暂无数据</div>
</div>
</el-card>
</div>
<!-- 搜索过滤 -->
<div class="roll-filter">
<el-input v-model="filterNo" size="small" placeholder="编号搜索" prefix-icon="el-icon-search"
clearable @input="filterRolls" style="margin-bottom:8px" />
<el-input v-model="filterManufacturer" size="small" placeholder="厂家搜索" prefix-icon="el-icon-search"
clearable @input="filterRolls" style="margin-bottom:8px" />
<el-radio-group v-model="filterType" size="small" @change="filterRolls" style="margin-bottom:8px">
<el-radio-button label="">全部</el-radio-button>
<el-radio-button label="WR">WR</el-radio-button>
<el-radio-button label="BR">BR</el-radio-button>
<el-radio-button label="CR">CR</el-radio-button>
</el-radio-group>
<!-- 右侧明细 & 磨削台账 -->
<div class="detail-panel" v-loading="grindLoading">
<template v-if="!selectedRoll">
<div class="grind-empty"><i class="el-icon-arrow-left" /> 请从左侧选择一个轧辊</div>
</template>
<template v-else>
<!-- 轧辊基本信息 -->
<el-card shadow="never" class="detail-card" style="margin-bottom:10px">
<div slot="header" class="card-header">
<span class="card-title"><i class="el-icon-info" /> 轧辊明细</span>
</div>
<div class="roll-header-grid">
<div class="rh-item"><span class="rh-k">轧辊编号</span><span class="rh-v bold">{{ selectedRoll.rollNo }}</span></div>
<div class="rh-item"><span class="rh-k">辊型</span><span class="rh-v">{{ { WR: '工作辊', BR: '支撑辊', CR: '中间辊' }[selectedRoll.rollType] || '—' }}</span></div>
<div class="rh-item"><span class="rh-k">材质</span><span class="rh-v">{{ selectedRoll.material || '—' }}</span></div>
<div class="rh-item"><span class="rh-k">初始辊径</span><span class="rh-v">{{ selectedRoll.initialDia != null ? selectedRoll.initialDia + ' mm' : '—' }}</span></div>
<div class="rh-item"><span class="rh-k">当前辊径</span><span class="rh-v bold accent">{{ effectiveCurrentDia != null ? effectiveCurrentDia + ' mm' : '—' }}</span></div>
<div class="rh-item"><span class="rh-k">最小辊径</span><span class="rh-v">{{ selectedRoll.minDia != null ? selectedRoll.minDia + ' mm' : '—' }}</span></div>
<div class="rh-item"><span class="rh-k">磨削次数</span><span class="rh-v">{{ tableData.length ? tableData.length + ' 次' : '0 次' }}</span></div>
<div class="rh-item"><span class="rh-k">粗糙度</span><span class="rh-v">{{ selectedRoll.roughness != null ? selectedRoll.roughness + ' μm' : '—' }}</span></div>
<div class="rh-item"><span class="rh-k">凸度</span><span class="rh-v">{{ selectedRoll.crown != null ? selectedRoll.crown + ' mm' : '—' }}</span></div>
<div class="rh-item"><span class="rh-k">状态</span>
<span :class="['rh-v', 'st-' + selectedRoll.status]">{{ statusLabel(selectedRoll.status) }}</span>
</div>
<div class="rh-item"><span class="rh-k">制造日期</span><span class="rh-v">{{ selectedRoll.manufactureDate || '—' }}</span></div>
<div class="rh-item"><span class="rh-k">备注</span><span class="rh-v">{{ selectedRoll.remark || '—' }}</span></div>
</div>
</el-card>
<!-- 磨削台账 -->
<el-card shadow="never" class="detail-card" body-style="padding:10px;overflow:auto">
<div slot="header" class="card-header">
<span class="card-title"><i class="el-icon-document" /> 磨削台账</span>
<el-button
type="primary"
size="mini"
icon="el-icon-plus"
style="margin-left:auto"
:disabled="!!editRow"
@click="startAdd"
>新增磨削记录</el-button>
</div>
<el-table
:data="tableData"
size="small"
border
style="width:100%"
:row-class-name="rowClassName"
>
<el-table-column label="序号" type="index" width="46" align="center" />
<el-table-column label="磨削时间" align="center" width="200">
<template slot-scope="{row}">
<el-date-picker
v-if="isEditing(row)"
v-model="editRow.grindTime"
type="datetime"
size="mini"
value-format="yyyy-MM-dd HH:mm:ss"
style="width:182px"
placeholder="请选择"
/>
<span v-else>{{ row.grindTime }}</span>
</template>
</el-table-column>
<el-table-column label="班组" align="center" width="100">
<template slot-scope="{row}">
<el-select
v-if="isEditing(row)"
v-model="editRow.team"
size="mini"
placeholder="班组"
clearable
filterable
allow-create
>
<el-option label="甲班" value="甲班" />
<el-option label="乙班" value="乙班" />
</el-select>
<span v-else>{{ row.team || '' }}</span>
</template>
</el-table-column>
<el-table-column label="磨前径(mm)" align="center" width="100">
<template slot-scope="{row}">
<el-input
v-if="isEditing(row)"
v-model="editRow.diaBefore"
type="number"
size="mini"
style="width:80px"
/>
<span v-else>{{ row.diaBefore }}</span>
</template>
</el-table-column>
<el-table-column label="磨后径(mm)" align="center" width="100">
<template slot-scope="{row}">
<el-input
v-if="isEditing(row)"
v-model="editRow.diaAfter"
type="number"
size="mini"
style="width:80px"
/>
<span v-else>{{ row.diaAfter }}</span>
</template>
</el-table-column>
<el-table-column label="磨削量(mm)" align="center" width="88">
<template slot-scope="{row}">
<span v-if="isEditing(row)" class="computed-val">
{{ grindAmountOf(editRow) }}
</span>
<span v-else>{{ row.grindAmount }}</span>
</template>
</el-table-column>
<el-table-column label="辊型" align="center" width="100">
<template slot-scope="{row}">
<el-select
v-if="isEditing(row)"
v-model="editRow.rollShape"
size="mini"
style="width:84px"
>
<el-option label="平" value="平" />
<el-option label="凸" value="凸" />
<el-option label="凹" value="凹" />
</el-select>
<span v-else>{{ row.rollShape || '' }}</span>
</template>
</el-table-column>
<el-table-column label="探伤结果" align="center" width="110">
<template slot-scope="{row}">
<el-select
v-if="isEditing(row)"
v-model="editRow.flawResult"
size="mini"
style="width:94px"
>
<el-option label="合格" value="合格" />
<el-option label="不合格" value="不合格" />
</el-select>
<el-tag v-else size="mini" :type="row.flawResult === '合格' ? 'success' : 'danger'">
{{ row.flawResult || '—' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="硬度" align="center" width="80">
<template slot-scope="{row}">
<el-input
v-if="isEditing(row)"
v-model.number="editRow.hardness"
type="number"
size="mini"
style="width:64px"
/>
<span v-else>{{ row.hardness || '' }}</span>
</template>
</el-table-column>
<el-table-column label="操作者" align="center" width="140">
<template slot-scope="{row}">
<el-select
v-if="isEditing(row)"
v-model="editRow.operator"
size="mini"
placeholder="选填"
clearable
filterable
allow-create
>
<el-option
v-for="item in dict.type.mes_roll_operator"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<span v-else class="remark-text">{{ row.operator || '' }}</span>
</template>
</el-table-column>
<el-table-column label="备注" align="left" width="120">
<template slot-scope="{row}">
<el-input
v-if="isEditing(row)"
v-model="editRow.remark"
size="mini"
placeholder="选填"
/>
<span v-else class="remark-text">{{ row.remark || '' }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="100" fixed="right">
<template slot-scope="{row}">
<template v-if="isEditing(row)">
<el-button
size="mini"
type="text"
icon="el-icon-check"
:loading="grindSaving"
@click="saveRow"
>保存</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-close"
style="color:#909399"
@click="cancelEdit"
>取消</el-button>
</template>
<template v-else>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
:disabled="!!editRow"
@click="startEdit(row)"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
style="color:#c5221f"
:disabled="!!editRow"
@click="handleDelete(row)"
>删除</el-button>
</template>
</template>
</el-table-column>
</el-table>
<!-- 月度汇总 -->
<div v-if="grindList.length > 0" class="monthly-wrap">
<div class="monthly-title">
<span>{{ currentYear }} 年月度汇总</span>
<el-button-group size="mini" style="margin-left:8px">
<el-button icon="el-icon-arrow-left" @click="changeYear(-1)" />
<el-button icon="el-icon-arrow-right" @click="changeYear(1)" />
</el-button-group>
</div>
<el-table :data="monthlyList" size="mini" border style="width:100%;margin-top:8px">
<el-table-column label="月份" prop="month" align="center" width="90" />
<el-table-column label="磨削次数" prop="grindCount" align="center" width="90" />
<el-table-column label="累计磨削量(mm)" prop="totalGrindAmount" align="center" min-width="120" />
</el-table>
</div>
</el-card>
</template>
</div>
<div v-loading="rollLoading" class="roll-list">
<div
v-for="r in filteredRolls"
:key="r.rollId"
:class="['roll-item', selectedRollId === r.rollId ? 'roll-item--active' : '']"
@click="selectRoll(r)"
>
<div class="ri-no">{{ r.rollNo }}</div>
<div class="ri-meta">
<el-tag size="mini" :type="r.rollType === 'WR' ? 'primary' : 'warning'">{{ r.rollType }}</el-tag>
<span :class="['ri-status', 'st-' + r.status]">{{ statusLabel(r.status) }}</span>
<span class="ri-dia">φ{{ r.currentDia != null ? r.currentDia : r.initialDia }}</span>
</div>
<div v-if="r.manufacturer" class="ri-manufacturer">{{ r.manufacturer }}</div>
<div v-if="filterLineId === null && r.lineName" class="ri-line">{{ r.lineName }}</div>
</div>
<div v-if="!rollLoading && filteredRolls.length === 0" class="roll-empty">暂无数据</div>
</div>
</el-card>
</div>
<!-- 右侧台账 -->
<div class="grind-right">
<template v-if="!selectedRoll">
<div class="grind-empty"><i class="el-icon-arrow-left" /> 请从左侧选择一个轧辊</div>
</template>
<template v-else>
<!-- 轧辊基本信息头 -->
<el-card shadow="never" class="grind-card" style="margin-bottom:12px">
<div class="roll-header-grid">
<div class="rh-item"><span class="rh-k">轧辊编号</span><span class="rh-v bold">{{ selectedRoll.rollNo }}</span></div>
<div class="rh-item"><span class="rh-k">辊型</span><span class="rh-v">{{ selectedRoll.rollType === 'WR' ? '工作辊' : '支撑辊' }}</span></div>
<div class="rh-item"><span class="rh-k">材质</span><span class="rh-v">{{ selectedRoll.material || '—' }}</span></div>
<div class="rh-item"><span class="rh-k">初始辊径</span><span class="rh-v">{{ selectedRoll.initialDia != null ? selectedRoll.initialDia + ' mm' : '—' }}</span></div>
<div class="rh-item"><span class="rh-k">当前辊径</span><span class="rh-v bold accent">{{ effectiveCurrentDia != null ? effectiveCurrentDia + ' mm' : '—' }}</span></div>
<div class="rh-item"><span class="rh-k">最小辊径</span><span class="rh-v">{{ selectedRoll.minDia != null ? selectedRoll.minDia + ' mm' : '—' }}</span></div>
<div class="rh-item"><span class="rh-k">磨削次数</span><span class="rh-v">{{ tableData.length ? tableData.length + ' 次' : '0 次' }}</span></div>
<div class="rh-item"><span class="rh-k">粗糙度</span><span class="rh-v">{{ selectedRoll.roughness != null ? selectedRoll.roughness + ' μm' : '—' }}</span></div>
<div class="rh-item"><span class="rh-k">凸度</span><span class="rh-v">{{ selectedRoll.crown != null ? selectedRoll.crown + ' mm' : '—' }}</span></div>
<div class="rh-item"><span class="rh-k">状态</span>
<span :class="['rh-v', 'st-' + selectedRoll.status]">{{ statusLabel(selectedRoll.status) }}</span>
</div>
<div class="rh-item"><span class="rh-k">制造日期</span><span class="rh-v">{{ selectedRoll.manufactureDate || '—' }}</span></div>
<div class="rh-item"><span class="rh-k">备注</span><span class="rh-v">{{ selectedRoll.remark || '—' }}</span></div>
</div>
</el-card>
<!-- 磨削台账行内编辑 -->
<el-card shadow="never" class="grind-card">
<div slot="header" class="card-header">
<span class="card-title"><i class="el-icon-document" /> 磨削台账</span>
<el-button type="primary" size="mini" icon="el-icon-plus"
style="margin-left:auto" :disabled="!!editRow" @click="startAdd">新增磨削记录</el-button>
</div>
<el-table v-loading="grindLoading" :data="tableData" size="small" border
style="width:100%" :row-class-name="rowClassName">
<el-table-column label="序号" type="index" width="46" align="center" />
<!-- 磨削时间 -->
<el-table-column label="磨削时间" align="center" width="200">
<template slot-scope="{row}">
<el-date-picker v-if="isEditing(row)" v-model="editRow.grindTime"
type="datetime" size="mini" value-format="yyyy-MM-dd HH:mm:ss"
style="width:182px" placeholder="请选择" />
<span v-else>{{ row.grindTime }}</span>
</template>
</el-table-column>
<!-- 班组 -->
<el-table-column label="班组" align="center" width="80">
<template slot-scope="{row}">
<el-input v-if="isEditing(row)" v-model="editRow.team"
size="mini" placeholder="甲班" style="width:64px" />
<span v-else>{{ row.team || '' }}</span>
</template>
</el-table-column>
<!-- 磨前直径 -->
<el-table-column label="磨前径(mm)" align="center" width="100">
<template slot-scope="{row}">
<el-input v-if="isEditing(row)" v-model.number="editRow.diaBefore"
type="number" size="mini" style="width:80px" />
<span v-else>{{ row.diaBefore }}</span>
</template>
</el-table-column>
<!-- 磨后直径 -->
<el-table-column label="磨后径(mm)" align="center" width="100">
<template slot-scope="{row}">
<el-input v-if="isEditing(row)" v-model.number="editRow.diaAfter"
type="number" size="mini" style="width:80px" />
<span v-else>{{ row.diaAfter }}</span>
</template>
</el-table-column>
<!-- 磨削量只读计算 -->
<el-table-column label="磨削量(mm)" align="center" width="88">
<template slot-scope="{row}">
<span v-if="isEditing(row)" class="computed-val">
{{ grindAmountOf(editRow) }}
</span>
<span v-else>{{ row.grindAmount }}</span>
</template>
</el-table-column>
<!-- 辊型 -->
<el-table-column label="辊型" align="center" width="100">
<template slot-scope="{row}">
<el-select v-if="isEditing(row)" v-model="editRow.rollShape"
size="mini" style="width:84px">
<el-option label="平" value="平" />
<el-option label="凸" value="凸" />
<el-option label="凹" value="凹" />
</el-select>
<span v-else>{{ row.rollShape || '' }}</span>
</template>
</el-table-column>
<!-- 探伤结果 -->
<el-table-column label="探伤结果" align="center" width="110">
<template slot-scope="{row}">
<el-select v-if="isEditing(row)" v-model="editRow.flawResult"
size="mini" style="width:94px">
<el-option label="合格" value="合格" />
<el-option label="不合格" value="不合格" />
</el-select>
<el-tag v-else size="mini" :type="row.flawResult === '合格' ? 'success' : 'danger'">
{{ row.flawResult || '—' }}
</el-tag>
</template>
</el-table-column>
<!-- 硬度 -->
<el-table-column label="硬度" align="center" width="80">
<template slot-scope="{row}">
<el-input v-if="isEditing(row)" v-model.number="editRow.hardness"
type="number" size="mini" style="width:64px" />
<span v-else>{{ row.hardness || '' }}</span>
</template>
</el-table-column>
<!-- 操作者自动填入仅展示 -->
<el-table-column label="操作者" align="center" width="100">
<template slot-scope="{row}">
<el-input v-if="isEditing(row)" v-model="editRow.operator"
size="mini" placeholder="选填" />
<span v-else class="remark-text">{{ row.operator || '' }}</span>
<!-- <span :class="isEditing(row) ? 'auto-operator' : ''">
{{ isEditing(row) ? currentUserName : (row.operator || '—') }}
</span> -->
</template>
</el-table-column>
<!-- 备注 -->
<el-table-column label="备注" align="left" width="120">
<template slot-scope="{row}">
<el-input v-if="isEditing(row)" v-model="editRow.remark"
size="mini" placeholder="选填" />
<span v-else class="remark-text">{{ row.remark || '' }}</span>
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column label="操作" align="center" width="100" fixed="right">
<template slot-scope="{row}">
<template v-if="isEditing(row)">
<el-button size="mini" type="text" icon="el-icon-check"
:loading="grindSaving" @click="saveRow">保存</el-button>
<el-button size="mini" type="text" icon="el-icon-close"
style="color:#909399" @click="cancelEdit">取消</el-button>
</template>
<template v-else>
<el-button size="mini" type="text" icon="el-icon-edit"
:disabled="!!editRow" @click="startEdit(row)">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete"
style="color:#c5221f" :disabled="!!editRow" @click="handleDelete(row)">删除</el-button>
</template>
</template>
</el-table-column>
</el-table>
<!-- 月度汇总 -->
<div class="monthly-wrap" v-if="grindList.length > 0">
<div class="monthly-title">
<span>{{ currentYear }} 年月度汇总</span>
<el-button-group size="mini" style="margin-left:8px">
<el-button icon="el-icon-arrow-left" @click="changeYear(-1)" />
<el-button icon="el-icon-arrow-right" @click="changeYear(1)" />
</el-button-group>
</div>
<el-table :data="monthlyList" size="mini" border style="width:100%;margin-top:8px">
<el-table-column label="月份" prop="month" align="center" width="90" />
<el-table-column label="磨削次数" prop="grindCount" align="center" width="90" />
<el-table-column label="累计磨削量(mm)" prop="totalGrindAmount" align="center" min-width="120" />
</el-table>
</div>
</el-card>
</template>
</div>
</div>
</div>
</div>
@@ -251,14 +344,13 @@ import rollLineMixin from '../rollLineMixin'
export default {
name: 'GrindRoom',
mixins: [rollLineMixin],
dicts: ['mes_roll_operator'],
data() {
return {
// 产线列表
productionLines: [],
filterLineId: null,
lineTabOrder: [], // 本地记录的点击顺序(最近点过的在前)
lineTabOrder: [],
// 左侧辊列表
rollLoading: false,
allRolls: [],
filteredRolls: [],
@@ -266,32 +358,25 @@ export default {
filterType: '',
filterManufacturer: '',
// 右侧选中辊
selectedRollId: null,
selectedRoll: null,
// 磨削记录
grindLoading: false,
grindList: [],
// 月度汇总
currentYear: new Date().getFullYear(),
monthlyList: [],
// 行内编辑editRow 不为 null 时表示当前正在编辑/新增的行数据
// __isNew: true → 新增行;存在 grindId → 修改行
editRow: null,
grindSaving: false
}
},
computed: {
// 当前登录用户名RuoYi Plus 的 store 路径)
currentUserName() {
return this.$store.state.user.name || this.$store.getters.name || ''
},
// 产线 tab 按本地点击顺序排序
sortedProductionLines() {
const order = this.lineTabOrder
return [...this.productionLines].sort((a, b) => {
@@ -304,11 +389,15 @@ export default {
})
},
// 有效当前辊径:优先取 currentDia无则取最新磨削记录的磨后径
manufacturerOptions() {
const set = new Set()
this.allRolls.forEach(r => {
if (r.manufacturer) set.add(r.manufacturer)
})
return [...set].sort()
},
effectiveCurrentDia() {
// if (this.selectedRoll && this.selectedRoll.currentDia != null) {
// return parseFloat(this.selectedRoll.currentDia)
// }
if (this.grindList.length > 0) {
const latest = [...this.grindList].sort((a, b) => {
const ta = a.grindTime ? new Date(a.grindTime).getTime() : 0
@@ -316,13 +405,10 @@ export default {
return tb - ta
})[0]
if (latest && latest.diaAfter != null) return parseFloat(latest.diaAfter)
} else {
return null
}
return null
},
// 表格数据:新增时在顶部插入一个编辑行占位
tableData() {
if (this.editRow && this.editRow.__isNew) {
return [this.editRow, ...this.grindList]
@@ -331,20 +417,17 @@ export default {
}
},
created() {},
methods: {
onLineResolved() {
this.filterLineId = this.lineId
const uid = this.$store.state.user?.userId || 0
try { this.lineTabOrder = JSON.parse(localStorage.getItem(`grind_line_order_${uid}`) || '[]') } catch {}
try { this.lineTabOrder = JSON.parse(localStorage.getItem(`grind_line_order_${uid}`) || '[]') } catch { /* ignore */ }
listProductionLine({ pageNum: 1, pageSize: 100 }).then(res => {
this.productionLines = res.rows || []
})
this.loadRolls()
},
// ── 轧辊列表 ──────────────────────────────────────
loadRolls() {
this.rollLoading = true
listRollInfo({ pageNum: 1, pageSize: 500, lineId: this.filterLineId }).then(res => {
@@ -368,9 +451,9 @@ export default {
},
filterRolls() {
this.filteredRolls = this.allRolls.filter(r => {
const matchNo = !this.filterNo || r.rollNo.includes(this.filterNo)
const matchNo = !this.filterNo || r.rollNo.includes(this.filterNo)
const matchType = !this.filterType || r.rollType === this.filterType
const matchMfr = !this.filterManufacturer || (r.manufacturer || '').toLowerCase().includes(this.filterManufacturer.toLowerCase())
const matchMfr = !this.filterManufacturer || r.manufacturer === this.filterManufacturer
return matchNo && matchType && matchMfr
})
},
@@ -385,7 +468,6 @@ export default {
this.loadGrindList(r.rollId)
},
// ── 磨削记录 ──────────────────────────────────────
loadGrindList(rollId) {
this.grindLoading = true
listRollGrind(rollId).then(res => {
@@ -408,7 +490,6 @@ export default {
this.loadMonthlyStats()
},
// ── 行内编辑 ──────────────────────────────────────
isEditing(row) {
if (!this.editRow) return false
if (row.__isNew && this.editRow.__isNew) return true
@@ -421,20 +502,20 @@ export default {
startAdd() {
const now = new Date()
const pad = n => String(n).padStart(2, '0')
const grindTime = `${now.getFullYear()}-${pad(now.getMonth()+1)}-${pad(now.getDate())} ` +
const grindTime = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ` +
`${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`
this.editRow = {
__isNew: true,
rollId: this.selectedRollId,
__isNew: true,
rollId: this.selectedRollId,
grindTime,
team: undefined,
diaBefore: this.effectiveCurrentDia != null ? this.effectiveCurrentDia : undefined,
diaAfter: undefined,
rollShape: '平',
team: undefined,
diaBefore: this.effectiveCurrentDia != null ? this.effectiveCurrentDia : undefined,
diaAfter: undefined,
rollShape: '平',
flawResult: '合格',
hardness: undefined,
operator: this.currentUserName,
remark: undefined
hardness: undefined,
operator: this.currentUserName,
remark: undefined
}
},
startEdit(row) {
@@ -448,10 +529,7 @@ export default {
const r = this.editRow
if (!r.grindTime) { this.$modal.msgWarning('请填写磨削时间'); return }
if (r.diaBefore == null) { this.$modal.msgWarning('请填写磨前直径'); return }
if (r.diaAfter == null) { this.$modal.msgWarning('请填写磨后直径'); return }
// 自动带入操作人
r.operator = this.currentUserName
if (r.diaAfter == null) { this.$modal.msgWarning('请填写磨后直径'); return }
this.grindSaving = true
const isNew = !!r.__isNew
@@ -480,7 +558,6 @@ export default {
})
},
// ── 计算磨削量 ──────────────────────────────────────
grindAmountOf(row) {
const b = parseFloat(row.diaBefore)
const a = parseFloat(row.diaAfter)
@@ -488,7 +565,6 @@ export default {
return '—'
},
// 辅助
statusLabel(s) {
return { Online: '在线', Standby: '备用', Offline: '离线', Scrapped: '报废' }[s] || s
}
@@ -500,7 +576,7 @@ export default {
.grind-page { background: #f4f5f7; height: 100%; }
.grind-layout { display: flex; gap: 12px; height: 100%; }
/* 产线 Tab */
/* ── 左侧产线 Tab ── */
.line-tabs {
width: 64px;
flex-shrink: 0;
@@ -530,31 +606,87 @@ export default {
font-weight: 600;
}
/* 轧辊列表 */
.grind-left { width: 220px; flex-shrink: 0; }
.grind-right { flex: 1; min-width: 0; }
/* ── 右侧主体 ── */
.grind-main {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 10px;
}
.grind-card { border: 1px solid #dcdee0; border-radius: 4px; }
.h-full { height: calc(100vh - 120px); display: flex; flex-direction: column; }
/* 顶部检索栏 */
.search-bar {
display: flex;
align-items: center;
gap: 20px;
padding: 10px 14px;
background: #fff;
border: 1px solid #dcdee0;
border-radius: 4px;
flex-shrink: 0;
}
/* 下方内容区:左右分栏 */
.content-area {
flex: 1;
min-height: 0;
display: flex;
gap: 10px;
}
/* 左侧轧辊列表面板 */
.roll-list-panel {
width: 220px;
flex-shrink: 0;
height: calc(100vh - 140px);
overflow-y: auto;
}
/* 右侧明细面板 */
.detail-panel {
flex: 1;
min-width: 0;
overflow-y: auto;
}
/* 明细卡片 */
.detail-card {
border: 1px solid #dcdee0;
border-radius: 4px;
}
.detail-card ::v-deep .el-card__body {
overflow: auto;
}
/* 通用卡片 */
.panel-card {
border: 1px solid #dcdee0;
border-radius: 4px;
height: 100%;
display: flex;
flex-direction: column;
}
.panel-card ::v-deep .el-card__body {
flex: 1;
min-height: 0;
overflow-y: auto;
}
.card-header { display: flex; align-items: center; gap: 8px; }
.card-title { font-size: 13px; font-weight: 600; color: #3d4b5c; }
.card-count { font-size: 11px; color: #9aa0a6; background: #f0f2f5; padding: 1px 8px; border-radius: 10px; margin-left: auto; }
/* 辊列表 */
.roll-filter { padding: 0 0 4px; }
::v-deep .el-card .el-card__body {
overflow-y: scroll;
overflow-x: hidden;
}
.roll-list { overflow-y: auto; flex: 1; min-height: 0; padding: 0; }
/* 辊列表 */
.roll-list { padding: 0; }
.roll-item { padding: 8px 12px; cursor: pointer; border-bottom: 1px solid #f0f2f5; }
.roll-item:hover { background: #f5f7fa; }
.roll-item--active { background: #e8f4ff !important; border-left: 3px solid #409eff; }
.ri-no { font-family: 'Consolas', monospace; font-size: 13px; font-weight: 600; color: #1f2329; }
.ri-meta { display: flex; align-items: center; gap: 6px; margin-top: 3px; }
.ri-dia { font-size: 11px; color: #9aa0a6; }
.ri-no { font-family: 'Consolas', monospace; font-size: 13px; font-weight: 600; color: #1f2329; }
.ri-meta { display: flex; align-items: center; gap: 6px; margin-top: 3px; }
.ri-dia { font-size: 11px; color: #9aa0a6; }
.ri-manufacturer { font-size: 10px; color: #909399; margin-top: 2px; }
.ri-line { font-size: 10px; color: #b0b3bb; margin-top: 2px; }
.ri-line { font-size: 10px; color: #b0b3bb; margin-top: 2px; }
.ri-status { font-size: 11px; }
.roll-empty { text-align: center; color: #c0c4cc; padding: 20px 0; font-size: 12px; }
@@ -582,17 +714,18 @@ export default {
/* 行内编辑 */
.computed-val { color: #409eff; font-weight: 600; font-size: 13px; }
.auto-operator { color: #0a7c42; font-size: 12px; }
.remark-text { font-size: 12px; color: #5f6368; }
/* 去掉 number input 的默认上下箭头,保持表格整洁 */
.el-table :deep(input[type=number]::-webkit-inner-spin-button),
.el-table :deep(input[type=number]::-webkit-outer-spin-button) { -webkit-appearance: none; }
.el-table :deep(input[type=number]) { -moz-appearance: textfield; }
</style>
<!-- 编辑行高亮 scoped作用于 el-table row-class-name -->
<style>
.el-table .editing-row { background: #fffbf0 !important; }
.el-table .editing-row:hover > td { background: #fffbf0 !important; }
.el-table ::v-deep .cell {
padding: 0;
}
</style>

View File

@@ -56,11 +56,6 @@
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="queryParams.remark" placeholder="请输入备注" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>