wlzboy
5 天以前 cfe0b79fbea0fb1d7a5a796e71ada7d3b7812046
ruoyi-ui/src/views/system/mileageStats/index.vue
@@ -131,9 +131,7 @@
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="GPS点数" align="center" prop="gpsPointCount" width="90" />
      <el-table-column label="任务数" align="center" prop="taskCount" width="80" />
      <el-table-column label="分段数" align="center" prop="segmentCount" width="80" />
      <el-table-column label="统计时间" align="center" prop="createTime" width="160">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.createTime) }}</span>
@@ -170,8 +168,30 @@
    <!-- 手动统计对话框 -->
    <el-dialog title="手动里程统计" :visible.sync="calculateOpen" width="500px" append-to-body>
      <el-form ref="calculateForm" :model="calculateForm" :rules="calculateRules" label-width="100px">
        <el-form-item label="车辆ID" prop="vehicleId">
          <el-input v-model="calculateForm.vehicleId" placeholder="请输入车辆ID" type="number" />
        <el-form-item label="车牌号" prop="vehicleId">
          <el-select
            v-model="calculateForm.vehicleId"
            placeholder="请输入车牌号搜索"
            filterable
            remote
            :remote-method="searchVehicles"
            :loading="vehicleSearchLoading"
            clearable
            style="width: 100%"
            @change="handleVehicleChange"
          >
            <el-option
              v-for="vehicle in vehicleOptions"
              :key="vehicle.vehicleId"
              :label="vehicle.vehicleNo"
              :value="vehicle.vehicleId"
            >
              <span style="float: left">{{ vehicle.vehicleNo }}</span>
              <span style="float: right; color: #8492a6; font-size: 13px" v-if="vehicle.deptName">
                {{ vehicle.deptName }}
              </span>
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="统计日期" prop="statDate">
          <el-date-picker
@@ -216,7 +236,7 @@
    </el-dialog>
    <!-- 详情对话框 -->
    <el-dialog title="里程统计详情" :visible.sync="detailOpen" width="600px" append-to-body>
    <el-dialog title="里程统计详情" :visible.sync="detailOpen" width="900px" append-to-body>
      <el-descriptions :column="2" border>
        <el-descriptions-item label="车牌号">{{ detailData.vehicleNo }}</el-descriptions-item>
        <el-descriptions-item label="归属分公司">{{ detailData.deptName || '-' }}</el-descriptions-item>
@@ -237,18 +257,58 @@
            {{ formatRatio(detailData.taskRatio) }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="GPS点数">{{ detailData.gpsPointCount }}</el-descriptions-item>
        <el-descriptions-item label="任务数">{{ detailData.taskCount }}</el-descriptions-item>
        <el-descriptions-item label="分段数">{{ detailData.segmentCount }}</el-descriptions-item>
        <el-descriptions-item label="数据来源">
          <el-tag :type="detailData.dataSource === 'segment' ? 'success' : 'info'" size="small">
            {{ detailData.dataSource === 'segment' ? '从分段汇总' : '直接计算' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="统计时间" :span="2">
          {{ parseTime(detailData.createTime) }}
        </el-descriptions-item>
      </el-descriptions>
      <!-- 分段明细表格 -->
      <div v-if="segmentList.length > 0" style="margin-top: 20px;">
        <el-divider content-position="left">
          <i class="el-icon-tickets"></i> 里程分段明细
        </el-divider>
        <el-table
          :data="segmentList"
          size="small"
          :max-height="400"
          stripe
          border
          v-loading="segmentLoading"
        >
          <el-table-column type="index" label="序号" width="50" align="center" />
          <el-table-column label="开始时间" prop="segmentStartTime" width="160" align="center">
            <template slot-scope="scope">
              {{ parseTime(scope.row.segmentStartTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
            </template>
          </el-table-column>
          <el-table-column label="结束时间" prop="segmentEndTime" width="160" align="center">
            <template slot-scope="scope">
              {{ parseTime(scope.row.segmentEndTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
            </template>
          </el-table-column>
          <el-table-column label="里程(km)" prop="segmentDistance" width="100" align="center">
            <template slot-scope="scope">
              <span class="mileage-value">{{ (scope.row.segmentDistance || 0).toFixed(2) }}</span>
            </template>
          </el-table-column>
          <el-table-column label="关联任务" prop="taskCode" align="center" min-width="120">
            <template slot-scope="scope">
              <el-tag v-if="scope.row.taskCode" size="small" type="success">{{ scope.row.taskCode }}</el-tag>
              <span v-else style="color: #909399;">无任务</span>
            </template>
          </el-table-column>
          <el-table-column label="计算方式" prop="calculateMethod" align="center" width="100">
            <template slot-scope="scope">
              <el-tag size="small" :type="scope.row.calculateMethod === 'haversine' ? 'primary' : 'info'">
                {{ scope.row.calculateMethod === 'haversine' ? '球面距离' : '直线距离' }}
              </el-tag>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="detailOpen = false">关 闭</el-button>
      </div>
@@ -257,8 +317,9 @@
</template>
<script>
import { listMileageStats, getMileageStats, delMileageStats, calculateMileageStats, batchCalculateMileageStats } from "@/api/system/mileageStats";
import { listMileageStats, getMileageStats, delMileageStats, calculateMileageStats, batchCalculateMileageStats, getSegmentsByDateRange } from "@/api/system/mileageStats";
import { listDept } from "@/api/system/dept";
import { listVehicle } from "@/api/system/vehicle";
export default {
  name: "MileageStats",
@@ -292,10 +353,18 @@
      detailOpen: false,
      // 详情数据
      detailData: {},
      // 分段明细列表
      segmentList: [],
      // 分段明细加载状态
      segmentLoading: false,
      // 手动统计加载状态
      calculateLoading: false,
      // 批量统计加载状态
      batchCalculateLoading: false,
      // 车辆搜索加载状态
      vehicleSearchLoading: false,
      // 车辆选项列表
      vehicleOptions: [],
      // 查询参数
      queryParams: {
        pageNum: 1,
@@ -317,7 +386,7 @@
      // 手动统计表单校验
      calculateRules: {
        vehicleId: [
          { required: true, message: "车辆ID不能为空", trigger: "blur" }
          { required: true, message: "请选择车辆", trigger: "change" }
        ],
        statDate: [
          { required: true, message: "统计日期不能为空", trigger: "change" }
@@ -371,7 +440,43 @@
    /** 手动统计按钮操作 */
    handleCalculate() {
      this.reset();
      this.vehicleOptions = [];
      this.calculateOpen = true;
      // 打开对话框时加载一些车辆数据
      this.searchVehicles('');
    },
    /** 搜索车辆 */
    searchVehicles(query) {
      if (query !== '') {
        this.vehicleSearchLoading = true;
        listVehicle({
          vehicleNo: query,
          pageNum: 1,
          pageSize: 50
        }).then(response => {
          this.vehicleOptions = response.rows || [];
          this.vehicleSearchLoading = false;
        }).catch(() => {
          this.vehicleSearchLoading = false;
        });
      } else {
        // 如果查询为空,加载前50条车辆数据
        this.vehicleSearchLoading = true;
        listVehicle({
          pageNum: 1,
          pageSize: 50
        }).then(response => {
          this.vehicleOptions = response.rows || [];
          this.vehicleSearchLoading = false;
        }).catch(() => {
          this.vehicleSearchLoading = false;
        });
      }
    },
    /** 车辆选择变化 */
    handleVehicleChange(value) {
      // 可以在这里添加额外的处理逻辑
      console.log('选择的车辆ID:', value);
    },
    /** 批量统计按钮操作 */
    handleBatchCalculate() {
@@ -417,9 +522,44 @@
    /** 查看详情按钮操作 */
    handleView(row) {
      const statsId = row.statsId;
      // 重置分段明细
      this.segmentList = [];
      // 加载统计详情
      getMileageStats(statsId).then(response => {
        this.detailData = response.data;
        this.detailOpen = true;
        // 如果有车辆ID和统计日期,加载分段明细
        if (this.detailData.vehicleId && this.detailData.statDate) {
          this.loadSegmentDetails(this.detailData.vehicleId, this.detailData.statDate);
        }
      });
    },
    /** 加载分段明细 */
    loadSegmentDetails(vehicleId, statDate) {
      this.segmentLoading = true;
      // 格式化日期:统计日期的开始和结束时间
      const startDate = this.parseTime(statDate, '{y}-{m}-{d}');
      const endDate = this.parseTime(statDate, '{y}-{m}-{d}');
      // 查询该日期的分段里程明细
      getSegmentsByDateRange(vehicleId, startDate, endDate).then(response => {
        if (response.code === 200 && response.data) {
          this.segmentList = response.data;
          console.log('分段明细数据:', this.segmentList);
        } else {
          this.segmentList = [];
        }
      }).catch(error => {
        console.error('加载分段明细失败', error);
        this.segmentList = [];
        this.$modal.msgWarning('加载分段明细失败,但不影响统计数据查看');
      }).finally(() => {
        this.segmentLoading = false;
      });
    },
    /** 删除按钮操作 */