From 2d3530a7c11557a40807ad7c0b9e302ce6ce3a9f Mon Sep 17 00:00:00 2001
From: hsy <1029150275@qq.com>
Date: 星期五, 28 八月 2026 10:16:32 +0800
Subject: [PATCH] feat: 综合业务模块页面重构与交互完善

---
 src/views/inventoryManagement/vehicleFuelManagement/index.vue |  765 +++++++++++++++++++++++-----------------------------------
 1 files changed, 309 insertions(+), 456 deletions(-)

diff --git a/src/views/inventoryManagement/vehicleFuelManagement/index.vue b/src/views/inventoryManagement/vehicleFuelManagement/index.vue
index eaf543c..8ce40c3 100644
--- a/src/views/inventoryManagement/vehicleFuelManagement/index.vue
+++ b/src/views/inventoryManagement/vehicleFuelManagement/index.vue
@@ -1,281 +1,179 @@
 <template>
   <div class="app-container">
+
+
     <!-- 鏌ヨ鏉′欢 -->
-    <div class="search_form">
-      <div>
-        <span class="search_title">杞﹁締缂栧彿锛�</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"
-        />
-
-        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">
-          鎼滅储
-        </el-button>
-        <el-button @click="resetSearch">閲嶇疆</el-button>
+        <div class="search_form">
+      <div style="flex: 1; padding-right: 20px;">
+        <el-row :gutter="16" style="margin-bottom: 16px;">
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鎵�灞為儴闂細</span>
+            <el-tree-select v-model="queryParams.deptId" :data="deptOptions" :props="{ value: 'id', label: 'label', children: 'children' }" value-key="id" placeholder="璇烽�夋嫨閮ㄩ棬" check-strictly clearable filterable style="flex: 1;" />
+          </el-col>
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鍔犳补杞﹁締锛�</span>
+            <el-select v-model="queryParams.vehicleId" placeholder="鎸夎溅杈嗙瓫閫�" clearable filterable style="flex: 1;">
+              <el-option v-for="item in vehicleList" :key="item.id" :label="item.plateNumber" :value="item.id" />
+            </el-select>
+          </el-col>
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鍔犳补鍗★細</span>
+            <el-select v-model="queryParams.fuelCardId" placeholder="璇烽�夋嫨鍔犳补鍗�" clearable style="flex: 1;">
+              <el-option v-for="item in fuelCardList" :key="item.id" :label="item.cardNumber + ' - ' + item.issuer" :value="item.id" />
+            </el-select>
+          </el-col>
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鐘舵�侊細</span>
+            <el-select v-model="queryParams.status" placeholder="鐘舵�佺瓫閫�" clearable style="flex: 1;">
+              <el-option label="鑽夌" value="0" />
+              <el-option label="宸叉彁浜�" value="1" />
+            </el-select>
+          </el-col>
+        </el-row>
+        <el-row :gutter="16">
+          <el-col :span="6" style="display: flex; align-items: center;">
+            <span class="search_title" style="white-space: nowrap;">鍔犳补鏃堕棿锛�</span>
+            <el-date-picker v-model="dateRange" type="daterange" range-separator="鑷�" start-placeholder="寮�濮�" end-placeholder="缁撴潫" value-format="YYYY-MM-DD" clearable style="flex: 1; width: 100%;" />
+          </el-col>
+          <el-col :span="18" style="display: flex; align-items: center;">
+            <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+            <el-button @click="resetQuery">閲嶇疆</el-button>
+          </el-col>
+        </el-row>
       </div>
-      <div>
-        <el-button type="primary" icon="Plus" @click="openAdd">
-          鏂板鍔犳补璁板綍
-        </el-button>
+      <div style="display: flex; align-items: flex-start; height: 100%;">
+        <el-button type="primary" icon="Plus" @click="handleAdd">鏂板鍔犳补璁板綍</el-button>
       </div>
     </div>
-
     <!-- 琛ㄦ牸 -->
     <div class="table_list">
       <el-table
+        v-loading="loading"
         :data="tableData"
         border
         style="width: 100%"
-        height="calc(100vh - 18.5em)"
+        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="vehicleCode"
-          label="杞﹁締缂栧彿"
-          width="130"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          prop="plateNumber"
-          label="杞︾墝鍙风爜"
-          width="120"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          prop="fuelDate"
-          label="鍔犳补鏃ユ湡"
-          width="120"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          prop="gunNo"
-          label="娌规灙鍙�"
-          width="90"
-          align="center"
-        />
-        <el-table-column
-          prop="amount"
-          label="閲戦(鍏�)"
-          width="100"
-          align="right"
-        >
+        <el-table-column prop="fuelDate" label="鍔犳补鏃ユ湡" width="120" />
+        <el-table-column prop="deptName" label="鎵�灞為儴闂�" min-width="150" show-overflow-tooltip />
+        <el-table-column prop="plateNumber" label="鍔犳补杞﹁締(鐗岀収)" width="140" />
+        <el-table-column prop="cardNumber" label="鍔犳补鍗″彿" min-width="150" />
+        <el-table-column prop="amount" label="閲戦(鍏�)" width="100" align="right" />
+        <el-table-column prop="liters" label="鍗囨暟(L)" width="100" align="right" />
+        <el-table-column prop="startMileage" label="璧峰閲岀▼(km)" width="120" align="right" />
+        <el-table-column prop="endMileage" label="缁撴潫閲岀▼(km)" width="120" align="right" />
+        <el-table-column prop="invoiceNo" label="鍙戠エ鍙风爜" width="140" />
+        <el-table-column prop="status" label="鐘舵��" width="100" align="center">
           <template #default="scope">
-            <span>{{ scope.row.amount?.toFixed(2) }}</span>
+            <el-tag v-if="scope.row.status === '0'" type="info">鑽夌</el-tag>
+            <el-tag v-else-if="scope.row.status === '1'" type="success">宸叉彁浜�</el-tag>
+            <el-tag v-else type="info">鑽夌</el-tag>
           </template>
         </el-table-column>
-        <el-table-column
-          prop="liters"
-          label="鍗囨暟(L)"
-          width="90"
-          align="right"
-        >
+        <el-table-column prop="remark" label="澶囨敞" min-width="150" show-overflow-tooltip />
+        <el-table-column label="鎿嶄綔" fixed="right" width="200" align="center">
           <template #default="scope">
-            <span>{{ scope.row.liters?.toFixed(2) }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column
-          prop="startMileage"
-          label="璧峰閲岀▼(km)"
-          width="120"
-          align="right"
-        />
-        <el-table-column
-          prop="endMileage"
-          label="缁撴潫閲岀▼(km)"
-          width="120"
-          align="right"
-        />
-        <el-table-column
-          prop="distance"
-          label="琛岄┒閲岀▼(km)"
-          width="120"
-          align="right"
-        />
-        <el-table-column
-          prop="fuelConsumption"
-          label="娌硅��(L/100km)"
-          width="130"
-          align="center"
-        >
-          <template #default="scope">
-            <span
-              :style="scope.row.isAbnormal ? 'color:#F56C6C;font-weight:600;' : ''"
-            >
-              {{ scope.row.fuelConsumption != null ? scope.row.fuelConsumption.toFixed(2) : '-' }}
-            </span>
-          </template>
-        </el-table-column>
-        <el-table-column
-          prop="avgConsumption"
-          label="杞﹁締骞冲潎娌硅��"
-          width="130"
-          align="center"
-        >
-          <template #default="scope">
-            <span>
-              {{ scope.row.avgConsumption != null ? scope.row.avgConsumption.toFixed(2) : '-' }}
-            </span>
-          </template>
-        </el-table-column>
-        <el-table-column label="寮傚父棰勮" width="100" align="center">
-          <template #default="scope">
-            <el-tag v-if="scope.row.isAbnormal" type="danger" size="small">
-              寮傚父
-            </el-tag>
-            <span v-else>-</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="鎿嶄綔" fixed="right" width="140" 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>
+            <el-button v-if="scope.row.status === '0' || !scope.row.status" type="success" link size="small" @click="handleSubmitRow(scope.row)">鎻愪氦</el-button>
+            <el-button v-if="scope.row.status === '0' || !scope.row.status" type="primary" link size="small" @click="handleUpdate(scope.row)">缂栬緫</el-button>
+            <el-button v-if="scope.row.status === '0' || !scope.row.status" type="danger" link size="small" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+            <el-button v-if="scope.row.status === '1'" type="warning" link size="small" @click="handleRevokeRow(scope.row)">鎾ゅ洖</el-button>
           </template>
         </el-table-column>
       </el-table>
-    </div>
 
-    <!-- 鏂板/缂栬緫寮圭獥 -->
-    <el-dialog
-      v-model="dialogVisible"
-      :title="dialogTitle"
-      width="640px"
-      destroy-on-close
-    >
-      <el-form
-        ref="formRef"
-        :model="form"
-        :rules="rules"
-        label-width="110px"
-        label-position="right"
-      >
+      <!-- 鍒嗛〉 -->
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        v-model:page="queryParams.current"
+        v-model:limit="queryParams.size"
+        @pagination="getList"
+      />
+    </div>
+<!-- 寮圭獥 -->
+    <el-dialog :title="title" v-model="open" width="640px" append-to-body>
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="杞﹁締缂栧彿锛�" prop="vehicleCode">
-              <el-input
-                v-model="form.vehicleCode"
-                placeholder="璇疯緭鍏ヨ溅杈嗙紪鍙�"
-              />
+            <el-form-item label="鍔犳补杞﹁締" prop="vehicleId">
+              <el-select v-model="form.vehicleId" placeholder="璇烽�夋嫨杞﹁締(鐗岀収)" style="width: 100%" filterable>
+                <el-option
+                  v-for="item in vehicleList"
+                  :key="item.id"
+                  :label="item.plateNumber"
+                  :value="item.id"
+                />
+              </el-select>
             </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 label="鍏宠仈鍔犳补鍗�" prop="fuelCardId">
+              <el-select v-model="form.fuelCardId" placeholder="璇烽�夋嫨鍔犳补鍗�" style="width: 100%" filterable>
+                <el-option
+                  v-for="item in availableFuelCardList"
+                  :key="item.id"
+                  :label="item.cardNumber + ' - ' + item.issuer"
+                  :value="item.id"
+                />
+              </el-select>
+              <div v-if="form.fuelCardId" style="font-size: 12px; color: #999; margin-top: 5px;">
+                褰撳墠浣欓: {{ getFuelCardBalance(form.fuelCardId) }} 鍏�
+              </div>
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="鍔犳补鏃ユ湡锛�" prop="fuelDate">
+            <el-form-item label="鍔犳补鏃ユ湡" prop="fuelDate">
               <el-date-picker
                 v-model="form.fuelDate"
                 type="date"
                 value-format="YYYY-MM-DD"
-                format="YYYY-MM-DD"
-                placeholder="璇烽�夋嫨鍔犳补鏃ユ湡"
+                placeholder="璇烽�夋嫨鏃ユ湡"
                 style="width: 100%"
               />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="娌规灙鍙凤細" prop="gunNo">
-              <el-input
-                v-model="form.gunNo"
-                placeholder="璇疯緭鍏ユ补鏋彿"
-              />
+            <el-form-item label="鍙戠エ鍙风爜" prop="invoiceNo">
+              <el-input v-model="form.invoiceNo" placeholder="璇疯緭鍏ュ彂绁ㄥ彿鐮�" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="閲戦(鍏�)锛�" prop="amount">
-              <el-input-number
-                v-model="form.amount"
-                :min="0"
-                :step="0.01"
-                :precision="2"
-                placeholder="璇疯緭鍏ラ噾棰�"
-                style="width: 100%"
-              />
+            <el-form-item label="閲戦(鍏�)" prop="amount">
+              <el-input-number v-model="form.amount" :min="0" :precision="2" :step="100" style="width: 100%" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="鍗囨暟(L)锛�" prop="liters">
-              <el-input-number
-                v-model="form.liters"
-                :min="0"
-                :step="0.01"
-                :precision="2"
-                placeholder="璇疯緭鍏ュ崌鏁�"
-                style="width: 100%"
-              />
+            <el-form-item label="鍗囨暟(L)" prop="liters">
+              <el-input-number v-model="form.liters" :min="0" :precision="2" :step="10" style="width: 100%" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="璧峰閲岀▼(km)锛�" prop="startMileage">
-              <el-input-number
-                v-model="form.startMileage"
-                :min="0"
-                :step="1"
-                placeholder="璇疯緭鍏ヨ捣濮嬮噷绋�"
-                style="width: 100%"
-              />
+            <el-form-item label="璧峰閲岀▼(km)" prop="startMileage">
+              <el-input-number v-model="form.startMileage" :min="0" :precision="2" :step="100" style="width: 100%" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="缁撴潫閲岀▼(km)锛�" prop="endMileage">
-              <el-input-number
-                v-model="form.endMileage"
-                :min="0"
-                :step="1"
-                placeholder="璇疯緭鍏ョ粨鏉熼噷绋�"
-                style="width: 100%"
-              />
+            <el-form-item label="缁撴潫閲岀▼(km)" prop="endMileage">
+              <el-input-number v-model="form.endMileage" :min="0" :precision="2" :step="100" style="width: 100%" />
             </el-form-item>
           </el-col>
         </el-row>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ娉ㄥ唴瀹�" />
+        </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button @click="handleCancel">鍙� 娑�</el-button>
-          <el-button type="primary" @click="handleSubmit">淇� 瀛�</el-button>
+          <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+          <el-button @click="cancel">鍙� 娑�</el-button>
         </div>
       </template>
     </el-dialog>
@@ -283,274 +181,229 @@
 </template>
 
 <script setup>
-import { ref, reactive, onMounted } from "vue";
-import { ElMessage, ElMessageBox } from "element-plus";
+import { ref, reactive, onMounted, computed } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import request from '@/utils/request';
+import { 
+  listFuelRecord, 
+  addFuelRecord, 
+  updateFuelRecord, 
+  delFuelRecord,
+  listVehicleInfo,
+  listAllFuelCard,
+  submitFuelRecord,
+  revokeFuelRecord
+} from '@/api/inventoryManagement/vehicle';
 
-// 妯℃嫙鍔犳补璁板綍鏁版嵁
-const rawRecords = ref([
-  {
-    id: 1,
-    vehicleCode: "CL-202401",
-    plateNumber: "绮12345",
-    fuelDate: "2024-12-01",
-    gunNo: "01",
-    amount: 500,
-    liters: 70,
-    startMileage: 12000,
-    endMileage: 12600,
-  },
-  {
-    id: 2,
-    vehicleCode: "CL-202401",
-    plateNumber: "绮12345",
-    fuelDate: "2024-12-15",
-    gunNo: "02",
-    amount: 520,
-    liters: 72,
-    startMileage: 12600,
-    endMileage: 13250,
-  },
-  {
-    id: 3,
-    vehicleCode: "CL-202402",
-    plateNumber: "绮67890",
-    fuelDate: "2024-12-05",
-    gunNo: "03",
-    amount: 430,
-    liters: 60,
-    startMileage: 8000,
-    endMileage: 8520,
-  },
-  {
-    id: 4,
-    vehicleCode: "CL-202402",
-    plateNumber: "绮67890",
-    fuelDate: "2024-12-20",
-    gunNo: "01",
-    amount: 450,
-    liters: 63,
-    startMileage: 8520,
-    endMileage: 9000,
-  },
-  {
-    id: 5,
-    vehicleCode: "CL-202401",
-    plateNumber: "绮12345",
-    fuelDate: "2025-01-05",
-    gunNo: "01",
-    amount: 700,
-    liters: 90,
-    startMileage: 13250,
-    endMileage: 13600, // 鏄庢樉寮傚父娌硅��
-  },
-]);
+const loading = ref(true);
+const tableData = ref([]);
+const total = ref(0);
+const open = ref(false);
+const title = ref("");
+const formRef = ref(null);
 
-// 鏌ヨ琛ㄥ崟
-const searchForm = reactive({
-  vehicleCode: "",
-  dateRange: [],
+const vehicleList = ref([]);
+const fuelCardList = ref([]);
+const deptOptions = ref([]);
+const dateRange = ref([]);
+
+const availableFuelCardList = computed(() => {
+  return fuelCardList.value.filter(item => item.status !== 'CANCELLED');
 });
 
-// 琛ㄦ牸鏁版嵁锛堝寘鍚绠楀瓧娈碉級
-const tableData = ref([]);
+const queryParams = reactive({
+  current: 1,
+  size: 10,
+  deptId: undefined,
+  vehicleId: undefined,
+  fuelCardId: undefined,
+  beginDate: undefined,
+  endDate: undefined
+});
 
-// 寮圭獥 & 琛ㄥ崟
-const dialogVisible = ref(false);
-const dialogTitle = ref("鏂板鍔犳补璁板綍");
-const isEdit = ref(false);
-const formRef = ref(null);
 const form = reactive({
-  id: null,
-  vehicleCode: "",
-  plateNumber: "",
-  fuelDate: "",
-  gunNo: "",
-  amount: null,
-  liters: null,
-  startMileage: null,
-  endMileage: null,
+  id: undefined,
+  vehicleId: undefined,
+  fuelCardId: undefined,
+  fuelDate: undefined,
+  amount: undefined,
+  liters: undefined,
+  startMileage: undefined,
+  endMileage: undefined,
+  invoiceNo: undefined,
+  remark: undefined
 });
 
 const rules = {
-  vehicleCode: [{ required: true, message: "璇疯緭鍏ヨ溅杈嗙紪鍙�", trigger: "blur" }],
-  plateNumber: [{ required: true, message: "璇疯緭鍏ヨ溅鐗屽彿鐮�", trigger: "blur" }],
-  fuelDate: [{ required: true, message: "璇烽�夋嫨鍔犳补鏃ユ湡", trigger: "change" }],
-  gunNo: [{ required: true, message: "璇疯緭鍏ユ补鏋彿", trigger: "blur" }],
-  amount: [{ required: true, message: "璇疯緭鍏ラ噾棰�", trigger: "blur" }],
-  liters: [{ required: true, message: "璇疯緭鍏ュ崌鏁�", trigger: "blur" }],
-  startMileage: [{ required: true, message: "璇疯緭鍏ヨ捣濮嬮噷绋�", trigger: "blur" }],
-  endMileage: [{ required: true, message: "璇疯緭鍏ョ粨鏉熼噷绋�", trigger: "blur" }],
+  vehicleId: [{ required: true, message: "鍔犳补杞﹁締涓嶈兘涓虹┖", trigger: "change" }],
+  fuelCardId: [{ required: true, message: "鍔犳补鍗′笉鑳戒负绌�", trigger: "change" }],
+  fuelDate: [{ required: true, message: "鍔犳补鏃ユ湡涓嶈兘涓虹┖", trigger: "change" }],
+  amount: [{ required: true, message: "閲戦涓嶈兘涓虹┖", trigger: "blur" }]
 };
 
-// 閲嶆柊璁$畻娌硅�椼�佸钩鍧囨补鑰楀拰寮傚父棰勮
-const recomputeTable = () => {
-  const records = rawRecords.value;
-
-  // 1. 鍏堟寜杞﹁締缁熻骞冲潎娌硅��
-  const stats = {};
-  records.forEach((r) => {
-    const distance = r.endMileage - r.startMileage;
-    if (distance <= 0 || !r.liters) return;
-    const cons = (r.liters / distance) * 100; // L/100km
-    if (!stats[r.vehicleCode]) {
-      stats[r.vehicleCode] = { totalCons: 0, count: 0 };
-    }
-    stats[r.vehicleCode].totalCons += cons;
-    stats[r.vehicleCode].count += 1;
+function getDictData() {
+  request({url: '/system/user/deptTree', method: 'get'}).then(res => {
+    deptOptions.value = res.data || [];
   });
-
-  const avgMap = {};
-  Object.keys(stats).forEach((key) => {
-    avgMap[key] = stats[key].totalCons / stats[key].count;
+  listVehicleInfo({current: 1, size: 1000}).then(res => {
+    vehicleList.value = res.data.records;
   });
+  listAllFuelCard().then(res => {
+    fuelCardList.value = res.data;
+  });
+}
 
-  // 2. 鎸夌瓫閫夋潯浠惰繃婊ゅ苟琛ュ厖璁$畻瀛楁
-  const filtered = records
-    .filter((r) => {
-      if (
-        searchForm.vehicleCode &&
-        !r.vehicleCode.includes(searchForm.vehicleCode.trim())
-      ) {
-        return false;
-      }
-      if (Array.isArray(searchForm.dateRange) && searchForm.dateRange.length === 2) {
-        const [start, end] = searchForm.dateRange;
-        if (r.fuelDate < start || r.fuelDate > end) {
-          return false;
+function getFuelCardBalance(id) {
+  const c = fuelCardList.value.find(item => item.id === id);
+  return c ? c.currentBalance : 0;
+}
+
+
+const statTotalAmount = ref(0);
+const statTotalLiters = ref(0);
+
+function getStats() {
+  const query = { ...queryParams, current: 1, size: 10000 };
+  listFuelRecord(query).then(res => {
+    const arr = res.data.records || [];
+    statTotalAmount.value = arr.reduce((sum, item) => sum + (item.amount || 0), 0);
+    statTotalLiters.value = arr.reduce((sum, item) => sum + (item.liters || 0), 0);
+  });
+}
+
+function getList() {
+  loading.value = true;
+  if (dateRange.value && dateRange.value.length === 2) {
+    queryParams.beginDate = dateRange.value[0];
+    queryParams.endDate = dateRange.value[1];
+  } else {
+    queryParams.beginDate = undefined;
+    queryParams.endDate = undefined;
+  }
+  listFuelRecord(queryParams).then(response => {
+    tableData.value = response.data.records;
+    total.value = response.data.total;
+    loading.value = false;
+    getStats();
+  }).catch(() => {
+    loading.value = false;
+    getStats();
+  });
+}
+
+function handleQuery() {
+  queryParams.current = 1;
+  getList();
+}
+
+function resetQuery() {
+  queryParams.deptId = undefined;
+  queryParams.vehicleId = undefined;
+  queryParams.fuelCardId = undefined;
+  dateRange.value = [];
+  handleQuery();
+}
+
+function reset() {
+  Object.assign(form, {
+    id: undefined,
+    vehicleId: undefined,
+    fuelCardId: undefined,
+    fuelDate: undefined,
+    amount: undefined,
+    liters: undefined,
+    startMileage: undefined,
+    endMileage: undefined,
+    invoiceNo: undefined,
+    remark: undefined
+  });
+  if (formRef.value) formRef.value.resetFields();
+}
+
+function handleAdd() {
+  reset();
+  open.value = true;
+  title.value = "鏂板鍔犳补璁板綍";
+}
+
+function handleUpdate(row) {
+  reset();
+  Object.assign(form, row);
+  open.value = true;
+  title.value = "淇敼鍔犳补璁板綍";
+}
+
+function submitForm() {
+  formRef.value.validate(valid => {
+    if (valid) {
+      if (!form.id) {
+        const bal = getFuelCardBalance(form.fuelCardId);
+        if (bal < form.amount) {
+          ElMessage.warning("璇ュ姞娌瑰崱浣欓涓嶈冻锛佸綋鍓嶄綑棰�: " + bal);
         }
       }
-      return true;
-    })
-    .map((r) => {
-      const distance = r.endMileage - r.startMileage;
-      const fuelConsumption =
-        distance > 0 && r.liters
-          ? (r.liters / distance) * 100
-          : null;
-      const avgConsumption =
-        avgMap[r.vehicleCode] != null ? avgMap[r.vehicleCode] : null;
-      const isAbnormal =
-        avgConsumption != null &&
-        fuelConsumption != null &&
-        fuelConsumption > avgConsumption * 1.2;
-
-      return {
-        ...r,
-        distance,
-        fuelConsumption,
-        avgConsumption,
-        isAbnormal,
-      };
-    });
-
-  tableData.value = filtered;
-};
-
-// 鏌ヨ
-const handleQuery = () => {
-  recomputeTable();
-};
-
-const resetSearch = () => {
-  searchForm.vehicleCode = "";
-  searchForm.dateRange = [];
-  recomputeTable();
-};
-
-// 琛屾牱寮忥紙寮傚父楂樹寒锛�
-const tableRowClassName = ({ row }) => {
-  if (row.isAbnormal) {
-    return "row-abnormal";
-  }
-  return "";
-};
-
-// 鏂板
-const openAdd = () => {
-  dialogTitle.value = "鏂板鍔犳补璁板綍";
-  isEdit.value = false;
-  Object.assign(form, {
-    id: null,
-    vehicleCode: "",
-    plateNumber: "",
-    fuelDate: "",
-    gunNo: "",
-    amount: null,
-    liters: null,
-    startMileage: null,
-    endMileage: null,
-  });
-  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 (form.endMileage <= form.startMileage) {
-      ElMessage.warning("缁撴潫閲岀▼蹇呴』澶т簬璧峰閲岀▼");
-      return;
-    }
-
-    if (isEdit.value) {
-      const index = rawRecords.value.findIndex((r) => r.id === form.id);
-      if (index !== -1) {
-        rawRecords.value[index] = { ...form };
+      
+      if (form.id != null) {
+        updateFuelRecord(form).then(response => {
+          ElMessage.success("淇敼鎴愬姛");
+          open.value = false;
+          getList();
+          getDictData();
+        });
+      } else {
+        addFuelRecord(form).then(response => {
+          ElMessage.success("鏂板鎴愬姛");
+          open.value = false;
+          getList();
+          getDictData();
+        });
       }
-      ElMessage.success("鍔犳补璁板綍宸叉洿鏂�");
-    } else {
-      const newId = rawRecords.value.length
-        ? Math.max(...rawRecords.value.map((r) => r.id)) + 1
-        : 1;
-      rawRecords.value.push({ ...form, id: newId });
-      ElMessage.success("鍔犳补璁板綍宸叉柊澧�");
     }
-    dialogVisible.value = false;
-    recomputeTable();
   });
-};
+}
 
-const handleCancel = () => {
-  dialogVisible.value = false;
-};
-
-// 鍒犻櫎
-const removeRow = (row) => {
-  ElMessageBox.confirm("鏄惁纭鍒犻櫎璇ュ姞娌硅褰曪紵", "鍒犻櫎鎻愮ず", {
-    confirmButtonText: "纭",
+function handleDelete(row) {
+  ElMessageBox.confirm('鏄惁纭鍒犻櫎璇ヨ崏绋胯褰曪紵', "璀﹀憡", {
+    confirmButtonText: "纭畾",
     cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
-    .then(() => {
-      rawRecords.value = rawRecords.value.filter((r) => r.id !== row.id);
-      recomputeTable();
-      ElMessage.success("鍒犻櫎鎴愬姛");
-    })
-    .catch(() => {});
-};
+    type: "warning"
+  }).then(function() {
+    return delFuelRecord(row.id);
+  }).then(() => {
+    getList();
+    getDictData();
+    ElMessage.success("鍒犻櫎鎴愬姛");
+  });
+}
+
+function cancel() {
+  open.value = false;
+  reset();
+}
 
 onMounted(() => {
-  recomputeTable();
+  getDictData();
+  getList();
 });
-</script>
 
-<style scoped lang="scss">
-.dialog-footer {
-  text-align: right;
+function handleSubmitRow(row) {
+  ElMessageBox.confirm('纭鎻愪氦璇ョ瑪鍔犳补璁板綍鍚楋紵鎻愪氦鍚庡皢浠庡姞娌瑰崱涓墸闄や綑棰�', '鎻愮ず', { type: 'warning' }).then(() => {
+    return submitFuelRecord(row.id);
+  }).then(() => {
+    ElMessage.success('鎻愪氦鎴愬姛');
+    getList();
+    getStats();
+  }).catch(() => {});
 }
 
-:deep(.row-abnormal) {
-  background-color: #fff5f5;
+function handleRevokeRow(row) {
+  ElMessageBox.confirm('纭鎾ゅ洖璇ョ瑪鍔犳补璁板綍鍚楋紵鎾ゅ洖鍚庡皢閫�杩樺姞娌瑰崱浣欓', '鎻愮ず', { type: 'warning' }).then(() => {
+    return revokeFuelRecord(row.id);
+  }).then(() => {
+    ElMessage.success('鎾ゅ洖鎴愬姛');
+    getList();
+    getStats();
+  }).catch(() => {});
 }
-</style>
 
+</script>
\ No newline at end of file

--
Gitblit v1.9.3