| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <!-- ç»è®¡æ¦è§ --> |
| | | <el-row :gutter="16" style="margin-bottom: 16px"> |
| | | <el-col :span="6"> |
| | | <el-card shadow="never"> |
| | | <div>æ»ä»»å¡æ°</div> |
| | | <div style="font-size: 22px; font-weight: 600; margin-top: 4px"> |
| | | {{ totalTasks }} |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-card shadow="never"> |
| | | <div>è¿è¡ä¸ä»»å¡</div> |
| | | <div style="font-size: 22px; font-weight: 600; margin-top: 4px"> |
| | | {{ runningTasks }} |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-card shadow="never"> |
| | | <div>已宿任å¡</div> |
| | | <div style="font-size: 22px; font-weight: 600; margin-top: 4px"> |
| | | {{ finishedTasks }} |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-card shadow="never"> |
| | | <div>宿ç</div> |
| | | <div style="font-size: 22px; font-weight: 600; margin-top: 4px"> |
| | | {{ completionRate }}% |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- æ¥è¯¢æ¡ä»¶ --> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">ä»»å¡ç¼å·ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.taskNo" |
| | | style="width: 200px" |
| | | placeholder="请è¾å
¥ä»»å¡ç¼å·" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | |
| | | <span class="search_title ml10">车è¾ç¼å·ï¼</span> |
| | | <el-input |
| | | v-model="searchForm.vehicleCode" |
| | | style="width: 200px" |
| | | placeholder="请è¾å
¥è½¦è¾ç¼å·" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | |
| | | <span class="search_title ml10">任塿¥æï¼</span> |
| | | <el-date-picker |
| | | v-model="searchForm.dateRange" |
| | | type="daterange" |
| | | range-separator="è³" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | clearable |
| | | @change="handleQuery" |
| | | /> |
| | | |
| | | <span class="search_title ml10">ç¶æï¼</span> |
| | | <el-select |
| | | v-model="searchForm.status" |
| | | style="width: 140px" |
| | | placeholder="è¯·éæ©ä»»å¡ç¶æ" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in statusOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | |
| | | <el-button type="primary" @click="handleQuery" style="margin-left: 10px"> |
| | | æç´¢ |
| | | </el-button> |
| | | <el-button @click="resetSearch">éç½®</el-button> |
| | | </div> |
| | | <div> |
| | | <el-button type="primary" icon="Plus" @click="openAdd"> |
| | | æ°å»ºè¿è¾ä»»å¡ |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- è¡¨æ ¼ --> |
| | | <div class="table_list"> |
| | | <el-table |
| | | :data="tableData" |
| | | border |
| | | style="width: 100%" |
| | | height="calc(100vh - 22em)" |
| | | :header-cell-style="{ background: '#F0F1F5', color: '#333333' }" |
| | | :row-class-name="tableRowClassName" |
| | | > |
| | | <el-table-column type="index" label="åºå·" width="60" align="center" /> |
| | | <el-table-column |
| | | prop="taskNo" |
| | | label="ä»»å¡ç¼å·" |
| | | width="150" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | prop="outboundOrderNo" |
| | | label="åºåºè®¢åå·" |
| | | width="180" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | prop="vehicleCode" |
| | | label="车è¾ç¼å·" |
| | | width="130" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | prop="plateNumber" |
| | | label="车çå·ç " |
| | | width="120" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | prop="driverName" |
| | | label="叿º" |
| | | width="100" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | prop="loadAddress" |
| | | label="è£
è´§å°ç¹" |
| | | width="160" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | prop="deliveryAddress" |
| | | label="éè´§å°ç¹" |
| | | width="160" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | prop="loadTime" |
| | | label="è£
è´§æ¶é´" |
| | | width="160" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | prop="deliveryTime" |
| | | label="éè´§æ¶é´" |
| | | width="160" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | prop="signTime" |
| | | label="ç¾æ¶æ¶é´" |
| | | width="160" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column label="ç¶æ" width="110" align="center"> |
| | | <template #default="scope"> |
| | | <el-tag :type="statusTagType(scope.row.status)"> |
| | | {{ scope.row.status }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="è¿åº¦" width="150" align="center"> |
| | | <template #default="scope"> |
| | | <el-progress |
| | | :percentage="scope.row.progress" |
| | | :status="scope.row.status === '已宿' ? 'success' : undefined" |
| | | :stroke-width="12" |
| | | :show-text="false" |
| | | /> |
| | | <div style="font-size: 12px; margin-top: 4px"> |
| | | {{ scope.row.progress }}% |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" fixed="right" width="160" align="center"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | type="primary" |
| | | link |
| | | size="small" |
| | | @click="openEdit(scope.row)" |
| | | > |
| | | ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | type="danger" |
| | | link |
| | | size="small" |
| | | @click="removeRow(scope.row)" |
| | | v-hasPermi="['inventoryManagement:transportTaskManagement:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | |
| | | <!-- æ°å¢/ç¼è¾å¼¹çª --> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | :title="dialogTitle" |
| | | width="780px" |
| | | destroy-on-close |
| | | > |
| | | <el-form |
| | | ref="formRef" |
| | | :model="form" |
| | | :rules="rules" |
| | | label-width="110px" |
| | | label-position="right" |
| | | > |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä»»å¡ç¼å·ï¼" prop="taskNo"> |
| | | <el-input |
| | | v-model="form.taskNo" |
| | | placeholder="请è¾å
¥ä»»å¡ç¼å·" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåºè®¢åå·ï¼" prop="outboundOrderNo"> |
| | | <el-input |
| | | v-model="form.outboundOrderNo" |
| | | placeholder="请è¾å
¥å
³èåºåºè®¢åå·" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="车è¾ç¼å·ï¼" prop="vehicleCode"> |
| | | <el-input |
| | | v-model="form.vehicleCode" |
| | | placeholder="请è¾å
¥è½¦è¾ç¼å·" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="车çå·ç ï¼" prop="plateNumber"> |
| | | <el-input |
| | | v-model="form.plateNumber" |
| | | placeholder="请è¾å
¥è½¦çå·ç " |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="叿ºï¼" prop="driverName"> |
| | | <el-input |
| | | v-model="form.driverName" |
| | | placeholder="请è¾å
¥å¸æºå§å" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="叿ºçµè¯ï¼" prop="driverPhone"> |
| | | <el-input |
| | | v-model="form.driverPhone" |
| | | placeholder="请è¾å
¥å¸æºèç³»çµè¯" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è£
è´§å°ç¹ï¼" prop="loadAddress"> |
| | | <el-input |
| | | v-model="form.loadAddress" |
| | | placeholder="请è¾å
¥è£
è´§å°ç¹" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éè´§å°ç¹ï¼" prop="deliveryAddress"> |
| | | <el-input |
| | | v-model="form.deliveryAddress" |
| | | placeholder="请è¾å
¥éè´§å°ç¹" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="è£
è´§æ¶é´ï¼" prop="loadTime"> |
| | | <el-date-picker |
| | | v-model="form.loadTime" |
| | | type="datetime" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | format="YYYY-MM-DD HH:mm" |
| | | placeholder="è¯·éæ©è£
è´§æ¶é´" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="éè´§æ¶é´ï¼" prop="deliveryTime"> |
| | | <el-date-picker |
| | | v-model="form.deliveryTime" |
| | | type="datetime" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | format="YYYY-MM-DD HH:mm" |
| | | placeholder="è¯·éæ©éè´§æ¶é´" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="ç¾æ¶æ¶é´ï¼" prop="signTime"> |
| | | <el-date-picker |
| | | v-model="form.signTime" |
| | | type="datetime" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | format="YYYY-MM-DD HH:mm" |
| | | placeholder="è¯·éæ©ç¾æ¶æ¶é´" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¶æï¼" prop="status"> |
| | | <el-select v-model="form.status" placeholder="è¯·éæ©ä»»å¡ç¶æ"> |
| | | <el-option |
| | | v-for="item in statusOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è®¡åæ¥æï¼" prop="planDate"> |
| | | <el-date-picker |
| | | v-model="form.planDate" |
| | | type="date" |
| | | value-format="YYYY-MM-DD" |
| | | format="YYYY-MM-DD" |
| | | placeholder="è¯·éæ©è®¡åæ¥æ" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="handleCancel">å æ¶</el-button> |
| | | <el-button type="primary" @click="handleSubmit">ä¿ å</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, computed, onMounted } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | |
| | | // 模æè¿è¾ä»»å¡æ°æ® |
| | | const rawTasks = ref([ |
| | | { |
| | | id: 1, |
| | | taskNo: "T2024-1201-001", |
| | | outboundOrderNo: "OUT-2024-1201-1001", |
| | | vehicleCode: "CL-202401", |
| | | plateNumber: "粤A12345", |
| | | driverName: "å¼ å¸å
", |
| | | driverPhone: "13800000001", |
| | | loadAddress: "æ·±å³ä»åºAåº", |
| | | deliveryAddress: "广å·å®¢æ·ä¸é¨", |
| | | planDate: "2024-12-01", |
| | | loadTime: "2024-12-01 09:00:00", |
| | | deliveryTime: "2024-12-01 14:30:00", |
| | | signTime: "2024-12-01 15:00:00", |
| | | status: "已宿", |
| | | }, |
| | | { |
| | | id: 2, |
| | | taskNo: "T2024-1201-002", |
| | | outboundOrderNo: "OUT-2024-1201-1002", |
| | | vehicleCode: "CL-202402", |
| | | plateNumber: "粤B67890", |
| | | driverName: "æå¸å
", |
| | | driverPhone: "13800000002", |
| | | loadAddress: "æ·±å³ä»åºBåº", |
| | | deliveryAddress: "ä¸è客æ·äºé¨", |
| | | planDate: "2024-12-01", |
| | | loadTime: "2024-12-01 10:00:00", |
| | | deliveryTime: "2024-12-01 13:00:00", |
| | | signTime: "", |
| | | status: "è¿è¾ä¸", |
| | | }, |
| | | { |
| | | id: 3, |
| | | taskNo: "T2024-1202-001", |
| | | outboundOrderNo: "OUT-2024-1202-1003", |
| | | vehicleCode: "CL-202401", |
| | | plateNumber: "粤A12345", |
| | | driverName: "å¼ å¸å
", |
| | | driverPhone: "13800000001", |
| | | loadAddress: "æ·±å³ä»åºAåº", |
| | | deliveryAddress: "ä½å±±å®¢æ·ä¸é¨", |
| | | planDate: "2024-12-02", |
| | | loadTime: "2024-12-02 08:30:00", |
| | | deliveryTime: "", |
| | | signTime: "", |
| | | status: "å¾
å车", |
| | | }, |
| | | { |
| | | id: 4, |
| | | taskNo: "T2024-1203-001", |
| | | outboundOrderNo: "OUT-2024-1203-1004", |
| | | vehicleCode: "CL-202403", |
| | | plateNumber: "粤C11223", |
| | | driverName: "çå¸å
", |
| | | driverPhone: "13800000003", |
| | | loadAddress: "æ·±å³ä»åºCåº", |
| | | deliveryAddress: "æ å·å®¢æ·åé¨", |
| | | planDate: "2024-12-03", |
| | | loadTime: "", |
| | | deliveryTime: "", |
| | | signTime: "", |
| | | status: "æªå¼å§", |
| | | }, |
| | | ]); |
| | | |
| | | // ç¶ææä¸¾ |
| | | const statusOptions = [ |
| | | { label: "æªå¼å§", value: "æªå¼å§" }, |
| | | { label: "å¾
å车", value: "å¾
å车" }, |
| | | { label: "è¿è¾ä¸", value: "è¿è¾ä¸" }, |
| | | { label: "å¾
ç¾æ¶", value: "å¾
ç¾æ¶" }, |
| | | { label: "已宿", value: "已宿" }, |
| | | ]; |
| | | |
| | | // æ¥è¯¢è¡¨å |
| | | const searchForm = reactive({ |
| | | taskNo: "", |
| | | vehicleCode: "", |
| | | dateRange: [], |
| | | status: "", |
| | | }); |
| | | |
| | | // è¡¨æ ¼æ°æ®ï¼å¸¦è¿åº¦ç计ç®åæ®µï¼ |
| | | const tableData = ref([]); |
| | | |
| | | // ç»è®¡ |
| | | const totalTasks = computed(() => rawTasks.value.length); |
| | | const finishedTasks = computed( |
| | | () => rawTasks.value.filter((t) => t.status === "已宿").length |
| | | ); |
| | | const runningTasks = computed( |
| | | () => |
| | | rawTasks.value.filter((t) => |
| | | ["å¾
å车", "è¿è¾ä¸", "å¾
ç¾æ¶"].includes(t.status) |
| | | ).length |
| | | ); |
| | | const completionRate = computed(() => { |
| | | if (!totalTasks.value) return 0; |
| | | return Math.round((finishedTasks.value / totalTasks.value) * 100); |
| | | }); |
| | | |
| | | // 计ç®åæ¡ä»»å¡è¿åº¦ |
| | | const computeProgress = (task) => { |
| | | if (task.status === "已宿" || task.signTime) return 100; |
| | | if (task.status === "å¾
ç¾æ¶" || task.deliveryTime) return 80; |
| | | if (task.status === "è¿è¾ä¸") return 60; |
| | | if (task.status === "å¾
å车" || task.loadTime) return 30; |
| | | if (task.status === "æªå¼å§") return 0; |
| | | return 0; |
| | | }; |
| | | |
| | | // ç¶æ tag æ ·å¼ |
| | | const statusTagType = (status) => { |
| | | if (status === "已宿") return "success"; |
| | | if (status === "è¿è¾ä¸") return "warning"; |
| | | if (status === "å¾
ç¾æ¶" || status === "å¾
å车") return "info"; |
| | | return "default"; |
| | | }; |
| | | |
| | | // éç®è¡¨æ ¼æ°æ® |
| | | const recomputeTable = () => { |
| | | const filtered = rawTasks.value |
| | | .filter((t) => { |
| | | if (searchForm.taskNo && !t.taskNo.includes(searchForm.taskNo.trim())) { |
| | | return false; |
| | | } |
| | | if ( |
| | | searchForm.vehicleCode && |
| | | !t.vehicleCode.includes(searchForm.vehicleCode.trim()) |
| | | ) { |
| | | return false; |
| | | } |
| | | if (searchForm.status && t.status !== searchForm.status) { |
| | | return false; |
| | | } |
| | | if (Array.isArray(searchForm.dateRange) && searchForm.dateRange.length === 2) { |
| | | const [start, end] = searchForm.dateRange; |
| | | if (!t.planDate || t.planDate < start || t.planDate > end) { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | }) |
| | | .map((t) => ({ |
| | | ...t, |
| | | progress: computeProgress(t), |
| | | })); |
| | | |
| | | tableData.value = filtered; |
| | | }; |
| | | |
| | | // æ¥è¯¢ |
| | | const handleQuery = () => { |
| | | recomputeTable(); |
| | | }; |
| | | |
| | | const resetSearch = () => { |
| | | searchForm.taskNo = ""; |
| | | searchForm.vehicleCode = ""; |
| | | searchForm.dateRange = []; |
| | | searchForm.status = ""; |
| | | recomputeTable(); |
| | | }; |
| | | |
| | | // è¡æ ·å¼ |
| | | const tableRowClassName = ({ row }) => { |
| | | if (row.status === "已宿") { |
| | | return "row-finished"; |
| | | } |
| | | if (row.status === "è¿è¾ä¸") { |
| | | return "row-running"; |
| | | } |
| | | return ""; |
| | | }; |
| | | |
| | | // å¼¹çª & 表å |
| | | const dialogVisible = ref(false); |
| | | const dialogTitle = ref("æ°å»ºè¿è¾ä»»å¡"); |
| | | const isEdit = ref(false); |
| | | const formRef = ref(null); |
| | | const form = reactive({ |
| | | id: null, |
| | | taskNo: "", |
| | | outboundOrderNo: "", |
| | | vehicleCode: "", |
| | | plateNumber: "", |
| | | driverName: "", |
| | | driverPhone: "", |
| | | loadAddress: "", |
| | | deliveryAddress: "", |
| | | planDate: "", |
| | | loadTime: "", |
| | | deliveryTime: "", |
| | | signTime: "", |
| | | status: "æªå¼å§", |
| | | }); |
| | | |
| | | const rules = { |
| | | taskNo: [{ required: true, message: "请è¾å
¥ä»»å¡ç¼å·", trigger: "blur" }], |
| | | outboundOrderNo: [ |
| | | { required: true, message: "请è¾å
¥åºåºè®¢åå·", trigger: "blur" }, |
| | | ], |
| | | vehicleCode: [{ required: true, message: "请è¾å
¥è½¦è¾ç¼å·", trigger: "blur" }], |
| | | plateNumber: [{ required: true, message: "请è¾å
¥è½¦çå·ç ", trigger: "blur" }], |
| | | driverName: [{ required: true, message: "请è¾å
¥å¸æºå§å", trigger: "blur" }], |
| | | loadAddress: [{ required: true, message: "请è¾å
¥è£
è´§å°ç¹", trigger: "blur" }], |
| | | deliveryAddress: [ |
| | | { required: true, message: "请è¾å
¥éè´§å°ç¹", trigger: "blur" }, |
| | | ], |
| | | planDate: [{ required: true, message: "è¯·éæ©è®¡åæ¥æ", trigger: "change" }], |
| | | }; |
| | | |
| | | // æ°å»º |
| | | const openAdd = () => { |
| | | dialogTitle.value = "æ°å»ºè¿è¾ä»»å¡"; |
| | | isEdit.value = false; |
| | | Object.assign(form, { |
| | | id: null, |
| | | taskNo: "", |
| | | outboundOrderNo: "", |
| | | vehicleCode: "", |
| | | plateNumber: "", |
| | | driverName: "", |
| | | driverPhone: "", |
| | | loadAddress: "", |
| | | deliveryAddress: "", |
| | | planDate: "", |
| | | loadTime: "", |
| | | deliveryTime: "", |
| | | signTime: "", |
| | | status: "æªå¼å§", |
| | | }); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // ç¼è¾ |
| | | const openEdit = (row) => { |
| | | dialogTitle.value = "ç¼è¾è¿è¾ä»»å¡"; |
| | | isEdit.value = true; |
| | | Object.assign(form, row); |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // ä¿å |
| | | const handleSubmit = () => { |
| | | if (!formRef.value) return; |
| | | formRef.value.validate((valid) => { |
| | | if (!valid) return; |
| | | |
| | | if (isEdit.value) { |
| | | const index = rawTasks.value.findIndex((t) => t.id === form.id); |
| | | if (index !== -1) { |
| | | rawTasks.value[index] = { ...form }; |
| | | } |
| | | ElMessage.success("è¿è¾ä»»å¡å·²æ´æ°"); |
| | | } else { |
| | | const newId = rawTasks.value.length |
| | | ? Math.max(...rawTasks.value.map((t) => t.id)) + 1 |
| | | : 1; |
| | | rawTasks.value.push({ ...form, id: newId }); |
| | | ElMessage.success("è¿è¾ä»»å¡å·²æ°å¢"); |
| | | } |
| | | dialogVisible.value = false; |
| | | recomputeTable(); |
| | | }); |
| | | }; |
| | | |
| | | const handleCancel = () => { |
| | | dialogVisible.value = false; |
| | | }; |
| | | |
| | | // å é¤ |
| | | const removeRow = (row) => { |
| | | ElMessageBox.confirm("æ¯å¦ç¡®è®¤å é¤è¯¥è¿è¾ä»»å¡ï¼", "å é¤æç¤º", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | rawTasks.value = rawTasks.value.filter((t) => t.id !== row.id); |
| | | recomputeTable(); |
| | | ElMessage.success("å 餿å"); |
| | | }) |
| | | .catch(() => {}); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | recomputeTable(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .dialog-footer { |
| | | text-align: right; |
| | | } |
| | | |
| | | :deep(.row-finished) { |
| | | background-color: #f6ffed; |
| | | } |
| | | |
| | | :deep(.row-running) { |
| | | background-color: #fffbe6; |
| | | } |
| | | </style> |
| | | |