2 changed files with 730 additions and 0 deletions
@ -0,0 +1,25 @@ |
|||||
|
import request from '@/utils/httpRequest' |
||||
|
|
||||
|
export function routingOperationsSearch (data) { |
||||
|
return request({ |
||||
|
url: request.adornUrl('/plm/routingOperations/search'), |
||||
|
method: 'post', |
||||
|
data: request.adornData(data) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function routingOperationsBatchSave (data) { |
||||
|
return request({ |
||||
|
url: request.adornUrl('/plm/routingOperations/batchSave'), |
||||
|
method: 'post', |
||||
|
data: request.adornData(data) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export function routingOperationsGetDesc (data) { |
||||
|
return request({ |
||||
|
url: request.adornUrl('/plm/routingOperations/getDesc'), |
||||
|
method: 'post', |
||||
|
data: request.adornData(data) |
||||
|
}) |
||||
|
} |
||||
@ -0,0 +1,705 @@ |
|||||
|
<template> |
||||
|
<div class="mod-config routing-operations" ref="pageRoot"> |
||||
|
<el-form |
||||
|
:inline="true" |
||||
|
label-position="top" |
||||
|
:model="searchData" |
||||
|
@keyup.enter.native="getDataList()"> |
||||
|
<el-form-item label="物料编码"> |
||||
|
<el-input v-model="searchData.partNo" clearable style="width: 120px" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="物料名称"> |
||||
|
<el-input v-model="searchData.partDesc" clearable style="width: 150px" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="工艺类型"> |
||||
|
<el-select v-model="searchData.routingType" clearable style="width: 150px"> |
||||
|
<el-option label="Manufacturing" value="Manufacturing"></el-option> |
||||
|
<el-option label="Repair" value="Repair"></el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="Routing版本号"> |
||||
|
<el-input v-model="searchData.routingRevision" clearable style="width: 120px" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="替代号"> |
||||
|
<el-input v-model="searchData.alternativeNo" clearable style="width: 120px" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="工序编码"> |
||||
|
<el-input v-model="searchData.operationNo" clearable style="width: 120px" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="工序名称"> |
||||
|
<el-input v-model="searchData.operationName" clearable style="width: 150px" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item> |
||||
|
<span style="cursor: pointer" slot="label" @click="openWorkCenterChooser()"><a href="javascript:void(0)">加工中心</a></span> |
||||
|
<el-input v-model="searchData.workCenterNo" @change="workCenterBlur()" clearable style="width: 120px"></el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label=" "> |
||||
|
<el-button type="primary" :loading="queryLoading" @click="getDataList()">查询</el-button> |
||||
|
<el-button @click="openFindReplaceDialog">编辑</el-button> |
||||
|
<el-button type="success" :loading="saveLoading" :disabled="!hasAnyDirty" @click="saveModifications">保存</el-button> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<div class="rq"> |
||||
|
<el-table |
||||
|
ref="dataTable" |
||||
|
:height="height" |
||||
|
:data="dataList" |
||||
|
border |
||||
|
v-loading="dataListLoading" |
||||
|
:cell-class-name="tableCellClassName" |
||||
|
:row-style="rowStyle" |
||||
|
@row-click="onRowClick" |
||||
|
@cell-click="onTableCellClick" |
||||
|
style="width: 100%;"> |
||||
|
<el-table-column |
||||
|
v-for="(item, index) in columnList" |
||||
|
:key="index" |
||||
|
:sortable="item.columnSortable" |
||||
|
:prop="item.columnProp" |
||||
|
:header-align="item.headerAlign" |
||||
|
:show-overflow-tooltip="item.showOverflowTooltip" |
||||
|
:align="item.align" |
||||
|
:fixed="item.fixed === '' ? false : item.fixed" |
||||
|
:min-width="item.columnWidth" |
||||
|
:label="item.columnLabel"> |
||||
|
<template slot-scope="scope"> |
||||
|
<template v-if="!item.columnHidden && isEditableProp(item.columnProp)"> |
||||
|
<el-input |
||||
|
v-if="item.columnProp === 'workCenterNo' || item.columnProp === 'setupLaborClassNo' || item.columnProp === 'laborClassNo' || item.columnProp === 'runTimeCode'" |
||||
|
v-model="scope.row[item.columnProp]" |
||||
|
size="mini" |
||||
|
@blur="onStringPropBlur(scope.row, item.columnProp)" |
||||
|
:class="['ms-cell-editor', { 'ms-modified': isCellDirty(scope.row, item.columnProp) }]" /> |
||||
|
<el-input-number |
||||
|
v-else-if="item.columnProp === 'efficiencyFactor'" |
||||
|
v-model="scope.row[item.columnProp]" |
||||
|
:controls="false" |
||||
|
:step="0" |
||||
|
:min="0" |
||||
|
:max="100" |
||||
|
size="mini" |
||||
|
class="ms-num-input" |
||||
|
:class="{ 'ms-modified': isCellDirty(scope.row, item.columnProp) }" |
||||
|
style="width: 100%" /> |
||||
|
<el-input-number |
||||
|
v-else-if="item.columnProp === 'crewSize'" |
||||
|
v-model="scope.row[item.columnProp]" |
||||
|
:controls="false" |
||||
|
:step="1" |
||||
|
size="mini" |
||||
|
class="ms-num-input" |
||||
|
:class="{ 'ms-modified': isCellDirty(scope.row, item.columnProp) }" |
||||
|
style="width: 100%" /> |
||||
|
<el-input-number |
||||
|
v-else |
||||
|
v-model="scope.row[item.columnProp]" |
||||
|
:controls="false" |
||||
|
:step="0" |
||||
|
:precision="10" |
||||
|
size="mini" |
||||
|
class="ms-num-input" |
||||
|
:class="{ 'ms-modified': isCellDirty(scope.row, item.columnProp) }" |
||||
|
style="width: 100%" /> |
||||
|
</template> |
||||
|
<template v-else-if="!item.columnHidden && ['machSetupTime', 'laborSetupTime', 'setupCrewSize', 'machRunFactor', 'laborRunFactor', 'efficiencyFactor', 'crewSize'].includes(item.columnProp)"> |
||||
|
<span>{{ formatNumber(scope.row[item.columnProp]) }}</span> |
||||
|
</template> |
||||
|
<template v-else-if="!item.columnHidden"> |
||||
|
<span>{{ scope.row[item.columnProp] }}</span> |
||||
|
</template> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
|
||||
|
<Chooselist ref="baseList" @getBaseData="getBaseData"></Chooselist> |
||||
|
|
||||
|
<el-dialog |
||||
|
title="查找和替换" |
||||
|
:visible.sync="findReplaceVisible" |
||||
|
width="450px" |
||||
|
v-drag |
||||
|
:modal="false" |
||||
|
custom-class="ms-find-replace-dialog" |
||||
|
append-to-body |
||||
|
@closed="onFindReplaceClosed"> |
||||
|
<div class="fr-container"> |
||||
|
<div class="fr-form"> |
||||
|
<div class="fr-row"> |
||||
|
<span class="fr-label">查找内容:</span> |
||||
|
<el-input v-model="frFindWhat" ref="frFindInput" size="small" clearable class="fr-input" /> |
||||
|
</div> |
||||
|
<div class="fr-row"> |
||||
|
<span class="fr-label">替换为:</span> |
||||
|
<el-input v-model="frReplaceWith" size="small" clearable class="fr-input" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="fr-buttons"> |
||||
|
<el-button size="small" @click="frFindNext">查找下一个</el-button> |
||||
|
<el-button size="small" @click="findReplaceVisible = false">取消</el-button> |
||||
|
<el-button size="small" type="primary" plain @click="frReplaceOne">替换</el-button> |
||||
|
<el-button size="small" type="primary" plain @click="frReplaceAll">全部替换</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
|
||||
|
<el-pagination |
||||
|
style="margin-top: 0px" |
||||
|
@size-change="sizeChangeHandle" |
||||
|
@current-change="currentChangeHandle" |
||||
|
:current-page="pageIndex" |
||||
|
:page-sizes="[20, 50, 100, 200, 500]" |
||||
|
:page-size="pageSize" |
||||
|
:total="totalPage" |
||||
|
layout="total, sizes, prev, pager, next, jumper" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { routingOperationsSearch, routingOperationsBatchSave, routingOperationsGetDesc } from '@/api/part/routingOperations.js' |
||||
|
import Chooselist from '@/views/modules/common/Chooselist' |
||||
|
import { verifyData } from '@/api/chooselist/chooselist.js' |
||||
|
|
||||
|
const EDITABLE_PROPS = ['workCenterNo', 'machSetupTime', 'laborSetupTime', 'setupLaborClassNo', 'setupCrewSize', 'machRunFactor', 'laborRunFactor', 'runTimeCode', 'laborClassNo', 'efficiencyFactor', 'crewSize'] |
||||
|
|
||||
|
export default { |
||||
|
name: 'RoutingOperations', |
||||
|
components: { |
||||
|
Chooselist |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
height: 200, |
||||
|
pageIndex: 1, |
||||
|
pageSize: 50, |
||||
|
totalPage: 0, |
||||
|
queryLoading: false, |
||||
|
saveLoading: false, |
||||
|
dataListLoading: false, |
||||
|
dataList: [], |
||||
|
currentRow: null, |
||||
|
activeFindColumn: null, |
||||
|
lastFindRowIndex: -1, |
||||
|
findHighlightRowIndex: -1, |
||||
|
findHighlightColumnProp: '', |
||||
|
findReplaceVisible: false, |
||||
|
frFindWhat: '', |
||||
|
frReplaceWith: '', |
||||
|
searchData: { |
||||
|
site: this.$store.state.user.site, |
||||
|
partNo: '', |
||||
|
partDesc: '', |
||||
|
routingType: '', |
||||
|
routingRevision: '', |
||||
|
alternativeNo: '', |
||||
|
operationNo: '', |
||||
|
operationName: '', |
||||
|
workCenterNo: '', |
||||
|
page: 1, |
||||
|
limit: 50 |
||||
|
}, |
||||
|
columnList: [ |
||||
|
{ columnProp: 'site', columnLabel: '工厂', headerAlign: 'center', align: 'center', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 80 }, |
||||
|
{ columnProp: 'partNo', columnLabel: '物料编码', headerAlign: 'center', align: 'left', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 120 }, |
||||
|
{ columnProp: 'partDesc', columnLabel: '物料名称', headerAlign: 'center', align: 'left', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 180 }, |
||||
|
{ columnProp: 'routingType', columnLabel: '工艺类型', headerAlign: 'center', align: 'center', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 120 }, |
||||
|
{ columnProp: 'routingRevision', columnLabel: 'Routing版本号', headerAlign: 'center', align: 'center', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 120 }, |
||||
|
{ columnProp: 'alternativeNo', columnLabel: '替代号', headerAlign: 'center', align: 'center', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 100 }, |
||||
|
{ columnProp: 'status', columnLabel: '状态', headerAlign: 'center', align: 'center', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 100 }, |
||||
|
{ columnProp: 'operationNo', columnLabel: '工序编码', headerAlign: 'center', align: 'center', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 90 }, |
||||
|
{ columnProp: 'operationName', columnLabel: '工序名称', headerAlign: 'center', align: 'left', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 150 }, |
||||
|
{ columnProp: 'workCenterNo', columnLabel: '加工中心编码', headerAlign: 'center', align: 'center', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 120 }, |
||||
|
{ columnProp: 'workCenterDesc', columnLabel: '加工中心描述', headerAlign: 'center', align: 'left', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 150 }, |
||||
|
{ columnProp: 'machSetupTime', columnLabel: '机器调机时间', headerAlign: 'center', align: 'right', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 120 }, |
||||
|
{ columnProp: 'machRunFactor', columnLabel: '机器单位产出', headerAlign: 'center', align: 'right', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 120 }, |
||||
|
{ columnProp: 'setupLaborClassNo', columnLabel: '调机过程中人员等级', headerAlign: 'center', align: 'center', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 150 }, |
||||
|
{ columnProp: 'setupLaborClassDesc', columnLabel: '调机人员等级描述', headerAlign: 'center', align: 'left', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 150 }, |
||||
|
{ columnProp: 'laborSetupTime', columnLabel: '人工调机时间', headerAlign: 'center', align: 'right', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 120 }, |
||||
|
{ columnProp: 'setupCrewSize', columnLabel: '调机过程中人数', headerAlign: 'center', align: 'right', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 130 }, |
||||
|
{ columnProp: 'laborClassNo', columnLabel: '人员等级', headerAlign: 'center', align: 'center', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 100 }, |
||||
|
{ columnProp: 'laborClassDesc', columnLabel: '人员等级描述', headerAlign: 'center', align: 'left', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 150 }, |
||||
|
{ columnProp: 'laborRunFactor', columnLabel: '人工单位产出', headerAlign: 'center', align: 'right', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 120 }, |
||||
|
{ columnProp: 'runTimeCode', columnLabel: '产出单位', headerAlign: 'center', align: 'center', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 100 }, |
||||
|
{ columnProp: 'crewSize', columnLabel: '生产过程中人数', headerAlign: 'center', align: 'right', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 130 }, |
||||
|
{ columnProp: 'phaseInDate', columnLabel: '生效日期', headerAlign: 'center', align: 'center', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 160 }, |
||||
|
{ columnProp: 'phaseOutDate', columnLabel: '失效日期', headerAlign: 'center', align: 'center', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 160 }, |
||||
|
{ columnProp: 'overlap', columnLabel: '重叠', headerAlign: 'center', align: 'right', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 100 }, |
||||
|
{ columnProp: 'efficiencyFactor', columnLabel: '效率%', headerAlign: 'center', align: 'right', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 90 }, |
||||
|
{ columnProp: 'outsideOpItem', columnLabel: '外协采购料号', headerAlign: 'center', align: 'left', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 150 }, |
||||
|
{ columnProp: 'createDate', columnLabel: '创建日期', headerAlign: 'center', align: 'center', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 160 }, |
||||
|
{ columnProp: 'machineNo', columnLabel: '机台', headerAlign: 'center', align: 'left', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 120 }, |
||||
|
{ columnProp: 'noteText', columnLabel: '备注', headerAlign: 'center', align: 'left', columnSortable: false, columnHidden: false, showOverflowTooltip: true, fixed: '', columnWidth: 160 } |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
hasAnyDirty () { |
||||
|
return this.dataList.some(row => EDITABLE_PROPS.some(p => this.isCellDirty(row, p))) |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
searchData: { |
||||
|
deep: true, |
||||
|
handler: function () { |
||||
|
if (typeof this.searchData.partNo === 'string') { |
||||
|
this.searchData.partNo = this.searchData.partNo.toUpperCase() |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
this.$nextTick(() => { |
||||
|
this.height = window.innerHeight - 170 |
||||
|
}) |
||||
|
}, |
||||
|
methods: { |
||||
|
isEditableProp (prop) { |
||||
|
return EDITABLE_PROPS.includes(prop) |
||||
|
}, |
||||
|
openFindReplaceDialog () { |
||||
|
if (!this.activeFindColumn) { |
||||
|
this.$message.warning('请先单击选择一个可编辑列中的单元格') |
||||
|
return |
||||
|
} |
||||
|
if (this.lastFindRowIndex >= 0 && this.lastFindRowIndex < this.dataList.length) { |
||||
|
const val = this.dataList[this.lastFindRowIndex][this.activeFindColumn] |
||||
|
this.frFindWhat = val === null || val === undefined ? '' : String(this.formatNumber(val)) |
||||
|
} |
||||
|
this.findReplaceVisible = true |
||||
|
this.$nextTick(() => { |
||||
|
if (this.$refs.frFindInput && this.$refs.frFindInput.focus) { |
||||
|
this.$refs.frFindInput.focus() |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
onFindReplaceClosed () { |
||||
|
this.frFindWhat = '' |
||||
|
this.frReplaceWith = '' |
||||
|
}, |
||||
|
rowStyle ({ row }) { |
||||
|
if (this.currentRow === row) { |
||||
|
return { 'background-color': '#E8F7F6', cursor: 'pointer' } |
||||
|
} |
||||
|
return { cursor: 'pointer' } |
||||
|
}, |
||||
|
onRowClick (row) { |
||||
|
this.currentRow = row |
||||
|
}, |
||||
|
setHighlight (rowIndex, colProp) { |
||||
|
if (this.findHighlightRowIndex >= 0 && this.findHighlightRowIndex < this.dataList.length) { |
||||
|
this.$set(this.dataList[this.findHighlightRowIndex], '_highlightCol', '') |
||||
|
} |
||||
|
this.findHighlightRowIndex = rowIndex |
||||
|
this.findHighlightColumnProp = colProp |
||||
|
if (rowIndex >= 0 && rowIndex < this.dataList.length) { |
||||
|
this.$set(this.dataList[rowIndex], '_highlightCol', colProp) |
||||
|
} |
||||
|
}, |
||||
|
tableCellClassName ({ row, column }) { |
||||
|
let p = column.property |
||||
|
if (row._highlightCol === p) { |
||||
|
return 'ms-find-highlight' |
||||
|
} |
||||
|
return '' |
||||
|
}, |
||||
|
onTableCellClick (row, column) { |
||||
|
let p = column.property |
||||
|
if (!this.isEditableProp(p)) return |
||||
|
this.activeFindColumn = p |
||||
|
const idx = this.dataList.indexOf(row) |
||||
|
this.lastFindRowIndex = idx |
||||
|
this.setHighlight(idx, p) |
||||
|
}, |
||||
|
normalizeRowFromServer (raw) { |
||||
|
const row = { ...raw } |
||||
|
row.machSetupTime = row.machSetupTime === null || row.machSetupTime === undefined ? null : Number(row.machSetupTime) |
||||
|
row.laborSetupTime = row.laborSetupTime === null || row.laborSetupTime === undefined ? null : Number(row.laborSetupTime) |
||||
|
row.setupCrewSize = row.setupCrewSize === null || row.setupCrewSize === undefined ? null : Number(row.setupCrewSize) |
||||
|
row.machRunFactor = row.machRunFactor === null || row.machRunFactor === undefined ? null : Number(row.machRunFactor) |
||||
|
row.laborRunFactor = row.laborRunFactor === null || row.laborRunFactor === undefined ? null : Number(row.laborRunFactor) |
||||
|
row.efficiencyFactor = row.efficiencyFactor === null || row.efficiencyFactor === undefined ? null : Number(row.efficiencyFactor) |
||||
|
row.crewSize = row.crewSize === null || row.crewSize === undefined ? null : Number(row.crewSize) |
||||
|
row._original = { |
||||
|
workCenterNo: row.workCenterNo, |
||||
|
machSetupTime: row.machSetupTime, |
||||
|
laborSetupTime: row.laborSetupTime, |
||||
|
setupLaborClassNo: row.setupLaborClassNo, |
||||
|
setupCrewSize: row.setupCrewSize, |
||||
|
machRunFactor: row.machRunFactor, |
||||
|
laborRunFactor: row.laborRunFactor, |
||||
|
runTimeCode: row.runTimeCode, |
||||
|
laborClassNo: row.laborClassNo, |
||||
|
efficiencyFactor: row.efficiencyFactor, |
||||
|
crewSize: row.crewSize, |
||||
|
operationName: row.operationName, |
||||
|
ifsRowId: row.ifsRowId, |
||||
|
ifsRowVersion: row.ifsRowVersion |
||||
|
} |
||||
|
return row |
||||
|
}, |
||||
|
snapshotOriginal (row) { |
||||
|
row._original = { |
||||
|
workCenterNo: row.workCenterNo, |
||||
|
machSetupTime: row.machSetupTime, |
||||
|
laborSetupTime: row.laborSetupTime, |
||||
|
setupLaborClassNo: row.setupLaborClassNo, |
||||
|
setupCrewSize: row.setupCrewSize, |
||||
|
machRunFactor: row.machRunFactor, |
||||
|
laborRunFactor: row.laborRunFactor, |
||||
|
runTimeCode: row.runTimeCode, |
||||
|
laborClassNo: row.laborClassNo, |
||||
|
efficiencyFactor: row.efficiencyFactor, |
||||
|
crewSize: row.crewSize, |
||||
|
operationName: row.operationName, |
||||
|
ifsRowId: row.ifsRowId, |
||||
|
ifsRowVersion: row.ifsRowVersion |
||||
|
} |
||||
|
}, |
||||
|
normalizeForCompare (val, prop) { |
||||
|
if (['workCenterNo', 'setupLaborClassNo', 'laborClassNo', 'runTimeCode'].includes(prop)) { |
||||
|
if (prop === 'runTimeCode') return (val == null ? '' : String(val)).trim() |
||||
|
return (val == null ? '' : String(val)).trim().toUpperCase() |
||||
|
} |
||||
|
if (val === null || val === undefined || val === '') return '' |
||||
|
const n = Number(val) |
||||
|
if (Number.isNaN(n)) return String(val).trim() |
||||
|
return String(n) |
||||
|
}, |
||||
|
isCellDirty (row, prop) { |
||||
|
if (!row || !row._original) return false |
||||
|
return this.normalizeForCompare(row[prop], prop) !== this.normalizeForCompare(row._original[prop], prop) |
||||
|
}, |
||||
|
cellMatchesFind (val, findWhat) { |
||||
|
const needle = (findWhat || '').trim() |
||||
|
if (needle === '') return false |
||||
|
const col = this.activeFindColumn |
||||
|
if (!col) return false |
||||
|
if (['workCenterNo', 'setupLaborClassNo', 'laborClassNo', 'runTimeCode'].includes(col)) { |
||||
|
if (col === 'runTimeCode') return this.normalizeForCompare(val, col) === needle |
||||
|
return this.normalizeForCompare(val, col) === needle.toUpperCase() |
||||
|
} |
||||
|
return this.normalizeForCompare(val, col) === this.normalizeForCompare(needle, col) |
||||
|
}, |
||||
|
coerceColumnValue (prop, strVal) { |
||||
|
if (['workCenterNo', 'setupLaborClassNo', 'laborClassNo', 'runTimeCode'].includes(prop)) { |
||||
|
if (prop === 'runTimeCode') return (strVal || '').trim() |
||||
|
return (strVal || '').trim().toUpperCase() |
||||
|
} |
||||
|
const n = parseFloat(strVal) |
||||
|
if (Number.isNaN(n)) return null |
||||
|
return n |
||||
|
}, |
||||
|
frFindNext () { |
||||
|
const col = this.activeFindColumn |
||||
|
const needle = (this.frFindWhat || '').trim() |
||||
|
if (!col) { |
||||
|
this.$message.warning('未选择列') |
||||
|
return |
||||
|
} |
||||
|
if (needle === '') { |
||||
|
this.$message.warning('请输入查找内容') |
||||
|
return |
||||
|
} |
||||
|
const n = this.dataList.length |
||||
|
if (n === 0) return |
||||
|
const start = this.lastFindRowIndex + 1 |
||||
|
for (let k = 0; k < n; k++) { |
||||
|
const i = (start + k) % n |
||||
|
const val = this.dataList[i][col] |
||||
|
if (this.cellMatchesFind(val, needle)) { |
||||
|
this.lastFindRowIndex = i |
||||
|
this.setHighlight(i, col) |
||||
|
this.$nextTick(() => this.scrollToRow(i)) |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
this.$message.info('未找到匹配项') |
||||
|
}, |
||||
|
frReplaceOne () { |
||||
|
const col = this.findHighlightColumnProp |
||||
|
const rowIdx = this.findHighlightRowIndex |
||||
|
if (col == null || rowIdx < 0 || rowIdx >= this.dataList.length) { |
||||
|
this.$message.warning('请先使用「查找」定位单元格') |
||||
|
return |
||||
|
} |
||||
|
const row = this.dataList[rowIdx] |
||||
|
const nextVal = this.coerceColumnValue(col, this.frReplaceWith) |
||||
|
if (nextVal === null && !['workCenterNo', 'setupLaborClassNo', 'laborClassNo', 'runTimeCode'].includes(col)) { |
||||
|
this.$message.warning('替换为的数值无效') |
||||
|
return |
||||
|
} |
||||
|
this.$set(row, col, nextVal === null ? '' : nextVal) |
||||
|
this.updateDescIfNeeded(row, col) |
||||
|
}, |
||||
|
frReplaceAll () { |
||||
|
const col = this.activeFindColumn |
||||
|
const needle = (this.frFindWhat || '').trim() |
||||
|
if (!col) { |
||||
|
this.$message.warning('未选择列') |
||||
|
return |
||||
|
} |
||||
|
if (needle === '') { |
||||
|
this.$message.warning('请输入查找内容') |
||||
|
return |
||||
|
} |
||||
|
let cnt = 0 |
||||
|
this.dataList.forEach(row => { |
||||
|
if (this.cellMatchesFind(row[col], needle)) { |
||||
|
const nextVal = this.coerceColumnValue(col, this.frReplaceWith) |
||||
|
if (nextVal !== null || ['workCenterNo', 'setupLaborClassNo', 'laborClassNo', 'runTimeCode'].includes(col)) { |
||||
|
this.$set(row, col, nextVal === null ? '' : nextVal) |
||||
|
this.updateDescIfNeeded(row, col) |
||||
|
cnt++ |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
this.$message.success(`已替换 ${cnt} 处`) |
||||
|
}, |
||||
|
scrollToRow (rowIndex) { |
||||
|
const table = this.$refs.dataTable |
||||
|
if (!table || !table.$el) return |
||||
|
const rows = table.$el.querySelectorAll('.el-table__body-wrapper tbody tr') |
||||
|
if (rows[rowIndex]) { |
||||
|
rows[rowIndex].scrollIntoView({ block: 'nearest', behavior: 'smooth' }) |
||||
|
} |
||||
|
}, |
||||
|
updateDescIfNeeded (row, prop) { |
||||
|
if (prop === 'workCenterNo' || prop === 'setupLaborClassNo' || prop === 'laborClassNo') { |
||||
|
if (!row[prop]) { |
||||
|
if (prop === 'workCenterNo') row.workCenterDesc = '' |
||||
|
if (prop === 'setupLaborClassNo') row.setupLaborClassDesc = '' |
||||
|
if (prop === 'laborClassNo') row.laborClassDesc = '' |
||||
|
return |
||||
|
} |
||||
|
const typeMap = { |
||||
|
'workCenterNo': 'workCenter', |
||||
|
'setupLaborClassNo': 'laborClass', |
||||
|
'laborClassNo': 'laborClass' |
||||
|
} |
||||
|
routingOperationsGetDesc({ |
||||
|
site: row.site, |
||||
|
type: typeMap[prop], |
||||
|
code: row[prop] |
||||
|
}).then(({ data }) => { |
||||
|
if (data && data.code === 0) { |
||||
|
if (prop === 'workCenterNo') row.workCenterDesc = data.desc |
||||
|
if (prop === 'setupLaborClassNo') row.setupLaborClassDesc = data.desc |
||||
|
if (prop === 'laborClassNo') row.laborClassDesc = data.desc |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
onStringPropBlur (row, prop) { |
||||
|
if (row[prop]) { |
||||
|
if (prop === 'runTimeCode') { |
||||
|
row[prop] = String(row[prop]).trim() |
||||
|
} else { |
||||
|
row[prop] = String(row[prop]).trim().toUpperCase() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Update descriptions |
||||
|
this.updateDescIfNeeded(row, prop) |
||||
|
}, |
||||
|
openWorkCenterChooser () { |
||||
|
this.$nextTick(() => { |
||||
|
this.$refs.baseList.init(107, this.searchData.workCenterNo) |
||||
|
}) |
||||
|
}, |
||||
|
getBaseData (val) { |
||||
|
if (val && val.work_center_no) { |
||||
|
this.searchData.workCenterNo = val.work_center_no |
||||
|
} |
||||
|
}, |
||||
|
workCenterBlur () { |
||||
|
let tempData = { |
||||
|
tagno: 107, |
||||
|
conditionSql: " and work_center_no = '" + this.searchData.workCenterNo + "'" + " and site = '" + this.searchData.site + "'" |
||||
|
} |
||||
|
verifyData(tempData).then(({ data }) => { |
||||
|
if (data && data.code === 0) { |
||||
|
if (data.baseListData.length > 0) { |
||||
|
this.searchData.workCenterNo = data.baseListData[0].work_center_no |
||||
|
} else { |
||||
|
this.searchData.workCenterNo = '' |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
formatNumber (value) { |
||||
|
if (value === null || value === undefined || value === '') return value |
||||
|
let numStr = String(value) |
||||
|
if (numStr.includes('e') || numStr.includes('E')) { |
||||
|
return Number(value).toLocaleString('fullwide', { useGrouping: false, maximumFractionDigits: 20 }) |
||||
|
} |
||||
|
return value |
||||
|
}, |
||||
|
sizeChangeHandle (val) { |
||||
|
this.pageSize = val |
||||
|
this.pageIndex = 1 |
||||
|
this.getDataList() |
||||
|
}, |
||||
|
currentChangeHandle (val) { |
||||
|
this.pageIndex = val |
||||
|
this.getDataList() |
||||
|
}, |
||||
|
hasSearchCondition () { |
||||
|
const s = this.searchData |
||||
|
return !!(s.partNo || s.partDesc || s.routingType || s.routingRevision || |
||||
|
s.alternativeNo || s.operationNo || s.operationName || s.workCenterNo) |
||||
|
}, |
||||
|
getDataList () { |
||||
|
if (!this.hasSearchCondition()) { |
||||
|
this.$message.warning('请至少填写一项查询条件') |
||||
|
return |
||||
|
} |
||||
|
this.searchData.limit = this.pageSize |
||||
|
this.searchData.page = this.pageIndex |
||||
|
this.queryLoading = true |
||||
|
this.dataListLoading = true |
||||
|
routingOperationsSearch(this.searchData) |
||||
|
.then(({ data }) => { |
||||
|
if (data.code === 0) { |
||||
|
const list = (data.page.list || []).map(r => this.normalizeRowFromServer(r)) |
||||
|
this.dataList = list |
||||
|
this.pageIndex = data.page.currPage |
||||
|
this.pageSize = data.page.pageSize |
||||
|
this.totalPage = data.page.totalCount |
||||
|
this.activeFindColumn = null |
||||
|
this.lastFindRowIndex = -1 |
||||
|
this.findHighlightRowIndex = -1 |
||||
|
this.findHighlightColumnProp = '' |
||||
|
this.currentRow = null |
||||
|
} else { |
||||
|
this.$message.error(data.msg || '查询失败') |
||||
|
} |
||||
|
}) |
||||
|
.catch(() => { |
||||
|
this.$message.error('请求失败') |
||||
|
}) |
||||
|
.finally(() => { |
||||
|
this.queryLoading = false |
||||
|
this.dataListLoading = false |
||||
|
}) |
||||
|
}, |
||||
|
buildPayload (row) { |
||||
|
return { |
||||
|
site: row.site, |
||||
|
partNo: row.partNo, |
||||
|
routingRevision: row.routingRevision, |
||||
|
routingType: row.routingType, |
||||
|
alternativeNo: row.alternativeNo == null ? '' : String(row.alternativeNo), |
||||
|
operationId: row.operationId, |
||||
|
operationNo: row.operationNo, |
||||
|
operationName: row.operationName, |
||||
|
workCenterNo: row.workCenterNo, |
||||
|
machSetupTime: row.machSetupTime, |
||||
|
laborSetupTime: row.laborSetupTime, |
||||
|
setupLaborClassNo: row.setupLaborClassNo, |
||||
|
setupCrewSize: row.setupCrewSize, |
||||
|
machRunFactor: row.machRunFactor, |
||||
|
laborRunFactor: row.laborRunFactor, |
||||
|
runTimeCode: row.runTimeCode, |
||||
|
laborClassNo: row.laborClassNo, |
||||
|
efficiencyFactor: row.efficiencyFactor, |
||||
|
crewSize: row.crewSize, |
||||
|
ifsRowId: row.ifsRowId, |
||||
|
ifsRowVersion: row.ifsRowVersion, |
||||
|
updateBy: this.$store.state.user.name |
||||
|
} |
||||
|
}, |
||||
|
async saveModifications () { |
||||
|
const dirtyRows = this.dataList.filter(row => EDITABLE_PROPS.some(p => this.isCellDirty(row, p))) |
||||
|
if (dirtyRows.length === 0) { |
||||
|
this.$message.warning('没有需要保存的修改') |
||||
|
return |
||||
|
} |
||||
|
for (const row of dirtyRows) { |
||||
|
if (!row.workCenterNo) { |
||||
|
this.$message.warning('加工中心编码不能为空') |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
const items = dirtyRows.map(r => this.buildPayload(r)) |
||||
|
this.saveLoading = true |
||||
|
routingOperationsBatchSave({ items }) |
||||
|
.then(({ data }) => { |
||||
|
if (data && data.code === 0) { |
||||
|
this.$message.success('保存成功') |
||||
|
dirtyRows.forEach(r => this.snapshotOriginal(r)) |
||||
|
} else { |
||||
|
this.$alert((data && data.msg) || '保存失败', '错误', { confirmButtonText: '确定' }) |
||||
|
} |
||||
|
}) |
||||
|
.catch(() => { |
||||
|
this.$message.error('保存请求失败') |
||||
|
}) |
||||
|
.finally(() => { |
||||
|
this.saveLoading = false |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.ms-hint { |
||||
|
font-size: 12px; |
||||
|
color: #909399; |
||||
|
margin: 0 0 8px 0; |
||||
|
} |
||||
|
.ms-cell-editor.ms-modified >>> .el-input__inner { |
||||
|
color: #f56c6c; |
||||
|
} |
||||
|
.ms-num-input.ms-modified >>> .el-input__inner { |
||||
|
color: #f56c6c; |
||||
|
} |
||||
|
|
||||
|
/* 查找替换对话框样式 */ |
||||
|
.fr-container { |
||||
|
display: flex; |
||||
|
gap: 15px; |
||||
|
} |
||||
|
.fr-form { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 15px; |
||||
|
margin-top: 5px; |
||||
|
} |
||||
|
.fr-row { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
.fr-label { |
||||
|
width: 70px; |
||||
|
font-size: 13px; |
||||
|
color: #606266; |
||||
|
} |
||||
|
.fr-input { |
||||
|
flex: 1; |
||||
|
} |
||||
|
.fr-buttons { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 10px; |
||||
|
width: 100px; |
||||
|
margin-top: -30px; |
||||
|
} |
||||
|
.fr-buttons .el-button { |
||||
|
margin-left: 0; |
||||
|
width: 100%; |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
<style> |
||||
|
.routing-operations .ms-find-highlight { |
||||
|
background-color: #ffc107 !important; |
||||
|
} |
||||
|
.ms-find-replace-dialog .el-dialog__body { |
||||
|
padding: 15px 20px 20px; |
||||
|
} |
||||
|
.ms-find-replace-dialog .el-dialog__header { |
||||
|
padding: 15px 20px 10px; |
||||
|
} |
||||
|
</style> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue