From 908555743c2c36d7e13a129f4ad78f3f69602489 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 16 十月 2025 09:14:17 +0800
Subject: [PATCH] 生产管控-生产订单添加随机排产功能
---
src/views/production/index.vue | 452 +++++++++++++++++++++++++++----------------------------
1 files changed, 223 insertions(+), 229 deletions(-)
diff --git a/src/views/production/index.vue b/src/views/production/index.vue
index dbad178..e9198ea 100644
--- a/src/views/production/index.vue
+++ b/src/views/production/index.vue
@@ -1,278 +1,272 @@
<template>
- <div class="production-container">
- <div class="search-bar">
- <el-input v-model="searchForm.keyword" placeholder="璇疯緭鍏ュ叧閿瘝" clearable />
- <el-input v-model="searchForm.addUser" placeholder="璇疯緭鍏ヤ汉" clearable />
- <el-button type="primary" @click="handleSearch">鏌ヨ</el-button>
- <el-button @click="handleReset">閲嶇疆</el-button>
- </div>
+ <div class="app-container">
+ <!-- 鎼滅储琛ㄥ崟 -->
+ <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>
- <div class="operation-bar">
- <el-button type="primary" @click="handleAdd">鏂板閰嶉」</el-button>
- <el-button type="success" @click="handleAddBatch">鏂板鍔犲伐</el-button>
- <el-button type="warning">淇敼</el-button>
- <el-button type="danger">鍒犻櫎</el-button>
- <el-button type="info">瀵煎嚭</el-button>
- </div>
-
- <el-table :data="tableData" border style="width: 100%" @selection-change="handleSelectionChange">
- <el-table-column type="selection" width="55" />
- <el-table-column prop="sequence" label="搴忓彿" width="80" />
- <el-table-column prop="category" label="鐓ょ" width="120" />
- <el-table-column prop="unit" label="鍗曚綅" width="100" />
- <el-table-column prop="productionVolume" label="鐢熶骇鏁伴噺" width="120" />
- <el-table-column prop="laborCost" label="浜哄伐鎴愭湰" width="120" />
- <el-table-column prop="materialCost" label="鍘熸枡鎴愭湰" width="120" />
- <el-table-column prop="equipmentCost" label="璁惧璐圭敤" width="120" />
- <el-table-column prop="totalCost" label="鎬绘垚鏈�" width="120" />
- <el-table-column prop="totalPrice" label="鎬绘垚鏈�" width="120" />
- <el-table-column prop="profit" label="鍒╂鼎" width="100" />
- <el-table-column prop="reviewer" label="澶嶈浜�" width="120" />
- <el-table-column prop="date" label="鏃ユ湡" width="120" />
- <el-table-column label="鎿嶄綔" fixed="right" width="220">
- <template #default="scope">
- <el-button type="primary" link @click="handleEdit(scope.row)">鐧昏</el-button>
- <el-button type="success" link @click="handleEdit(scope.row)">缂栬緫</el-button>
- <el-button type="danger" link @click="handleDelete(scope.row)">鍒犻櫎</el-button>
- <el-button type="warning" link @click="handleExport(scope.row)">瀵煎嚭</el-button>
+ <!-- 涓昏鍐呭鍖哄煙 -->
+ <el-card>
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <div class="toolbar">
+ <el-button type="success" :icon="Plus" @click="openDialog('add')">
+ 鏂板鍔犲伐
+ </el-button>
+ <el-button
+ type="danger"
+ :icon="Delete"
+ :disabled="!selectedRows.length"
+ @click="() => deleteSelected(delPM)"
+ >
+ 鍒犻櫎
+ </el-button>
+ <el-button type="primary" @click="handleRandomScheduling">
+ 闅忔満鎺掍骇
+ </el-button>
+ </div>
+ <!-- 鏁版嵁琛ㄦ牸 -->
+ <ETable
+ :showOverflowTooltip="false"
+ :loading="loading"
+ :table-data="tableData"
+ :columns="columns"
+ :current-page="queryParams.current"
+ :page-size="queryParams.size"
+ @selection-change="handleSelectionChange"
+ @edit="(row) => openDialog('edit', row)"
+ :show-selection="true"
+ :border="true"
+ @viewRow="(row) => (viewRow('viewRow', row))"
+ :operations="['edit', 'viewRow']"
+ :operationsWidth="200"
+ :show-overflow-tooltip="false"
+ style="width: 100%; height: calc(100vh - 26em)"
+ >
+ <template #coalId="{ row }">
+ <div class="coal-tags">
+ <template v-if="row.coalId">
+ <el-tag
+ v-for="coal in parseCoalArray(row.coalId)"
+ :key="coal"
+ size="small"
+ type="primary"
+ class="coal-tag"
+ >
+ {{ getDisplayCoalName(coal) }}
+ </el-tag>
+ </template>
+ <span v-else class="no-data">--</span>
+ </div>
</template>
- </el-table-column>
- </el-table>
-
- <div class="pagination">
- <el-pagination
- v-model:current-page="pagination.currentPage"
- v-model:page-size="pagination.pageSize"
- :page-sizes="[10, 20, 30, 50]"
- :total="pagination.total"
- layout="total, sizes, prev, pager, next, jumper"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
+ </ETable>
+ <!-- 鍒嗛〉缁勪欢 -->
+ <Pagination
+ :layout="'total, prev, pager, next, jumper'"
+ :total="total"
+ v-model:page="queryParams.current"
+ :limit="queryParams.size"
+ @pagination="handlePageChange"
/>
- </div>
+ </el-card>
- <!-- 寮圭獥缁勪欢 -->
- <ProductionDialog-dialog
+ <!-- 鐢熶骇瀵硅瘽妗� -->
+ <!-- handleProductionAndProcessing -->
+ <ProductionDialog
v-model:visible="dialogVisible"
+ ref="dialogRef"
:type="dialogType"
- :row-data="currentRow"
+ @update:productionAndProcessing="handleProductionAndProcessing"
@success="handleDialogSuccess"
/>
</div>
</template>
<script setup>
-import { ref, reactive, onMounted } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { getProductionList, addProduction, updateProduction, deleteProduction, exportProduction } from '@/api/production'
-import ProductionDialog from './components/ProductionDialog.vue'
+import { onMounted, ref } from "vue";
+import { ElMessage } from "element-plus";
+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, delPM, randomScheduling } from "@/api/production";
+import { parseCoalArray } from "@/utils/production";
+import { useTableData } from "./components/useTableData.js";
+import { useDialog } from "./components/useDialog.js";
+import { useCoalData } from "./components/useCoalData.js";
+import { getCoalInfoList } from "@/api/production";
-// 鎼滅储琛ㄥ崟鏁版嵁
-const searchForm = reactive({
- keyword: '',
- addUser: ''
-})
+// 鐓ょ淇℃伅鍒楄〃
+const coalInfoList = ref([]);
-// 琛ㄦ牸鏁版嵁
-const tableData = ref([])
-const loading = ref(false)
+// 琛ㄦ牸鍒楅厤缃�
+const columns = [
+ { prop: "coalId", label: "鐓ょ", minWidth: 150, slot: true },
+ { prop: "productionQuantity", label: "鐢熶骇鏁伴噺", minWidth: 120 },
+ { prop: "laborCost", label: "浜哄伐鎴愭湰", minWidth: 150 },
+ { prop: "energyConsumptionCost", label: "鑳借�楁垚鏈�", minWidth: 120 },
+ { prop: "equipmentDepreciation", label: "璁惧鎶樻棫", minWidth: 143 },
+ { prop: "totalCost", label: "鎬绘垚鏈�", minWidth: 150 },
+];
-// 鍒嗛〉鏁版嵁
-const pagination = reactive({
- currentPage: 1,
- pageSize: 10,
- total: 0
-})
+// 浣跨敤琛ㄦ牸鏁版嵁缁勫悎寮忓嚱鏁�
+const {
+ tableData,
+ loading,
+ total,
+ selectedRows,
+ queryParams,
+ getList,
+ handleSearch,
+ handleReset,
+ handlePageChange,
+ handleSelectionChange,
+ deleteSelected,
+} = useTableData(getProductionMasterList, { pageSize: 10 });
-// 閫変腑鐨勮鏁版嵁
-const selectedRows = ref([])
+// 浣跨敤瀵硅瘽妗嗙粍鍚堝紡鍑芥暟
+const {
+ dialogVisible,
+ dialogType,
+ dialogRef,
+ openDialog,
+ viewRow,
+ handleDialogSuccess: onDialogSuccess,
+} = useDialog();
-// 寮圭獥鐩稿叧
-const dialogVisible = ref(false)
-const dialogType = ref('add')
-const currentRow = ref(null)
+// 浣跨敤鐓ょ鏁版嵁缁勫悎寮忓嚱鏁�
+const { getCoalNameById, getCoalData } = useCoalData();
-// 鑾峰彇琛ㄦ牸鏁版嵁
-const getList = async () => {
- loading.value = true
- try {
- const params = {
- ...searchForm,
- pageNum: pagination.currentPage,
- pageSize: pagination.pageSize
- }
- // const res = await getProductionList(params)
- // 鍋囨暟鎹�
- const res = {
- data: {
- list: [{
- sequence: 1,
- category: '鐓ょ',
- unit: '鍗曚綅',
- productionVolume: '鐢熶骇鏁伴噺',
- laborCost: '浜哄伐鎴愭湰',
- materialCost: '鍘熸枡鎴愭湰',
- equipmentCost: '璁惧璐圭敤',
- totalCost: '鎬绘垚鏈�',
- totalPrice: '鎬绘垚鏈�',
- profit: '鍒╂鼎',
- reviewer: '澶嶈浜�',
- date: '鏃ユ湡'
- }],
- total: 0
- }
- }
-
+// 鑾峰彇鐓ょ鏄剧ず鍚嶇О锛堝甫澶囩敤閫昏緫锛�
+const getDisplayCoalName = (coalId) => {
+ // 浼樺厛浣跨敤 useCoalData 鐨勬柟娉�
+ let name = getCoalNameById(coalId);
- tableData.value = res.data.list
- pagination.total = res.data.total
- } catch (error) {
- console.error('鑾峰彇鏁版嵁澶辫触:', error)
- ElMessage.error('鑾峰彇鏁版嵁澶辫触')
- } finally {
- loading.value = false
+ // 濡傛灉娌℃湁鎵惧埌锛屽皾璇曚粠 coalInfoList 涓煡鎵�
+ if (name === coalId && coalInfoList.value.length > 0) {
+ const found = coalInfoList.value.find((item) => item.id == coalId);
+ name = found ? found.coal : coalId;
}
-}
-// 澶勭悊琛ㄦ牸閫夋嫨鍙樺寲
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection
-}
+ return name || coalId;
+};
-// 鎼滅储鏂规硶
-const handleSearch = () => {
- pagination.currentPage = 1
- getList()
-}
+// 澶勭悊鐢熶骇鏁版嵁鏇存柊
+const handleProductionAndProcessing = (row, rows) => {
+ const index = tableData.value.findIndex((item) => item.id === rows.id);
+ if (index !== -1) {
+ tableData.value[index] = { ...tableData.value[index], ...row };
+ }
+};
-// 閲嶇疆鎼滅储
-const handleReset = () => {
- searchForm.keyword = ''
- searchForm.addUser = ''
- handleSearch()
-}
+// 瀵硅瘽妗嗘垚鍔熷洖璋�
+const handleDialogSuccess = () => {
+ onDialogSuccess(() => {
+ getList();
+ ElMessage.success("鎿嶄綔鎴愬姛");
+ });
+};
-// 鏂板閰嶉」
-const handleAdd = () => {
- dialogType.value = 'add'
- dialogVisible.value = true
-}
-
-// 鏂板鍔犲伐
-const handleAddBatch = () => {
- dialogType.value = 'add'
- dialogVisible.value = true
-}
-
-// 缂栬緫
-const handleEdit = (row) => {
- currentRow.value = row
- dialogType.value = 'edit'
- dialogVisible.value = true
-}
-
-// 澶勭悊寮圭獥鎻愪氦
-const handleDialogSuccess = async (formData) => {
+// 闅忔満鎺掍骇澶勭悊鍑芥暟
+const handleRandomScheduling = async () => {
try {
- if (dialogType.value === 'add') {
- await addProduction(formData)
- ElMessage.success('鏂板鎴愬姛')
+ const { ElMessage } = await import('element-plus');
+ const res = await randomScheduling();
+ if (res.code === 200) {
+ ElMessage.success('闅忔満鎺掍骇鎴愬姛');
+ getList(); // 鍒锋柊鍒楄〃
} else {
- await updateProduction({
- ...formData,
- id: currentRow.value.id
- })
- ElMessage.success('鏇存柊鎴愬姛')
- }
- getList()
- } catch (error) {
- console.error(dialogType.value === 'add' ? '鏂板澶辫触:' : '鏇存柊澶辫触:', error)
- ElMessage.error(dialogType.value === 'add' ? '鏂板澶辫触' : '鏇存柊澶辫触')
- }
-}
-
-// 鍒犻櫎
-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)
+ ElMessage.error(res.msg || '闅忔満鎺掍骇澶辫触');
}
} catch (error) {
- console.error('瀵煎嚭澶辫触:', error)
- ElMessage.error('瀵煎嚭澶辫触')
+ const { ElMessage } = await import('element-plus');
+ ElMessage.error('璇锋眰澶辫触锛岃绋嶅悗閲嶈瘯');
}
-}
-
-// 澶勭悊姣忛〉鏄剧ず鏁伴噺鍙樺寲
-const handleSizeChange = (val) => {
- pagination.pageSize = val
- getList()
-}
-
-// 澶勭悊椤电爜鍙樺寲
-const handleCurrentChange = (val) => {
- pagination.currentPage = val
- getList()
-}
+};
// 缁勪欢鎸傝浇鏃跺姞杞芥暟鎹�
-onMounted(() => {
- getList()
-})
+onMounted(async () => {
+ try {
+ // 骞惰鍔犺浇鐓ょ鏁版嵁鍜岃〃鏍兼暟鎹�
+ await Promise.all([
+ getCoalData(), // 棰勫姞杞界叅绉嶆暟鎹�
+ (async () => {
+ const res = await getCoalInfoList();
+ if (res.code === 200) {
+ coalInfoList.value = res.data;
+ }
+ })(),
+ ]);
+
+ // 鍔犺浇琛ㄦ牸鏁版嵁
+ getList();
+ } catch (error) {
+ ElMessage.error("鏁版嵁鍔犺浇澶辫触锛岃鍒锋柊椤甸潰閲嶈瘯");
+ }
+});
</script>
-<style scoped>
+<style scoped lang="scss">
.production-container {
padding: 20px;
+
+ .el-card:nth-child(1) {
+ margin-bottom: 20px;
+ }
}
.search-bar {
margin-bottom: 20px;
display: flex;
gap: 10px;
+
+ .el-input {
+ width: 20%;
+ }
}
-.operation-bar {
+.search-form {
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
margin-bottom: 20px;
- display: flex;
- gap: 10px;
+
+ .el-form-item {
+ margin-right: 10px;
+ }
+
+ .el-button {
+ margin-left: 10px;
+ }
}
-.pagination {
- margin-top: 20px;
+.coal-tags {
display: flex;
- justify-content: flex-end;
+ flex-wrap: wrap;
+ gap: 4px;
+ align-items: center;
+
+ .coal-tag {
+ margin-right: 4px;
+ margin-bottom: 4px;
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+
+ .no-data {
+ color: #999;
+ font-style: italic;
+ }
}
-</style>
\ No newline at end of file
+</style>
--
Gitblit v1.9.3