From 9ea5ff67655241271bdf04bb50ca3a8d60c4e22a Mon Sep 17 00:00:00 2001
From: yuan <123@>
Date: 星期二, 11 八月 2026 15:07:02 +0800
Subject: [PATCH] fix: 用河南鹤壁代码覆盖山西长治
---
src/views/qualityManagement/metricBinding/index.vue | 1095 ++++++++++++++++++++++++++++++--------------------------
1 files changed, 584 insertions(+), 511 deletions(-)
diff --git a/src/views/qualityManagement/metricBinding/index.vue b/src/views/qualityManagement/metricBinding/index.vue
index 6e7a881..ba989ea 100644
--- a/src/views/qualityManagement/metricBinding/index.vue
+++ b/src/views/qualityManagement/metricBinding/index.vue
@@ -1,167 +1,168 @@
<template>
<div class="app-container metric-binding">
- <el-row :gutter="16"
- class="metric-binding-row">
+ <el-row :gutter="16" class="metric-binding-row">
<!-- 宸︿晶锛氭娴嬫爣鍑嗗垪琛� -->
- <el-col :xs="24"
- :sm="24"
- :md="12"
- :lg="14"
- :xl="14"
- class="left-col">
+ <el-col :xs="24" :sm="24" :md="12" :lg="14" :xl="14" class="left-col">
<div class="panel left-panel">
- <PIMTable rowKey="id"
- :column="standardColumns"
- :tableData="standardTableData"
- :page="page"
- :isSelection="false"
- :rowClassName="rowClassNameCenter"
- :tableLoading="tableLoading"
- :rowClick="handleTableRowClick"
- @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
- 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>
+ <PIMTable
+ rowKey="id"
+ :column="standardColumns"
+ :tableData="standardTableData"
+ :page="page"
+ :isSelection="false"
+ :rowClassName="rowClassNameCenter"
+ :tableLoading="tableLoading"
+ :rowClick="handleTableRowClick"
+ @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
+ 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>
</el-col>
+
<!-- 鍙充晶锛氱粦瀹氬垪琛� -->
- <el-col :xs="24"
- :sm="24"
- :md="12"
- :lg="10"
- :xl="10"
- class="right-col">
+ <el-col :xs="24" :sm="24" :md="12" :lg="10" :xl="10" class="right-col">
<div class="panel 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="openBindingDialog">娣诲姞缁戝畾</el-button>
- <el-button type="danger"
- plain
- :disabled="!currentStandard"
- @click="handleBatchUnbind">鍒犻櫎</el-button>
- </div>
- <el-table v-loading="bindingLoading"
- :data="bindingTableData"
- border
- :row-class-name="() => 'row-center'"
- class="center-table"
- style="width: 100%"
- height="calc(100vh - 220px)"
- @selection-change="handleBindingSelectionChange">
- <el-table-column type="selection"
- width="48"
- align="center" />
- <el-table-column type="index"
- label="搴忓彿"
- width="60"
- align="center" />
- <el-table-column prop="productName"
- label="浜у搧鍚嶇О"
- min-width="140" />
- <el-table-column label="鎿嶄綔"
- width="120"
- fixed="right"
- align="center">
- <template #default="{ row }">
- <el-button link
- type="danger"
- size="small"
- @click="handleUnbind(row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
+ <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="openBindingDialog">娣诲姞缁戝畾</el-button>
+ <el-button type="danger" plain :disabled="!currentStandard" @click="handleBatchUnbind">鍒犻櫎</el-button>
+ </div>
+
+ <el-table
+ v-loading="bindingLoading"
+ :data="bindingTableData"
+ border
+ :row-class-name="() => 'row-center'"
+ class="center-table"
+ style="width: 100%"
+ height="calc(100vh - 220px)"
+ @selection-change="handleBindingSelectionChange"
+ >
+ <el-table-column type="selection" width="48" align="center" />
+ <el-table-column type="index" label="搴忓彿" width="60" align="center" />
+ <el-table-column prop="productName" label="浜у搧鍚嶇О" min-width="140" />
+ <el-table-column label="鎿嶄綔" width="120" fixed="right" align="center">
+ <template #default="{ row }">
+ <el-button link type="danger" size="small" @click="handleUnbind(row)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
</div>
</el-col>
</el-row>
+
<!-- 娣诲姞缁戝畾寮规 -->
- <el-dialog v-model="bindingDialogVisible"
- title="娣诲姞缁戝畾"
- width="520px"
- @close="closeBindingDialog">
- <el-form label-width="100px">
- <el-form-item label="浜у搧">
- <PIMTreeSelect v-model="selectedProductIds"
- multiple
- filterable
- collapse-tags
- collapse-tags-tooltip
- placeholder="璇烽�夋嫨浜у搧锛堝彲澶氶�夛級"
- clearable
- check-strictly
- :data="productOptions"
- :render-after-expand="false"
- style="width: 100%" />
- </el-form-item>
- </el-form>
+ <el-dialog
+ v-model="bindingDialogVisible"
+ title="娣诲姞缁戝畾"
+ width="640px"
+ @close="closeBindingDialog"
+ >
+ <div class="binding-dialog">
+ <el-input
+ v-model="productSearchKeyword"
+ placeholder="鎼滅储浜у搧"
+ clearable
+ prefix-icon="Search"
+ class="binding-search"
+ />
+ <el-tree
+ ref="productTreeRef"
+ :key="productTreeKey"
+ v-loading="productTreeLoading"
+ :data="productTreeData"
+ show-checkbox
+ check-strictly
+ node-key="id"
+ :props="{ label: 'label', children: 'children', disabled: 'disabled' }"
+ :filter-node-method="filterProductNode"
+ class="product-binding-tree"
+ @check="handleProductTreeCheck"
+ />
+ <div v-if="selectedProductLabels.length" class="selected-products">
+ <div class="selected-title">宸查�夋嫨锛坽{ selectedProductLabels.length }}锛�</div>
+ <div class="selected-tags">
+ <el-tag
+ v-for="item in selectedProductLabels"
+ :key="item.id"
+ closable
+ type="info"
+ @close="removeSelectedProduct(item.id)"
+ >
+ {{ item.label }}
+ </el-tag>
+ </div>
+ </div>
+ </div>
<template #footer>
<span class="dialog-footer">
<el-button @click="closeBindingDialog">鍙栨秷</el-button>
- <el-button type="primary"
- @click="submitBinding">纭畾</el-button>
+ <el-button type="primary" @click="submitBinding">纭畾</el-button>
</span>
</template>
</el-dialog>
@@ -169,404 +170,476 @@
</template>
<script setup>
- import { Search } from "@element-plus/icons-vue";
- import { ref, reactive, toRefs, onMounted, getCurrentInstance } from "vue";
- import { ElMessageBox } from "element-plus";
- import PIMTable from "@/components/PIMTable/PIMTable.vue";
- import PIMTreeSelect from "@/components/PIMTreeSelect/index.vue";
- import { productTreeList } from "@/api/basicData/product.js";
- import { qualityTestStandardListPage } from "@/api/qualityManagement/metricMaintenance.js";
- import { productProcessListPage } from "@/api/basicData/productProcess.js";
- import {
- qualityTestStandardBindingList,
- qualityTestStandardBindingAdd,
- qualityTestStandardBindingDel,
- } from "@/api/qualityManagement/qualityTestStandardBinding.js";
+import { ref, reactive, toRefs, computed, watch, nextTick, onMounted, getCurrentInstance } from 'vue'
+import { ElMessageBox } from 'element-plus'
+import PIMTable from '@/components/PIMTable/PIMTable.vue'
+import { productTreeList } from '@/api/basicData/product.js'
+import {
+ qualityTestStandardListPage
+} from '@/api/qualityManagement/metricMaintenance.js'
+import { productProcessListPage } from '@/api/basicData/productProcess.js'
+import {
+ qualityTestStandardBindingList,
+ qualityTestStandardBindingAdd,
+ qualityTestStandardBindingDel
+} from '@/api/qualityManagement/qualityTestStandardBinding.js'
- const { proxy } = getCurrentInstance();
+const { proxy } = getCurrentInstance()
- // 宸︿晶鏍囧噯鍒楄〃锛氭暣琛屽唴瀹瑰眳涓紙閰嶅悎鏍峰紡锛�
- const rowClassNameCenter = () => "row-center";
+// 宸︿晶鏍囧噯鍒楄〃锛氭暣琛屽唴瀹瑰眳涓紙閰嶅悎鏍峰紡锛�
+const rowClassNameCenter = () => 'row-center'
- const data = reactive({
- searchForm: {
- standardNo: "",
- standardName: "",
- state: "",
- inspectType: "",
- },
- });
- const { searchForm } = toRefs(data);
-
- // 宸︿晶
- const standardTableData = ref([]);
- const tableLoading = ref(false);
- const page = reactive({ current: 1, size: 10, 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 standardColumns = ref([
- {
- label: "鏍囧噯缂栧彿",
- prop: "standardNo",
- dataType: "slot",
- slot: "standardNoCell",
- minWidth: 160,
- align: "center",
- headerSlot: "standardNoHeader",
- },
- {
- label: "鏍囧噯鍚嶇О",
- prop: "standardName",
- minWidth: 180,
- align: "center",
- headerSlot: "standardNameHeader",
- },
- {
- label: "绫诲埆",
- prop: "inspectType",
- headerSlot: "inspectTypeHeader",
- align: "center",
- dataType: "tag",
- formatData: val => {
- const map = { 0: "鍘熸潗鏂欐楠�", 1: "杩囩▼妫�楠�", 2: "鍑哄巶妫�楠�" };
- return map[val] || val;
- },
- },
- {
- label: "宸ュ簭",
- prop: "processId",
- align: "center",
- dataType: "tag",
- formatData: val => {
- const target = processOptions.value.find(
- item => String(item.value) === String(val)
- );
- return target?.label || val;
- },
- },
- {
- label: "澶囨敞",
- prop: "remark",
- minWidth: 160,
- 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) return 'success'
- // if (val == 2) return 'warning'
- // return 'info'
- // }
- // }
- ]);
-
- const currentStandard = ref(null);
-
- // 鍙充晶缁戝畾
- const bindingTableData = ref([]);
- const bindingLoading = ref(false);
- const bindingSelectedRows = ref([]);
- const bindingDialogVisible = ref(false);
-
- // 浜у搧鏍戯紙鐢ㄤ簬缁戝畾閫夋嫨锛�
- const productOptions = ref([]);
- const selectedProductIds = ref([]);
-
- const getProductOptions = async () => {
- // 閬垮厤閲嶅璇锋眰
- if (productOptions.value?.length) return;
- const res = await productTreeList();
- productOptions.value = convertIdToValue(Array.isArray(res) ? res : []);
- };
-
- function convertIdToValue(data) {
- return (data || []).map(item => {
- const { id, children, ...rest } = item;
- const newItem = {
- ...rest,
- value: id,
- };
- if (children && children.length > 0) {
- newItem.children = convertIdToValue(children);
- }
- return newItem;
- });
+const data = reactive({
+ searchForm: {
+ standardNo: '',
+ standardName: '',
+ state: '',
+ inspectType: ''
}
+})
+const { searchForm } = toRefs(data)
- const handleQuery = () => {
- page.current = 1;
- getStandardList();
- };
+// 宸︿晶
+const standardTableData = ref([])
+const tableLoading = ref(false)
+const page = reactive({ current: 1, size: 10, total: 0 })
- const handlePagination = obj => {
- page.current = obj.page;
- page.size = obj.limit;
- getStandardList();
- };
+// 宸ュ簭涓嬫媺锛堢敤浜庡垪琛ㄥ洖鏄撅級
+const processOptions = ref([])
- const getStandardList = () => {
- tableLoading.value = true;
- qualityTestStandardListPage({
- ...searchForm.value,
- current: page.current,
- size: page.size,
- state: 1,
+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 standardColumns = ref([
+ { label: '鏍囧噯缂栧彿', prop: 'standardNo', dataType: 'slot', slot: 'standardNoCell', minWidth: 160, align: 'center', headerSlot: 'standardNoHeader' },
+ { label: '鏍囧噯鍚嶇О', prop: 'standardName', minWidth: 180, align: 'center', headerSlot: 'standardNameHeader' },
+ {
+ label: '绫诲埆',
+ prop: 'inspectType',
+ headerSlot: 'inspectTypeHeader',
+ align: 'center',
+ dataType: 'tag',
+ formatData: (val) => {
+ const map = { 0: '鍘熸潗鏂欐楠�', 1: '杩囩▼妫�楠�', 2: '鍑哄巶妫�楠�' }
+ return map[val] || val
+ }
+ },
+ {
+ label: '宸ュ簭',
+ prop: 'processId',
+ align: 'center',
+ dataType: 'tag',
+ formatData: (val) => {
+ const target = processOptions.value.find(
+ (item) => String(item.value) === String(val)
+ )
+ return target?.label || val
+ }
+ },
+ {
+ label: '澶囨敞',
+ prop: 'remark',
+ minWidth: 160,
+ 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) return 'success'
+ // if (val == 2) return 'warning'
+ // return 'info'
+ // }
+ // }
+])
+
+const currentStandard = ref(null)
+
+// 鍙充晶缁戝畾
+const bindingTableData = ref([])
+const bindingLoading = ref(false)
+const bindingSelectedRows = ref([])
+const bindingDialogVisible = ref(false)
+
+// 浜у搧鏍戯紙鐢ㄤ簬缁戝畾閫夋嫨锛�
+const productTreeData = ref([])
+const productTreeLoading = ref(false)
+const productTreeRef = ref(null)
+const productTreeKey = ref(0)
+const productSearchKeyword = ref('')
+const selectedProductIds = ref([])
+
+const markParentNodesDisabled = (nodes) => {
+ return (nodes || []).map((node) => {
+ const children = node.children?.length ? markParentNodesDisabled(node.children) : []
+ return {
+ ...node,
+ children,
+ disabled: children.length > 0
+ }
+ })
+}
+
+const buildProductLabelMap = (nodes, map = {}) => {
+ ;(nodes || []).forEach((node) => {
+ if (node.id != null) {
+ map[node.id] = node.label
+ }
+ if (node.children?.length) {
+ buildProductLabelMap(node.children, map)
+ }
+ })
+ return map
+}
+
+const productLabelMap = computed(() => buildProductLabelMap(productTreeData.value))
+
+const selectedProductLabels = computed(() =>
+ selectedProductIds.value.map((id) => ({
+ id,
+ label: productLabelMap.value[id] || id
+ }))
+)
+
+const filterProductNode = (value, data) => {
+ if (!value) return true
+ return String(data.label || '').includes(value)
+}
+
+watch(productSearchKeyword, (val) => {
+ productTreeRef.value?.filter(val)
+})
+
+const getProductTreeData = async () => {
+ if (productTreeData.value?.length) return
+ productTreeLoading.value = true
+ try {
+ const res = await productTreeList()
+ productTreeData.value = markParentNodesDisabled(Array.isArray(res) ? res : [])
+ } catch (error) {
+ console.error('鑾峰彇浜у搧鏍戝け璐�:', error)
+ } finally {
+ productTreeLoading.value = false
+ }
+}
+
+const handleProductTreeCheck = () => {
+ selectedProductIds.value = productTreeRef.value?.getCheckedKeys(true) || []
+}
+
+const removeSelectedProduct = (id) => {
+ selectedProductIds.value = selectedProductIds.value.filter((item) => item !== id)
+ productTreeRef.value?.setChecked(id, false, false)
+}
+
+const handleQuery = () => {
+ page.current = 1
+ getStandardList()
+}
+
+const handlePagination = (obj) => {
+ page.current = obj.page
+ page.size = obj.limit
+ getStandardList()
+}
+
+const getStandardList = () => {
+ tableLoading.value = true
+ qualityTestStandardListPage({
+ ...searchForm.value,
+ current: page.current,
+ size: page.size,
+ state: 1
+ })
+ .then((res) => {
+ const records = res?.data?.records || []
+ standardTableData.value = records
+ page.total = res?.data?.total || records.length
})
- .then(res => {
- const records = res?.data?.records || [];
- standardTableData.value = records;
- page.total = res?.data?.total || records.length;
- })
- .finally(() => {
- tableLoading.value = false;
- });
- };
+ .finally(() => {
+ tableLoading.value = false
+ })
+}
- // 琛ㄦ牸琛岀偣鍑伙紝鍔犺浇鍙充晶缁戝畾鍒楄〃
- const handleTableRowClick = row => {
- currentStandard.value = row;
- loadBindingList();
- };
+// 琛ㄦ牸琛岀偣鍑伙紝鍔犺浇鍙充晶缁戝畾鍒楄〃
+const handleTableRowClick = (row) => {
+ currentStandard.value = row
+ loadBindingList()
+}
- // 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶缁戝畾鍒楄〃锛堜繚鐣欑敤浜庢爣鍑嗙紪鍙峰垪鐨勭偣鍑伙級
- const handleStandardRowClick = row => {
- currentStandard.value = row;
- loadBindingList();
- };
+// 宸︿晶琛岀偣鍑伙紝鍔犺浇鍙充晶缁戝畾鍒楄〃锛堜繚鐣欑敤浜庢爣鍑嗙紪鍙峰垪鐨勭偣鍑伙級
+const handleStandardRowClick = (row) => {
+ currentStandard.value = row
+ loadBindingList()
+}
- const loadBindingList = () => {
- if (!currentStandard.value?.id) {
- bindingTableData.value = [];
- return;
- }
- bindingLoading.value = true;
- qualityTestStandardBindingList({ testStandardId: currentStandard.value.id })
- .then(res => {
- const base = res?.data || [];
- // 灏嗗綋鍓嶆爣鍑嗙殑宸ュ簭鍜屽娉ㄥ甫鍒扮粦瀹氬垪琛ㄤ腑灞曠ず
- bindingTableData.value = base.map(item => ({
- ...item,
- processId: currentStandard.value?.processId,
- remark: currentStandard.value?.remark,
- }));
- })
- .finally(() => {
- bindingLoading.value = false;
- });
- };
+const loadBindingList = () => {
+ if (!currentStandard.value?.id) {
+ bindingTableData.value = []
+ return
+ }
+ bindingLoading.value = true
+ qualityTestStandardBindingList({ testStandardId: currentStandard.value.id })
+ .then((res) => {
+ const base = res?.data || []
+ // 灏嗗綋鍓嶆爣鍑嗙殑宸ュ簭鍜屽娉ㄥ甫鍒扮粦瀹氬垪琛ㄤ腑灞曠ず
+ bindingTableData.value = base.map((item) => ({
+ ...item,
+ processId: currentStandard.value?.processId,
+ remark: currentStandard.value?.remark
+ }))
+ })
+ .finally(() => {
+ bindingLoading.value = false
+ })
+}
- const handleBindingSelectionChange = selection => {
- bindingSelectedRows.value = selection;
- };
+const handleBindingSelectionChange = (selection) => {
+ bindingSelectedRows.value = selection
+}
- const openBindingDialog = () => {
- if (!currentStandard.value?.id) return;
- selectedProductIds.value = [];
- getProductOptions();
- bindingDialogVisible.value = true;
- };
+const openBindingDialog = () => {
+ if (!currentStandard.value?.id) return
+ selectedProductIds.value = []
+ productSearchKeyword.value = ''
+ productTreeKey.value += 1
+ bindingDialogVisible.value = true
+ nextTick(() => {
+ productTreeRef.value?.setCheckedKeys([])
+ productTreeRef.value?.filter('')
+ })
+}
- const closeBindingDialog = () => {
- bindingDialogVisible.value = false;
- };
+const closeBindingDialog = () => {
+ bindingDialogVisible.value = false
+ selectedProductIds.value = []
+ productSearchKeyword.value = ''
+ productTreeRef.value?.setCheckedKeys([])
+}
- const submitBinding = async () => {
- const testStandardId = currentStandard.value?.id;
- if (!testStandardId) return;
- const ids = (selectedProductIds.value || []).filter(Boolean);
- if (!ids.length) {
- proxy.$message.warning("璇烽�夋嫨浜у搧");
- return;
- }
- const payload = ids.map(pid => ({
- productId: pid,
- testStandardId,
- }));
- await qualityTestStandardBindingAdd(payload);
- proxy.$message.success("娣诲姞鎴愬姛");
- bindingDialogVisible.value = false;
- loadBindingList();
- };
+const submitBinding = async () => {
+ const testStandardId = currentStandard.value?.id
+ if (!testStandardId) return
+ const ids = (selectedProductIds.value || []).filter(Boolean)
+ if (!ids.length) {
+ proxy.$message.warning('璇烽�夋嫨浜у搧')
+ return
+ }
+ const payload = ids.map((pid) => ({
+ productId: pid,
+ testStandardId
+ }))
+ await qualityTestStandardBindingAdd(payload)
+ proxy.$message.success('娣诲姞鎴愬姛')
+ bindingDialogVisible.value = false
+ loadBindingList()
+}
- const handleUnbind = async row => {
- const id = row?.id ?? row?.qualityTestStandardBindingId;
- if (id == null || id === "") return;
- try {
- await ElMessageBox.confirm("纭鍒犻櫎璇ョ粦瀹氾紵", "鎻愮ず", { type: "warning" });
- } catch {
- return;
- }
- try {
- await qualityTestStandardBindingDel([id]);
- proxy.$message.success("鍒犻櫎鎴愬姛");
- loadBindingList();
- } catch (err) {
- console.error("鍒犻櫎缁戝畾澶辫触:", err);
- proxy.$message?.error(err?.message || "鍒犻櫎澶辫触");
- }
- };
+const handleUnbind = async (row) => {
+ const id = row?.id ?? row?.qualityTestStandardBindingId
+ if (id == null || id === '') return
+ try {
+ await ElMessageBox.confirm('纭鍒犻櫎璇ョ粦瀹氾紵', '鎻愮ず', { type: 'warning' })
+ } catch {
+ return
+ }
+ try {
+ await qualityTestStandardBindingDel([id])
+ proxy.$message.success('鍒犻櫎鎴愬姛')
+ loadBindingList()
+ } catch (err) {
+ console.error('鍒犻櫎缁戝畾澶辫触:', err)
+ proxy.$message?.error(err?.message || '鍒犻櫎澶辫触')
+ }
+}
- const handleBatchUnbind = async () => {
- if (!bindingSelectedRows.value.length) {
- proxy.$message.warning("璇烽�夋嫨鏁版嵁");
- return;
- }
- const ids = bindingSelectedRows.value
- .map(i => i?.id ?? i?.qualityTestStandardBindingId)
- .filter(id => id != null && id !== "");
- if (!ids.length) {
- proxy.$message.warning("閫変腑鏁版嵁缂哄皯鏈夋晥 id");
- return;
- }
- try {
- await ElMessageBox.confirm(
- "閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�",
- "鍒犻櫎鎻愮ず",
- { type: "warning" }
- );
- } catch {
- return;
- }
- try {
- await qualityTestStandardBindingDel(ids);
- proxy.$message.success("鍒犻櫎鎴愬姛");
- loadBindingList();
- } catch (err) {
- console.error("鎵归噺鍒犻櫎缁戝畾澶辫触:", err);
- proxy.$message?.error(err?.message || "鍒犻櫎澶辫触");
- }
- };
+const handleBatchUnbind = async () => {
+ if (!bindingSelectedRows.value.length) {
+ proxy.$message.warning('璇烽�夋嫨鏁版嵁')
+ return
+ }
+ const ids = bindingSelectedRows.value
+ .map((i) => i?.id ?? i?.qualityTestStandardBindingId)
+ .filter((id) => id != null && id !== '')
+ if (!ids.length) {
+ proxy.$message.warning('閫変腑鏁版嵁缂哄皯鏈夋晥 id')
+ return
+ }
+ try {
+ await ElMessageBox.confirm('閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�', '鍒犻櫎鎻愮ず', { type: 'warning' })
+ } catch {
+ return
+ }
+ try {
+ await qualityTestStandardBindingDel(ids)
+ proxy.$message.success('鍒犻櫎鎴愬姛')
+ loadBindingList()
+ } catch (err) {
+ console.error('鎵归噺鍒犻櫎缁戝畾澶辫触:', err)
+ proxy.$message?.error(err?.message || '鍒犻櫎澶辫触')
+ }
+}
- onMounted(() => {
- getStandardList();
- getProcessList();
- });
+onMounted(() => {
+ getStandardList()
+ getProcessList()
+ getProductTreeData()
+})
</script>
<style scoped>
- .metric-binding-row {
- width: 100%;
- }
+.metric-binding-row {
+ width: 100%;
+}
- .metric-binding-row .left-col,
- .metric-binding-row .right-col {
- margin-bottom: 16px;
- }
+.metric-binding-row .left-col,
+.metric-binding-row .right-col {
+ margin-bottom: 16px;
+}
- .metric-binding-row .panel {
- background: #ffffff;
- padding: 16px;
- box-sizing: border-box;
- height: 100%;
- min-height: 400px;
- }
+.metric-binding-row .panel {
+ background: #ffffff;
+ padding: 16px;
+ box-sizing: border-box;
+ height: 100%;
+ min-height: 400px;
+}
- .left-panel,
- .right-panel {
- height: 100%;
- }
+.left-panel,
+.right-panel {
+ height: 100%;
+}
- .toolbar {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 12px;
- }
+.toolbar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 12px;
+}
- .toolbar-right {
- flex-shrink: 0;
- }
+.toolbar-right {
+ flex-shrink: 0;
+}
- .right-header {
- display: flex;
- align-items: baseline;
- justify-content: space-between;
- margin-bottom: 10px;
- }
+.right-header {
+ display: flex;
+ align-items: baseline;
+ justify-content: space-between;
+ margin-bottom: 10px;
+}
- .right-header .title {
- font-size: 16px;
- font-weight: 600;
- }
+.right-header .title {
+ font-size: 16px;
+ font-weight: 600;
+}
- .right-header .desc {
- font-size: 13px;
- color: #666;
- }
+.right-header .desc {
+ font-size: 13px;
+ color: #666;
+}
- .right-toolbar {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
- margin-bottom: 10px;
- }
+.right-toolbar {
+ display: flex;
+ justify-content: flex-end;
+ gap: 10px;
+ margin-bottom: 10px;
+}
- .link-text {
- color: #409eff;
- cursor: default;
- }
+.link-text {
+ color: #409eff;
+ cursor: default;
+}
- .clickable-link {
- color: #409eff;
- cursor: pointer;
- }
+.clickable-link {
+ color: #409eff;
+ cursor: pointer;
+}
- .clickable-link:hover {
- text-decoration: underline;
- }
+.clickable-link:hover {
+ text-decoration: underline;
+}
- :deep(.row-center td) {
- text-align: center !important;
- }
+:deep(.row-center td) {
+ text-align: center !important;
+}
- /* el-table 琛ㄥご/鍐呭缁熶竴灞呬腑锛坮ow-class-name 涓嶄綔鐢ㄤ簬琛ㄥご锛� */
- :deep(.center-table .el-table__header-wrapper th .cell) {
- text-align: center !important;
- }
- :deep(.center-table .el-table__body-wrapper td .cell) {
- text-align: center !important;
- }
+/* el-table 琛ㄥご/鍐呭缁熶竴灞呬腑锛坮ow-class-name 涓嶄綔鐢ㄤ簬琛ㄥご锛� */
+:deep(.center-table .el-table__header-wrapper th .cell) {
+ text-align: center !important;
+}
+:deep(.center-table .el-table__body-wrapper td .cell) {
+ text-align: center !important;
+}
- /* PIMTable 琛ㄥご灞呬腑 */
- :deep(.lims-table .pim-table-header-cell) {
- text-align: center;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- }
+/* PIMTable 琛ㄥご灞呬腑 */
+:deep(.lims-table .pim-table-header-cell) {
+ text-align: center;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
- :deep(.lims-table .pim-table-header-title) {
- text-align: center;
- width: 100%;
- }
+:deep(.lims-table .pim-table-header-title) {
+ text-align: center;
+ width: 100%;
+}
- :deep(.lims-table .pim-table-header-extra) {
- width: 100%;
- margin-top: 4px;
- }
+:deep(.lims-table .pim-table-header-extra) {
+ width: 100%;
+ margin-top: 4px;
+}
+
+.binding-dialog {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+}
+
+.binding-search {
+ width: 100%;
+}
+
+.product-binding-tree {
+ max-height: 360px;
+ overflow-y: auto;
+ border: 1px solid #ebeef5;
+ border-radius: 4px;
+ padding: 8px;
+}
+
+.selected-products {
+ border-top: 1px solid #ebeef5;
+ padding-top: 12px;
+}
+
+.selected-title {
+ font-size: 13px;
+ color: #606266;
+ margin-bottom: 8px;
+}
+
+.selected-tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+}
</style>
--
Gitblit v1.9.3