From e545f964005b0c80b29a4417ca8275570778ac75 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期六, 14 三月 2026 13:29:44 +0800
Subject: [PATCH] 工艺路线加上产品和bom 样式优化
---
src/components/PIMTable/PIMTable.vue | 689 +++++++++++++++++++++++++++-----------------------------
1 files changed, 333 insertions(+), 356 deletions(-)
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index a418280..f83bc0a 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -1,82 +1,73 @@
<template>
- <el-table
- ref="multipleTable"
- v-loading="tableLoading"
- :border="border"
- :data="tableData"
- :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
- :height="height"
- :highlight-current-row="highlightCurrentRow"
- :row-class-name="rowClassName"
- :row-style="rowStyle"
- :row-key="rowKey"
- :style="tableStyle"
- tooltip-effect="dark"
- :expand-row-keys="expandRowKeys"
- :show-summary="isShowSummary"
- :summary-method="summaryMethod"
- @row-click="rowClick"
- @current-change="currentChange"
- @selection-change="handleSelectionChange"
- @expand-change="expandChange"
- class="lims-table"
- >
- <el-table-column
- align="center"
- type="selection"
- width="55"
- v-if="isSelection"
- />
- <el-table-column align="center" label="搴忓彿" type="index" width="60" />
-
- <el-table-column
- v-for="(item, index) in column"
- :key="index"
- :column-key="item.columnKey"
- :filter-method="item.filterHandler"
- :filter-multiple="item.filterMultiple"
- :filtered-value="item.filteredValue"
- :filters="item.filters"
- :fixed="item.fixed"
- :label="item.label"
- :prop="item.prop"
- :show-overflow-tooltip="item.dataType !== 'action' && item.dataType !== 'slot'"
- :align="item.align"
- :sortable="!!item.sortable"
- :type="item.type"
- :width="item.width"
- >
+ <el-table ref="multipleTable"
+ v-loading="tableLoading"
+ :border="border"
+ :data="tableData"
+ :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
+ :height="height"
+ :highlight-current-row="highlightCurrentRow"
+ :row-class-name="rowClassName"
+ :row-style="rowStyle"
+ :row-key="rowKey"
+ :style="tableStyle"
+ tooltip-effect="dark"
+ :expand-row-keys="expandRowKeys"
+ :show-summary="isShowSummary"
+ :summary-method="summaryMethod"
+ @row-click="rowClick"
+ @current-change="currentChange"
+ @selection-change="handleSelectionChange"
+ @expand-change="expandChange"
+ class="lims-table">
+ <el-table-column align="center"
+ type="selection"
+ width="55"
+ v-if="isSelection" />
+ <el-table-column align="center"
+ label="搴忓彿"
+ type="index"
+ width="60" />
+ <el-table-column v-for="(item, index) in column"
+ :key="index"
+ :column-key="item.columnKey"
+ :filter-method="item.filterHandler"
+ :filter-multiple="item.filterMultiple"
+ :filtered-value="item.filteredValue"
+ :filters="item.filters"
+ :fixed="item.fixed"
+ :label="item.label"
+ :prop="item.prop"
+ :show-overflow-tooltip="item.dataType !== 'action' && item.dataType !== 'slot'"
+ :align="item.align"
+ :sortable="!!item.sortable"
+ :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 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"
- >
- <slot
- v-if="item.theadSlot"
- :name="item.theadSlot"
- :index="scope.$index"
- :row="scope.row"
- />
+ <template v-if="item.hasOwnProperty('colunmTemplate')"
+ #[item.colunmTemplate]="scope">
+ <slot v-if="item.theadSlot"
+ :name="item.theadSlot"
+ :index="scope.$index"
+ :row="scope.row" />
</template>
-
<template #default="scope">
<!-- 鎻掓Ы -->
<div v-if="item.dataType == 'slot'">
- <slot
- v-if="item.slot"
- :index="scope.$index"
- :name="item.slot"
- :row="scope.row"
- />
+ <slot v-if="item.slot"
+ :index="scope.$index"
+ :name="item.slot"
+ :row="scope.row" />
</div>
<!-- 杩涘害鏉� -->
<div v-else-if="item.dataType == 'progress'">
@@ -84,373 +75,359 @@
</div>
<!-- 鍥剧墖 -->
<div v-else-if="item.dataType == 'image'">
- <img
- :src="javaApi + '/img/' + scope.row[item.prop]"
- alt=""
- style="width: 40px; height: 40px; margin-top: 10px"
- />
+ <img :src="javaApi + '/img/' + scope.row[item.prop]"
+ alt=""
+ style="width: 40px; height: 40px; margin-top: 10px" />
</div>
-
<!-- tag -->
<div v-else-if="item.dataType == 'tag'">
- <el-tag
- v-if="
+ <el-tag v-if="
typeof dataTypeFn(scope.row[item.prop], item.formatData) ===
'string'
"
- :title="formatters(scope.row[item.prop], item.formatData)"
- :type="formatType(scope.row[item.prop], item.formatType)"
- >
- {{ formatters(scope.row[item.prop], item.formatData) }}
+ :title="formatters(scope.row[item.prop], item.formatData, scope.row)"
+ :type="formatType(scope.row[item.prop], item.formatType)">
+ {{ formatters(scope.row[item.prop], item.formatData, scope.row) }}
</el-tag>
-
- <el-tag
- v-for="(tag, index) in dataTypeFn(
+ <el-tag v-for="(tag, index) in dataTypeFn(
scope.row[item.prop],
item.formatData
)"
- v-else-if="
+ v-else-if="
typeof dataTypeFn(scope.row[item.prop], item.formatData) ===
'object'
"
- :key="index"
- :title="formatters(scope.row[item.prop], item.formatData)"
- :type="formatType(tag, item.formatType)"
- >
+ :key="index"
+ :title="formatters(scope.row[item.prop], item.formatData, scope.row)"
+ :type="formatType(tag, item.formatType)">
{{ item.tagGroup ? tag[item.tagGroup.label] ?? tag : tag }}
</el-tag>
-
- <el-tag
- v-else
- :title="formatters(scope.row[item.prop], item.formatData)"
- :type="formatType(scope.row[item.prop], item.formatType)"
- >
- {{ formatters(scope.row[item.prop], item.formatData) }}
+ <el-tag v-else
+ :title="formatters(scope.row[item.prop], item.formatData, scope.row)"
+ :type="formatType(scope.row[item.prop], item.formatType)">
+ {{ formatters(scope.row[item.prop], item.formatData, scope.row) }}
</el-tag>
</div>
-
<!-- 鎸夐挳 -->
- <div v-else-if="item.dataType == 'action'" @click.stop>
- <template v-for="(o, key) in item.operation" :key="key">
- <el-button
- v-show="o.type != 'upload'"
- v-if="o.showHide ? o.showHide(scope.row) : true"
- :disabled="o.disabled ? o.disabled(scope.row) : false"
- :plain="o.plain"
- type="primary"
- :style="{
+ <div v-else-if="item.dataType == 'action'"
+ @click.stop>
+ <template v-for="(o, key) in item.operation"
+ :key="key">
+ <el-button v-show="o.type != 'upload'"
+ v-if="o.showHide ? o.showHide(scope.row) : true"
+ :disabled="o.disabled ? o.disabled(scope.row) : false"
+ :plain="o.plain"
+ type="primary"
+ :style="{
color:
o.name === '鍒犻櫎' || o.name === 'delete'
? '#f56c6c'
: o.color,
}"
- link
- @click.stop="o.clickFun(scope.row)"
- :key="key"
- >
+ link
+ @click.stop="o.clickFun(scope.row)"
+ :key="key">
{{ o.name }}
</el-button>
- <el-upload
- :action="
+ <el-upload :action="
javaApi +
o.url +
'?id=' +
(o.uploadIdFun ? o.uploadIdFun(scope.row) : scope.row.id)
"
- ref="uploadRef"
- :multiple="o.multiple ? o.multiple : false"
- :limit="1"
- :disabled="o.disabled ? o.disabled(scope.row) : false"
- :accept="
+ ref="uploadRef"
+ :multiple="o.multiple ? o.multiple : false"
+ :limit="1"
+ :disabled="o.disabled ? o.disabled(scope.row) : false"
+ :accept="
o.accept
? o.accept
: '.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'
"
- v-if="o.type == 'upload'"
- style="display: inline-block; width: 50px"
- v-show="o.showHide ? o.showHide(scope.row) : true"
- :headers="uploadHeader"
- :before-upload="(file) => beforeUpload(file, scope.$index)"
- :on-change="
+ v-if="o.type == 'upload'"
+ style="display: inline-block; width: 50px"
+ v-show="o.showHide ? o.showHide(scope.row) : true"
+ :headers="uploadHeader"
+ :before-upload="(file) => beforeUpload(file, scope.$index)"
+ :on-change="
(file, fileList) => handleChange(file, fileList, scope.$index)
"
- :on-error="
+ :on-error="
(error, file, fileList) =>
onError(error, file, fileList, scope.$index)
"
- :on-success="
+ :on-success="
(response, file, fileList) =>
handleSuccessUp(response, file, fileList, scope.$index)
"
- :on-exceed="onExceed"
- :show-file-list="false"
- >
- <el-button
- link
- type="primary"
- :disabled="o.disabled ? o.disabled(scope.row) : false"
- >{{ o.name }}</el-button
- >
+ :on-exceed="onExceed"
+ :show-file-list="false">
+ <el-button link
+ type="primary"
+ :disabled="o.disabled ? o.disabled(scope.row) : false">{{ o.name }}</el-button>
</el-upload>
</template>
</div>
<!-- 鍙偣鍑荤殑鏂囧瓧 -->
- <div
- v-else-if="item.dataType == 'link'"
- class="cell link"
- style="width: 100%"
- @click="goLink(scope.row, item.linkMethod)"
- >
+ <div v-else-if="item.dataType == 'link'"
+ class="cell link"
+ style="width: 100%"
+ @click="goLink(scope.row, item.linkMethod)">
<span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
</div>
<!-- 榛樿绾睍绀烘暟鎹� -->
- <div v-else class="cell" style="width: 100%">
+ <div v-else
+ class="cell"
+ style="width: 100%">
<span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
<span v-else>{{
- formatters(scope.row[item.prop], item.formatData)
+ formatters(scope.row[item.prop], item.formatData, scope.row)
}}</span>
</div>
</template>
</el-table-column>
</el-table>
- <pagination
- v-if="isShowPagination"
- :total="page.total"
- :layout="page.layout"
- :page="page.current"
- :limit="page.size"
- @pagination="paginationSearch"
- />
+ <pagination v-if="isShowPagination"
+ :total="page.total"
+ :layout="page.layout"
+ :page="page.current"
+ :limit="page.size"
+ @pagination="paginationSearch" />
</template>
<script setup>
-import pagination from "./Pagination.vue";
-import { ref, inject, getCurrentInstance } from "vue";
-import { ElMessage } from "element-plus";
+ import pagination from "./Pagination.vue";
+ import { ref, inject, getCurrentInstance } from "vue";
+ import { ElMessage } from "element-plus";
-// 鑾峰彇鍏ㄥ眬鐨� uploadHeader
-const { proxy } = getCurrentInstance();
-const uploadHeader = proxy.uploadHeader;
-const javaApi = proxy.javaApi;
+ // 鑾峰彇鍏ㄥ眬鐨� uploadHeader
+ const { proxy } = getCurrentInstance();
+ const uploadHeader = proxy.uploadHeader;
+ const javaApi = proxy.javaApi;
-const emit = defineEmits(["pagination", "expand-change", "selection-change", "row-click"]);
+ const emit = defineEmits([
+ "pagination",
+ "expand-change",
+ "selection-change",
+ "row-click",
+ ]);
-// Filters
-const typeFn = (val, row) => {
- return typeof val === "function" ? val(row) : val;
-};
+ // Filters
+ const typeFn = (val, row) => {
+ return typeof val === "function" ? val(row) : val;
+ };
-const formatters = (val, format) => {
- return typeof format === "function" ? format(val) : val;
-};
+ const formatters = (val, format, row) => {
+ return typeof format === "function" ? format(val, row) : val;
+ };
-// Props锛堜娇鐢� defineProps 鐨勯潪 TS 褰㈠紡锛�
-const props = defineProps({
- tableLoading: {
- type: Boolean,
- default: false,
- },
- height: {
- type: [Number, String],
- default: "calc(100vh - 22em)",
- },
- expandRowKeys: {
- type: Array,
- default: () => [],
- },
- summaryMethod: {
- type: Function,
- default: () => {},
- },
- rowClick: {
- type: Function,
- default: () => {},
- },
- currentChange: {
- type: Function,
- default: () => {},
- },
- border: {
- type: Boolean,
- default: true,
- },
- isSelection: {
- type: Boolean,
- default: false,
- },
- isShowPagination: {
- type: Boolean,
- default: true,
- },
- isShowSummary: {
- type: Boolean,
- default: false,
- },
- highlightCurrentRow: {
- type: Boolean,
- default: false,
- },
- headerCellStyle: {
- type: Object,
- default: () => ({}),
- },
- column: {
- type: Array,
- default: () => [],
- },
- rowClassName: {
- type: Function,
- default: () => "",
- },
- rowStyle: {
- type: [Object, Function],
- default: () => ({}),
- },
- tableData: {
- type: Array,
- default: () => [],
- },
- rowKey: {
- type: String,
- default: 'id',
- },
- page: {
- type: Object,
- default: () => ({
- total: 0,
- current: 0,
- size: 10,
- layout: "total, sizes, prev, pager, next, jumper",
- }),
- },
- total: {
- type: Number,
- default: 0,
- },
- tableStyle: {
- type: [String, Object],
- default: () => ({ width: "100%" }),
- },
-});
+ // Props锛堜娇鐢� defineProps 鐨勯潪 TS 褰㈠紡锛�
+ const props = defineProps({
+ tableLoading: {
+ type: Boolean,
+ default: false,
+ },
+ height: {
+ type: [Number, String],
+ default: "calc(100vh - 22em)",
+ },
+ expandRowKeys: {
+ type: Array,
+ default: () => [],
+ },
+ summaryMethod: {
+ type: Function,
+ default: () => {},
+ },
+ rowClick: {
+ type: Function,
+ default: () => {},
+ },
+ currentChange: {
+ type: Function,
+ default: () => {},
+ },
+ border: {
+ type: Boolean,
+ default: true,
+ },
+ isSelection: {
+ type: Boolean,
+ default: false,
+ },
+ isShowPagination: {
+ type: Boolean,
+ default: true,
+ },
+ isShowSummary: {
+ type: Boolean,
+ default: false,
+ },
+ highlightCurrentRow: {
+ type: Boolean,
+ default: false,
+ },
+ headerCellStyle: {
+ type: Object,
+ default: () => ({}),
+ },
+ column: {
+ type: Array,
+ default: () => [],
+ },
+ rowClassName: {
+ type: Function,
+ default: () => "",
+ },
+ rowStyle: {
+ type: [Object, Function],
+ default: () => ({}),
+ },
+ tableData: {
+ type: Array,
+ default: () => [],
+ },
+ rowKey: {
+ type: String,
+ default: "id",
+ },
+ page: {
+ type: Object,
+ default: () => ({
+ total: 0,
+ current: 0,
+ size: 10,
+ layout: "total, sizes, prev, pager, next, jumper",
+ }),
+ },
+ total: {
+ type: Number,
+ default: 0,
+ },
+ tableStyle: {
+ type: [String, Object],
+ default: () => ({ width: "100%" }),
+ },
+ });
-// Data
-const uploadRefs = ref([]);
-const currentFiles = ref({});
-const uploadKeys = ref({});
+ // Data
+ const uploadRefs = ref([]);
+ const currentFiles = ref({});
+ const uploadKeys = ref({});
-const indexMethod = (index) => {
- return (props.page.current - 1) * props.page.size + index + 1;
-};
+ const indexMethod = index => {
+ return (props.page.current - 1) * props.page.size + index + 1;
+ };
-// 鐐瑰嚮 link 浜嬩欢
-const goLink = (row, linkMethod) => {
- if (!linkMethod) {
- return ElMessage.warning("璇烽厤缃� link 浜嬩欢");
- }
- const parentMethod = getParentMethod(linkMethod);
- if (typeof parentMethod === "function") {
- parentMethod(row);
- } else {
- console.warn(`鐖剁粍浠朵腑鏈壘鍒版柟娉�: ${linkMethod}`);
- }
-};
-
-// 鑾峰彇鐖剁粍浠舵柟娉曪紙绀轰緥瀹炵幇锛�
-const getParentMethod = (methodName) => {
- const parentMethods = inject("parentMethods", {});
- return parentMethods[methodName];
-};
-
-const dataTypeFn = (val, format) => {
- if (typeof format === "function") {
- return format(val);
- } else return val;
-};
-
-const formatType = (val, format) => {
- if (typeof format === "function") {
- return format(val);
- } else return "";
-};
-
-// 鏂囦欢鍙樺寲澶勭悊
-const handleChange = (file, fileList, index) => {
- if (fileList.length > 1) {
- const earliestFile = fileList[0];
- uploadRefs.value[index]?.handleRemove(earliestFile);
- }
- currentFiles.value[index] = file;
-};
-
-// 鏂囦欢涓婁紶鍓嶆牎楠�
-const beforeUpload = (rawFile, index) => {
- currentFiles.value[index] = {};
- if (rawfile.size > 1024 * 1024 * 10 * 10) {
- ElMessage.error("涓婁紶鏂囦欢涓嶈秴杩�10M");
- return false;
- }
- return true;
-};
-
-// 涓婁紶鎴愬姛
-const handleSuccessUp = (response, file, fileList, index) => {
- if (response.code == 200) {
- if (uploadRefs[index]) {
- uploadRefs[index].clearFiles();
+ // 鐐瑰嚮 link 浜嬩欢
+ const goLink = (row, linkMethod) => {
+ if (!linkMethod) {
+ return ElMessage.warning("璇烽厤缃� link 浜嬩欢");
}
- currentFiles[index] = file;
- ElMessage.success("涓婁紶鎴愬姛");
- resetUploadComponent(index);
- } else {
- ElMessage.error(response.message);
- }
-};
+ const parentMethod = getParentMethod(linkMethod);
+ if (typeof parentMethod === "function") {
+ parentMethod(row);
+ } else {
+ console.warn(`鐖剁粍浠朵腑鏈壘鍒版柟娉�: ${linkMethod}`);
+ }
+ };
-const resetUploadComponent = (index) => {
- uploadKeys[index] = Date.now();
-};
+ // 鑾峰彇鐖剁粍浠舵柟娉曪紙绀轰緥瀹炵幇锛�
+ const getParentMethod = methodName => {
+ const parentMethods = inject("parentMethods", {});
+ return parentMethods[methodName];
+ };
-// 涓婁紶澶辫触
-const onError = (error, file, fileList, index) => {
- ElMessage.error("鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯");
- if (uploadRefs.value[index]) {
- uploadRefs.value[index].clearFiles();
- }
-};
+ const dataTypeFn = (val, format) => {
+ if (typeof format === "function") {
+ return format(val);
+ } else return val;
+ };
-// 鏂囦欢鏁伴噺瓒呴檺鎻愮ず
-const onExceed = () => {
- ElMessage.warning("瓒呭嚭鏂囦欢涓暟");
-};
+ const formatType = (val, format) => {
+ if (typeof format === "function") {
+ return format(val);
+ } else return "";
+ };
-const paginationSearch = ({ page, limit }) => {
- emit("pagination", { page: page, limit: limit });
-};
+ // 鏂囦欢鍙樺寲澶勭悊
+ const handleChange = (file, fileList, index) => {
+ if (fileList.length > 1) {
+ const earliestFile = fileList[0];
+ uploadRefs.value[index]?.handleRemove(earliestFile);
+ }
+ currentFiles.value[index] = file;
+ };
-const rowClick = (row) => {
- emit("row-click", row);
-};
+ // 鏂囦欢涓婁紶鍓嶆牎楠�
+ const beforeUpload = (rawFile, index) => {
+ currentFiles.value[index] = {};
+ if (rawfile.size > 1024 * 1024 * 10 * 10) {
+ ElMessage.error("涓婁紶鏂囦欢涓嶈秴杩�10M");
+ return false;
+ }
+ return true;
+ };
-const expandChange = (row, expandedRows) => {
- emit("expand-change", row, expandedRows);
-};
+ // 涓婁紶鎴愬姛
+ const handleSuccessUp = (response, file, fileList, index) => {
+ if (response.code == 200) {
+ if (uploadRefs[index]) {
+ uploadRefs[index].clearFiles();
+ }
+ currentFiles[index] = file;
+ ElMessage.success("涓婁紶鎴愬姛");
+ resetUploadComponent(index);
+ } else {
+ ElMessage.error(response.message);
+ }
+ };
-const handleSelectionChange = (newSelection) => {
- emit("selection-change", newSelection);
-};
+ const resetUploadComponent = index => {
+ uploadKeys[index] = Date.now();
+ };
+
+ // 涓婁紶澶辫触
+ const onError = (error, file, fileList, index) => {
+ ElMessage.error("鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯");
+ if (uploadRefs.value[index]) {
+ uploadRefs.value[index].clearFiles();
+ }
+ };
+
+ // 鏂囦欢鏁伴噺瓒呴檺鎻愮ず
+ const onExceed = () => {
+ ElMessage.warning("瓒呭嚭鏂囦欢涓暟");
+ };
+
+ const paginationSearch = ({ page, limit }) => {
+ emit("pagination", { page: page, limit: limit });
+ };
+
+ const rowClick = row => {
+ emit("row-click", row);
+ };
+
+ const expandChange = (row, expandedRows) => {
+ emit("expand-change", row, expandedRows);
+ };
+
+ const handleSelectionChange = newSelection => {
+ emit("selection-change", newSelection);
+ };
</script>
<style scoped lang="scss">
-.cell {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- padding-right: 0 !important;
- padding-left: 0 !important;
-}
+ .cell {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ padding-right: 0 !important;
+ padding-left: 0 !important;
+ }
-.pim-table-header-extra :deep(.el-input),
-.pim-table-header-extra :deep(.el-select) {
- width: 100%;
-}
+ .pim-table-header-extra :deep(.el-input),
+ .pim-table-header-extra :deep(.el-select) {
+ width: 100%;
+ }
</style>
--
Gitblit v1.9.3