parent
cb841c3136
commit
babc35eea1
7 changed files with 568 additions and 15 deletions
@ -0,0 +1,28 @@ |
||||
import request from '@/axios'; |
||||
|
||||
// 获取列表
|
||||
export const getList = (params) => { |
||||
return request({ |
||||
url: '/api/blade-desk/mesOemStandardProcess/page', |
||||
method: 'get', |
||||
params, |
||||
}); |
||||
}; |
||||
|
||||
// 删除
|
||||
export const removeItem = params => { |
||||
return request({ |
||||
url: '/api/blade-desk/mesOemStandardProcess/remove', |
||||
method: 'post', |
||||
params |
||||
}); |
||||
}; |
||||
|
||||
// 提交
|
||||
export const saveData = data => { |
||||
return request({ |
||||
url: '/api/blade-desk/mesOemStandardProcess/submit', |
||||
method: 'post', |
||||
data |
||||
}); |
||||
}; |
||||
@ -0,0 +1,272 @@ |
||||
<template> |
||||
<basic-container> |
||||
<!-- 标准工序代码 --> |
||||
<avue-crud |
||||
:option="option" |
||||
:table-loading="loading" |
||||
:data="data" |
||||
v-model="form" |
||||
v-model:page="page" |
||||
ref="crud" |
||||
@search-change="searchChange" |
||||
@search-reset="searchReset" |
||||
@current-change="currentChange" |
||||
@size-change="sizeChange" |
||||
@refresh-change="refreshChange" |
||||
@selection-change="selectionChange" |
||||
@on-load="onLoad" |
||||
@cell-click="cellClick" |
||||
@sort-change="sortChange" |
||||
> |
||||
<template #menu-right> |
||||
<el-button type="primary" @click="handleImport">导入</el-button> |
||||
</template> |
||||
<template #menu-left> |
||||
<el-button type="primary" @click="handleMaintain">维护</el-button> |
||||
<el-button type="danger" @click="handleDelete">删除</el-button> |
||||
</template> |
||||
</avue-crud> |
||||
<basic-import v-if="isShowImport" title="导入" :isShow="isShowImport" |
||||
templateUrl="/blade-desk/mesOemStandardProcess/download-excel-template" |
||||
templateName="标准工序代码.xls" |
||||
importUrl="/blade-desk/mesOemStandardProcess/import-excel" |
||||
@closeDialog="closeDialog"> |
||||
</basic-import> |
||||
<maintainDailog |
||||
v-if="showDialog" |
||||
:showDialog="showDialog" |
||||
@closeDialog="closeDialog" |
||||
:selectData="selectionList" |
||||
> |
||||
</maintainDailog> |
||||
</basic-container> |
||||
</template> |
||||
|
||||
<script> |
||||
import basicImport from '@/components/basic-import/main.vue' |
||||
import maintainDailog from "./maintainDailog.vue" |
||||
import {getList,removeItem} from "@/api/oem/standardProcedure" |
||||
export default { |
||||
components:{ |
||||
basicImport, |
||||
maintainDailog |
||||
}, |
||||
data() { |
||||
return { |
||||
loading:false, |
||||
isShowImport:false, |
||||
showDialog:false, |
||||
data:[], |
||||
selectionList:[], |
||||
form:{}, |
||||
query:{}, |
||||
page:{ |
||||
pageSize: 10, |
||||
currentPage: 1, |
||||
total: 0, |
||||
}, |
||||
selectionList:[], |
||||
option: { |
||||
height: 'auto', |
||||
align: 'center', |
||||
calcHeight: 32, |
||||
rowKey: 'id', |
||||
rowParentKey: 'parentId', |
||||
tip: false, |
||||
simplePage: true, |
||||
searchShow: true, |
||||
searchMenuSpan: 6, |
||||
searchIcon: true, |
||||
searchIndex: 3, |
||||
tree: false, |
||||
border: true, |
||||
index: false, |
||||
selection: true, |
||||
viewBtn: false, |
||||
delBtn: false, |
||||
addBtn: false, |
||||
editBtn: false, |
||||
editBtnText: '修改', |
||||
addBtnIcon: ' ', |
||||
viewBtnIcon: ' ', |
||||
delBtnIcon: ' ', |
||||
editBtnIcon: ' ', |
||||
viewBtnText: '详情', |
||||
// labelWidth: 120, |
||||
searchLabelWidth: 'auto', |
||||
menu: false, |
||||
menuWidth: 120, |
||||
dialogWidth: 1200, |
||||
dialogClickModal: false, |
||||
searchEnter: true, |
||||
excelBtn: false, |
||||
filterBtn: true, |
||||
searchShowBtn: false, |
||||
columnSort: true, |
||||
excelBtn: true, |
||||
columnSort: true, |
||||
showOverflowTooltip: true, |
||||
searchLabelPosition: 'left', |
||||
searchGutter: 24, |
||||
searchSpan: 6, |
||||
menuAlign: 'left', |
||||
gridBtn: false, |
||||
searchMenuPosition: 'right', |
||||
column: [ |
||||
{ |
||||
label: '工序', |
||||
prop:'processName', |
||||
search:true, |
||||
sortable:'custom', |
||||
searchOrder:4 |
||||
}, |
||||
{ |
||||
label:"镀种", |
||||
prop:"plate", |
||||
search:true, |
||||
sortable:'custom', |
||||
searchOrder: 3 |
||||
}, |
||||
{ |
||||
label:"镀层厚度", |
||||
prop:"plateThickness", |
||||
search:true, |
||||
sortable:'custom', |
||||
searchOrder: 2 |
||||
}, |
||||
{ |
||||
label:"零件名称", |
||||
prop:"partName", |
||||
search:true, |
||||
sortable:'custom', |
||||
searchOrder: 1 |
||||
}, |
||||
{ |
||||
label:"标准工序代码", |
||||
prop:"standardProcessCode", |
||||
search:true, |
||||
sortable:'custom', |
||||
searchOrder: 5, |
||||
}, |
||||
{ |
||||
label:"维护人", |
||||
sortable:'custom', |
||||
prop:"updateUserName" |
||||
}, |
||||
{ |
||||
label:"维护时间", |
||||
sortable:'custom', |
||||
prop:"updateTime" |
||||
} |
||||
] |
||||
} |
||||
} |
||||
}, |
||||
created(){ |
||||
|
||||
}, |
||||
methods:{ |
||||
// 表格排序 |
||||
sortChange({ prop, order }) { |
||||
if (!prop) { |
||||
// 如果取消排序,清空排序参数 |
||||
this.query.orderByField = undefined; |
||||
// this.query.isAsc = undefined; |
||||
this.query.asc = undefined; |
||||
} else { |
||||
const orderByField = prop.replace(/([a-z])([A-Z0-9])/g, '$1_$2').toUpperCase(); |
||||
this.query.orderByField = orderByField; |
||||
// this.query.isAsc = order === 'ascending' ? true : false; |
||||
this.query.asc = order === 'ascending' ? true : false; |
||||
} |
||||
// // 重新加载数据 |
||||
this.onLoad(this.page, this.query); |
||||
}, |
||||
searchChange(params, done){ |
||||
this.page.currentPage = 1; |
||||
this.query = params; |
||||
this.onLoad(); |
||||
done(); |
||||
}, |
||||
searchReset(){ |
||||
this.query = {} |
||||
this.onLoad() |
||||
}, |
||||
currentChange(currentPage){ |
||||
this.page.currentPage = currentPage |
||||
}, |
||||
sizeChange(pageSize){ |
||||
this.page.pageSize = pageSize |
||||
}, |
||||
refreshChange(){ |
||||
this.onLoad() |
||||
}, |
||||
handleImport(){ |
||||
this.isShowImport = true |
||||
}, |
||||
closeDialog(val){ |
||||
this.isShowImport = false |
||||
this.showDialog = false |
||||
if(val){ |
||||
this.onLoad() |
||||
} |
||||
}, |
||||
selectionChange(list){ |
||||
this.selectionList = list |
||||
}, |
||||
handleDelete(){ |
||||
if (this.selectionList.length === 0) { |
||||
this.$message.error('请选择至少一条数据'); |
||||
return; |
||||
} |
||||
this.$confirm('确定将选择数据删除?', { |
||||
confirmButtonText: '确定', |
||||
cancelButtonText: '取消', |
||||
type: 'warning', |
||||
}).then(() => { |
||||
removeItem({ |
||||
ids:this.selectionList.map(item => item.id).join(',') |
||||
}).then(res =>{ |
||||
if(res.data.code == 200){ |
||||
this.$message.success('删除成功') |
||||
this.onLoad() |
||||
} |
||||
}) |
||||
}) |
||||
}, |
||||
handleMaintain(){ |
||||
if (this.selectionList.length === 0) { |
||||
this.$message.error('请选择至少一条数据'); |
||||
return; |
||||
} |
||||
this.showDialog = true |
||||
}, |
||||
onLoad(){ |
||||
this.loading = true |
||||
getList({ |
||||
current:this.page.currentPage, |
||||
size:this.page.pageSize, |
||||
...this.query |
||||
}).then(res =>{ |
||||
this.data = res.data.data.records |
||||
this.page.total = res.data.data.total |
||||
this.loading = false |
||||
}) |
||||
// this.data = [ |
||||
// { |
||||
// id:'001', |
||||
// processName:"镀后", |
||||
// plate:"Au", |
||||
// plateThickness:'3.2', |
||||
// } |
||||
// ] |
||||
// this.page.total = this.data.length |
||||
// this.loading = false |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style> |
||||
|
||||
</style> |
||||
@ -0,0 +1,232 @@ |
||||
<template> |
||||
<el-dialog title="维护" append-to-body :modelValue="openShow" width="70%" @close="closeDialog()"> |
||||
<!-- 单个 Form 包裹整个表格 --> |
||||
<el-form |
||||
ref="tableForm" |
||||
:model="form" |
||||
:rules="formRules" |
||||
label-width="0px" |
||||
> |
||||
<!-- 全局错误提示 --> |
||||
<div v-if="formError" class="error-message" style="color: #f56c6c; margin-bottom: 10px;"> |
||||
{{ formError }} |
||||
</div> |
||||
<el-table :data="form.tableData" @select="selectChange" border> |
||||
<el-table-column type="index" width="55"></el-table-column> |
||||
<!-- 工序 --> |
||||
<el-table-column align="center" label="工序" prop="processName"> |
||||
<template #header> |
||||
<span><i style="color: red">*</i>工序</span> |
||||
</template> |
||||
</el-table-column> |
||||
<!-- 镀种 --> |
||||
<el-table-column align="center" label="镀种" prop="plate"> |
||||
<template #default="scope"> |
||||
<el-form-item :prop="`tableData[${scope.$index}].plate`" :rules="formRules.plate"> |
||||
<el-input v-model="scope.row.plate" placeholder="请输入"></el-input> |
||||
</el-form-item> |
||||
</template> |
||||
</el-table-column> |
||||
<!-- 镀层厚度 --> |
||||
<el-table-column align="center" label="镀层厚度" prop="plateThickness"> |
||||
<template #default="scope"> |
||||
<el-form-item :prop="`tableData[${scope.$index}].plateThickness`" :rules="formRules.plateThickness"> |
||||
<el-input v-model="scope.row.plateThickness" placeholder="请输入"></el-input> |
||||
</el-form-item> |
||||
</template> |
||||
</el-table-column> |
||||
<!-- 零件名称 --> |
||||
<el-table-column align="center" label="零件名称" prop="partName"> |
||||
<template #default="scope"> |
||||
<el-form-item :prop="`tableData[${scope.$index}].partName`" :rules="formRules.partName"> |
||||
<el-input v-model="scope.row.partName" placeholder="请输入"></el-input> |
||||
</el-form-item> |
||||
</template> |
||||
</el-table-column> |
||||
<!-- 标准工序代码 --> |
||||
<el-table-column align="center" label="标准工序代码" prop="standardProcessCode"> |
||||
<template #header> |
||||
<span><i style="color: red">*</i>标准工序代码</span> |
||||
</template> |
||||
<template #default="scope"> |
||||
<el-form-item :prop="`tableData[${scope.$index}].standardProcessCode`" :rules="formRules.standardProcessCode"> |
||||
<el-input v-model="scope.row.standardProcessCode" placeholder="请输入"></el-input> |
||||
</el-form-item> |
||||
</template> |
||||
</el-table-column> |
||||
</el-table> |
||||
</el-form> |
||||
<template #footer> |
||||
<span class="dialog-footer"> |
||||
<el-button @click="closeDialog()">取 消</el-button> |
||||
<el-button type="primary" @click="submitForm">确 定</el-button> |
||||
</span> |
||||
</template> |
||||
</el-dialog> |
||||
</template> |
||||
|
||||
<script> |
||||
import {saveData} from "@/api/oem/standardProcedure" |
||||
export default { |
||||
props:{ |
||||
showDialog:{ |
||||
type:Boolean, |
||||
default:false |
||||
}, |
||||
selectData:{ |
||||
type:Array, |
||||
default:[] |
||||
} |
||||
}, |
||||
data(){ |
||||
return{ |
||||
openShow:false, |
||||
form:{ |
||||
tableData:[] |
||||
}, |
||||
formRules:{ |
||||
// 表格数据数组的整体校验(可选:如最少1行数据) |
||||
tableData: [ |
||||
{ |
||||
required: true, |
||||
message: '请至少添加一行数据', |
||||
trigger: 'submit', |
||||
type: 'array' // 明确类型为数组 |
||||
}, |
||||
{ |
||||
validator: (rule, value, callback) => { |
||||
if (value.length === 0) { |
||||
callback(new Error('请至少添加一行数据')); |
||||
} else { |
||||
callback(); |
||||
} |
||||
}, |
||||
trigger: 'submit' |
||||
} |
||||
], |
||||
processName:[ |
||||
{ required: true, message: '请填写工序', trigger: ['change', 'submit'] } |
||||
], |
||||
standardProcessCode:[ |
||||
{ required: true, message: '请填写标准工序代码', trigger: ['change', 'submit'] } |
||||
] |
||||
}, |
||||
formError:'' |
||||
} |
||||
}, |
||||
mounted(){ |
||||
console.log('showDialog=========',this.showDialog) |
||||
this.openShow = this.showDialog |
||||
this.form.tableData = this.selectData |
||||
}, |
||||
methods:{ |
||||
closeDialog(val){ |
||||
this.openShow = false |
||||
this.$emit('closeDialog',val); |
||||
}, |
||||
checkDuplicate(arr) { |
||||
const map = new Map(); // 用于存储 "name_value" 字符串和它第一次出现的行号 |
||||
|
||||
for (let i = 0; i < arr.length; i++) { |
||||
const item = arr[i]; |
||||
// 1. 生成唯一标识字符串:只拼接 name 和 value |
||||
// 注意:这里明确指定了字段,从而忽略了 id 和 age |
||||
const key = `${item.processName}_${item.plate}_${item.plateThickness}_${item.partName}`; |
||||
|
||||
// 2. 检查 Map 中是否已存在该标识 |
||||
if (map.has(key)) { |
||||
// 存在则说明重复,返回错误信息 |
||||
return { |
||||
success: false, |
||||
rowIndex: i + 1, // 当前行号(从1开始) |
||||
message: `第 ${i + 1} 行错误:数据已存在` |
||||
}; |
||||
} else { |
||||
// 不存在则存入 Map,记录行号(i+1) |
||||
map.set(key, i + 1); |
||||
} |
||||
} |
||||
return { success: true }; |
||||
}, |
||||
// 提交表单(单次校验所有行) |
||||
submitForm() { |
||||
this.formError = ''; |
||||
|
||||
// 调用单个 Form 的校验方法 |
||||
this.$refs.tableForm.validate((isValid, invalidFields) => { |
||||
if (!isValid) { |
||||
// 校验失败:显示提示并滚动到第一个错误字段 |
||||
this.formError = '存在未完善的字段,请检查表格中的红色提示'; |
||||
|
||||
this.$nextTick(() => { |
||||
// 找到第一个错误字段并滚动到视图 |
||||
const firstError = document.querySelector('.el-form-item.is-error'); |
||||
if (firstError) { |
||||
firstError.scrollIntoView({ behavior: 'smooth', block: 'center' }); |
||||
} |
||||
}); |
||||
return; |
||||
} |
||||
// 校验通过:准备提交数据(过滤无用字段) |
||||
const submitData = this.form.tableData.map(row => { |
||||
const { _select, ...validData } = row; // 剔除选择状态字段 |
||||
return validData; |
||||
}); |
||||
console.log('submit----------',submitData) |
||||
|
||||
// --- 重复项校验逻辑开始 --- |
||||
const result = this.checkDuplicate(submitData); |
||||
console.log('res==========',result) |
||||
if(!result.success){ |
||||
this.$message.error(result.message) |
||||
return |
||||
} |
||||
|
||||
saveData(submitData).then(res => { |
||||
if(res.data.code === 200){ |
||||
this.$message.success('维护成功') |
||||
this.closeDialog(true) |
||||
} |
||||
}) |
||||
}) |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
// 优化表单字段样式 |
||||
:deep(.el-table .el-form-item) { |
||||
margin-bottom: 0; // 去掉默认边距 |
||||
} |
||||
|
||||
// 错误提示样式优化 |
||||
:deep(.el-form-item__error) { |
||||
font-size: 12px; |
||||
white-space: nowrap; |
||||
z-index: 10; |
||||
background: #fff; |
||||
padding: 2px 4px; |
||||
border: 1px solid #f56c6c; |
||||
border-radius: 4px; |
||||
} |
||||
|
||||
// 表格行高适配 textarea |
||||
.el-table__row { |
||||
height: 80px !important; |
||||
} |
||||
|
||||
.el-table__cell { |
||||
vertical-align: middle !important; |
||||
} |
||||
|
||||
.error-message { |
||||
font-size: 14px; |
||||
line-height: 1.5; |
||||
} |
||||
:deep(.el-table .el-table__cell) { |
||||
height: 50px !important; |
||||
padding: 0 !important; |
||||
line-height: 50px !important; |
||||
} |
||||
</style> |
||||
Loading…
Reference in new issue