From 67c560c0cad4224c41b36b2ec755bf3d5aa7e68f Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 06 二月 2026 10:51:51 +0800
Subject: [PATCH] Merge branch 'dev_New' into dev_湖南鹏创电子

---
 src/views/inventoryManagement/transportTaskManagement/index.vue |  692 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 692 insertions(+), 0 deletions(-)

diff --git a/src/views/inventoryManagement/transportTaskManagement/index.vue b/src/views/inventoryManagement/transportTaskManagement/index.vue
new file mode 100644
index 0000000..1feb54b
--- /dev/null
+++ b/src/views/inventoryManagement/transportTaskManagement/index.vue
@@ -0,0 +1,692 @@
+<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)"
+            >
+              鍒犻櫎
+            </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: "绮12345",
+    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: "绮67890",
+    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: "绮12345",
+    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: "绮11223",
+    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;
+}
+
+::v-deep(.row-finished) {
+  background-color: #f6ffed;
+}
+
+::v-deep(.row-running) {
+  background-color: #fffbe6;
+}
+</style>
+

--
Gitblit v1.9.3