From 7c86b549b27bd54f6bd5de81c13f8242f91c87ff Mon Sep 17 00:00:00 2001 From: 张诺 <zhang_12370@163.com> Date: 星期一, 16 六月 2025 18:03:27 +0800 Subject: [PATCH] 优化文件上传组件及表格显示 --- src/views/production/components/ProductionDetailsTable.vue | 6 src/views/archiveManagement/mould/archiveDialog.vue | 68 +- src/components/Table/EtableModify.vue | 279 ++++++++----- src/views/production/index.vue | 319 +++++++------- src/components/FileUpload/index.vue | 27 src/components/Table/ETable.vue | 126 +++++ src/views/production/components/ProductionDetailsTableExample.vue | 4 src/views/production/components/ProductionDialog.vue | 417 +++++++++++++++---- 8 files changed, 821 insertions(+), 425 deletions(-) diff --git a/src/components/FileUpload/index.vue b/src/components/FileUpload/index.vue index b77d2a1..e68df58 100644 --- a/src/components/FileUpload/index.vue +++ b/src/components/FileUpload/index.vue @@ -121,15 +121,15 @@ // 涓婁紶鍓嶆牎妫�鏍煎紡鍜屽ぇ灏� function handleBeforeUpload(file) { // 鏍℃鏂囦欢绫诲瀷 - if (props.fileType.length) { - const fileName = file.name.split('.') - const fileExt = fileName[fileName.length - 1] - const isTypeOk = props.fileType.indexOf(fileExt) >= 0 - if (!isTypeOk) { - proxy.$modal.msgError(`鏂囦欢鏍煎紡涓嶆纭紝璇蜂笂浼�${props.fileType.join("/")}鏍煎紡鏂囦欢!`) - return false - } - } + // if (props.fileType.length) { + // const fileName = file.name.split('.') + // const fileExt = fileName[fileName.length - 1] + // const isTypeOk = props.fileType.indexOf(fileExt) >= 0 + // if (!isTypeOk) { + // proxy.$modal.msgError(`鏂囦欢鏍煎紡涓嶆纭紝璇蜂笂浼�${props.fileType.join("/")}鏍煎紡鏂囦欢!`) + // return false + // } + // } // 鏍℃鏂囦欢鍚嶆槸鍚﹀寘鍚壒娈婂瓧绗� if (file.name.includes(',')) { proxy.$modal.msgError('鏂囦欢鍚嶄笉姝g‘锛屼笉鑳藉寘鍚嫳鏂囬�楀彿!') @@ -237,6 +237,11 @@ .upload-file-uploader { margin-bottom: 5px; } +.upload-file-list { + margin-top: 10px; + max-height: 150px; + overflow-y: auto; +} .upload-file-list .el-upload-list__item { border: 1px solid #e4e7ed; line-height: 2; @@ -249,8 +254,12 @@ justify-content: space-between; align-items: center; color: inherit; + max-height: 20px; } .ele-upload-list__item-content-action .el-link { margin-right: 10px; } +.el-icon-document{ + padding-left: 10px; +} </style> diff --git a/src/components/Table/ETable.vue b/src/components/Table/ETable.vue index 7f0f3fc..13d2dda 100644 --- a/src/components/Table/ETable.vue +++ b/src/components/Table/ETable.vue @@ -1,9 +1,24 @@ -<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"> - <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> <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" /> + <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="shouldShowTooltip(col, tableData)" :formatter="col.formatter || defaultFormatter" align="center"> @@ -32,7 +47,7 @@ </template> <script setup> -import { defineEmits } from 'vue' +import { defineEmits, ref , defineProps, onMounted ,defineExpose, watch, nextTick} from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' const props = defineProps({ // 鏈�澶у搴� @@ -110,13 +125,27 @@ operations: { type: Array, default: () => ['edit', 'delete', 'export'] - }, - // 鍒犻櫎纭淇℃伅 + }, // 鍒犻櫎纭淇℃伅 deleteConfirmText: { type: String, default: '纭鍒犻櫎璇ヨ褰曪紵' + }, + // 榛樿閫変腑鐨勮 ID 鏁扮粍 + defaultSelectedIds: { + type: Array, + default: () => [] + }, + // 琛屽敮涓�鏍囪瘑瀛楁鍚嶏紙榛樿涓� id锛� + rowKey: { + type: String, + default: 'id' + }, + showOverflowTooltip: { + type: Boolean, + default: true } }) +const tableRef = ref(null) // 妫�鏌ュ垪鏄惁闇�瑕佹樉绀簍ooltip const shouldShowTooltip = (col, data) => { // 濡傛灉鍒楅厤缃腑鏄庣‘璁剧疆浜唖howOverflowTooltip锛屼娇鐢ㄨ璁剧疆 @@ -159,6 +188,85 @@ const handleExport = (row) => { emit('export', row) } + +// 姝g‘鐨� toggleRowSelection 鏂规硶锛氶拡瀵瑰崟琛� +const toggleRowSelection = (row, selected) => { + if (tableRef.value && row) { + tableRef.value.toggleRowSelection(row, selected); + } +}; + +// 鎵归噺璁剧疆琛岄�変腑鐘舵�佺殑鏂规硶 +const setRowsSelection = (rows, selected = true) => { + if (tableRef.value && Array.isArray(rows)) { + rows.forEach((row) => { + tableRef.value.toggleRowSelection(row, selected); + }); + } +}; + +// 澶嶉�夋榛樿閫変腑鐘舵�� +const defaultSelection = ref([]) +// 璁剧疆榛樿閫変腑鐘舵�� +const setDefaultSelection = () => { + if (!tableRef.value || !props.defaultSelectedIds.length || !props.tableData.length) { + return; + } + + + // 寤惰繜鎵ц锛岀‘淇濊〃鏍煎畬鍏ㄦ覆鏌� + 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(); + } +}, { + 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> diff --git a/src/components/Table/EtableModify.vue b/src/components/Table/EtableModify.vue index d4678c6..cf21bc2 100644 --- a/src/components/Table/EtableModify.vue +++ b/src/components/Table/EtableModify.vue @@ -1,36 +1,92 @@ <template> - <el-table v-loading="loading" :data="tableData" :border="border" :show-selection="showSelection" :height="height" :max-height="maxHeight" - :header-cell-style="{ background: '#EBEEF5', color: '#3D3D3D' }" @selection-change="handleSelectionChange" - @row-click="handleRowClick" @row-dblclick="handleRowDblClick" :row-class-name="tableRowClassName" @cell-click="handleCellClick" :max-width="maxWidth" - @export="handleExport"> - <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="shouldShowTooltip(col, tableData)" align="center"> <template - #default="scope"> + <el-table + v-loading="loading" + :data="tableData" + :border="border" + :show-selection="showSelection" + :height="height" + :max-height="maxHeight" + :header-cell-style="{ background: '#EBEEF5', color: '#3D3D3D' }" + @selection-change="handleSelectionChange" + @row-click="handleRowClick" + @row-dblclick="handleRowDblClick" + :row-class-name="tableRowClassName" + @cell-click="handleCellClick" + :max-width="maxWidth" + @export="handleExport" + :show-overflow-tooltip="showOverflowTooltip" + > + <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="shouldShowTooltip(col, tableData)" + align="center" + > + <template #default="scope"> <template v-if="col.slot"> <slot></slot> </template> <template v-else> - <div class="cell-edit" @dblclick="handleCellEdit(scope.row, col.prop)" - :class="{'editable': isColumnEditable(col.prop)}"> <span - v-if="!scope.row.editing || !scope.row.editing[col.prop]" class="cell-text"> - {{ scope.row[col.prop] == null || scope.row[col.prop] === '' ? '--' : scope.row[col.prop] }} + <div + class="cell-edit" + @dblclick="handleCellEdit(scope.row, col.prop)" + :class="{ editable: isColumnEditable(col.prop) }" + > + <span + v-if="!scope.row.editing || !scope.row.editing[col.prop]" + class="cell-text" + > + {{ + scope.row[col.prop] == null || scope.row[col.prop] === "" + ? "--" + : scope.row[col.prop] + }} </span> - <el-input v-else v-model="scope.row[col.prop]" size="small" - @focus="handleCellFocus(scope.row, col.prop, $event)" @blur="handleCellSave(scope.row, col.prop)" - @keyup.enter="handleCellSave(scope.row, col.prop)" class="cell-input" /> + <el-input + v-else + v-model="scope.row[col.prop]" + size="small" + @focus="handleCellFocus(scope.row, col.prop, $event)" + @blur="handleCellSave(scope.row, col.prop)" + @keyup.enter="handleCellSave(scope.row, col.prop)" + class="cell-input" + /> </div> </template> </template> </el-table-column> </template> <!-- 鎿嶄綔鍒� --> - <el-table-column v-if="showOperations" :label="operationsLabel" :width="operationsWidth" fixed="right" align="center"> + <el-table-column + v-if="showOperations" + :label="operationsLabel" + :width="operationsWidth" + fixed="right" + align="center" + > <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('edit')" + link + type="primary" + size="small" + @click="handleEdit(scope.row)" + >缂栬緫</el-button + > <!-- <el-button--> <!-- v-if="operations.includes('delete')"--> <!-- link--> @@ -43,119 +99,123 @@ </el-table-column> </el-table> </template> - - <script setup> -import { defineEmits, nextTick } from 'vue' -import { ElMessage, ElMessageBox } from 'element-plus' + +<script setup> +import { defineEmits, nextTick } from "vue"; +import { ElMessage, ElMessageBox } from "element-plus"; const props = defineProps({ // 鑾峰彇琛屾牱寮� tableRowClassName: { type: Function, - default: () => '' + default: () => "", }, // 鑾峰彇楂樺害 height: { type: [String, Number], - default: 'auto' + default: "auto", }, // 鏄惁鍏佽缂栬緫鍗曞厓鏍� editableCells: { type: Boolean, - default: true + default: true, }, // 鎸囧畾鍙紪杈戠殑鍒楋紝濡傛灉涓虹┖鏁扮粍鍒欒〃绀烘墍鏈夊垪閮戒笉鍙紪杈� editableColumns: { type: Array, - default: () => [] + default: () => [], }, // 鏈�澶у搴� maxWidth: { type: [String, Number], - default: 'auto' + default: "auto", }, handleCellClick: { type: Function, - default: () => { } + default: () => {}, }, handleRowClick: { type: Function, - default: () => { } + default: () => {}, }, handleExport: { type: Function, - default: () => { } + default: () => {}, }, handleRowDblClick: { type: Function, - default: () => { } + default: () => {}, }, // 楂樺害 maxHeight: { type: [String, Number], - default: 'auto' + default: "auto", }, // 鍔犺浇鐘舵�� loading: { type: Boolean, - default: false + default: false, }, // border border: { type: Boolean, - default: false + default: false, }, // 琛ㄦ牸鏁版嵁 tableData: { type: Array, - default: () => [] + default: () => [], }, // 鏄惁鏄剧ず閫夋嫨鍒� showSelection: { type: Boolean, - default: false + default: false, }, // 鏄惁鏄剧ず搴忓彿鍒� showIndex: { type: Boolean, - default: true + default: true, }, // 鍒楅厤缃� columns: { type: Array, - default: () => [] + default: () => [], }, // 鏄惁鏄剧ず鎿嶄綔鍒� showOperations: { type: Boolean, - default: true + default: true, }, // 鎿嶄綔鍒楁爣绛� operationsLabel: { type: String, - default: '鎿嶄綔' + default: "鎿嶄綔", }, // 鎿嶄綔鍒楀搴� operationsWidth: { type: [String, Number], - default: 100 + default: 100, }, // 鏄剧ず鍝簺鎿嶄綔鎸夐挳 operations: { type: Array, - default: () => ['edit', 'delete', 'export'] + default: () => ["edit", "delete", "export"], }, // 鍒犻櫎纭淇℃伅 deleteConfirmText: { type: String, - default: '纭鍒犻櫎璇ヨ褰曪紵' - } -}) + default: "纭鍒犻櫎璇ヨ褰曪紵", + }, + showOverflowTooltip: { + type: Boolean, + default: true, + }, +}); // 妫�鏌ュ垪鏄惁闇�瑕佹樉绀簍ooltip const shouldShowTooltip = (col, data) => { // 濡傛灉娌℃湁prop锛岀洿鎺ヨ繑鍥瀎alse if (!col.prop) return false; // 妫�鏌ヨ鍒楀湪鎵�鏈夋暟鎹腑鏄惁鏈夐潪绌哄�� - return data.some(row => row[col.prop] != null && row[col.prop] !== ''); + return data.some((row) => row[col.prop] != null && row[col.prop] !== ""); }; // 澶勭悊鍗曞厓鏍肩紪杈� @@ -164,7 +224,8 @@ if (!props.editableCells) return; // 濡傛灉鎸囧畾浜嗗彲缂栬緫鍒楋紝涓斿綋鍓嶅垪涓嶅湪鍙紪杈戝垪涓紝鍒欎笉鍏佽缂栬緫 - if (props.editableColumns.length > 0 && !props.editableColumns.includes(prop)) return; + if (props.editableColumns.length > 0 && !props.editableColumns.includes(prop)) + return; // 鍒濆鍖杄diting瀵硅薄 if (!row.editing) { @@ -175,28 +236,29 @@ // 鍦ㄤ笅涓�涓狣OM鏇存柊鍛ㄦ湡锛岃杈撳叆妗嗚幏寰楃劍鐐瑰苟閫変腑鍐呭 setTimeout(() => { - const inputElement = document.querySelector('.cell-edit .el-input__inner'); + const inputElement = document.querySelector(".cell-edit .el-input__inner"); if (inputElement) { inputElement.focus(); inputElement.select(); } }, 10); -} +}; // 澶勭悊鍗曞厓鏍间繚瀛� const handleCellSave = (row, prop) => { // 鍏抽棴缂栬緫鐘舵�� row.editing[prop] = false; // 瑙﹀彂鍗曞厓鏍肩紪杈戝畬鎴愪簨浠� - emit('cell-edit', row, prop, row[prop]); -} + emit("cell-edit", row, prop, row[prop]); +}; // 澶勭悊鍗曞厓鏍艰仛鐒︿簨浠� const handleCellFocus = (row, prop, event) => { // 濡傛灉涓嶅厑璁哥紪杈戝崟鍏冩牸锛岀洿鎺ヨ繑鍥� if (!props.editableCells) return; // 濡傛灉鎸囧畾浜嗗彲缂栬緫鍒楋紝涓斿綋鍓嶅垪涓嶅湪鍙紪杈戝垪涓紝鍒欎笉鍏佽缂栬緫 - if (props.editableColumns.length > 0 && !props.editableColumns.includes(prop)) return; + if (props.editableColumns.length > 0 && !props.editableColumns.includes(prop)) + return; // 鍒濆鍖杄diting瀵硅薄 if (!row.editing) { @@ -209,70 +271,75 @@ if (event && event.target) { event.target.select(); } -} +}; // 鍒ゆ柇鍒楁槸鍚﹀彲缂栬緫 const isColumnEditable = (prop) => { if (props.editableColumns.length === 0) { return props.editableCells; } return props.editableColumns.includes(prop); -} +}; // 澶勭悊閫夋嫨鍙樺寲銆佺紪杈戙�佸垹闄ゅ拰瀵煎嚭鎿嶄綔 -const emit = defineEmits(['selection-change', 'edit', 'delete', 'export', 'cell-edit']) +const emit = defineEmits([ + "selection-change", + "edit", + "delete", + "export", + "cell-edit", +]); const handleSelectionChange = (selection) => { - emit('selection-change', selection) -} + emit("selection-change", selection); +}; const handleEdit = (row) => { - emit('edit', row) -} + emit("edit", row); +}; const handleExport = (row) => { - emit('export', row) -} - </script> - <style scoped lang="scss"> + emit("export", row); +}; +</script> +<style scoped lang="scss"> .el-table { - margin: 20px 0 !important; - } - - :deep(.el-table th) { - background-color: #f5f7fa; - } - - :deep(.cell-edit) { + margin: 20px 0 !important; +} + +:deep(.el-table th) { + background-color: #f5f7fa; +} + +:deep(.cell-edit) { + width: 100%; + height: 100%; + position: relative; +} + +:deep(.cell-edit .cell-text) { + width: 100%; + display: block; +} + +:deep(.cell-edit.editable:hover .cell-text) { + color: #409eff; + cursor: pointer; +} + +:deep(.cell-input) { + width: 80%; + max-width: 120px; + min-width: 60px; +} + +:deep(.cell-input .el-input__inner) { + border-radius: 4px; + text-align: center; + transition: all 0.2s; +} + +/* 鍝嶅簲寮忔牱寮� */ +@media screen and (max-width: 768px) { + :deep(.el-table) { width: 100%; - height: 100%; - position: relative; + overflow-x: auto; } - - :deep(.cell-edit .cell-text) { - width: 100%; - display: block; - } - - :deep(.cell-edit.editable:hover .cell-text) { - color: #409EFF; - cursor: pointer; - } - - :deep(.cell-input) { - width: 80%; - max-width: 120px; - min-width: 60px; - } - - :deep(.cell-input .el-input__inner) { - border-radius: 4px; - text-align: center; - transition: all 0.2s; - } - - - /* 鍝嶅簲寮忔牱寮� */ - @media screen and (max-width: 768px) { - :deep(.el-table) { - width: 100%; - overflow-x: auto; - } - } -</style> \ No newline at end of file +} +</style> diff --git a/src/views/archiveManagement/mould/archiveDialog.vue b/src/views/archiveManagement/mould/archiveDialog.vue index c976722..521ae1a 100644 --- a/src/views/archiveManagement/mould/archiveDialog.vue +++ b/src/views/archiveManagement/mould/archiveDialog.vue @@ -1,5 +1,5 @@ <template> - <el-dialog v-model="centerDialogVisible" title="Warning" width="500" center> + <el-dialog v-model="centerDialogVisible" title="鏂囨。绠$悊" width="500" center> <el-form ref="ruleFormRef" style="max-width: 600px" @@ -8,7 +8,7 @@ label-width="auto" > <el-form-item label="鍚嶇О" prop="name"> - <el-input v-model="ruleForm.name" placeholder="璇疯緭鍏ユ枃妗e悕绉�"/> + <el-input v-model="ruleForm.name" placeholder="璇疯緭鍏ユ枃妗e悕绉�" /> </el-form-item> <el-form-item label="璇疯緭鍏ユ枃妗g被鍨�" prop="type"> <el-select v-model="ruleForm.type" placeholder="璇疯緭鍏ユ枃妗g被鍨�"> @@ -18,24 +18,36 @@ </el-form-item> <el-form-item label="璇疯緭鍏ユ枃妗g姸鎬�" prop="status"> <el-select v-model="ruleForm.status" placeholder="璇疯緭鍏ユ枃妗g姸鎬�"> - <el-option v-for="option in options" :key="option.value" :label="option.label" :value="option.value" /> + <el-option + v-for="option in options" + :key="option.value" + :label="option.label" + :value="option.value" + /> </el-select> </el-form-item> </el-form> <template #footer> - <div class="dialog-footer"> - <el-button @click="centerDialogVisible = false">Cancel</el-button> - <el-button type="primary" @click="submit"> - Confirm - </el-button> - </div> + <el-row> + <el-col :span="24" style="text-align: right"> + <el-button @click="centerDialogVisible = false">鍙� 娑�</el-button> + <el-button type="primary" @click="submit"> 纭� 瀹� </el-button> + </el-col> + </el-row> </template> + <fileUpload + v-model="ruleForm.file" + :fileSize="1024" + :fileType="['pdf', 'docx', 'txt', 'xlsx', 'pptx....']" + :limit="10" + /> </el-dialog> </template> <script setup> import { ref, watch } from "vue"; -import { addOrEditArchive } from "@/api/archiveManagement" +import { addOrEditArchive } from "@/api/archiveManagement"; +import fileUpload from "@/components/FileUpload/index.vue"; const centerDialogVisible = defineModel("centerDialogVisible", { type: Boolean, @@ -66,22 +78,20 @@ // 鍒濆鍖栬〃鍗曟暟鎹� const ruleFormRef = ref(null); const ruleForm = ref(initFormData(props.row)); -const copyForm = ref() +const copyForm = ref(); // 鐩戝惉 row 鐨勫彉鍖栵紝鏇存柊 ruleForm -watch(() => props.row, (newRow) => { - copyForm.value = initFormData(newRow); - ruleForm.value = JSON.parse(JSON.stringify(copyForm.value)); -}, { deep: true }); +watch( + () => props.row, + (newRow) => { + copyForm.value = initFormData(newRow); + ruleForm.value = JSON.parse(JSON.stringify(copyForm.value)); + }, + { deep: true } +); const rules = { - name: [ - { required: true, message: "Please input activity name", trigger: "blur" }, - ], - type: [ - { required: true, message: "Please select activity zone", trigger: "change" }, - ], - status: [ - { required: true, message: "Please select activity count", trigger: "change" }, - ], + name: [{ required: true, message: "璇疯緭鍏ユ枃妗e悕绉�", trigger: "blur" }], + type: [{ required: true, message: "璇烽�夋嫨鏂囨。绫诲瀷", trigger: "blur" }], + status: [{ required: true, message: "璇烽�夋嫨鏂囨。鐘舵��", trigger: "blur" }], }; const options = [ @@ -93,27 +103,27 @@ const submit = async () => { // 楠岃瘉琛ㄥ崟 if (!ruleFormRef.value) return; - + try { const valid = await ruleFormRef.value.validate(); if (!valid) { return; } - + // 璋冪敤 API let res = await addOrEditArchive(ruleForm.value); console.log("API 鍝嶅簲:", res); - + // 鍙戦�� emit 浜嬩欢 emit("submitForm", res); console.log("emit submitForm 宸插彂閫�"); - + // 鍏抽棴瀵硅瘽妗� centerDialogVisible.value = false; } catch (error) { console.error("琛ㄥ崟楠岃瘉澶辫触鎴朅PI璋冪敤澶辫触:", error); } -} +}; </script> <style lang="less" scoped></style> diff --git a/src/views/production/components/ProductionDetailsTable.vue b/src/views/production/components/ProductionDetailsTable.vue index 1d1ca7a..678ab65 100644 --- a/src/views/production/components/ProductionDetailsTable.vue +++ b/src/views/production/components/ProductionDetailsTable.vue @@ -3,9 +3,9 @@ <el-table-column label="鐓ょ" min-width="120" > <template #default="{ row, $index }" > <el-input - v-model="row.coalType" + v-model="row.coal" placeholder="璇疯緭鍏ョ叅绉�" - @input="handleInput('coalType', $index, $event)" + @input="handleInput('coal', $index, $event)" /> </template> </el-table-column> @@ -191,7 +191,7 @@ calculateTotalCost, addRow: (rowData = {}) => { const defaultRow = { - coalType: '', + coal: '', calorificValue: '', productionQuantity: '', laborCost: '', diff --git a/src/views/production/components/ProductionDetailsTableExample.vue b/src/views/production/components/ProductionDetailsTableExample.vue index d5d72a7..eda5955 100644 --- a/src/views/production/components/ProductionDetailsTableExample.vue +++ b/src/views/production/components/ProductionDetailsTableExample.vue @@ -36,7 +36,7 @@ // 琛ㄦ牸鏁版嵁 const tableData = ref([ { - coalType: '鍔ㄥ姏鐓�', + coal: '鍔ㄥ姏鐓�', calorificValue: '5000', productionQuantity: '100', laborCost: '1000', @@ -63,7 +63,7 @@ const addRow = () => { if (tableRef.value) { tableRef.value.addRow({ - coalType: '鏂扮叅绉�', + coal: '', calorificValue: '0', productionQuantity: '0', laborCost: '0', diff --git a/src/views/production/components/ProductionDialog.vue b/src/views/production/components/ProductionDialog.vue index b75a3e2..d95d9ae 100644 --- a/src/views/production/components/ProductionDialog.vue +++ b/src/views/production/components/ProductionDialog.vue @@ -1,4 +1,4 @@ -div<template> +<template> <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '鏂板鐢熶骇鍔犲伐' : '缂栬緫鐢熶骇鍔犲伐'" @@ -6,57 +6,91 @@ :close-on-click-modal="false" @close="handleClose" > - <el-button type="primary" @click="handlData">閫夋嫨鏁版嵁</el-button> - <ETableModify - :columns="columns" - height="200" - @cell-edit="handleCellEdit" - :showOperations="false" - :tableData="tableData" - @row-click="handleRowClick" - :editableColumns="['used']" - /> - <div class="empty-table"> - <h1>鐢熶骇鏄庣粏</h1> - <el-row :gutter="10"> - <el-col :span="2"> - <el-button type="primary" @click="addNewRow"> - <el-icon> - <Plus /> - </el-icon> - 鏂板 - </el-button> + <el-row :gutter="10" style="margin-bottom: 10px"> + <el-col :span="3"> + <el-button type="primary" @click="handlData" + ><el-icon> + <Plus /> </el-icon + >閫夋嫨鏁版嵁</el-button + > </el-col> - <el-col :span="2"> - <el-button type="danger" @click="clearAllRows"> + <el-col :span="4"> + <el-button + type="danger" + @click="removeSelectedData" + :disabled="tableData.length === 0" + > <el-icon> <Delete /> </el-icon> - 娓呯┖ + 娓呯┖宸查�� </el-button> </el-col> - <!-- <el-col :span="2"> + <el-col :span="17" style="text-align: right; line-height: 32px"> + <el-text type="info" size="small"> + 宸查�夋嫨 {{ tableData.length }} 椤规暟鎹� + <span v-if="tableData.length > 0"> + 锛屾�讳娇鐢ㄩ噺: {{ totalUsedQuantity.toFixed(2) }} + </span> + </el-text> + </el-col> + </el-row> + <ETableModify + :columns="columns" + :showOperations="false" + height="200" + @cell-edit="handleCellEdit" + :tableData="tableData" + :showOverflowTooltip="false" + @row-click="handleRowClick" + :editableColumns="['usedQuantity']" + @delete="handleRemoveItem" + /> + <div class="empty-table"> + <h1>鐢熶骇鏄庣粏</h1> + <el-row :gutter="10"> + <el-col :span="2"> + <el-button type="primary" @click="addNewRow"> + <el-icon> + <Plus /> + </el-icon> + 鏂板 + </el-button> + </el-col> + <el-col :span="2"> + <el-button type="danger" @click="clearAllRows"> + <el-icon> + <Delete /> + </el-icon> + 娓呯┖ + </el-button> + </el-col> + <!-- <el-col :span="2"> <el-button type="warning" @click="calculateAllCosts"> <el-icon> <Warning /> </el-icon> 閲嶆柊璁$畻 </el-button> </el-col> --> - </el-row> - <ProductionDetailsTable - v-model="detailsTableData" - :border="false" - :show-operations="true" - :auto-calculate="true" - @input-change="handleDetailsChange" - @delete-row="handleDeleteRow" - /> - + </el-row> + <ProductionDetailsTable + v-model="detailsTableData" + :border="false" + :show-operations="true" + :auto-calculate="true" + @input-change="handleDetailsChange" + @delete-row="handleDeleteRow" + /> </div> <template #footer> <div class="dialog-footer"> - <el-button @click="handleClose">鍙� 娑�</el-button> + <el-button @click="handleClose" v-if="dialogType === 'add'" + >鍙� 娑�</el-button + > + <el-button @click="handleReset" v-if="dialogType === 'edit'" + >閲� 缃�</el-button + > <el-button type="primary" :loading="loading" @click="handleSubmit" >纭� 瀹�</el-button > @@ -70,31 +104,56 @@ center append-to-body > + <div style="margin-bottom: 10px"> + <el-alert + v-if="tableData.length > 0" + :title="`褰撳墠宸查�夋嫨 ${tableData.length} 鏉℃暟鎹甡" + type="info" + :closable="false" + show-icon + /> + </div> <ETable @selection-change="handleSelectionChange" :showOperations="false" + ref="etableRef" :columns="formalDatabaseColumns" :tableData="formalDatabaseData" + :defaultSelectedIds="selectedIds" + :rowKey="'id'" height="400" @cell-edit="handleCellEdit" :show-selection="true" /> - <el-row :gutter="24"> - <el-col :span="2" :offset="22"> - <el-button type="primary" @click="handleSelectData">纭畾</el-button> + <el-row :gutter="24" style="margin-top: 15px"> + <el-col :span="12"> + <el-text type="info"> + 宸查�夋嫨 {{ formalDatabaseSelectedData.length }} 鏉℃暟鎹� + </el-text> + </el-col> + <el-col :span="12" style="text-align: right"> + <el-button @click="innerVisible = false">鍙栨秷</el-button> + <el-button + type="primary" + @click="handleSelectData" + :disabled="formalDatabaseSelectedData.length === 0" + > + 纭畾娣诲姞 + </el-button> </el-col> </el-row> </el-dialog> </template> <script setup> -import { ref, reactive, watch } from "vue"; +import { ref, reactive, watch, onMounted, nextTick, computed } from "vue"; import ETable from "@/components/Table/ETable.vue"; import ETableModify from "@/components/Table/EtableModify.vue"; import ProductionDetailsTable from "./ProductionDetailsTable.vue"; -import { ElMessage } from "element-plus"; +import { ElMessage, ElMessageBox, ElAlert, ElText } from "element-plus"; import { Delete, Warning, Plus } from "@element-plus/icons-vue"; -import { getOfficialAll } from "@/api/production/index.js"; +import { getOfficialAll, addOrEditPM } from "@/api/production/index.js"; +import { getCurrentInstance } from "vue"; const props = defineProps({ visible: { @@ -123,22 +182,27 @@ const tableData = ref([]); const currentRow = ref(null); const columns = [ - { label: "渚涘簲鍟嗗悕绉�", prop: "supplierName" }, - { label: "鐓ょ", prop: "coal" }, - { label: "鍗曚环(涓嶅惈绋�)", prop: "priceExcludingTax" }, - { label: "搴撳瓨鏁伴噺", prop: "inventoryQuantity" }, + { label: "鐓ょ", prop: "coal", minwidth: 120 }, + { label: "搴撳瓨鏁伴噺", prop: "inventoryQuantity", minwidth: 100 }, { label: "浣跨敤鏁伴噺", - prop: "used", + prop: "usedQuantity", editable: true, - width: 120, + minwidth: 120, editType: "number", }, - ]; -const detailsTableData = ref([ - -]); +const etableRef = ref(null); +const selectedIds = ref([]); // 榛樿閫変腑鐨処D鏁扮粍 +// 璋冭瘯鍑芥暟锛氶獙璇両D鍖归厤閫昏緫 +const debugIdMatching = () => { + if (formalDatabaseData.value.length > 0 && selectedIds.value.length > 0) { + const matchedRows = formalDatabaseData.value.filter((row) => + selectedIds.value.includes(row.id) + ); + } +}; +const detailsTableData = ref([]); const handleRowClick = (row) => { currentRow.value = row; }; @@ -164,70 +228,166 @@ reviewer: "", date: "", }); -const handlData =async () => { +const handlData = async () => { innerVisible.value = true; let res = await getOfficialAll(); - console.log("鑾峰彇閰嶇疆鏁版嵁", res); if (res.code === 200) { formalDatabaseData.value = res.data; + const existingOfficialIds = tableData.value + .map((item) => item.officialId) + .filter((id) => id); + selectedIds.value = existingOfficialIds; + debugIdMatching(); + nextTick(() => { + setTimeout(() => { + if (etableRef.value && existingOfficialIds.length > 0) { + etableRef.value.setDefaultSelection(); + } + }, 100); + }); } else { ElMessage.error("鑾峰彇閰嶇疆鏁版嵁澶辫触"); } }; +// 鎵嬪姩璁剧疆琛ㄦ牸閫変腑鐘舵�� +const setTableSelection = (ids) => { + if (!etableRef.value || !Array.isArray(ids) || ids.length === 0) { + return; + } + + nextTick(() => { + setTimeout(() => { + try { + // 鍏堟竻闄ゆ墍鏈夐�変腑 + etableRef.value.clearSelection(); + + // 鎵惧埌闇�瑕侀�変腑鐨勮骞惰缃�変腑鐘舵�� + // 娉ㄦ剰锛歩ds涓槸officialId锛岄渶瑕佸尮閰峟ormalDatabaseData涓殑id瀛楁 + const rowsToSelect = formalDatabaseData.value.filter((row) => + ids.includes(row.id) + ); + if (rowsToSelect.length > 0) { + etableRef.value.setRowsSelection(rowsToSelect, true); + console.log("閫変腑鐘舵�佽缃畬鎴�"); + } else { + } + } catch (error) { + console.error("璁剧疆閫変腑鐘舵�佸け璐�:", error); + } + }, 150); + }); +}; + const formalDatabaseData = ref([]); const formalDatabaseSelectedData = ref([]); -formalDatabaseData.value = [ -]; +formalDatabaseData.value = []; // 鍒濆鍖� const Initialization = () => { tableData.value = []; + detailsTableData.value = []; + copyForm.value = null; + dialogType.value = "add"; }; +const copyForm = ref(null); +const editInitialization = (data) => { + copyForm.value = { ...data }; // 娣辨嫹璐濇暟鎹� + tableData.value = data.productionInventoryList || []; + detailsTableData.value = data.productionList || []; + dialogType.value = "edit"; + + // 璁剧疆榛樿閫変腑鐨処D锛屼娇鐢╫fficialId鏉ュ尮閰� + const existingOfficialIds = tableData.value + .map((item) => item.officialId) + .filter((id) => id); + selectedIds.value = existingOfficialIds; +}; +// 鐩戝惉瀵硅瘽妗嗙姸鎬侊紝鍦ㄦ墦寮�鏃惰缃�変腑鐘舵�� +watch(innerVisible, (newVal) => { + if (newVal && selectedIds.value.length > 0) { + console.log("瀵硅瘽妗嗘墦寮�锛岃缃�変腑鐘舵��"); + setTimeout(() => setTableSelection(selectedIds.value), 200); + } + // 瀵硅瘽妗嗗叧闂椂娓呯┖閫夋嫨鐘舵�� + if (!newVal) { + formalDatabaseSelectedData.value = []; + } +}); + defineExpose({ - Initialization + Initialization, + editInitialization, }); const handleSelectData = (row) => { + tableData.value = []; if (!innerVisible.value) return; - // 鑾峰彇閫変腑鐨勬暟鎹� const selectedData = formalDatabaseSelectedData.value; if (selectedData.length === 0) { ElMessage.warning("璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�"); return; } - // 灏嗛�変腑鐨勬暟鎹牴鎹渶瑕佺瓫閫夊埌琛ㄦ牸涓� + let addedCount = 0; + let duplicateCount = 0; selectedData.forEach((item) => { - const existingItem = tableData.value.find( - (row) => row.id === item.id - ); - if (!existingItem) { - tableData.value.push( - Object.assign({}, item, { - used: 0, // 鍒濆浣跨敤鏁伴噺涓�0 - }) - ); - } + const newItem = { + ...item, // 澶嶅埗鎵�鏈夊師濮嬫暟鎹� + officialId: item.id, // 淇濆瓨鍘熷鐨刬d浣滀负officialId + usedQuantity: 0, // 鍒濆浣跨敤鏁伴噺涓�0 + // 鍙互鏍规嵁闇�瑕佹坊鍔犲叾浠栧瓧娈� + }; + tableData.value.push(newItem); + addedCount++; }); + + // 鏇存柊selectedIds锛岀‘淇濆寘鍚墍鏈夊綋鍓峵ableData涓殑officialId + const allOfficialIds = tableData.value + .map((item) => item.officialId) + .filter((id) => id); + selectedIds.value = allOfficialIds; + + console.log("鏇存柊鍚庣殑琛ㄦ牸鏁版嵁:", tableData.value); + console.log("鏇存柊鍚庣殑閫変腑ID:", selectedIds.value); + + // 鍏抽棴閫夋嫨瀵硅瘽妗� innerVisible.value = false; + + // 鏄剧ず缁撴灉娑堟伅 + let message = ""; + if (addedCount > 0) { + message += `鎴愬姛娣诲姞 ${addedCount} 鏉℃暟鎹甡; + } + if (duplicateCount > 0) { + message += (message ? "锛�" : "") + `璺宠繃 ${duplicateCount} 鏉¢噸澶嶆暟鎹甡; + } + if (message) { + ElMessage.success(message); + } else { + ElMessage.info("娌℃湁鏂版暟鎹娣诲姞"); + } }; const handleSelectionChange = (selection) => { formalDatabaseSelectedData.value = selection; }; -const reset = () => { - // formRef - formRef.value?.resetFields(); +const handleReset = () => { + console.log(copyForm.value); + tableData.value = + JSON.parse(JSON.stringify(copyForm.value.productionInventoryList)) || []; + detailsTableData.value = + JSON.parse(JSON.stringify(copyForm.value.productionList)) || []; }; - -const selectChange = (value) => {}; - // 鎻愪氦琛ㄥ崟 const handleSubmit = async () => { - console.log("鎻愪氦琛ㄥ崟鏁版嵁:", tableData.value); - console.log(detailsTableData.value); let data = { productionList: detailsTableData.value, productionInventoryList: tableData.value, + ...copyForm.value, }; - console.log("鎻愪氦鏁版嵁", data); - // dialogVisible.value = false; + let res = await addOrEditPM(data); + if (res.code === 200) { + dialogVisible.value = false; + emit("success"); + } else { + ElMessage.error("鎻愪氦澶辫触"); + } }; // 鍏抽棴寮圭獥 @@ -251,46 +411,46 @@ // 娣诲姞鍗曞厓鏍肩紪杈戝鐞嗗嚱鏁� const handleCellEdit = (row, prop, value) => { - if (prop === "used" && Number(value) > Number(row.stock)) { - ElMessage.warning("浣跨敤鏁伴噺涓嶈兘澶т簬搴撳瓨鏁伴噺锛�"); - row.used = row.stock; + if (prop === "usedQuantity") { + const numValue = Number(value); + const inventory = Number(row.inventoryQuantity); + + // 楠岃瘉杈撳叆鍊� + if (isNaN(numValue) || numValue < 0) { + ElMessage.warning("浣跨敤鏁伴噺蹇呴』鏄潪璐熸暟锛�"); + row.usedQuantity = 0; + return; + } + + if (numValue > inventory) { + ElMessage.warning(`浣跨敤鏁伴噺涓嶈兘澶т簬搴撳瓨鏁伴噺锛�${inventory}锛夛紒`); + row.usedQuantity = inventory; + return; + } + + // 鏇存柊鍊� + row.usedQuantity = numValue; + console.log(`鏇存柊 ${row.coal} 鐨勪娇鐢ㄦ暟閲忎负: ${numValue}`); } }; // 澶勭悊鐢熶骇鏄庣粏琛ㄦ牸鐨勬搷浣� const addNewRow = () => { detailsTableData.value.push({ - coalType: "", + coal: "", productionQuantity: "", laborCost: "", energyConsumptionCost: "", equipmentDepreciation: "", purchasePrice: "", autoCalculate: "0.00", - producer:"", + producer: "", }); }; const clearAllRows = () => { detailsTableData.value = []; ElMessage.success("宸叉竻绌烘墍鏈夋暟鎹�"); -}; - -const calculateAllCosts = () => { - detailsTableData.value.forEach((row) => { - const laborCost = parseFloat(row.laborCost) || 0; - const energyCost = parseFloat(row.energyCost) || 0; - const equipmentDepreciation = parseFloat(row.equipmentDepreciation) || 0; - const purchasePrice = parseFloat(row.purchasePrice) || 0; - - row.totalCost = ( - laborCost + - energyCost + - equipmentDepreciation + - purchasePrice - ).toFixed(2); - }); - ElMessage.success("閲嶆柊璁$畻瀹屾垚"); }; const handleDetailsChange = (data) => { @@ -300,6 +460,59 @@ const handleDeleteRow = (index) => { ElMessage.success(`宸插垹闄ょ ${index + 1} 琛屾暟鎹甡); }; + +// 鍒犻櫎鍗曚釜宸查�夋暟鎹」 +const handleRemoveItem = (row) => { + console.log("鍒犻櫎椤�:", row); + const index = tableData.value.findIndex( + (item) => item.officialId === row.officialId + ); + if (index > -1) { + tableData.value.splice(index, 1); + + // 鏇存柊selectedIds + const updatedOfficialIds = tableData.value + .map((item) => item.officialId) + .filter((id) => id); + selectedIds.value = updatedOfficialIds; + + console.log("鍒犻櫎鍚庣殑琛ㄦ牸鏁版嵁:", tableData.value); + console.log("鏇存柊鍚庣殑閫変腑ID:", selectedIds.value); + + ElMessage.success("宸插垹闄ら�変腑椤�"); + } +}; + +// 娓呯┖鎵�鏈夊凡閫夋暟鎹� +const removeSelectedData = () => { + if (tableData.value.length === 0) { + ElMessage.warning("娌℃湁鍙竻绌虹殑鏁版嵁"); + return; + } + + ElMessageBox.confirm("纭娓呯┖鎵�鏈夊凡閫夋嫨鐨勬暟鎹悧锛�", "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning", + }) + .then(() => { + tableData.value = []; + selectedIds.value = []; + console.log("宸叉竻绌烘墍鏈夊凡閫夋暟鎹�"); + ElMessage.success("宸叉竻绌烘墍鏈夋暟鎹�"); + }) + .catch(() => { + console.log("鍙栨秷娓呯┖鎿嶄綔"); + }); +}; + +// 璁$畻鎬讳娇鐢ㄩ噺 +const totalUsedQuantity = computed(() => { + return tableData.value.reduce((total, item) => { + const usedQty = Number(item.usedQuantity) || 0; + return total + usedQty; + }, 0); +}); </script> <style scoped lang="scss"> @@ -313,7 +526,7 @@ .el-row > .el-col > h1 { font-weight: bolder; } -.empty-table > .el-row{ +.empty-table > .el-row { margin-bottom: 12px; } </style> diff --git a/src/views/production/index.vue b/src/views/production/index.vue index d298680..531640a 100644 --- a/src/views/production/index.vue +++ b/src/views/production/index.vue @@ -1,226 +1,201 @@ <template> <div class="production-container"> - <el-form :inline="true" :model="queryParams" class="search-form" style="width: 100%"> - <el-form-item label="鎼滅储"> - <el-input v-model="queryParams.searchAll" placeholder="璇疯緭鍏ュ叧閿瘝" clearable /> - </el-form-item> - <el-form-item> - <el-button type="primary" @click="handleSearch">鏌ヨ</el-button> - <el-button @click="handleReset">閲嶇疆</el-button> - </el-form-item> - </el-form> + <!-- 鎼滅储琛ㄥ崟 --> + <el-form :inline="true" :model="queryParams" class="search-form"> + <el-form-item label="鎼滅储"> + <el-input + v-model="queryParams.searchAll" + placeholder="璇疯緭鍏ュ叧閿瘝" + clearable + /> + </el-form-item> + <el-form-item> + <el-button type="primary" @click="handleSearch">鏌ヨ</el-button> + <el-button @click="handleReset">閲嶇疆</el-button> + </el-form-item> + </el-form> + + <!-- 涓昏鍐呭鍖哄煙 --> <el-card> - <el-button type="success" :icon="Plus" @click="handleAddBatch">鏂板鍔犲伐</el-button> - <el-button type="danger" :icon="Delete">鍒犻櫎</el-button> - <el-button type="info" :icon="Download">瀵煎嚭</el-button> - <ETable :loading="loading" :table-data="tableData" :columns="columns" @selection-change="handleSelectionChange" - @edit="handleEdit" @view-detail="handleViewDetail" :show-selection="true" :border="true" :maxHeight="480" /> + <!-- 鎿嶄綔鎸夐挳 --> + <div class="toolbar"> + <el-button type="success" :icon="Plus" @click="openDialog('add')"> + 鏂板鍔犲伐 + </el-button> + <el-button type="danger" :icon="Delete" :disabled="!selectedRows.length"> + 鍒犻櫎 + </el-button> + </div> + + <!-- 鏁版嵁琛ㄦ牸 --> + <ETable + :loading="loading" + :table-data="tableData" + :columns="columns" + @selection-change="handleSelectionChange" + @edit="row => openDialog('edit', row)" + :show-selection="true" + :border="true" + :maxHeight="480" + > + <template #coal="{ row }"> + <div class="coal-tags"> + <el-tag v-for="coal in parseCoalArray(row.coal)" :key="coal" size="small"> + {{ coal }} + </el-tag> + <span v-if="!row.coal">--</span> + </div> + </template> + </ETable> + + <!-- 鍒嗛〉缁勪欢 --> <Pagination :total="total" :page="queryParams.current" :limit="queryParams.size" - :show-total="true" @pagination="handlePageChange" - :layout="'total, prev, pager, next, jumper'" - ></Pagination> + /> </el-card> - <ProductionDialog v-model:visible="dialogVisible" ref="childRef" :type="dialogType" - @success="handleDialogSuccess" /> + + <!-- 鐢熶骇瀵硅瘽妗� --> + <ProductionDialog + v-model:visible="dialogVisible" + ref="dialogRef" + :type="dialogType" + @success="handleDialogSuccess" + /> </div> </template> <script setup> import { ref, reactive, onMounted } from "vue"; import { ElMessage, ElMessageBox } from "element-plus"; -import { Plus, Delete, Download, List } from "@element-plus/icons-vue"; +import { Plus, Delete } from "@element-plus/icons-vue"; import ProductionDialog from "./components/ProductionDialog.vue"; import ETable from "@/components/Table/ETable.vue"; import Pagination from "@/components/Pagination/index.vue"; import { getProductionMasterList } from "@/api/production"; -const childRef = ref(null); + +// 琛ㄦ牸鍒楅厤缃� const columns = [ - { prop: "category", label: "鐓ょ", minWidth: 150 }, - { prop: "unit", label: "鍗曚綅", minWidth: 120 }, - { prop: "productionVolume", label: "鐢熶骇鏁伴噺", minWidth: 150 }, + { prop: "coal", label: "鐓ょ", minWidth: 150, slot: 'coal' }, + { prop: "productionQuantity", label: "鐢熶骇鏁伴噺", minWidth: 120 }, { prop: "laborCost", label: "浜哄伐鎴愭湰", minWidth: 150 }, - { prop: "materialCost", label: "鍘熸枡鎴愭湰", minWidth: 120 }, - { prop: "equipmentCost", label: "璁惧璐圭敤", minWidth: 143 }, + { prop: "energyConsumptionCost", label: "鑳借�楁垚鏈�", minWidth: 120 }, + { prop: "equipmentDepreciation", label: "璁惧鎶樻棫", minWidth: 143 }, { prop: "totalCost", label: "鎬绘垚鏈�", minWidth: 150 }, - { prop: "totalPrice", label: "鎬诲敭浠�", minWidth: 150 }, - { prop: "profit", label: "鍒╂鼎", minWidth: 100 }, - { prop: "reviewer", label: "澶嶈浜�", minWidth: 120 }, - { prop: "date", label: "鏃ユ湡", minWidth: 150 }, + { prop: "producer", label: "鐢熶骇浜�", minWidth: 150 }, ]; -// 鎼滅储琛ㄥ崟鏁版嵁 - -// 琛ㄦ牸鏁版嵁 +// 鍝嶅簲寮忔暟鎹� const tableData = ref([]); const loading = ref(false); const total = ref(0); - -const queryParams = reactive({ - searchAll:"", - current: 1, - size: 10, // 鍥哄畾姣忛〉10鏉� -}); -const handlePageChange = ({ page }) => { - console.log("鍒嗛〉鍙樺寲:", { page }); - queryParams.current = page; - getList(); -}; -// 閫変腑鐨勮鏁版嵁 const selectedRows = ref([]); - -// 寮圭獥鐩稿叧 const dialogVisible = ref(false); const dialogType = ref("add"); -const currentRow = ref(null); +const dialogRef = ref(null); -// 鐢熶骇鏄庣粏瀵硅瘽妗嗘帶鍒� -const detailDialogVisible = ref(false); -const currentDetailRow = ref(null); +// 鏌ヨ鍙傛暟 +const queryParams = reactive({ + searchAll: "", + current: 1, + size: 10, +}); +// 鑾峰彇琛ㄦ牸鏁版嵁 // 鑾峰彇琛ㄦ牸鏁版嵁 const getList = async () => { loading.value = true; try { - const res = await getProductionMasterList({...queryParams}); + // 鏋勫缓姝g‘鐨勫垎椤靛弬鏁� + const params = { + searchAll: queryParams.searchAll, + // 灏濊瘯澶氱甯歌鐨勫垎椤靛弬鏁版牸寮� + current: queryParams.current, + size: queryParams.size, + page: queryParams.current, + pageSize: queryParams.size, + pageNum: queryParams.current, + limit: queryParams.size, + offset: (queryParams.current - 1) * queryParams.size + }; + + console.log('鍙戦�佸垎椤靛弬鏁�:', params); + console.log(`绗�${queryParams.current}椤靛簲璇ユ樉绀虹${(queryParams.current - 1) * queryParams.size + 1}-${queryParams.current * queryParams.size}鏉℃暟鎹甡); + + const res = await getProductionMasterList(params); tableData.value = res.data.records || []; total.value = res.data.total || 0; + + console.log('鎺ユ敹鍒扮殑鏁版嵁:', { + 褰撳墠椤�: queryParams.current, + 杩斿洖鏉℃暟: tableData.value.length, + 鎬绘潯鏁�: total.value + }); } catch (error) { ElMessage.error("鑾峰彇鏁版嵁澶辫触"); + console.error('API閿欒:', error); } finally { loading.value = false; } }; -// 澶勭悊琛ㄦ牸閫夋嫨鍙樺寲 +// 鎼滅储鍜岄噸缃� +const handleSearch = () => { + queryParams.current = 1; + getList(); +}; + +const handleReset = () => { + queryParams.searchAll = ""; + handleSearch(); +}; + +// 鍒嗛〉澶勭悊 +const handlePageChange = ({ page }) => { + queryParams.current = page; + getList(); +}; + +// 琛ㄦ牸閫夋嫨澶勭悊 const handleSelectionChange = (selection) => { selectedRows.value = selection; }; -// 鎼滅储鏂规硶 -const handleSearch = () => { - pagination.currentPage = 1; - getList(); -}; - -// 閲嶇疆鎼滅储 -const handleReset = () => { - handleSearch(); -}; - -// 鏂板鍔犲伐 -const handleAddBatch = () => { - dialogType.value = "add"; +// 鎵撳紑瀵硅瘽妗� - 缁熶竴澶勭悊鏂板鍜岀紪杈� +const openDialog = (type, row = null) => { + dialogType.value = type; dialogVisible.value = true; - childRef.value.Initialization(); -}; - -// 缂栬緫 -const handleEdit = (row) => { - currentRow.value = row; - dialogType.value = "edit"; - dialogVisible.value = true; -}; - -// 鎵撳紑鐢熶骇鏄庣粏瀵硅瘽妗� -const handleViewDetail = (row) => { - currentDetailRow.value = row; - detailDialogVisible.value = true; -}; - -// 澶勭悊寮圭獥鎻愪氦 -const handleDialogSuccess = async (formData) => { - try { - if (dialogType.value === "add") { - await addProduction(formData); - ElMessage.success("鏂板鎴愬姛"); - } else { - await updateProduction({ - ...formData, - id: currentRow.value.id, - }); - ElMessage.success("鏇存柊鎴愬姛"); - } - getList(); - } catch (error) { - ElMessage.error(dialogType.value === "add" ? "鏂板澶辫触" : "鏇存柊澶辫触"); + + if (type === 'add') { + dialogRef.value?.Initialization(); + } else if (type === 'edit' && row) { + dialogRef.value?.editInitialization({ ...row }); } }; -// 澶勭悊鐢熶骇鏄庣粏寮圭獥鎻愪氦 -const handleDetailDialogSuccess = async (formData) => { - try { - ElMessage.success("淇濆瓨鎴愬姛"); - getList(); - } catch (error) { - ElMessage.error("淇濆瓨澶辫触"); - } -}; - -// 鍒犻櫎 -const handleDelete = (row) => { - ElMessageBox.confirm("纭鍒犻櫎璇ヨ褰曞悧锛�", "鎻愮ず", { - confirmButtonText: "纭畾", - cancelButtonText: "鍙栨秷", - type: "warning", - }) - .then(async () => { - try { - await deleteProduction(row.id); - ElMessage.success("鍒犻櫎鎴愬姛"); - getList(); - } catch (error) { - console.error("鍒犻櫎澶辫触:", error); - ElMessage.error("鍒犻櫎澶辫触"); - } - }) - .catch(() => { - ElMessage.info("宸插彇娑堝垹闄�"); - }); -}; - -// 瀵煎嚭 -const handleExport = async (row) => { - try { - const res = await exportProduction({ id: row.id }); - const blob = new Blob([res], { type: "application/vnd.ms-excel" }); - const fileName = `鐢熶骇鍔犲伐璁板綍_${new Date().getTime()}.xlsx`; - if ("download" in document.createElement("a")) { - const elink = document.createElement("a"); - elink.download = fileName; - elink.style.display = "none"; - elink.href = URL.createObjectURL(blob); - document.body.appendChild(elink); - elink.click(); - URL.revokeObjectURL(elink.href); - document.body.removeChild(elink); - } else { - navigator.msSaveBlob(blob, fileName); - } - } catch (error) { - ElMessage.error("瀵煎嚭澶辫触"); - } -}; - -// 澶勭悊姣忛〉鏄剧ず鏁伴噺鍙樺寲 -const handleSizeChange = (val) => { - pagination.size = val; +// 瀵硅瘽妗嗘垚鍔熷洖璋� +const handleDialogSuccess = () => { getList(); + ElMessage.success("鎿嶄綔鎴愬姛"); }; -// 澶勭悊椤电爜鍙樺寲 -const handleCurrentChange = (val) => { - pagination.currentPage = val; - getList(); +// 瑙f瀽鐓ょ鏁扮粍 - 绠�鍖栭�昏緫 +const parseCoalArray = (coalString) => { + if (!coalString) return []; + + if (Array.isArray(coalString)) return coalString; + + return String(coalString) + .replace(/^\[|\]$/g, '') + .split(',') + .map(item => item.trim()) + .filter(Boolean); }; // 缁勪欢鎸傝浇鏃跺姞杞芥暟鎹� -onMounted(() => { - getList(); -}); +onMounted(getList); </script> <style scoped lang="scss"> @@ -241,7 +216,7 @@ width: 20%; } } -.search-form{ +.search-form { display: flex; justify-content: space-between; align-items: center; @@ -255,4 +230,18 @@ margin-left: 10px; } } +.coal-tags { + display: flex; + flex-wrap: wrap; + gap: 4px; + + .el-tag { + margin-right: 4px; + margin-bottom: 4px; + + &:last-child { + margin-right: 0; + } + } +} </style> -- Gitblit v1.9.3