From 2de51b11d22291c0b204378154fc407c1ea8b691 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期三, 14 一月 2026 14:39:11 +0800
Subject: [PATCH] fix: 参考中天的[检测标准]页面,设置总分两张表,总表代表着一个检测标准汇总(也要根据质检类型去选择),分表代表这个检测标准汇总下具体的检测参数信息。
---
src/views/qualityManagement/metricMaintenance/StandardFormDialog.vue | 129 ++++
src/views/qualityManagement/metricMaintenance/index0.vue | 415 +++++++++++++
src/api/system/message.js | 2
src/components/PIMTable/PIMTable.vue | 28
src/views/qualityManagement/metricMaintenance/index.vue | 1012 +++++++++++++++++++++------------
src/api/basicData/productProcess.js | 10
src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue | 78 ++
src/api/qualityManagement/metricMaintenance.js | 97 ++
8 files changed, 1,373 insertions(+), 398 deletions(-)
diff --git a/src/api/basicData/productProcess.js b/src/api/basicData/productProcess.js
new file mode 100644
index 0000000..e0208fa
--- /dev/null
+++ b/src/api/basicData/productProcess.js
@@ -0,0 +1,10 @@
+import request from '@/utils/request'
+
+// 宸ュ簭鍒楄〃鍒嗛〉鏌ヨ
+export function productProcessListPage(query) {
+ return request({
+ url: '/productProcess/listPage',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/src/api/qualityManagement/metricMaintenance.js b/src/api/qualityManagement/metricMaintenance.js
index 9bdff23..2f71bb1 100644
--- a/src/api/qualityManagement/metricMaintenance.js
+++ b/src/api/qualityManagement/metricMaintenance.js
@@ -1,45 +1,90 @@
-import request from '@/utils/request'
+import request from "@/utils/request";
// 鏌ヨ鎸囨爣鍒楄〃
export function qualityTestStandardListPage(query) {
- return request({
- url: '/quality/qualityTestStandard/listPage',
- method: 'get',
- params: query,
- })
+ return request({
+ url: "/qualityTestStandard/listPage",
+ method: "get",
+ params: query,
+ });
}
// 鏂板鎸囨爣鍒楄〃
export function qualityTestStandardAdd(query) {
- return request({
- url: '/quality/qualityTestStandard/add',
- method: 'post',
- data: query,
- })
+ return request({
+ url: "/qualityTestStandard/add",
+ method: "post",
+ data: query,
+ });
}
// 淇敼鎸囨爣鍒楄〃
export function qualityTestStandardUpdate(query) {
- return request({
- url: '/quality/qualityTestStandard/update',
- method: 'post',
- data: query,
- })
+ return request({
+ url: "/qualityTestStandard/update",
+ method: "post",
+ data: query,
+ });
}
// 鍒犻櫎鎸囨爣鍒楄〃
export function qualityTestStandardDel(query) {
- return request({
- url: '/quality/qualityTestStandard/del',
- method: 'delete',
- data: query,
- })
+ return request({
+ url: "/qualityTestStandard/del",
+ method: "delete",
+ data: query,
+ });
}
// 鍒犻櫎鎸囨爣鍒楄〃
export function qualityInspectDetailByProductId(productId) {
- return request({
- url: '/quality/qualityTestStandard/product/' + productId,
- method: 'get',
- })
-}
\ No newline at end of file
+ return request({
+ url: "/qualityTestStandard/product/" + productId,
+ method: "get",
+ });
+}
+
+// 澶嶅埗鏍囧噯鍙傛暟
+export function qualityTestStandardCopyParam(id) {
+ return request({
+ url: "/qualityTestStandard/copyParam",
+ method: "post",
+ data: { id },
+ });
+}
+
+// 鏍囧噯鍙傛暟锛氬垪琛紙涓嶅垎椤碉級
+export function qualityTestStandardParamList(query) {
+ return request({
+ url: "/qualityTestStandardParam/list",
+ method: "get",
+ params: query,
+ });
+}
+
+// 鏍囧噯鍙傛暟锛氭柊澧�
+export function qualityTestStandardParamAdd(data) {
+ return request({
+ url: "/qualityTestStandardParam/add",
+ method: "post",
+ data,
+ });
+}
+
+// 鏍囧噯鍙傛暟锛氫慨鏀�
+export function qualityTestStandardParamUpdate(data) {
+ return request({
+ url: "/qualityTestStandardParam/update",
+ method: "post",
+ data,
+ });
+}
+
+// 鏍囧噯鍙傛暟锛氬垹闄わ紙浼� id 鏁扮粍锛�
+export function qualityTestStandardParamDel(ids) {
+ return request({
+ url: "/qualityTestStandardParam/del",
+ method: "delete",
+ data: ids,
+ });
+}
diff --git a/src/api/system/message.js b/src/api/system/message.js
index 871d7e8..dd81cc5 100644
--- a/src/api/system/message.js
+++ b/src/api/system/message.js
@@ -30,7 +30,7 @@
// 涓�閿爣璁版墍鏈夋秷鎭负宸茶
export function markAllAsRead() {
return request({
- url: "/system/notice/markAllAsRead",
+ url: "/system/notice/readAll",
method: "post",
});
}
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index 1fa1695..ac4656d 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -46,6 +46,16 @@
:type="item.type"
:width="item.width"
>
+ <template #header="scope">
+ <div class="pim-table-header-cell">
+ <div class="pim-table-header-title">
+ {{ item.label }}
+ </div>
+ <div v-if="item.headerSlot" class="pim-table-header-extra">
+ <slot :name="item.headerSlot" :column="scope.column" />
+ </div>
+ </div>
+ </template>
<template
v-if="item.hasOwnProperty('colunmTemplate')"
#[item.colunmTemplate]="scope"
@@ -429,4 +439,22 @@
padding-right: 0 !important;
padding-left: 0 !important;
}
+
+.pim-table-header-cell {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 4px;
+ text-align: center;
+}
+
+.pim-table-header-title {
+ font-weight: 500;
+}
+
+.pim-table-header-extra :deep(.el-input),
+.pim-table-header-extra :deep(.el-select) {
+ width: 100%;
+}
</style>
diff --git a/src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue b/src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue
new file mode 100644
index 0000000..4c958a0
--- /dev/null
+++ b/src/views/qualityManagement/metricMaintenance/ParamFormDialog.vue
@@ -0,0 +1,78 @@
+<template>
+ <FormDialog
+ v-model="dialogVisible"
+ :title="computedTitle"
+ :operation-type="operationType"
+ width="520px"
+ @close="emit('close')"
+ @cancel="handleCancel"
+ @confirm="handleConfirm"
+ >
+ <el-form
+ ref="formRef"
+ :model="form"
+ :rules="rules"
+ label-width="100px"
+ >
+ <el-form-item label="鍙傛暟椤�" prop="parameterItem">
+ <el-input v-model="form.parameterItem" placeholder="璇疯緭鍏ュ弬鏁伴」" />
+ </el-form-item>
+ <el-form-item label="鍗曚綅" prop="unit">
+ <el-input v-model="form.unit" placeholder="璇疯緭鍏ュ崟浣�" />
+ </el-form-item>
+ <el-form-item label="鏍囧噯鍊�" prop="standardValue">
+ <el-input v-model="form.standardValue" placeholder="璇疯緭鍏ユ爣鍑嗗��" />
+ </el-form-item>
+ <el-form-item label="鍐呮帶鍊�" prop="controlValue">
+ <el-input v-model="form.controlValue" placeholder="璇疯緭鍏ュ唴鎺у��" />
+ </el-form-item>
+ <el-form-item label="榛樿鍊�" prop="defaultValue">
+ <el-input v-model="form.defaultValue" placeholder="璇疯緭鍏ラ粯璁ゅ��" />
+ </el-form-item>
+ </el-form>
+ </FormDialog>
+</template>
+
+<script setup>
+import { computed, ref } from 'vue'
+import FormDialog from '@/components/Dialog/FormDialog.vue'
+
+const props = defineProps({
+ modelValue: { type: Boolean, default: false },
+ operationType: { type: String, default: 'add' }, // add | edit
+ form: { type: Object, required: true }
+})
+
+const emit = defineEmits(['update:modelValue', 'close', 'cancel', 'confirm'])
+
+const dialogVisible = computed({
+ get: () => props.modelValue,
+ set: (val) => emit('update:modelValue', val)
+})
+
+const formRef = ref(null)
+
+const rules = {
+ parameterItem: [{ required: true, message: '璇疯緭鍏ュ弬鏁伴」', trigger: 'blur' }],
+ unit: [{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: 'blur' }]
+}
+
+const computedTitle = computed(() => (props.operationType === 'edit' ? '缂栬緫鏍囧噯鍙傛暟' : '鏂板鏍囧噯鍙傛暟'))
+
+const handleConfirm = () => {
+ formRef.value?.validate?.((valid) => {
+ if (valid) emit('confirm')
+ })
+}
+
+const handleCancel = () => {
+ emit('cancel')
+ dialogVisible.value = false
+}
+
+const resetFields = () => {
+ formRef.value?.resetFields?.()
+}
+
+defineExpose({ resetFields })
+</script>
diff --git a/src/views/qualityManagement/metricMaintenance/StandardFormDialog.vue b/src/views/qualityManagement/metricMaintenance/StandardFormDialog.vue
new file mode 100644
index 0000000..38d535a
--- /dev/null
+++ b/src/views/qualityManagement/metricMaintenance/StandardFormDialog.vue
@@ -0,0 +1,129 @@
+<template>
+ <FormDialog
+ v-model="dialogVisible"
+ :title="computedTitle"
+ :operation-type="operationType"
+ :width="width"
+ @close="emit('close')"
+ @cancel="handleCancel"
+ @confirm="handleConfirm"
+ >
+ <el-form
+ ref="formRef"
+ :model="form"
+ :rules="rules"
+ label-width="100px"
+ >
+ <el-form-item label="鏍囧噯缂栧彿" prop="standardNo">
+ <el-input v-model="form.standardNo" placeholder="璇疯緭鍏ユ爣鍑嗙紪鍙�" />
+ </el-form-item>
+ <el-form-item label="鏍囧噯鍚嶇О" prop="standardName">
+ <el-input v-model="form.standardName" placeholder="璇疯緭鍏ユ爣鍑嗗悕绉�" />
+ </el-form-item>
+ <el-form-item label="绫诲埆" prop="inspectType">
+ <el-select v-model="form.inspectType" placeholder="璇烽�夋嫨绫诲埆" style="width: 100%">
+ <el-option label="鍘熸潗鏂欐楠�" value="0" />
+ <el-option label="杩囩▼妫�楠�" value="1" />
+ <el-option label="鍑哄巶妫�楠�" value="2" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="宸ュ簭" prop="processId">
+ <el-select v-model="form.processId" placeholder="璇烽�夋嫨宸ュ簭" style="width: 100%">
+ <el-option
+ v-for="item in processOptions"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鐘舵��" prop="state">
+ <el-select v-model="form.state" placeholder="璇烽�夋嫨鐘舵��" style="width: 100%">
+ <el-option label="鑽夌" value="0" />
+ <el-option label="閫氳繃" value="1" />
+ <el-option label="鎾ら攢" value="2" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="澶囨敞" prop="remark">
+ <el-input
+ v-model="form.remark"
+ type="textarea"
+ :rows="3"
+ placeholder="璇疯緭鍏ュ娉�"
+ />
+ </el-form-item>
+ </el-form>
+ </FormDialog>
+</template>
+
+<script setup>
+import { computed, ref } from 'vue'
+import FormDialog from '@/components/Dialog/FormDialog.vue'
+
+const props = defineProps({
+ modelValue: {
+ type: Boolean,
+ default: false
+ },
+ operationType: {
+ type: String,
+ default: 'add'
+ },
+ form: {
+ type: Object,
+ required: true
+ },
+ rules: {
+ type: Object,
+ default: () => ({})
+ },
+ processOptions: {
+ type: Array,
+ default: () => []
+ },
+ width: {
+ type: String,
+ default: '500px'
+ }
+})
+
+const emit = defineEmits(['update:modelValue', 'close', 'cancel', 'confirm'])
+
+const dialogVisible = computed({
+ get: () => props.modelValue,
+ set: (val) => emit('update:modelValue', val)
+})
+
+const formRef = ref(null)
+
+const computedTitle = computed(() => {
+ if (props.operationType === 'edit') return '缂栬緫妫�娴嬫爣鍑�'
+ if (props.operationType === 'copy') return '澶嶅埗妫�娴嬫爣鍑�'
+ return '鏂板妫�娴嬫爣鍑�'
+})
+
+const handleConfirm = () => {
+ if (!formRef.value) {
+ emit('confirm')
+ return
+ }
+ formRef.value.validate((valid) => {
+ if (valid) {
+ emit('confirm')
+ }
+ })
+}
+
+const handleCancel = () => {
+ emit('cancel')
+ dialogVisible.value = false
+}
+
+const resetFields = () => {
+ formRef.value?.resetFields?.()
+}
+
+defineExpose({
+ resetFields
+})
+</script>
diff --git a/src/views/qualityManagement/metricMaintenance/index.vue b/src/views/qualityManagement/metricMaintenance/index.vue
index 016a4c1..4f62bca 100644
--- a/src/views/qualityManagement/metricMaintenance/index.vue
+++ b/src/views/qualityManagement/metricMaintenance/index.vue
@@ -1,415 +1,685 @@
<template>
- <div class="app-container product-view">
- <div class="left">
- <div>
- <el-input
- v-model="search"
- style="width: 210px"
- placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
- @change="searchFilter"
- @clear="searchFilter"
+ <div class="app-container metric-maintenance">
+ <!-- 宸︿晶锛氭娴嬫爣鍑嗗垪琛� -->
+ <div class="left-panel">
+ <div class="toolbar">
+ <div class="toolbar-left"></div>
+ <div class="toolbar-right">
+ <el-button type="primary" @click="openStandardDialog('add')">鏂板</el-button>
+ <el-button type="danger" plain @click="handleBatchDelete">鍒犻櫎</el-button>
+ </div>
+ </div>
+ <PIMTable
+ rowKey="id"
+ :column="standardColumns"
+ :tableData="standardTableData"
+ :page="page"
+ :isSelection="true"
+ :tableLoading="tableLoading"
+ @selection-change="handleSelectionChange"
+ @pagination="handlePagination"
+ :total="page.total"
+ >
+ <template #standardNoCell="{ row }">
+ <span class="clickable-link" @click="handleStandardRowClick(row)">
+ {{ row.standardNo }}
+ </span>
+ </template>
+
+ <!-- 琛ㄥご鎼滅储鎻掓Ы -->
+ <template #standardNoHeader>
+ <el-input
+ v-model="searchForm.standardNo"
+ placeholder="鏍囧噯缂栧彿"
clearable
- prefix-icon="Search"
- />
- </div>
- <div ref="containerRef">
- <el-tree
- ref="tree"
- v-loading="treeLoad"
- :data="list"
- @node-click="handleNodeClick"
- :expand-on-click-node="false"
- default-expand-all
- :default-expanded-keys="expandedKeys"
- :draggable="true"
- :filter-node-method="filterNode"
- :props="{ children: 'children', label: 'label' }"
- highlight-current
- node-key="id"
- style="
- height: calc(100vh - 190px);
- overflow-y: scroll;
- scrollbar-width: none;
- "
- >
- <template #default="{ node, data }">
- <div class="custom-tree-node">
- <span class="tree-node-content">
- <el-icon class="orange-icon">
- <component :is="data.children && data.children.length > 0
- ? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" />
- </el-icon>
- {{ data.label }}
- </span>
- </div>
- </template>
- </el-tree>
- </div>
+ size="small"
+ @change="handleQuery"
+ @clear="handleQuery"
+ />
+ </template>
+ <template #standardNameHeader>
+ <el-input
+ v-model="searchForm.standardName"
+ placeholder="鏍囧噯鍚嶇О"
+ clearable
+ size="small"
+ @change="handleQuery"
+ @clear="handleQuery"
+ />
+ </template>
+ <template #inspectTypeHeader>
+ <el-select
+ v-model="searchForm.inspectType"
+ placeholder="绫诲埆"
+ clearable
+ size="small"
+ style="width: 120px"
+ @change="handleQuery"
+ @clear="handleQuery"
+ >
+ <el-option label="鍘熸潗鏂欐楠�" value="0" />
+ <el-option label="杩囩▼妫�楠�" value="1" />
+ <el-option label="鍑哄巶妫�楠�" value="2" />
+ </el-select>
+ </template>
+ <template #stateHeader>
+ <el-select
+ v-model="searchForm.state"
+ placeholder="鐘舵��"
+ clearable
+ size="small"
+ style="width: 110px"
+ @change="handleQuery"
+ @clear="handleQuery"
+ >
+ <el-option label="鑽夌" value="0" />
+ <el-option label="閫氳繃" value="1" />
+ <el-option label="鎾ら攢" value="2" />
+ </el-select>
+ </template>
+ </PIMTable>
</div>
- <div class="right">
- <div style="margin-bottom: 10px">
- <el-button type="primary" @click="openModelDia('add')">
- 鏂板妫�娴嬫寚鏍�
+
+ <!-- 鍙充晶锛氭爣鍑嗗弬鏁板垪琛� -->
+ <div class="right-panel">
+ <div class="right-header">
+ <div class="title">鏍囧噯鍙傛暟</div>
+ <div class="desc" v-if="currentStandard">
+ 鎮ㄥ綋鍓嶉�夋嫨鐨勬娴嬫爣鍑嗙紪鍙锋槸锛�
+ <span class="link-text">{{ currentStandard.standardNo }}</span>
+ </div>
+ <div class="desc" v-else>璇峰厛鍦ㄥ乏渚ч�夋嫨涓�涓娴嬫爣鍑�</div>
+ </div>
+
+ <div class="right-toolbar">
+ <el-button type="primary" :disabled="!currentStandard" @click="openParamDialog('add')">
+ 鏂板
</el-button>
- <el-button @click="handleOut">瀵煎嚭</el-button>
- <el-button
- type="danger"
- @click="handleDelete"
- style="margin-left: 10px"
- plain
- >
+ <el-button type="danger" plain :disabled="!currentStandard" @click="handleParamBatchDelete">
鍒犻櫎
</el-button>
</div>
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :isSelection="true"
- @selection-change="handleSelectionChange"
- :tableLoading="tableLoading"
- @pagination="pagination"
- :total="page.total"
- ></PIMTable>
- </div>
- <el-dialog
- v-model="modelDia"
- title="妫�娴嬫寚鏍�"
- width="400px"
- @close="closeModelDia"
- >
- <el-form
- :model="modelForm"
- label-width="140px"
- label-position="top"
- :rules="modelRules"
- ref="modelFormRef"
+
+ <el-table
+ v-loading="detailLoading"
+ :data="detailTableData"
+ border
+ style="width: 100%"
+ height="calc(100vh - 220px)"
+ @selection-change="handleParamSelectionChange"
>
- <el-row>
- <el-col :span="24">
- <el-form-item label="鎸囨爣锛�" prop="parameterItem">
- <el-input
- v-model="modelForm.parameterItem"
- placeholder="璇疯緭鍏ユ寚鏍�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
- <el-form-item label="鍗曚綅锛�" prop="unit">
- <el-input
- v-model="modelForm.unit"
- placeholder="璇疯緭鍏ュ崟浣�"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
- <el-form-item label="鏍囧噯鍊硷細" prop="standardValue">
- <el-input
- v-model="modelForm.standardValue"
- placeholder="璇疯緭鍏ユ爣鍑嗗��"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="24">
- <el-form-item label="鍐呮帶鍊硷細" prop="controlValue">
- <el-input
- v-model="modelForm.controlValue"
- placeholder="璇疯緭鍏ュ唴鎺у��"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="submitModelForm">纭</el-button>
- <el-button @click="closeModelDia">鍙栨秷</el-button>
- </div>
- </template>
- </el-dialog>
+ <el-table-column type="selection" width="48" align="center" />
+ <el-table-column type="index" label="搴忓彿" width="60" align="center" />
+ <el-table-column prop="parameterItem" label="鍙傛暟椤�" min-width="120" />
+ <el-table-column prop="unit" label="鍗曚綅" width="80" />
+ <el-table-column prop="standardValue" label="鏍囧噯鍊�" min-width="120" />
+ <el-table-column prop="controlValue" label="鍐呮帶鍊�" min-width="120" />
+ <el-table-column prop="defaultValue" label="榛樿鍊�" min-width="120" />
+ <el-table-column label="鎿嶄綔" width="140" fixed="right" align="center">
+ <template #default="{ row }">
+ <el-button link type="primary" size="small" @click="openParamDialog('edit', row)">
+ 缂栬緫
+ </el-button>
+ <el-button link type="danger" size="small" @click="handleParamDelete(row)">
+ 鍒犻櫎
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+
+ <!-- 鏂板 / 缂栬緫妫�娴嬫爣鍑� -->
+ <StandardFormDialog
+ ref="standardFormDialogRef"
+ v-model="standardDialogVisible"
+ :operation-type="standardOperationType"
+ :form="standardForm"
+ :rules="standardRules"
+ :process-options="processOptions"
+ @confirm="submitStandardForm"
+ @close="closeStandardDialog"
+ @cancel="closeStandardDialog"
+ />
+
+ <ParamFormDialog
+ ref="paramFormDialogRef"
+ v-model="paramDialogVisible"
+ :operation-type="paramOperationType"
+ :form="paramForm"
+ @confirm="submitParamForm"
+ @close="closeParamDialog"
+ @cancel="closeParamDialog"
+ />
</div>
</template>
<script setup>
-import {ref} from "vue";
-import {addOrEditProductModel, delProductModel, modelListPage, productTreeList} from "@/api/basicData/product.js";
-import ImportExcel from "@/views/basicData/product/ImportExcel/index.vue";
-import {ElMessageBox} from "element-plus";
+import { Search } from '@element-plus/icons-vue'
+import { ref, reactive, toRefs, onMounted, getCurrentInstance } from 'vue'
+import { ElMessageBox } from 'element-plus'
import {
- qualityTestStandardAdd, qualityTestStandardDel,
qualityTestStandardListPage,
- qualityTestStandardUpdate
-} from "@/api/qualityManagement/metricMaintenance.js";
-const { proxy } = getCurrentInstance();
-// 鏍�
-const search = ref("");
-const treeLoad = ref(false);
-const list = ref([]);
-const expandedKeys = ref([]);
-const currentId = ref("");
-const currentParentId = ref("");
-// 鎸囨爣琛ㄦ牸
-const tableData = ref([]);
-const tableLoading = ref(false);
+ qualityTestStandardAdd,
+ qualityTestStandardUpdate,
+ qualityTestStandardDel,
+ qualityTestStandardCopyParam,
+ qualityTestStandardParamList,
+ qualityTestStandardParamAdd,
+ qualityTestStandardParamUpdate,
+ qualityTestStandardParamDel
+} from '@/api/qualityManagement/metricMaintenance.js'
+import { productProcessListPage } from '@/api/basicData/productProcess.js'
+import StandardFormDialog from './StandardFormDialog.vue'
+import ParamFormDialog from './ParamFormDialog.vue'
+
+const { proxy } = getCurrentInstance()
+
+// 鎼滅储鏉′欢
+const data = reactive({
+ searchForm: {
+ standardNo: '',
+ standardName: '',
+ remark: '',
+ state: '',
+ inspectType: '',
+ processId: ''
+ },
+ standardForm: {
+ id: undefined,
+ standardNo: '',
+ standardName: '',
+ remark: '',
+ state: '0',
+ inspectType: '',
+ processId: ''
+ },
+ standardRules: {
+ standardNo: [{ required: true, message: '璇疯緭鍏ユ爣鍑嗙紪鍙�', trigger: 'blur' }],
+ standardName: [{ required: true, message: '璇疯緭鍏ユ爣鍑嗗悕绉�', trigger: 'blur' }],
+ inspectType: [{ required: true, message: '璇烽�夋嫨妫�娴嬬被鍨�', trigger: 'change' }],
+ processId: [{ required: true, message: '璇烽�夋嫨宸ュ簭', trigger: 'change' }]
+ }
+})
+
+const { searchForm, standardForm, standardRules } = toRefs(data)
+
+// 宸︿晶琛ㄦ牸
+const standardTableData = ref([])
+const selectedRows = ref([])
+const tableLoading = ref(false)
const page = reactive({
current: 1,
size: 10,
-});
-const tableColumn = ref([
+ total: 0
+})
+
+// 宸ュ簭涓嬫媺
+const processOptions = ref([])
+
+// 鑾峰彇宸ュ簭鍒楄〃
+const getProcessList = async () => {
+ try {
+ const res = await productProcessListPage({ current: 1, size: 1000 })
+ if (res?.code === 200) {
+ const records = res?.data?.records || []
+ processOptions.value = records.map(item => ({
+ label: item.processName || item.name || item.label,
+ value: item.id || item.processId || item.value
+ }))
+ }
+ } catch (error) {
+ console.error('鑾峰彇宸ュ簭鍒楄〃澶辫触:', error)
+ }
+}
+
+// 褰撳墠閫変腑鐨勬爣鍑� & 鍙充晶璇︽儏
+const currentStandard = ref(null)
+const detailTableData = ref([])
+const detailLoading = ref(false)
+const paramSelectedRows = ref([])
+const paramDialogVisible = ref(false)
+const paramOperationType = ref('add') // add | edit
+const paramFormDialogRef = ref(null)
+const paramForm = reactive({
+ id: undefined,
+ parameterItem: '',
+ unit: '',
+ standardValue: '',
+ controlValue: '',
+ defaultValue: ''
+})
+
+// 寮圭獥
+const standardDialogVisible = ref(false)
+const standardOperationType = ref('add') // add | edit | copy
+const standardFormDialogRef = ref(null)
+
+// 鍒楀畾涔�
+const standardColumns = ref([
{
- label: "鎸囨爣",
- prop: "parameterItem",
+ label: '鏍囧噯缂栧彿',
+ prop: 'standardNo',
+ dataType: 'slot',
+ slot: 'standardNoCell',
+ minWidth: 160,
+ headerSlot: 'standardNoHeader'
},
{
- label: "鍗曚綅",
- prop: "unit",
+ label: '鏍囧噯鍚嶇О',
+ prop: 'standardName',
+ minWidth: 180,
+ headerSlot: 'standardNameHeader'
},
{
- label: "鏍囧噯鍊�",
- prop: "standardValue",
+ label: '绫诲埆',
+ prop: 'inspectType',
+ headerSlot: 'inspectTypeHeader',
+ dataType: 'tag',
+ formatData: (val) => {
+ const map = {
+ 0: '鍘熸潗鏂欐楠�',
+ 1: '杩囩▼妫�楠�',
+ 2: '鍑哄巶妫�楠�'
+ }
+ return map[val] || val
+ }
},
{
- label: "鍐呮帶鍊�",
- prop: "controlValue",
+ label: '宸ュ簭',
+ prop: 'processId'
},
{
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
+ label: '鐘舵��',
+ prop: 'state',
+ headerSlot: 'stateHeader',
+ dataType: 'tag',
+ formatData: (val) => {
+ const map = {
+ 0: '鑽夌',
+ 1: '閫氳繃',
+ 2: '鎾ら攢'
+ }
+ return map[val] || val
+ },
+ formatType: (val) => {
+ if (val === '1' || val === 1) return 'success'
+ if (val === '2' || val === 2) return 'warning'
+ return 'info'
+ }
+ },
+ {
+ label: '澶囨敞',
+ prop: 'remark',
+ minWidth: 160
+ },
+ {
+ dataType: 'action',
+ label: '鎿嶄綔',
+ align: 'center',
+ fixed: 'right',
+ width: 220,
operation: [
{
- name: "缂栬緫",
- type: "text",
+ name: '缂栬緫',
+ type: 'text',
clickFun: (row) => {
- openModelDia("edit", row);
- },
+ openStandardDialog('edit', row)
+ }
},
- ],
- },
-]);
-const selectedRows = ref([]);
-// 鎸囨爣寮规
-const modelDia = ref(false);
-const modelOperationType = ref("");
-const data = reactive({
- modelForm: {
- parameterItem: "",
- unit: "",
- standardValue: "",
- controlValue: "",
- },
- modelRules: {
- parameterItem: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- standardValue: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- controlValue: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- },
-});
-const { modelForm, modelRules } = toRefs(data);
-
-// 鏌ヨ浜у搧鏍�
-const getProductTreeList = () => {
- treeLoad.value = true;
- productTreeList().then((res) => {
- list.value = res;
- list.value.forEach((a) => {
- expandedKeys.value.push(a.label);
- });
- treeLoad.value = false;
- }).catch((err) => {
- treeLoad.value = false;
- });
-};
-// 杩囨护浜у搧鏍�
-const searchFilter = () => {
- proxy.$refs.tree.filter(search.value);
-};
-// 閫夋嫨浜у搧
-const handleNodeClick = (val, node, el) => {
- // 鍙湁鍙跺瓙鑺傜偣鎵嶆墽琛屼互涓嬮�昏緫
- currentId.value = val.id;
- currentParentId.value = val.parentId;
- getModelList();
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-// 鏌ヨ鎸囨爣鏁版嵁
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getModelList();
-};
-const getModelList = () => {
- tableLoading.value = true;
- qualityTestStandardListPage({
- productId: currentId.value,
- current: page.current,
- size: page.size,
- }).then((res) => {
- tableData.value = res.data.records;
- page.total = res.data.total;
- tableLoading.value = false;
- });
-};
-// 璋冪敤tree杩囨护鏂规硶 涓枃鑻辫繃婊�
-const filterNode = (value, data, node) => {
- if (!value) {
- //濡傛灉鏁版嵁涓虹┖锛屽垯杩斿洖true,鏄剧ず鎵�鏈夌殑鏁版嵁椤�
- return true;
- }
- // 鏌ヨ鍒楄〃鏄惁鏈夊尮閰嶆暟鎹紝灏嗗�煎皬鍐欙紝鍖归厤鑻辨枃鏁版嵁
- let val = value.toLowerCase();
- return chooseNode(val, data, node); // 璋冪敤杩囨护浜屽眰鏂规硶
-};
-// 杩囨护鐖惰妭鐐� / 瀛愯妭鐐� (濡傛灉杈撳叆鐨勫弬鏁版槸鐖惰妭鐐逛笖鑳藉尮閰嶏紝鍒欒繑鍥炶鑺傜偣浠ュ強鍏朵笅鐨勬墍鏈夊瓙鑺傜偣锛涘鏋滃弬鏁版槸瀛愯妭鐐癸紝鍒欒繑鍥炶鑺傜偣鐨勭埗鑺傜偣銆俷ame鏄腑鏂囧瓧绗︼紝enName鏄嫳鏂囧瓧绗�.
-const chooseNode = (value, data, node) => {
- if (data.label.indexOf(value) !== -1) {
- return true;
- }
- const level = node.level;
- // 濡傛灉浼犲叆鐨勮妭鐐规湰韬氨鏄竴绾ц妭鐐瑰氨涓嶇敤鏍¢獙浜�
- if (level === 1) {
- return false;
- }
- // 鍏堝彇褰撳墠鑺傜偣鐨勭埗鑺傜偣
- let parentData = node.parent;
- // 閬嶅巻褰撳墠鑺傜偣鐨勭埗鑺傜偣
- let index = 0;
- while (index < level - 1) {
- // 濡傛灉鍖归厤鍒扮洿鎺ヨ繑鍥烇紝姝ゅname鍊兼槸涓枃瀛楃锛宔nName鏄嫳鏂囧瓧绗︺�傚垽鏂尮閰嶄腑鑻辨枃杩囨护
- if (parentData.data.label.indexOf(value) !== -1) {
- return true;
- }
- // 鍚﹀垯鐨勮瘽鍐嶅線涓婁竴灞傚仛鍖归厤
- parentData = parentData.parent;
- index++;
- }
- // 娌″尮閰嶅埌杩斿洖false
- return false;
-};
-// 鎵撳紑鎸囨爣寮规
-const openModelDia = (type, data) => {
- modelOperationType.value = type;
- modelDia.value = true;
- modelForm.value.model = "";
- modelForm.value.model = "";
- modelForm.value.id = "";
- if (type === "edit") {
- modelForm.value = { ...data };
- }
-};
-// 瀵煎嚭
-const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(() => {
- proxy.download("/quality/qualityTestStandard/export", {}, "妫�娴嬫寚鏍�.xlsx");
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 鍒犻櫎鎸囨爣
-const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- ids = selectedRows.value.map((item) => item.id);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(() => {
- tableLoading.value = true;
- qualityTestStandardDel(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getModelList();
- }).finally(() => {
- tableLoading.value = false;
- });
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-
-// 鎻愪氦瑙勬牸鍨嬪彿淇敼
-const submitModelForm = () => {
- proxy.$refs.modelFormRef.validate((valid) => {
- if (valid) {
- modelForm.value.productId = Number(currentId.value);
- if(modelOperationType.value === 'add') {
- qualityTestStandardAdd(modelForm.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeModelDia();
- getModelList();
- });
- } else {
- qualityTestStandardUpdate(modelForm.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeModelDia();
- getModelList();
- });
+ {
+ name: '澶嶅埗',
+ type: 'text',
+ clickFun: async (row) => {
+ if (!row?.id) return
+ try {
+ await ElMessageBox.confirm('纭澶嶅埗璇ユ爣鍑嗗弬鏁帮紵', '鎻愮ず', { type: 'warning' })
+ } catch {
+ return
+ }
+ await qualityTestStandardCopyParam(row.id)
+ proxy.$message.success('澶嶅埗鎴愬姛')
+ getStandardList()
+ if (currentStandard.value?.id === row.id) {
+ loadDetail(row.id)
+ }
+ }
+ },
+ {
+ name: '鍒犻櫎',
+ type: 'text',
+ clickFun: (row) => {
+ handleDelete(row)
+ }
}
- }
- });
-};
-// 鍏抽棴鍨嬪彿寮规
-const closeModelDia = () => {
- proxy.$refs.modelFormRef.resetFields();
- modelDia.value = false;
-};
-getProductTreeList();
+ ]
+ }
+])
+
+// 鏌ヨ鍒楄〃
+const getStandardList = () => {
+ tableLoading.value = true
+ const params = {
+ ...searchForm.value,
+ current: page.current,
+ size: page.size
+ }
+ qualityTestStandardListPage(params)
+ .then((res) => {
+ const records = res?.data?.records || []
+ standardTableData.value = records
+ page.total = res?.data?.total || records.length
+ })
+ .finally(() => {
+ tableLoading.value = false
+ })
+}
+
+const handleQuery = () => {
+ page.current = 1
+ getStandardList()
+}
+
+const resetQuery = () => {
+ searchForm.value.standardNo = ''
+ searchForm.value.standardName = ''
+ searchForm.value.remark = ''
+ searchForm.value.state = ''
+ searchForm.value.inspectType = ''
+ searchForm.value.processId = ''
+ handleQuery()
+}
+
+const handlePagination = (obj) => {
+ page.current = obj.page
+ page.size = obj.limit
+ getStandardList()
+}
+
+const handleSelectionChange = (selection) => {
+ selectedRows.value = selection
+}
+
+// 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶鍙傛暟
+const handleStandardRowClick = (row) => {
+ currentStandard.value = row
+ loadDetail(row.id)
+}
+
+const loadDetail = (standardId) => {
+ if (!standardId) {
+ detailTableData.value = []
+ return
+ }
+ detailLoading.value = true
+ qualityTestStandardParamList({ testStandardId: standardId }).then((res) => {
+ detailTableData.value = res?.data || []
+ })
+ .finally(() => {
+ detailLoading.value = false
+ })
+}
+
+const handleParamSelectionChange = (selection) => {
+ paramSelectedRows.value = selection
+}
+
+const openParamDialog = (type, row) => {
+ if (!currentStandard.value?.id) return
+ paramOperationType.value = type
+ if (type === 'add') {
+ Object.assign(paramForm, {
+ id: undefined,
+ parameterItem: '',
+ unit: '',
+ standardValue: '',
+ controlValue: '',
+ defaultValue: ''
+ })
+ } else if (type === 'edit' && row) {
+ Object.assign(paramForm, row)
+ }
+ paramDialogVisible.value = true
+}
+
+const closeParamDialog = () => {
+ paramDialogVisible.value = false
+ paramFormDialogRef.value?.resetFields?.()
+}
+
+const submitParamForm = async () => {
+ const testStandardId = currentStandard.value?.id
+ if (!testStandardId) return
+ const payload = { ...paramForm, testStandardId }
+ if (paramOperationType.value === 'edit') {
+ await qualityTestStandardParamUpdate(payload)
+ proxy.$message.success('鎻愪氦鎴愬姛')
+ } else {
+ await qualityTestStandardParamAdd(payload)
+ proxy.$message.success('鎻愪氦鎴愬姛')
+ }
+ closeParamDialog()
+ loadDetail(testStandardId)
+}
+
+const handleParamDelete = async (row) => {
+ if (!row?.id) return
+ try {
+ await ElMessageBox.confirm('纭鍒犻櫎璇ュ弬鏁帮紵', '鎻愮ず', { type: 'warning' })
+ } catch {
+ return
+ }
+ await qualityTestStandardParamDel([row.id])
+ proxy.$message.success('鍒犻櫎鎴愬姛')
+ loadDetail(currentStandard.value?.id)
+}
+
+const handleParamBatchDelete = async () => {
+ if (!paramSelectedRows.value.length) {
+ proxy.$message.warning('璇烽�夋嫨鏁版嵁')
+ return
+ }
+ const ids = paramSelectedRows.value.map((i) => i.id)
+ try {
+ await ElMessageBox.confirm('閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�', '鍒犻櫎鎻愮ず', { type: 'warning' })
+ } catch {
+ return
+ }
+ await qualityTestStandardParamDel(ids)
+ proxy.$message.success('鍒犻櫎鎴愬姛')
+ loadDetail(currentStandard.value?.id)
+}
+
+// 鏂板 / 缂栬緫 / 澶嶅埗
+const openStandardDialog = (type, row) => {
+ standardOperationType.value = type
+ if (type === 'add') {
+ Object.assign(standardForm.value, {
+ id: undefined,
+ standardNo: '',
+ standardName: '',
+ remark: '',
+ state: '0',
+ inspectType: '',
+ processId: ''
+ })
+ } else if (type === 'edit' && row) {
+ Object.assign(standardForm.value, row)
+ } else if (type === 'copy' && row) {
+ const { id, ...rest } = row
+ Object.assign(standardForm.value, {
+ ...rest,
+ id: undefined,
+ standardNo: '',
+ state: '0'
+ })
+ }
+ standardDialogVisible.value = true
+}
+
+const closeStandardDialog = () => {
+ standardDialogVisible.value = false
+ standardFormDialogRef.value?.resetFields?.()
+}
+
+const submitStandardForm = () => {
+ const payload = { ...standardForm.value }
+ const isEdit = standardOperationType.value === 'edit'
+ if (isEdit) {
+ qualityTestStandardUpdate(payload).then(() => {
+ proxy.$message.success('鎻愪氦鎴愬姛')
+ standardDialogVisible.value = false
+ getStandardList()
+ })
+ } else {
+ qualityTestStandardAdd(payload).then(() => {
+ proxy.$message.success('鎻愪氦鎴愬姛')
+ standardDialogVisible.value = false
+ getStandardList()
+ })
+ }
+}
+
+// 鍒犻櫎锛堝崟鏉★級
+const handleDelete = (row) => {
+ const ids = [row.id]
+ ElMessageBox.confirm('閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�', '鍒犻櫎鎻愮ず', {
+ confirmButtonText: '纭',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ })
+ .then(() => {
+ tableLoading.value = true
+ qualityTestStandardDel(ids)
+ .then(() => {
+ proxy.$message.success('鍒犻櫎鎴愬姛')
+ getStandardList()
+ if (currentStandard.value && currentStandard.value.id === row.id) {
+ currentStandard.value = null
+ detailTableData.value = []
+ }
+ })
+ .finally(() => {
+ tableLoading.value = false
+ })
+ })
+ .catch(() => {
+ proxy.$modal?.msg('宸插彇娑�')
+ })
+}
+
+// 鎵归噺鍒犻櫎
+const handleBatchDelete = () => {
+ if (!selectedRows.value.length) {
+ proxy.$message.warning('璇烽�夋嫨鏁版嵁')
+ return
+ }
+ const ids = selectedRows.value.map((item) => item.id)
+ ElMessageBox.confirm('閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�', '鍒犻櫎鎻愮ず', {
+ confirmButtonText: '纭',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ })
+ .then(() => {
+ tableLoading.value = true
+ qualityTestStandardDel(ids)
+ .then(() => {
+ proxy.$message.success('鍒犻櫎鎴愬姛')
+ getStandardList()
+ if (currentStandard.value && ids.includes(currentStandard.value.id)) {
+ currentStandard.value = null
+ detailTableData.value = []
+ }
+ })
+ .finally(() => {
+ tableLoading.value = false
+ })
+ })
+ .catch(() => {
+ proxy.$modal?.msg('宸插彇娑�')
+ })
+}
+
+onMounted(() => {
+ getProcessList()
+ getStandardList()
+})
</script>
<style scoped>
-.product-view {
+.metric-maintenance {
display: flex;
+ gap: 16px;
}
-.left {
- width: 380px;
- padding: 16px;
- background: #ffffff;
-}
-.right {
- width: calc(100% - 380px);
- padding: 16px;
- margin-left: 20px;
- background: #ffffff;
-}
-.custom-tree-node {
+
+.left-panel,
+.right-panel {
flex: 1;
+ background: #ffffff;
+ padding: 16px;
+ box-sizing: border-box;
+}
+
+.toolbar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 12px;
+}
+
+.toolbar-left {
display: flex;
align-items: center;
- justify-content: space-between;
- font-size: 14px;
- padding-right: 8px;
+ flex-wrap: wrap;
+ gap: 4px;
}
-.tree-node-content {
+
+.toolbar-right {
+ flex-shrink: 0;
+}
+
+.search-label {
+ margin: 0 4px 0 12px;
+}
+
+.search-label:first-of-type {
+ margin-left: 0;
+}
+
+.right-header {
display: flex;
- align-items: center; /* 鍨傜洿灞呬腑 */
- height: 100%;
+ align-items: baseline;
+ justify-content: space-between;
+ margin-bottom: 10px;
}
-.orange-icon {
- color: orange;
- font-size: 18px;
- margin-right: 8px; /* 鍥炬爣涓庢枃瀛椾箣闂村姞鐐归棿璺� */
+
+.right-header .title {
+ font-size: 16px;
+ font-weight: 600;
+}
+
+.right-header .desc {
+ font-size: 13px;
+ color: #666;
+}
+
+.right-toolbar {
+ display: flex;
+ justify-content: flex-end;
+ gap: 10px;
+ margin-bottom: 10px;
+}
+
+.link-text {
+ color: #409eff;
+ cursor: default;
+}
+
+.clickable-link {
+ color: #409eff;
+ cursor: pointer;
+}
+
+.clickable-link:hover {
+ text-decoration: underline;
}
</style>
\ No newline at end of file
diff --git a/src/views/qualityManagement/metricMaintenance/index0.vue b/src/views/qualityManagement/metricMaintenance/index0.vue
new file mode 100644
index 0000000..016a4c1
--- /dev/null
+++ b/src/views/qualityManagement/metricMaintenance/index0.vue
@@ -0,0 +1,415 @@
+<template>
+ <div class="app-container product-view">
+ <div class="left">
+ <div>
+ <el-input
+ v-model="search"
+ style="width: 210px"
+ placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
+ @change="searchFilter"
+ @clear="searchFilter"
+ clearable
+ prefix-icon="Search"
+ />
+ </div>
+ <div ref="containerRef">
+ <el-tree
+ ref="tree"
+ v-loading="treeLoad"
+ :data="list"
+ @node-click="handleNodeClick"
+ :expand-on-click-node="false"
+ default-expand-all
+ :default-expanded-keys="expandedKeys"
+ :draggable="true"
+ :filter-node-method="filterNode"
+ :props="{ children: 'children', label: 'label' }"
+ highlight-current
+ node-key="id"
+ style="
+ height: calc(100vh - 190px);
+ overflow-y: scroll;
+ scrollbar-width: none;
+ "
+ >
+ <template #default="{ node, data }">
+ <div class="custom-tree-node">
+ <span class="tree-node-content">
+ <el-icon class="orange-icon">
+ <component :is="data.children && data.children.length > 0
+ ? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" />
+ </el-icon>
+ {{ data.label }}
+ </span>
+ </div>
+ </template>
+ </el-tree>
+ </div>
+ </div>
+ <div class="right">
+ <div style="margin-bottom: 10px">
+ <el-button type="primary" @click="openModelDia('add')">
+ 鏂板妫�娴嬫寚鏍�
+ </el-button>
+ <el-button @click="handleOut">瀵煎嚭</el-button>
+ <el-button
+ type="danger"
+ @click="handleDelete"
+ style="margin-left: 10px"
+ plain
+ >
+ 鍒犻櫎
+ </el-button>
+ </div>
+ <PIMTable
+ rowKey="id"
+ :column="tableColumn"
+ :tableData="tableData"
+ :page="page"
+ :isSelection="true"
+ @selection-change="handleSelectionChange"
+ :tableLoading="tableLoading"
+ @pagination="pagination"
+ :total="page.total"
+ ></PIMTable>
+ </div>
+ <el-dialog
+ v-model="modelDia"
+ title="妫�娴嬫寚鏍�"
+ width="400px"
+ @close="closeModelDia"
+ >
+ <el-form
+ :model="modelForm"
+ label-width="140px"
+ label-position="top"
+ :rules="modelRules"
+ ref="modelFormRef"
+ >
+ <el-row>
+ <el-col :span="24">
+ <el-form-item label="鎸囨爣锛�" prop="parameterItem">
+ <el-input
+ v-model="modelForm.parameterItem"
+ placeholder="璇疯緭鍏ユ寚鏍�"
+ clearable
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-col :span="24">
+ <el-form-item label="鍗曚綅锛�" prop="unit">
+ <el-input
+ v-model="modelForm.unit"
+ placeholder="璇疯緭鍏ュ崟浣�"
+ clearable
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-col :span="24">
+ <el-form-item label="鏍囧噯鍊硷細" prop="standardValue">
+ <el-input
+ v-model="modelForm.standardValue"
+ placeholder="璇疯緭鍏ユ爣鍑嗗��"
+ clearable
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-col :span="24">
+ <el-form-item label="鍐呮帶鍊硷細" prop="controlValue">
+ <el-input
+ v-model="modelForm.controlValue"
+ placeholder="璇疯緭鍏ュ唴鎺у��"
+ clearable
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary" @click="submitModelForm">纭</el-button>
+ <el-button @click="closeModelDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import {ref} from "vue";
+import {addOrEditProductModel, delProductModel, modelListPage, productTreeList} from "@/api/basicData/product.js";
+import ImportExcel from "@/views/basicData/product/ImportExcel/index.vue";
+import {ElMessageBox} from "element-plus";
+import {
+ qualityTestStandardAdd, qualityTestStandardDel,
+ qualityTestStandardListPage,
+ qualityTestStandardUpdate
+} from "@/api/qualityManagement/metricMaintenance.js";
+const { proxy } = getCurrentInstance();
+// 鏍�
+const search = ref("");
+const treeLoad = ref(false);
+const list = ref([]);
+const expandedKeys = ref([]);
+const currentId = ref("");
+const currentParentId = ref("");
+// 鎸囨爣琛ㄦ牸
+const tableData = ref([]);
+const tableLoading = ref(false);
+const page = reactive({
+ current: 1,
+ size: 10,
+});
+const tableColumn = ref([
+ {
+ label: "鎸囨爣",
+ prop: "parameterItem",
+ },
+ {
+ label: "鍗曚綅",
+ prop: "unit",
+ },
+ {
+ label: "鏍囧噯鍊�",
+ prop: "standardValue",
+ },
+ {
+ label: "鍐呮帶鍊�",
+ prop: "controlValue",
+ },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ operation: [
+ {
+ name: "缂栬緫",
+ type: "text",
+ clickFun: (row) => {
+ openModelDia("edit", row);
+ },
+ },
+ ],
+ },
+]);
+const selectedRows = ref([]);
+// 鎸囨爣寮规
+const modelDia = ref(false);
+const modelOperationType = ref("");
+const data = reactive({
+ modelForm: {
+ parameterItem: "",
+ unit: "",
+ standardValue: "",
+ controlValue: "",
+ },
+ modelRules: {
+ parameterItem: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ standardValue: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ controlValue: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ },
+});
+const { modelForm, modelRules } = toRefs(data);
+
+// 鏌ヨ浜у搧鏍�
+const getProductTreeList = () => {
+ treeLoad.value = true;
+ productTreeList().then((res) => {
+ list.value = res;
+ list.value.forEach((a) => {
+ expandedKeys.value.push(a.label);
+ });
+ treeLoad.value = false;
+ }).catch((err) => {
+ treeLoad.value = false;
+ });
+};
+// 杩囨护浜у搧鏍�
+const searchFilter = () => {
+ proxy.$refs.tree.filter(search.value);
+};
+// 閫夋嫨浜у搧
+const handleNodeClick = (val, node, el) => {
+ // 鍙湁鍙跺瓙鑺傜偣鎵嶆墽琛屼互涓嬮�昏緫
+ currentId.value = val.id;
+ currentParentId.value = val.parentId;
+ getModelList();
+};
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+ selectedRows.value = selection;
+};
+// 鏌ヨ鎸囨爣鏁版嵁
+const pagination = (obj) => {
+ page.current = obj.page;
+ page.size = obj.limit;
+ getModelList();
+};
+const getModelList = () => {
+ tableLoading.value = true;
+ qualityTestStandardListPage({
+ productId: currentId.value,
+ current: page.current,
+ size: page.size,
+ }).then((res) => {
+ tableData.value = res.data.records;
+ page.total = res.data.total;
+ tableLoading.value = false;
+ });
+};
+// 璋冪敤tree杩囨护鏂规硶 涓枃鑻辫繃婊�
+const filterNode = (value, data, node) => {
+ if (!value) {
+ //濡傛灉鏁版嵁涓虹┖锛屽垯杩斿洖true,鏄剧ず鎵�鏈夌殑鏁版嵁椤�
+ return true;
+ }
+ // 鏌ヨ鍒楄〃鏄惁鏈夊尮閰嶆暟鎹紝灏嗗�煎皬鍐欙紝鍖归厤鑻辨枃鏁版嵁
+ let val = value.toLowerCase();
+ return chooseNode(val, data, node); // 璋冪敤杩囨护浜屽眰鏂规硶
+};
+// 杩囨护鐖惰妭鐐� / 瀛愯妭鐐� (濡傛灉杈撳叆鐨勫弬鏁版槸鐖惰妭鐐逛笖鑳藉尮閰嶏紝鍒欒繑鍥炶鑺傜偣浠ュ強鍏朵笅鐨勬墍鏈夊瓙鑺傜偣锛涘鏋滃弬鏁版槸瀛愯妭鐐癸紝鍒欒繑鍥炶鑺傜偣鐨勭埗鑺傜偣銆俷ame鏄腑鏂囧瓧绗︼紝enName鏄嫳鏂囧瓧绗�.
+const chooseNode = (value, data, node) => {
+ if (data.label.indexOf(value) !== -1) {
+ return true;
+ }
+ const level = node.level;
+ // 濡傛灉浼犲叆鐨勮妭鐐规湰韬氨鏄竴绾ц妭鐐瑰氨涓嶇敤鏍¢獙浜�
+ if (level === 1) {
+ return false;
+ }
+ // 鍏堝彇褰撳墠鑺傜偣鐨勭埗鑺傜偣
+ let parentData = node.parent;
+ // 閬嶅巻褰撳墠鑺傜偣鐨勭埗鑺傜偣
+ let index = 0;
+ while (index < level - 1) {
+ // 濡傛灉鍖归厤鍒扮洿鎺ヨ繑鍥烇紝姝ゅname鍊兼槸涓枃瀛楃锛宔nName鏄嫳鏂囧瓧绗︺�傚垽鏂尮閰嶄腑鑻辨枃杩囨护
+ if (parentData.data.label.indexOf(value) !== -1) {
+ return true;
+ }
+ // 鍚﹀垯鐨勮瘽鍐嶅線涓婁竴灞傚仛鍖归厤
+ parentData = parentData.parent;
+ index++;
+ }
+ // 娌″尮閰嶅埌杩斿洖false
+ return false;
+};
+// 鎵撳紑鎸囨爣寮规
+const openModelDia = (type, data) => {
+ modelOperationType.value = type;
+ modelDia.value = true;
+ modelForm.value.model = "";
+ modelForm.value.model = "";
+ modelForm.value.id = "";
+ if (type === "edit") {
+ modelForm.value = { ...data };
+ }
+};
+// 瀵煎嚭
+const handleOut = () => {
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ }).then(() => {
+ proxy.download("/quality/qualityTestStandard/export", {}, "妫�娴嬫寚鏍�.xlsx");
+ }).catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+};
+
+// 鍒犻櫎鎸囨爣
+const handleDelete = () => {
+ let ids = [];
+ if (selectedRows.value.length > 0) {
+ ids = selectedRows.value.map((item) => item.id);
+ } else {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
+ }
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ }).then(() => {
+ tableLoading.value = true;
+ qualityTestStandardDel(ids).then((res) => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getModelList();
+ }).finally(() => {
+ tableLoading.value = false;
+ });
+ }).catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+};
+
+// 鎻愪氦瑙勬牸鍨嬪彿淇敼
+const submitModelForm = () => {
+ proxy.$refs.modelFormRef.validate((valid) => {
+ if (valid) {
+ modelForm.value.productId = Number(currentId.value);
+ if(modelOperationType.value === 'add') {
+ qualityTestStandardAdd(modelForm.value).then((res) => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeModelDia();
+ getModelList();
+ });
+ } else {
+ qualityTestStandardUpdate(modelForm.value).then((res) => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeModelDia();
+ getModelList();
+ });
+ }
+ }
+ });
+};
+// 鍏抽棴鍨嬪彿寮规
+const closeModelDia = () => {
+ proxy.$refs.modelFormRef.resetFields();
+ modelDia.value = false;
+};
+getProductTreeList();
+</script>
+
+<style scoped>
+.product-view {
+ display: flex;
+}
+.left {
+ width: 380px;
+ padding: 16px;
+ background: #ffffff;
+}
+.right {
+ width: calc(100% - 380px);
+ padding: 16px;
+ margin-left: 20px;
+ background: #ffffff;
+}
+.custom-tree-node {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ font-size: 14px;
+ padding-right: 8px;
+}
+.tree-node-content {
+ display: flex;
+ align-items: center; /* 鍨傜洿灞呬腑 */
+ height: 100%;
+}
+.orange-icon {
+ color: orange;
+ font-size: 18px;
+ margin-right: 8px; /* 鍥炬爣涓庢枃瀛椾箣闂村姞鐐归棿璺� */
+}
+</style>
\ No newline at end of file
--
Gitblit v1.9.3