From dd9171eef52864b6d025ef9cc2b5770f5d40ce15 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期六, 11 十月 2025 15:33:48 +0800
Subject: [PATCH] 生产管控-生产报表与绩效分析、库存与物料看板、智能排产三个前端页面开发
---
src/components/Table/ETable.vue | 491 ++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 330 insertions(+), 161 deletions(-)
diff --git a/src/components/Table/ETable.vue b/src/components/Table/ETable.vue
index 88c6f57..b7089d2 100644
--- a/src/components/Table/ETable.vue
+++ b/src/components/Table/ETable.vue
@@ -1,177 +1,334 @@
-<template>
- <el-table
- v-loading="loading"
- :data="tableData"
- style="width: 100%"
- :border="border"
- :show-selection="showSelection"
- :max-height="maxHeight"
- @selection-change="handleSelectionChange"
-<<<<<<< HEAD
-=======
- @row-click="handleRowClick"
- @row-dblclick="handleRowDblClick"
- @cell-click="handleCellClick"
- :max-width="maxWidth"
- @export="handleExport"
->>>>>>> master
- >
- <el-table-column v-if="showSelection" type="selection" width="55" align="center" />
- <el-table-column v-if="showIndex" label="搴忓彿" type="index" width="60" align="center" />
- <template v-for="col in columns" :key="col.prop">
- <el-table-column
- v-bind="col"
- :show-overflow-tooltip="col.showOverflowTooltip !== false"
- >
- <template v-if="col.slot" #default>
- <slot></slot>
- </template>
- </el-table-column>
+<template> <el-table
+ v-loading="loading"
+ :data="tableData"
+ :border="border"
+ :show-selection="showSelection"
+ :max-height="maxHeight"
+ :header-cell-style="{ background: '#EBEEF5', color: '#3D3D3D' }"
+ @selection-change="handleSelectionChange"
+ @row-click="handleRowClick"
+ @row-dblclick="handleRowDblClick"
+ @cell-click="handleCellClick"
+ :max-width="maxWidth"
+ @export="handleExport"
+ :default-selection="defaultSelection"
+ :show-overflow-tooltip="showOverflowTooltip"
+ ref="tableRef"
+ :row-key="rowKey"
+ style="width: 100%;"
+ >
+ <el-table-column v-if="showSelection" type="selection" width="55" align="center" :show-overflow-tooltip="false" />
+ <el-table-column v-if="showIndex" label="搴忓彿" width="60" align="center" fixed="left" :show-overflow-tooltip="false">
+ <template #default="scope">
+ {{ getRowIndex(scope.$index) }}
</template>
- <!-- 鎿嶄綔鍒� -->
- <el-table-column v-if="showOperations" :label="operationsLabel" :width="operationsWidth" fixed="right">
- <template #default="scope">
- <slot name="operations" :row="scope.row">
- <el-button
- v-if="operations.includes('edit')"
- link
- type="primary"
- size="small"
- @click="handleEdit(scope.row)"
- >缂栬緫</el-button>
- <el-button
- v-if="operations.includes('delete')"
- link
- type="danger"
- size="small"
- @click="handleDelete(scope.row)"
- >鍒犻櫎</el-button>
- </slot>
+ </el-table-column>
+ <template v-for="col in columns" :key="col.prop">
+ <el-table-column v-bind="col"
+ :formatter="col.formatter || defaultFormatter" align="center">
+ <template v-if="col.slot" #default="scope">
+ <slot :name="col.prop" :row="scope.row" :column="scope.column" :index="scope.$index"></slot>
</template>
</el-table-column>
- </el-table>
- </template>
+ </template>
+ <!-- 鎿嶄綔鍒� -->
+ <el-table-column v-if="showOperations" :label="operationsLabel" :width="operationsWidth" :show-overflow-tooltip="false" fixed="right" align="center">
+ <template #default="scope">
+ <slot name="operations" :row="scope.row">
+ <!-- 鑷畾涔夋寜閽� - 鏀惧湪榛樿鎸夐挳涔嬪墠 -->
+ <el-button
+ v-for="button in customButtons"
+ :key="button.name"
+ v-show="!button.show || button.show(scope.row)"
+ :link="button.link !== false"
+ :type="button.type || 'primary'"
+ :size="button.size || 'small'"
+ :icon="button.icon"
+ :disabled="button.disabled && button.disabled(scope.row)"
+ @click="handleCustomClick(button.name, scope.row)"
+ >
+ {{ button.label }}
+ </el-button>
+
+ <!-- 榛樿鎿嶄綔鎸夐挳 -->
+ <el-button v-if="operations.includes('edit')" link type="primary" size="small"
+ @click="handleEdit(scope.row)">缂栬緫</el-button>
+ <el-button v-if="operations.includes('scheduling') && scope.row.status != 3" link type="primary" size="small"
+ @click="handleEdit(scope.row)">鎺掍骇</el-button>
+ <el-button v-if="operations.includes('work') && scope.row.status != 3" link type="primary" size="small"
+ @click="handleEdit(scope.row)">鎶ュ伐</el-button>
+ <el-button v-if="operations.includes('viewRow')" link type="primary" size="small"
+ @click="handleView(scope.row)">鏌ョ湅</el-button>
+ <el-button v-if="operations.includes('viewFile')" link type="primary" size="small"
+ @click="handleViewFile(scope.row)">鏌ョ湅闄勪欢</el-button>
+ </slot>
+ </template>
+ </el-table-column>
+ </el-table>
+</template>
<script setup>
- import { defineEmits } from 'vue'
- import { ElMessage, ElMessageBox } from 'element-plus'
+import { defineEmits, ref , defineProps, onMounted ,defineExpose, watch, nextTick} from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+const props = defineProps({
+ // 鏈�澶у搴�
+ maxWidth: {
+ type: [String, Number],
+ default: 'auto'
+ },
+ handleCellClick: {
+ type: Function,
+ default: () => { }
+ },
+ handleRowClick: {
+ type: Function,
+ default: () => { }
+ },
+ handleExport: {
+ type: Function,
+ default: () => { }
+ },
+ handleRowDblClick: {
+ type: Function,
+ default: () => { }
+ },
+ // 楂樺害
+ maxHeight: {
+ type: [String, Number],
+ default: 'auto'
+ },
+ // 鍔犺浇鐘舵��
+ loading: {
+ type: Boolean,
+ default: false
+ },
+ // border
+ border: {
+ type: Boolean,
+ default: false
+ },
+ // 琛ㄦ牸鏁版嵁
+ tableData: {
+ type: Array,
+ default: () => []
+ },
+ // 鏄惁鏄剧ず閫夋嫨鍒�
+ showSelection: {
+ type: Boolean,
+ default: true
+ },
+ // 鏄惁鏄剧ず搴忓彿鍒�
+ showIndex: {
+ type: Boolean,
+ default: true
+ },
+ // 鍒楅厤缃�
+ columns: {
+ type: Array,
+ default: () => []
+ },
+ // 鏄惁鏄剧ず鎿嶄綔鍒�
+ showOperations: {
+ type: Boolean,
+ default: true
+ },
+ // 鎿嶄綔鍒楁爣绛�
+ operationsLabel: {
+ type: String,
+ default: '鎿嶄綔'
+ },
+ // 鎿嶄綔鍒楀搴�
+ operationsWidth: {
+ type: [String, Number],
+ default: 100
+ },
+ // 鏄剧ず鍝簺鎿嶄綔鎸夐挳
+ operations: {
+ type: Array,
+ default: () => ['edit', 'delete', 'export']
+ },
+ // 鑷畾涔夋寜閽厤缃�
+ customButtons: {
+ type: Array,
+ default: () => []
+ // 绀轰緥閰嶇疆锛�
+ // [
+ // {
+ // name: 'return', // 鎸夐挳鏍囪瘑
+ // label: '褰掕繕', // 鎸夐挳鏄剧ず鏂囨湰
+ // type: 'success', // 鎸夐挳绫诲瀷
+ // size: 'small', // 鎸夐挳澶у皬
+ // icon: '', // 鍥炬爣(鍙��)
+ // show: (row) => true, // 鏄剧ず鏉′欢鍑芥暟(鍙��)
+ // disabled: (row) => false, // 绂佺敤鏉′欢鍑芥暟(鍙��)
+ // }
+ // ]
+ },
+ // 鍒犻櫎纭淇℃伅
+ deleteConfirmText: {
+ type: String,
+ default: '纭鍒犻櫎璇ヨ褰曪紵'
+ },
+ // 榛樿閫変腑鐨勮 ID 鏁扮粍
+ defaultSelectedIds: {
+ type: Array,
+ default: () => []
+ },
+ // 琛屽敮涓�鏍囪瘑瀛楁鍚嶏紙榛樿涓� id锛�
+ rowKey: {
+ type: String,
+ default: 'id'
+ }, showOverflowTooltip: {
+ type: Boolean,
+ default: true
+ },
+ // 褰撳墠椤电爜
+ currentPage: {
+ type: Number,
+ default: 1
+ },
+ // 姣忛〉澶у皬
+ pageSize: {
+ type: Number,
+ default: 10
+ }
+})
+const tableRef = ref(null)
- const props = defineProps({
-<<<<<<< HEAD
-=======
- // 鏈�澶у搴�
- maxWidth: {
- type: [String, Number],
- default: 'auto'
- },
- handleCellClick: {
- type: Function,
- default: () => {}
- },
- handleRowClick: {
- type: Function,
- default: () => {}
- },
- handleExport: {
- type: Function,
- default: () => {}
- },
- handleRowDblClick: {
- type: Function,
- default: () => {}
- },
->>>>>>> master
- // 楂樺害
- maxHeight: {
- type: [String, Number],
- default: 'auto'
- },
- // 鍔犺浇鐘舵��
- loading: {
- type: Boolean,
- default: false
- },
- // border
- border: {
- type: Boolean,
- default: false
- },
- // 琛ㄦ牸鏁版嵁
- tableData: {
- type: Array,
- default: () => []
- },
- // 鏄惁鏄剧ず閫夋嫨鍒�
- showSelection: {
- type: Boolean,
- default: true
- },
- // 鏄惁鏄剧ず搴忓彿鍒�
- showIndex: {
- type: Boolean,
- default: true
- },
- // 鍒楅厤缃�
- columns: {
- type: Array,
- default: () => []
- },
- // 鏄惁鏄剧ず鎿嶄綔鍒�
- showOperations: {
- type: Boolean,
- default: true
- },
- // 鎿嶄綔鍒楁爣绛�
- operationsLabel: {
- type: String,
- default: '鎿嶄綔'
- },
- // 鎿嶄綔鍒楀搴�
- operationsWidth: {
- type: [String, Number],
- default: 160
- },
- // 鏄剧ず鍝簺鎿嶄綔鎸夐挳
- operations: {
- type: Array,
- default: () => ['edit', 'delete', 'export']
- },
- // 鍒犻櫎纭淇℃伅
- deleteConfirmText: {
- type: String,
- default: '纭鍒犻櫎璇ヨ褰曪紵'
+// 榛樿鐨勬牸寮忓寲鍑芥暟
+const defaultFormatter = (row, column, cellValue) => {
+ return cellValue == null || cellValue === '' || cellValue === 0 ? '--' : cellValue;
+};
+
+// 澶勭悊閫夋嫨鍙樺寲銆佺紪杈戙�佸垹闄ゅ拰瀵煎嚭鎿嶄綔
+const emit = defineEmits(['selection-change', 'edit', 'delete', 'export', 'viewRow', 'viewFile', 'custom-click'])
+const handleSelectionChange = (selection) => {
+ emit('selection-change', selection)
+}
+const handleEdit = (row) => {
+ emit('edit', row)
+}
+const handleView = (row) => {
+ emit('viewRow', row)
+}
+const handleViewFile = (row) => {
+ emit('viewFile', row)
+}
+
+// 澶勭悊鑷畾涔夋寜閽偣鍑�
+const handleCustomClick = (buttonName, row) => {
+ emit('custom-click', { buttonName, row })
+}
+
+const handleDelete = (row) => {
+ ElMessageBox.confirm(
+ props.deleteConfirmText,
+ '璀﹀憡',
+ {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
}
- })
- const emit = defineEmits(['selection-change', 'edit', 'delete', 'export'])
- const handleSelectionChange = (selection) => {
- emit('selection-change', selection)
+ ).then(() => {
+ emit('delete', row)
+ }).catch(() => { })
+}
+
+const handleExport = (row) => {
+ emit('export', row)
+}
+
+// 璁$畻鍒嗛〉搴忓彿
+const getRowIndex = (index) => {
+ return (props.currentPage - 1) * props.pageSize + index + 1;
+};
+
+// 姝g‘鐨� toggleRowSelection 鏂规硶锛氶拡瀵瑰崟琛�
+const toggleRowSelection = (row, selected) => {
+ if (tableRef.value && row) {
+ tableRef.value.toggleRowSelection(row, selected);
}
- const handleEdit = (row) => {
- emit('edit', row)
+};
+
+// 鎵归噺璁剧疆琛岄�変腑鐘舵�佺殑鏂规硶
+const setRowsSelection = (rows, selected = true) => {
+ if (tableRef.value && Array.isArray(rows)) {
+ rows.forEach((row) => {
+ tableRef.value.toggleRowSelection(row, selected);
+ });
}
- const handleDelete = (row) => {
- ElMessageBox.confirm(
- props.deleteConfirmText,
- '璀﹀憡',
- {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }
- ).then(() => {
- emit('delete', row)
- }).catch(() => {})
+};
+
+// 澶嶉�夋榛樿閫変腑鐘舵��
+const defaultSelection = ref([])
+// 璁剧疆榛樿閫変腑鐘舵��
+const setDefaultSelection = () => {
+ if (!tableRef.value || !props.defaultSelectedIds.length || !props.tableData.length) {
+ return;
}
- const handleExport = (row) => {
- emit('export', row)
+
+ // 寤惰繜鎵ц锛岀‘淇濊〃鏍煎畬鍏ㄦ覆鏌�
+ nextTick(() => {
+ setTimeout(() => {
+ try {
+ tableRef.value.clearSelection();
+ const rowsToSelect = props.tableData.filter(row => {
+ const rowId = row[props.rowKey];
+ return props.defaultSelectedIds.includes(rowId);
+ });
+ rowsToSelect.forEach(row => {
+ tableRef.value.toggleRowSelection(row, true);
+ });
+ } catch (error) {
+ }
+ }, 100);
+ });
+};
+
+// 鐩戝惉鏁版嵁鍙樺寲锛岃嚜鍔ㄨ缃粯璁ら�変腑
+watch(() => [props.tableData, props.defaultSelectedIds], () => {
+ if (props.tableData.length > 0 && props.defaultSelectedIds.length > 0) {
+ setDefaultSelection();
}
- </script>
+}, {
+ deep: true,
+ immediate: true
+});
+
+// 缁勪欢鎸傝浇鍚庤缃粯璁ら�変腑
+onMounted(() => {
+ if (props.defaultSelectedIds.length > 0) {
+ setDefaultSelection();
+ }
+});
+
+// 鏆撮湶 el-table 鐨勫疄渚嬪拰甯哥敤鏂规硶
+defineExpose({
+ // 鍗曡閫変腑/鍙栨秷閫変腑
+ toggleRowSelection,
+ // 鎵归噺璁剧疆琛岄�変腑鐘舵��
+ setRowsSelection,
+ // 鏍规嵁ID鏁扮粍閫変腑琛�
+ setDefaultSelection,
+ // 娓呴櫎鎵�鏈夐�変腑
+ clearSelection: () => tableRef.value?.clearSelection(),
+ // 鑾峰彇閫変腑鐨勮
+ getSelectionRows: () => tableRef.value?.getSelectionRows() || [],
+ // 璁剧疆褰撳墠琛�
+ setCurrentRow: (row) => tableRef.value?.setCurrentRow(row),
+ // 鑾峰彇琛ㄦ牸瀹炰緥锛堝闇�鐩存帴鎿嶄綔锛�
+ getTableRef: () => tableRef.value
+});
+
+</script>
<style scoped>
- :deep(.el-table) {
- margin-bottom: 20px;
- overflow-x: auto;
+ :deep(.el-tooltip) {
+ justify-content: center !important;
+ }
+.el-table {
+ margin: 20px 0 !important;
}
:deep(.el-table th) {
@@ -185,4 +342,16 @@
overflow-x: auto;
}
}
- </style>
\ No newline at end of file
+
+ /* 鏀寔鍦板潃鍒楁崲琛屾樉绀� */
+ :deep(.el-table .cell) {
+ white-space: normal !important;
+ word-break: break-all;
+ line-height: 1.4;
+ }
+
+ /* 涓哄湴鍧�鍒楄缃渶灏忛珮搴︿互瀹圭撼澶氳鏂囨湰 */
+ :deep(.el-table td) {
+ padding: 8px 0;
+ }
+</style>
\ No newline at end of file
--
Gitblit v1.9.3