<template>
|
<el-dialog v-model="visible"
|
:title="title"
|
width="800px"
|
destroy-on-close>
|
<div class="param-list-container">
|
<div class="params-header">
|
<span>参数列表</span>
|
<el-button v-if="editable"
|
type="primary"
|
link
|
size="small"
|
@click="handleAddParam">
|
<el-icon>
|
<Plus />
|
</el-icon>新增
|
</el-button>
|
</div>
|
<div class="params-list">
|
<div v-for="param in paramList"
|
:key="param.id"
|
class="param-item">
|
<div class="param-info">
|
<span class="param-code">{{ param.paramName }}</span>
|
<span v-if="param.valueMode == 1"
|
class="param-value">
|
标准值:{{ param.standardValue || "-" }} {{ param.unit }}
|
</span>
|
<span v-else
|
class="param-value">
|
标准值:{{ param.minValue || "-" }}-{{ param.maxValue || "-" }} {{ param.unit }}
|
</span>
|
</div>
|
<div class="param-actions">
|
<el-button v-if="editable"
|
link
|
type="primary"
|
size="small"
|
@click="handleEditParam(param)">
|
编辑
|
</el-button>
|
<el-button v-if="editable"
|
link
|
type="danger"
|
size="small"
|
@click="handleDeleteParam(param)">
|
删除
|
</el-button>
|
</div>
|
</div>
|
<el-empty v-if="!paramList || paramList.length === 0"
|
description="暂无参数"
|
:image-size="50" />
|
</div>
|
</div>
|
<!-- 选择参数对话框 -->
|
<el-dialog v-model="selectParamDialogVisible"
|
title="选择参数"
|
width="1000px">
|
<div class="param-select-container">
|
<!-- 左侧参数列表 -->
|
<div class="param-list-area">
|
<div class="area-title">可选参数</div>
|
<div class="search-box">
|
<el-input v-model="paramSearchKeyword"
|
placeholder="请输入参数名称搜索"
|
clearable
|
size="small"
|
@input="getBaseParamListData">
|
<template #prefix>
|
<el-icon>
|
<Search />
|
</el-icon>
|
</template>
|
</el-input>
|
</div>
|
<el-table :data="filteredParamList"
|
height="400"
|
border
|
highlight-current-row
|
@current-change="handleSelectParam">
|
<el-table-column prop="paramName"
|
label="参数名称" />
|
<el-table-column prop="paramType"
|
label="参数类型">
|
<template #default="scope">
|
<el-tag size="small"
|
:type="getParamTypeTag(scope.row.paramType)">{{ getParamTypeText(scope.row.paramType) }}</el-tag>
|
</template>
|
</el-table-column>
|
</el-table>
|
<!-- 分页控件 -->
|
<div class="pagination-container"
|
style="margin-top: 10px;">
|
<el-pagination v-model:current-page="paramPage.current"
|
v-model:page-size="paramPage.size"
|
:page-sizes="[10, 20, 50, 100]"
|
layout="total, sizes, prev, pager, next, jumper"
|
:total="paramPage.total"
|
@size-change="getBaseParamListData"
|
@current-change="getBaseParamListData"
|
size="small" />
|
</div>
|
</div>
|
<!-- 右侧参数详情 -->
|
<div class="param-detail-area">
|
<div class="area-title">参数详情</div>
|
<el-form v-if="selectedParam"
|
:model="selectedParam"
|
label-width="100px"
|
class="param-detail-form">
|
<el-form-item label="参数名称">
|
<span class="detail-text">{{ selectedParam.paramName }}</span>
|
</el-form-item>
|
<el-form-item label="参数模式">
|
<el-tag size="small"
|
:type="selectedParam.valueMode == '1' ? 'success' : 'warning'">
|
{{ selectedParam.valueMode == '1' ? '单值' : '区间' }}
|
</el-tag>
|
</el-form-item>
|
<el-form-item label="参数类型">
|
<el-tag size="small"
|
:type="getParamTypeTag(selectedParam.paramType)">{{ getParamTypeText(selectedParam.paramType) }}</el-tag>
|
</el-form-item>
|
<el-form-item label="参数格式">
|
<span class="detail-text">{{ selectedParam.paramFormat || '-' }}</span>
|
</el-form-item>
|
<el-form-item label="单位">
|
<span class="detail-text">{{ selectedParam.unit || '-' }}</span>
|
</el-form-item>
|
<el-form-item label="标准值"
|
v-if="selectedParam.valueMode == '1' && selectedParam.paramType == '1'">
|
<el-input v-model="selectedParam.standardValue"
|
type="number"
|
placeholder="请输入默认值" />
|
</el-form-item>
|
<el-form-item label="最小值"
|
v-if="selectedParam.valueMode == '2' && selectedParam.paramType == '1'">
|
<el-input v-model="selectedParam.minValue"
|
type="number"
|
placeholder="请输入最小值" />
|
</el-form-item>
|
<el-form-item label="最大值"
|
v-if="selectedParam.valueMode == '2' && selectedParam.paramType == '1'">
|
<el-input v-model="selectedParam.maxValue"
|
type="number"
|
placeholder="请输入最大值" />
|
</el-form-item>
|
<el-form-item label="排序">
|
<el-input v-model="selectedParam.sort"
|
type="number"
|
placeholder="请输入排序" />
|
</el-form-item>
|
<el-form-item label="是否必填">
|
<el-switch v-model="selectedParam.isRequired" />
|
</el-form-item>
|
</el-form>
|
<el-empty v-else
|
description="请从左侧选择参数"
|
:image-size="100" />
|
</div>
|
</div>
|
<template #footer>
|
<el-button @click="selectParamDialogVisible = false">取消</el-button>
|
<el-button type="primary"
|
@click="handleParamSelectSubmit">确定</el-button>
|
</template>
|
</el-dialog>
|
<!-- 编辑参数对话框 -->
|
<el-dialog v-model="editParamDialogVisible"
|
title="编辑参数"
|
width="600px">
|
<el-form :model="editParamForm"
|
:rules="editParamRules"
|
ref="editParamFormRef"
|
label-width="120px">
|
<el-form-item label="参数名称">
|
<span class="detail-text">{{ editParamForm.paramName }}</span>
|
</el-form-item>
|
<el-form-item label="参数模式">
|
<el-tag size="small"
|
:type="editParamForm.valueMode == '1' ? 'success' : 'warning'">
|
{{ editParamForm.valueMode == '1' ? '单值' : '区间' }}
|
</el-tag>
|
</el-form-item>
|
<el-form-item label="参数类型">
|
<el-tag size="small"
|
:type="getParamTypeTag(editParamForm.paramType)">
|
{{ getParamTypeText(editParamForm.paramType) }}
|
</el-tag>
|
</el-form-item>
|
<el-form-item label="参数格式">
|
<span class="detail-text">{{ editParamForm.paramFormat || '-' }}</span>
|
</el-form-item>
|
<el-form-item label="单位">
|
<span class="detail-text">{{ editParamForm.unit || '-' }}</span>
|
</el-form-item>
|
<el-form-item label="标准值"
|
v-if="editParamForm.valueMode == '1' && editParamForm.paramType == '1'"
|
prop="standardValue">
|
<el-input v-model="editParamForm.standardValue"
|
type="number"
|
placeholder="请输入标准值" />
|
</el-form-item>
|
<el-form-item label="最小值"
|
v-if="editParamForm.valueMode == '2' && editParamForm.paramType == '1'"
|
prop="minValue">
|
<el-input v-model="editParamForm.minValue"
|
type="number"
|
placeholder="请输入最小值" />
|
</el-form-item>
|
<el-form-item label="最大值"
|
v-if="editParamForm.valueMode == '2' && editParamForm.paramType == '1'"
|
prop="maxValue">
|
<el-input v-model="editParamForm.maxValue"
|
type="number"
|
placeholder="请输入最大值" />
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<el-button @click="editParamDialogVisible = false">取消</el-button>
|
<el-button type="primary"
|
@click="handleEditParamSubmit">确定</el-button>
|
</template>
|
</el-dialog>
|
</el-dialog>
|
</template>
|
|
<script setup>
|
import { ref, computed, watch } from "vue";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
import { Plus, Search } from "@element-plus/icons-vue";
|
import {
|
delProcessRouteItemParam,
|
editProcessRouteItemParam,
|
addProcessRouteItemParam,
|
} from "@/api/productionManagement/processRouteItem.js";
|
import { getBaseParamList } from "@/api/basicData/parameterMaintenance.js";
|
|
const props = defineProps({
|
modelValue: {
|
type: Boolean,
|
default: false,
|
},
|
title: {
|
type: String,
|
default: "参数列表",
|
},
|
routeId: {
|
type: Number,
|
default: 0,
|
},
|
process: {
|
type: Object,
|
default: () => ({}),
|
},
|
paramList: {
|
type: Array,
|
default: () => [],
|
},
|
editable: {
|
type: Boolean,
|
default: true,
|
},
|
});
|
|
const emit = defineEmits(["update:modelValue", "refresh"]);
|
|
const visible = computed({
|
get: () => props.modelValue,
|
set: value => emit("update:modelValue", value),
|
});
|
|
// 响应式数据
|
const selectParamDialogVisible = ref(false);
|
const editParamDialogVisible = ref(false);
|
const paramSearchKeyword = ref("");
|
const selectedParam = ref(null);
|
const filteredParamList = ref([]);
|
const paramPage = ref({
|
current: 1,
|
size: 10,
|
total: 0,
|
});
|
const editParamForm = ref({
|
id: null,
|
processId: null,
|
paramId: null,
|
paramName: "",
|
valueMode: "1",
|
standardValue: null,
|
minValue: null,
|
maxValue: null,
|
sort: 1,
|
isRequired: 0,
|
paramType: null,
|
paramFormat: "",
|
unit: "",
|
});
|
const editParamRules = ref({
|
standardValue: [{ required: true, message: "请输入标准值", trigger: "blur" }],
|
minValue: [{ required: true, message: "请输入最小值", trigger: "blur" }],
|
maxValue: [{ required: true, message: "请输入最大值", trigger: "blur" }],
|
});
|
const editParamFormRef = ref(null);
|
|
// 新增参数
|
const handleAddParam = () => {
|
selectedParam.value = null;
|
paramSearchKeyword.value = "";
|
paramPage.current = 1;
|
// 获取可选参数列表
|
getBaseParamListData();
|
selectParamDialogVisible.value = true;
|
};
|
|
// 编辑参数
|
const handleEditParam = param => {
|
editParamForm.value = {
|
id: param.id,
|
processId: props.process.id,
|
paramId: param.paramId,
|
paramName: param.parameterName || param.paramName,
|
valueMode: param.parameterType2 || param.valueMode || "1",
|
standardValue: param.standardValue,
|
minValue: param.minValue,
|
maxValue: param.maxValue,
|
sort: param.sort || 1,
|
isRequired: param.isRequired || 0,
|
paramType: param.parameterType || param.paramType,
|
paramFormat: param.parameterFormat || param.paramFormat,
|
unit: param.unit || param.unit,
|
};
|
editParamDialogVisible.value = true;
|
};
|
|
// 删除参数
|
const handleDeleteParam = param => {
|
ElMessageBox.confirm("确定要删除该参数吗?", "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
// 调用API删除参数
|
delProcessRouteItemParam(param.id)
|
.then(res => {
|
ElMessage.success("删除成功");
|
emit("refresh");
|
})
|
.catch(err => {
|
ElMessage.error("删除参数失败");
|
console.error("删除参数失败:", err);
|
});
|
})
|
.catch(() => {});
|
};
|
|
// 获取可选参数列表
|
const getBaseParamListData = () => {
|
getBaseParamList({
|
paramName: paramSearchKeyword.value,
|
current: paramPage.current,
|
size: paramPage.size,
|
}).then(res => {
|
if (res.code === 200) {
|
filteredParamList.value = res.data?.records || [];
|
paramPage.total = res.data?.total || 0;
|
} else {
|
ElMessage.error(res.msg || "查询失败");
|
}
|
});
|
};
|
|
// 选择参数
|
const handleSelectParam = param => {
|
selectedParam.value = param;
|
};
|
|
// 提交选择参数
|
const handleParamSelectSubmit = () => {
|
if (!selectedParam.value) {
|
ElMessage.warning("请先选择一个参数");
|
return;
|
}
|
|
if (!props.process || !props.process.id) {
|
ElMessage.error("工艺路线项目信息不完整");
|
return;
|
}
|
|
// 判断参数类型,只有数值类型才传标准值、最大值和最小值
|
const isNumericMode = selectedParam.value.valueMode === 1;
|
|
// 调用API新增参数
|
addProcessRouteItemParam({
|
routeItemId: props.process.id,
|
paramId: selectedParam.value.id,
|
standardValue: isNumericMode ? selectedParam.value.standardValue || "" : "",
|
minValue: isNumericMode ? selectedParam.value.minValue || 0 : null,
|
maxValue: isNumericMode ? selectedParam.value.maxValue || 0 : null,
|
isRequired: selectedParam.value.isRequired || 0,
|
sort: selectedParam.value.sort || 1,
|
})
|
.then(res => {
|
if (res.code === 200) {
|
ElMessage.success("添加参数成功");
|
selectParamDialogVisible.value = false;
|
emit("refresh");
|
} else {
|
ElMessage.error(res.msg || "添加参数失败");
|
}
|
})
|
.catch(err => {
|
ElMessage.error("添加参数失败");
|
console.error("添加参数失败:", err);
|
});
|
};
|
|
// 提交编辑参数
|
const handleEditParamSubmit = () => {
|
if (!editParamFormRef.value) return;
|
editParamFormRef.value.validate(valid => {
|
if (valid) {
|
// 判断参数类型,只有数值类型才传标准值、最大值和最小值
|
const isNumericMode = editParamForm.value.valueMode == 1;
|
|
// 调用API修改参数
|
editProcessRouteItemParam({
|
id: editParamForm.value.id,
|
routeItemId: props.process.id,
|
paramId: editParamForm.value.paramId,
|
standardValue: isNumericMode
|
? editParamForm.value.standardValue || ""
|
: "",
|
minValue: isNumericMode ? editParamForm.value.minValue || 0 : null,
|
maxValue: isNumericMode ? editParamForm.value.maxValue || 0 : null,
|
isRequired: editParamForm.value.isRequired || 0,
|
})
|
.then(res => {
|
if (res.code === 200) {
|
ElMessage.success("编辑成功");
|
editParamDialogVisible.value = false;
|
emit("refresh");
|
} else {
|
ElMessage.error(res.msg || "编辑失败");
|
}
|
})
|
.catch(err => {
|
ElMessage.error("编辑参数失败");
|
console.error("编辑参数失败:", err);
|
});
|
}
|
});
|
};
|
|
// 获取参数类型标签
|
const getParamTypeTag = type => {
|
const typeMap = {
|
1: "primary",
|
2: "info",
|
3: "warning",
|
4: "success",
|
};
|
return typeMap[type] || "default";
|
};
|
|
// 获取参数类型文本
|
const getParamTypeText = type => {
|
const typeMap = {
|
1: "数值格式",
|
2: "文本格式",
|
3: "下拉选项",
|
4: "时间格式",
|
};
|
return typeMap[type] || type;
|
};
|
|
watch(
|
() => props.modelValue,
|
newVal => {
|
if (!newVal) {
|
// 弹窗关闭时重置数据
|
selectParamDialogVisible.value = false;
|
editParamDialogVisible.value = false;
|
selectedParam.value = null;
|
paramSearchKeyword.value = "";
|
paramPage.current = 1;
|
filteredParamList.value = [];
|
editParamForm.value = {
|
id: null,
|
processId: null,
|
paramId: null,
|
paramName: "",
|
valueMode: "1",
|
standardValue: null,
|
minValue: null,
|
maxValue: null,
|
sort: 1,
|
isRequired: 0,
|
paramType: null,
|
paramFormat: "",
|
unit: "",
|
};
|
}
|
}
|
);
|
</script>
|
|
<style scoped>
|
.param-list-container {
|
padding: 10px 0;
|
}
|
|
.params-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 15px;
|
padding-bottom: 10px;
|
border-bottom: 1px solid #e4e7ed;
|
}
|
|
.params-header span {
|
font-size: 16px;
|
font-weight: 500;
|
color: #303133;
|
}
|
|
.params-list {
|
max-height: 400px;
|
overflow-y: auto;
|
}
|
|
.param-item {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 12px 16px;
|
margin-bottom: 8px;
|
background-color: #f9f9f9;
|
border-radius: 4px;
|
transition: all 0.3s ease;
|
}
|
|
.param-item:hover {
|
background-color: #ecf5ff;
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
}
|
|
.param-info {
|
display: flex;
|
align-items: center;
|
gap: 20px;
|
flex: 1;
|
}
|
|
.param-code {
|
font-weight: 500;
|
color: #303133;
|
min-width: 120px;
|
}
|
|
.param-value {
|
color: #606266;
|
font-size: 14px;
|
}
|
|
.param-actions {
|
display: flex;
|
gap: 10px;
|
}
|
|
/* 滚动条样式 */
|
.params-list::-webkit-scrollbar {
|
width: 6px;
|
}
|
|
.params-list::-webkit-scrollbar-track {
|
background: #f1f1f1;
|
border-radius: 3px;
|
}
|
|
.params-list::-webkit-scrollbar-thumb {
|
background: #c1c1c1;
|
border-radius: 3px;
|
}
|
|
.params-list::-webkit-scrollbar-thumb:hover {
|
background: #a8a8a8;
|
}
|
|
/* 选择参数对话框样式 */
|
.param-select-container {
|
display: flex;
|
gap: 20px;
|
}
|
|
.param-list-area {
|
flex: 1;
|
min-width: 400px;
|
}
|
|
.param-detail-area {
|
flex: 1;
|
min-width: 300px;
|
}
|
|
.area-title {
|
font-size: 14px;
|
font-weight: 500;
|
margin-bottom: 10px;
|
color: #303133;
|
}
|
|
.search-box {
|
display: flex;
|
gap: 10px;
|
margin-bottom: 10px;
|
}
|
|
.param-detail-form {
|
background: #f9f9f9;
|
padding: 15px;
|
border-radius: 4px;
|
}
|
|
.detail-text {
|
font-weight: 500;
|
}
|
</style>
|