Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
tangyu 2025-04-26 16:30:40 +08:00
commit 17dd8be72b
4 changed files with 731 additions and 2 deletions

View File

@ -0,0 +1,74 @@
import request from '@/router/axios'
import {iep} from '@/api/prefix'
// 设备分页查询
export function fetchResrcePage(query) {
return request({
url: iep('/z-product-structure-parameter/readParameterResrcePage'),
method: 'get',
params: query
})
}
// 派工工单分页查询
export function fetchShopOrderPage(query) {
return request({
url: iep('/z-product-structure-parameter/readTdsDispatchPage'),
method: 'get',
params: query
})
}
// 物料分页查询
export function fetchItemPage(query) {
return request({
url: iep('/item/page'),
method: 'get',
params: query
})
}
// 检索主列表数据
export function readZProductStructureParameterPage(query) {
return request({
url: iep('/z-product-structure-parameter/readZProductStructureParameterPage'),
method: 'get',
params: query
})
}
// 检索明细列表数据
export function readZProductStructureParameterDetailList(query) {
return request({
url: iep('/z-product-structure-parameter-detail/readZProductStructureParameterDetailList'),
method: 'get',
params: query
})
}
// 获取最大版本号
export function getMaxVersion(query) {
return request({
url: iep('/z-product-structure-parameter/getMaxVersion'),
method: 'get',
params: query
})
}
// 参数保存
export function doSaveParameter(obj) {
return request({
url: iep('/z-product-structure-parameter/doSave'),
method: 'post',
data: obj
})
}
// 参数明细提交
export function doSubmitParameter(obj) {
return request({
url: iep('/z-product-structure-parameter-detail/doSubmit'),
method: 'post',
data: obj
})
}

View File

@ -0,0 +1,621 @@
<template>
<!--产品结构化参数保存-->
<div class="execution">
<!-- 设备 开窗 -->
<input-select-dialog
:modal-obj.sync="resrceDialogObj"
:modal-show.sync="resrceDialogVisible"
:modal-fetch-fun="openResrceList"
@inputDialogSelected="resrceSelected"
></input-select-dialog>
<!-- 工单 开窗 -->
<input-select-dialog
:modal-obj.sync="shopOrderDialogObj"
:modal-show.sync="shopOrderDialogVisible"
:modal-fetch-fun="openShopOrderList"
@inputDialogSelected="shopOrderSelected"
></input-select-dialog>
<!-- 物料 开窗 -->
<input-select-dialog
:modal-obj.sync="itemDialogObj"
:modal-show.sync="itemDialogVisible"
:modal-fetch-fun="openItemList"
@inputDialogSelected="itemSelected"
></input-select-dialog>
<basic-container>
<!-- 搜尋框 -->
<el-form ref="searchForm" :model="searchForm" label-width="120px" label-suffix=":" :inline="true">
<el-row>
<el-col :span="6">
<el-form-item label="设备号" prop="resrce" :rules="[{ required: true, message: '设备号不能为空', trigger: 'change'}]">
<el-input v-model.trim="searchForm.resrce" readonly clearable>
<i
slot="suffix"
class="el-input__icon el-icon-copy-document"
@click.stop="showResrceDialog"
></i>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="工单号" prop="shopOrder" :rules="[{ required: true, message: '工单号不能为空', trigger: 'change'}]">
<el-input v-model.trim="searchForm.shopOrder" readonly clearable>
<i
slot="suffix"
class="el-input__icon el-icon-copy-document"
@click.stop="showShopOrderDialog"
></i>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="物料" prop="item">
<el-input v-model.trim="searchForm.item" clearable>
<i
slot="suffix"
class="el-input__icon el-icon-copy-document"
@click.stop="showItemDialog"
></i>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="等级" prop="inspectionLevel" :rules="[{ required: true, message: '等级不能为空', trigger: 'change'}]">
<el-select v-model="searchForm.inspectionLevel" clearable>
<el-option v-for="item in selectInspectionLevel" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<el-form-item label="时间始" prop="dateCreateFrom">
<el-date-picker
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
v-model="searchForm.dateCreateFrom"
type="date"
placeholder="选择日期">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="时间止" prop="dateCreateTo">
<el-date-picker
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
v-model="searchForm.dateCreateTo"
type="date"
placeholder="选择日期">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="产品配方编码" prop="productFormulaCode">
<el-input v-model.trim="searchForm.productFormulaCode" clearable>
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-button type="primary" icon="el-icon-search" size="small" @click="search(true)">检索</el-button>
<el-button type="primary" icon="el-icon-document" size="small" @click="doSave">保存</el-button>
<el-button type="primary" icon="el-icon-document-checked" size="small" @click="doSubmit">提交</el-button>
<el-button type="primary" icon="el-icon-document" size="small" @click="doExport">导出</el-button>
<el-button icon="el-icon-delete" size="small" @click="searchReset">清空</el-button>
</el-col>
</el-row>
</el-form>
<el-tabs v-model="tabActiveName">
<el-tab-pane label="产品结构化参数" name="tabActiveNameTab">
<el-table ref="productStructureParameterData" :data="productStructureParameterData" tooltip-effect="dark" border style="width: 100%;"
@selection-change="handleSelectionChange"
:row-key="'handle'"
:highlight-current-row="true"
height="250px"
stripe>
<!-- 选择框列 -->
<el-table-column type="selection"></el-table-column>
<el-table-column label="序号" align="center" prop="seq" width="50">
<template v-slot:default="scope">
{{ getSeq(scope.$index) }}
</template>
</el-table-column>
<el-table-column prop="shopOrder" label="工单号" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.shopOrder }}
</div>
</template>
</el-table-column>
<el-table-column prop="item" label="物料编号" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.item }}
</div>
</template>
</el-table-column>
<el-table-column prop="itemDesc" label="物料描述" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.itemDesc }}
</div>
</template>
</el-table-column>
<el-table-column prop="pdcCode" label="PDC编号" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.pdcCode }}
</div>
</template>
</el-table-column>
<el-table-column prop="inspectionLevel" label="等级" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.inspectionLevel }}
</div>
</template>
</el-table-column>
<el-table-column prop="productFormulaCode" label="产品配方编码" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.productFormulaCode }}
</div>
</template>
</el-table-column>
<el-table-column prop="productFormulaVersion" label="产品配方版本" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.productFormulaVersion }}
</div>
</template>
</el-table-column>
</el-table>
<div style="width: 100%;display: flex;flex-direction: column;align-items: center;justify-content: center;">
<el-pagination @current-change="handleCurrentChange"
@size-change="handleSizeChange"
:current-page.sync="page.current"
:page-sizes="[10, 20, 50, 100, 200]"
:page-size="page.size"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total">
</el-pagination>
</div>
</el-tab-pane>
</el-tabs>
<el-tabs v-model="tabActiveNameDetail">
<el-tab-pane label="产品结构化参数明细" name="tabActiveNameDetailTab">
<el-table ref="productStructureParameterDetailData" :data="productStructureParameterDetailData" tooltip-effect="dark" border style="width: 100%;"
@selection-change="handleSelectionDetailChange"
:row-key="'handle'"
:highlight-current-row="true"
height="250px"
stripe>
<!-- 选择框列 -->
<el-table-column type="selection"></el-table-column>
<el-table-column label="序号" align="center" prop="seq" width="50">
<template v-slot:default="scope">
{{ getSeq(scope.$index) }}
</template>
</el-table-column>
<el-table-column prop="shopOrder" label="工单号" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.shopOrder }}
</div>
</template>
</el-table-column>
<el-table-column prop="item" label="物料编号" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.item }}
</div>
</template>
</el-table-column>
<el-table-column prop="itemDesc" label="物料描述" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.itemDesc }}
</div>
</template>
</el-table-column>
<el-table-column prop="pdcCode" label="PDC编号" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.pdcCode }}
</div>
</template>
</el-table-column>
<el-table-column prop="inspectionLevel" label="等级" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.inspectionLevel }}
</div>
</template>
</el-table-column>
<el-table-column prop="productFormulaCode" label="产品配方编码" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.productFormulaCode }}
</div>
</template>
</el-table-column>
<el-table-column prop="productFormulaVersion" label="产品配方版本" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.productFormulaVersion }}
</div>
</template>
</el-table-column>
<el-table-column prop="parameterCode" label="参数编码" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.parameterCode }}
</div>
</template>
</el-table-column>
<el-table-column prop="parameterName" label="参数名称" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.parameterName }}
</div>
</template>
</el-table-column>
<el-table-column prop="parameterValue" header-align="center">
<template #header>
<span><span style="color: red;">*</span>参数值</span>
</template>
<template slot-scope="scope">
<div v-if="scope.row.isManualInput === 'Y'">
<el-input v-model="scope.row.parameterValue"/>
</div>
<div v-else>
{{ scope.row.parameterValue }}
</div>
</template>
</el-table-column>
<el-table-column prop="unitOfMeasure" label="单位" header-align="center">
<template slot-scope="scope">
<div>
{{ scope.row.unitOfMeasure }}
</div>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</basic-container>
</div>
</template>
<script>
import {mapGetters} from 'vuex';
import {getStore} from '@/util/store';
import {
doSaveParameter, doSubmitParameter,
fetchItemPage,
fetchResrcePage,
fetchShopOrderPage,
getMaxVersion,
readZProductStructureParameterDetailList,
readZProductStructureParameterPage
} from "@/api/mes/wip-nalinv/product-structure-parameter";
import {hideLoading, showLoading} from "@/const/loading";
import {
itemDialogObj,
shopOrderDialogObj,
resrceDialogObj
} from "@/views/mes/wip-nalinv/product-structure-parameter/init";
import {fetchItemList as fetchDictList} from "@/api/admin/dict";
export default {
name: 'product-structure-parameter',
data() {
return {
tabActiveName: "tabActiveNameTab",
tabActiveNameDetail: "tabActiveNameDetailTab",
searchForm: {
site: getStore({name: 'tenantId'}),
dateCreateFrom: this.formattedDate(),
dateCreateTo: this.formattedDate()
},
productStructureParameterData: [],
productStructureParameterDetailData: [],
site: getStore({name: 'tenantId'}),
resrceDialogObj: {...resrceDialogObj}, // 设备
openResrceList: null,
resrceDialogVisible: false,
shopOrderDialogObj: {...shopOrderDialogObj}, // 工单
openShopOrderList: null,
shopOrderDialogVisible: false,
itemDialogObj: {...itemDialogObj}, // 物料
openItemList: null,
itemDialogVisible: false,
selectInspectionLevel: [], // 基膜质检等级
selectedRows: [], // 主列表选中行数据列表
selectedDetailRows: [], // 明细列表选中行数据列表
page: {
total: 0,
current: 1,
size: 10
},
}
},
created() {
this.searchForm = Object.assign({}, this.searchForm);
this.getDataDictionary("JM_INSPEC_LEVEL", "selectInspectionLevel"); // 基膜质检等级
},
computed: {
//读取权限
...mapGetters(['permissions', 'userInfo']),
permissionList() {
return {
addBtn: false,
delBtn: false,
editBtn: false,
}
},
},
methods: {
getSeq(index) {
// 序号从 1 开始
return index + 1;
},
// 获取当前日期
formattedDate() {
const date = new Date();
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份是从 0 开始的,所以需要加 1
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`; // 格式化为 YYYY-MM-DD
},
// 获取数据字典
getDataDictionary(dictType, list) {
fetchDictList({
current: "1",
size: "1000",
dictType: dictType,
}).then((response) => {
this[list] = response.data.data.records
});
},
// 页面大小改变
handleSizeChange(val) {
this.page.size = val;
this.page.current = 1;
this.search();
},
//页面切换
handleCurrentChange(val) {
this.page.current = val;
this.search();
},
//主列表选中行赋值
handleSelectionChange(selection) {
this.selectedRows = selection;
let productFormulaCodeList = [];
this.selectedRows.forEach(item => {
productFormulaCodeList.push(item.productFormulaCode)
});
// 检索明细列表数据
showLoading();
readZProductStructureParameterDetailList({
site: this.site,
productFormulaCodeList: productFormulaCodeList
}).then((response) => {
hideLoading();
if (response.data.code !== 0) {
this.$message.error(response.data.message);
} else {
this.productStructureParameterDetailData = response.data.data;
}
}).catch(() => {
hideLoading();
});
},
//明细列表选中行赋值
handleSelectionDetailChange(selection) {
this.selectedDetailRows = selection;
},
// 检索列表数据
search(flag) {
if (!this.searchForm.resrce) {
this.$message.error("设备号不可为空!");
return;
}
if (!this.searchForm.dateCreateFrom) {
this.$message.error("时间始不可为空!");
return;
}
if (!this.searchForm.dateCreateTo) {
this.$message.error("时间止不可为空!");
return;
}
if (flag) {
this.page.current = 1;
}
showLoading();
readZProductStructureParameterPage({
...this.searchForm,
current: this.page.current,
size: this.page.size,
}).then((response) => {
hideLoading();
if (response.data.code !== 0) {
this.$message.error(response.data.message);
} else {
this.productStructureParameterData = response.data.data.records;
this.page.total = response.data.data.total;
this.page.current = response.data.data.current;
}
}).catch(() => {
hideLoading();
});
},
// 保存
doSave() {
this.$refs.searchForm.validate((valid) => {
if (valid) {
// 查询当前版本号
showLoading();
getMaxVersion(this.searchForm).then((response) => {
hideLoading();
if (response.data.code !== 0) {
this.$message.error(response.data.message);
} else {
this.searchForm.productFormulaVersion = response.data.data;
this.searchForm.productFormulaCode = this.searchForm.shopOrder+'-'+response.data.data;
this.$confirm(`是否确认保存工艺配方${this.searchForm.productFormulaCode}?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
showLoading();
doSaveParameter(this.searchForm).then((response) => {
hideLoading();
if (response.data.code !== 0) {
this.$message.error(response.data.message);
} else {
this.$message.success(`保存成功!`);
this.search(true)
}
}).catch(() => {
hideLoading();
});
}).catch(() => {
hideLoading();
});
}
}).catch(() => {
hideLoading();
});
}
})
},
// 提交
doSubmit() {
if (this.selectedDetailRows.length === 0) {
return this.$message.warning("请先勾选明细列表中需要提交的数据!");
} else {
for (let i = 0; i < this.selectedDetailRows.length; i++) {
if (this.selectedDetailRows[i].isManualInput === 'Y' && !this.selectedDetailRows[i].parameterValue) {
return this.$message.warning("明细列表中已勾选的数据存在未输入的参数值!");
}
}
}
this.$confirm(`是否确认提交?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
showLoading();
doSubmitParameter(this.selectedDetailRows).then((response) => {
hideLoading();
if (response.data.code !== 0) {
this.$message.error(response.data.message);
} else {
this.$message.success(`提交成功!`);
}
}).catch(() => {
hideLoading();
});
}).catch(() => {
hideLoading();
});
},
// 导出
doExport() {
let me = this;
if (!me.searchForm.resrce) {
me.$message.error("设备号不可为空!");
return;
}
if (!me.searchForm.dateCreateFrom) {
me.$message.error("时间始不可为空!");
return;
}
if (!me.searchForm.dateCreateTo) {
me.$message.error("时间止不可为空!");
return;
}
me.$confirm(`是否确认导出产品结构化参数?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.downBlobFile("/iep-app/z-product-structure-parameter/exportProductStructureParameter", me.searchForm, `产品结构化参数.xlsx`);
})
},
// 清空事件
searchReset() {
this.searchForm = {
site: this.site,
dateCreateFrom: this.formattedDate(),
dateCreateTo: this.formattedDate()
};
this.productStructureParameterData = [];
this.productStructureParameterDetailData = [];
},
// 设备点击开窗
showResrceDialog() {
this.resrceDialogObj.queryParam.site = this.site;
this.openResrceList = fetchResrcePage;
this.resrceDialogVisible = true
},
// 设备选择回填
resrceSelected(row) {
this.searchForm.resrce = row.resrce
this.searchForm.shopOrder = row.shopOrder
this.searchForm.item = row.item
this.searchForm.itemDesc = row.itemDesc
this.searchForm = Object.assign({}, this.searchForm)
},
// 工单点击开窗
showShopOrderDialog() {
if (!this.searchForm.resrce) {
this.$message.error("请先选择设备号!");
return;
}
this.shopOrderDialogObj.queryParam.site = this.site;
this.shopOrderDialogObj.queryParam.resrce = this.searchForm.resrce;
this.openShopOrderList = fetchShopOrderPage;
this.shopOrderDialogVisible = true
},
// 工单选择回填
shopOrderSelected(row) {
this.searchForm.shopOrder = row.shopOrder
this.searchForm.item = row.item
this.searchForm.itemDesc = row.itemDesc
this.searchForm = Object.assign({}, this.searchForm)
},
// 物料点击开窗
showItemDialog() {
this.itemDialogObj.queryParam.site = this.site;
this.openItemList = fetchItemPage;
this.itemDialogVisible = true
},
// 物料选择回填
itemSelected(row) {
this.searchForm.item = row.item
this.searchForm = Object.assign({}, this.searchForm)
},
},
}
</script>
<style lang="scss" scoped>
// 解决input框中添加disabled不可编辑属性后,改变字体颜色样式(主要解决:默认字体颜色为灰色)
::v-deep .el-input.is-disabled .el-input__inner {
color: black;
}
/* 禁用 el-input 时禁用图标和清除按钮 */
.el-input.is-disabled .el-input__icon,
.el-input.is-disabled .el-input__clear {
pointer-events: none;
}
</style>

View File

@ -0,0 +1,32 @@
export const resrceDialogObj = {
title: '设备',
condition: "resrce",
tableColumn: [
{prop: "resrce", label: "设备号"},
{prop: "resrceDesc", label: "设备描述"},
{prop: "shopOrder", label: "当前工单"}
],
queryParam: {}
}
export const shopOrderDialogObj = {
title: '工单',
condition: "shopOrder",
tableColumn: [
{prop: "shopOrder", label: "工单"},
{prop: "plannedItem", label: "计划物料"},
{prop: "plannedItemDescription", label: "计划物料描述"}
],
queryParam: {}
}
export const itemDialogObj = {
title: '物料',
condition: "item",
tableColumn: [
{prop: "item", label: "物料"},
{prop: "description", label: "物料描述"},
{prop: "uitem", label: "型号"}
],
queryParam: {}
}

View File

@ -176,8 +176,10 @@ export default {
site: this.site,
functionName: this.searchForm.functionName,
dateCreateRequest: this.searchForm.dateCreateRequest,
request: this.searchForm.request
}, this.page).then((response) => {
request: this.searchForm.request,
current: this.page.current,
size: this.page.size,
}).then((response) => {
hideLoading();
if (response.data.code !== 0) {
this.$message.error(response.data.message);