From 0bf199cf85a36157113d217363bb96314956b75f Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期四, 13 十一月 2025 22:14:12 +0800
Subject: [PATCH] feat: 修复小程序上传附件

---
 app/utils/request.js                                                              |    6 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleMileageStatsMapper.java |   72 +++++++++
 ruoyi-system/src/main/resources/mapper/system/VehicleMileageStatsMapper.xml       |   97 ++++++++++++
 sql/vehicle_mileage_stats.sql                                                     |   37 ++++
 app/components/AttachmentUpload.vue                                               |   99 +-----------
 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java   |    6 
 ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleMileageStats.java       |  141 +++++++++++++++++
 7 files changed, 366 insertions(+), 92 deletions(-)

diff --git a/app/components/AttachmentUpload.vue b/app/components/AttachmentUpload.vue
index ab0bcf5..2f319d3 100644
--- a/app/components/AttachmentUpload.vue
+++ b/app/components/AttachmentUpload.vue
@@ -67,8 +67,10 @@
 </template>
 
 <script>
-  import { getAttachmentList, uploadAttachmentFromWechat, deleteAttachment, getWechatAccessToken } from '@/api/task'
+  import { getAttachmentList, deleteAttachment } from '@/api/task'
   import { formatDateTime } from '@/utils/common'
+  import { getToken } from '@/utils/auth'
+  import config from '@/config'
   
   export default {
     name: 'AttachmentUpload',
@@ -106,16 +108,10 @@
           { label: '绯诲畨鍏ㄥ甫', value: '6' }
         ],
         selectedCategoryIndex: 0,
-        tempImagePath: null,
-        isWechatMiniProgram: false
+        tempImagePath: null
       }
     },
     mounted() {
-      // 妫�娴嬫槸鍚︽槸寰俊灏忕▼搴忕幆澧�
-      // #ifdef MP-WEIXIN
-      this.isWechatMiniProgram = true
-      // #endif
-      
       // 鑷姩鍔犺浇闄勪欢鍒楄〃
       if (this.autoLoad && this.taskId) {
         this.loadAttachmentList()
@@ -189,95 +185,20 @@
         const that = this
         const category = this.categoryList[this.selectedCategoryIndex].value
         
-        // 寰俊灏忕▼搴忕幆澧冿細鍏堣幏鍙朅ccessToken锛屽啀涓婁紶鍒板井淇℃湇鍔″櫒锛屾渶鍚庢彁浜ediaId鍒板悗绔�
-        // #ifdef MP-WEIXIN
-        if (this.isWechatMiniProgram) {
-          uni.showLoading({
-            title: '涓婁紶涓�...'
-          })
-          
-          // 绗竴姝ワ細浠庡悗绔幏鍙朅ccessToken
-          getWechatAccessToken().then(tokenResponse => {
-            // 鎺ュ彛杩斿洖鏍煎紡锛歿"msg":"token鍊�","code":200}
-            console.log('鑾峰彇AccessToken鎴愬姛:', tokenResponse)
-            const accessToken = tokenResponse.msg || tokenResponse.data || tokenResponse
-            if (!accessToken) {
-              uni.hideLoading()
-              that.$modal.showToast('鑾峰彇AccessToken澶辫触')
-              console.error('鑾峰彇AccessToken澶辫触锛屽搷搴旀暟鎹�:', tokenResponse)
-              return
-            }
-            
-            console.log('鑾峰彇鍒癆ccessToken:', accessToken)
-            
-            // 绗簩姝ワ細涓婁紶鍒板井淇℃湇鍔″櫒
-            const uploadUrl = `https://api.weixin.qq.com/cgi-bin/media/upload?access_token=${accessToken}&type=image`
-            
-            uni.uploadFile({
-              url: uploadUrl,
-              filePath: that.tempImagePath,
-              name: 'media',
-              success: function(res) {
-                console.log('寰俊涓婁紶鍝嶅簲:', res)
-                try {
-                  const data = JSON.parse(res.data)
-                  if (data.media_id) {
-                    // 绗笁姝ワ細鎻愪氦mediaId鍒板悗绔�
-                    uploadAttachmentFromWechat(that.taskId, data.media_id, category).then(response => {
-                      uni.hideLoading()
-                      that.$modal.showToast('涓婁紶鎴愬姛')
-                      that.closeUploadDialog()
-                      that.loadAttachmentList()
-                      that.$emit('uploaded', response)
-                    }).catch(error => {
-                      uni.hideLoading()
-                      console.error('鎻愪氦mediaId澶辫触:', error)
-                      that.$modal.showToast('涓婁紶澶辫触锛�' + (error.msg || '璇烽噸璇�'))
-                      that.$emit('error', error)
-                    })
-                  } else {
-                    uni.hideLoading()
-                    const errMsg = data.errmsg || '鏈煡閿欒'
-                    console.error('寰俊杩斿洖閿欒:', data)
-                    that.$modal.showToast('寰俊涓婁紶澶辫触锛�' + errMsg)
-                  }
-                } catch (e) {
-                  uni.hideLoading()
-                  console.error('瑙f瀽寰俊鍝嶅簲澶辫触:', e, res.data)
-                  that.$modal.showToast('涓婁紶澶辫触锛氬搷搴旇В鏋愰敊璇�')
-                }
-              },
-              fail: function(err) {
-                uni.hideLoading()
-                console.error('涓婁紶鍒板井淇″け璐�:', err)
-                that.$modal.showToast('涓婁紶澶辫触锛�' + (err.errMsg || '璇锋鏌ョ綉缁�'))
-                that.$emit('error', err)
-              }
-            })
-          }).catch(error => {
-            uni.hideLoading()
-            console.error('鑾峰彇AccessToken澶辫触:', error)
-            that.$modal.showToast('鑾峰彇AccessToken澶辫触')
-            that.$emit('error', error)
-          })
-          return
-        }
-        // #endif
-        
-        // 闈炲井淇″皬绋嬪簭鐜锛氱洿鎺ヤ笂浼犲埌鍚庣鏈嶅姟鍣�
+        // 缁熶竴鐩存帴涓婁紶鍒板悗绔湇鍔″櫒
         uni.showLoading({
           title: '涓婁紶涓�...'
         })
         
         uni.uploadFile({
-          url: that.$baseUrl + '/task/attachment/upload/' + that.taskId,
+          url: config.baseUrl + '/task/attachment/upload/' + that.taskId,
           filePath: that.tempImagePath,
           name: 'file',
           formData: {
             'category': category
           },
           header: {
-            'Authorization': 'Bearer ' + uni.getStorageSync('token')
+            'Authorization': 'Bearer ' + getToken()
           },
           success: function(uploadRes) {
             uni.hideLoading()
@@ -301,7 +222,7 @@
           fail: function(err) {
             uni.hideLoading()
             console.error('涓婁紶澶辫触:', err)
-            that.$modal.showToast('涓婁紶澶辫触')
+            that.$modal.showToast('涓婁紶澶辫触锛�' + (err.errMsg || '璇锋鏌ョ綉缁�'))
             that.$emit('error', err)
           }
         })
@@ -318,7 +239,7 @@
           let imageUrl = item.fileUrl
           // 濡傛灉娌℃湁fileUrl锛屽垯浣跨敤涓嬭浇鎺ュ彛
           if (!imageUrl) {
-            imageUrl = this.$baseUrl + '/task/attachment/download/' + item.attachmentId
+            imageUrl = config.baseUrl + '/task/attachment/download/' + item.attachmentId
           }
           
           // 寰俊灏忕▼搴忎腑棰勮鍥剧墖
@@ -405,7 +326,7 @@
         }
         // 浣跨敤涓嬭浇鎺ュ彛
         if (item.attachmentId) {
-          return this.$baseUrl + '/task/attachment/download/' + item.attachmentId
+          return config.baseUrl + '/task/attachment/download/' + item.attachmentId
         }
         // 榛樿鍗犱綅鍥�
         return '/static/images/default-image.png'
diff --git a/app/utils/request.js b/app/utils/request.js
index 860f0ef..bea5d40 100644
--- a/app/utils/request.js
+++ b/app/utils/request.js
@@ -11,8 +11,10 @@
   // 鏄惁闇�瑕佽缃� token
   const isToken = (config.headers || {}).isToken === false
   config.header = config.header || {}
-  if (getToken() && !isToken) {
-    config.header['Authorization'] = 'Bearer ' + getToken()
+  const token = getToken()
+  // 鍙湁褰搕oken瀛樺湪涓斾笉涓虹┖瀛楃涓叉椂鎵嶆坊鍔犲埌header
+  if (token && token.trim() !== '' && !isToken) {
+    config.header['Authorization'] = 'Bearer ' + token
   }
   // get璇锋眰鏄犲皠params鍙傛暟
   if (config.params) {
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
index 680cab6..2eb4422 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
@@ -76,9 +76,13 @@
             }
             catch (Exception e)
             {
-                log.error("鑾峰彇鐢ㄦ埛淇℃伅寮傚父'{}'", e.getMessage());
+                log.error("鑾峰彇鐢ㄦ埛淇℃伅寮傚父锛宼oken: [{}], 閿欒: {}", token.length() > 50 ? token.substring(0, 50) + "..." : token, e.getMessage());
             }
         }
+        else
+        {
+            log.warn("璇锋眰鏈惡甯︽湁鏁坱oken锛孒eader: {}", request.getHeader(header));
+        }
         return null;
     }
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleMileageStats.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleMileageStats.java
index e69de29..ab5cb3b 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleMileageStats.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleMileageStats.java
@@ -0,0 +1,141 @@
+package com.ruoyi.system.domain;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 杞﹁締閲岀▼缁熻瀵硅薄 vehicle_mileage_stats
+ * 
+ * @author ruoyi
+ * @date 2025-01-15
+ */
+public class VehicleMileageStats extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 缁熻ID */
+    private Long statsId;
+
+    /** 杞﹁締ID */
+    @Excel(name = "杞﹁締ID")
+    private Long vehicleId;
+
+    /** 缁熻鏃ユ湡 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "缁熻鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date statsDate;
+
+    /** 鎬婚噷绋�(鍏噷) */
+    @Excel(name = "鎬婚噷绋�(鍏噷)")
+    private BigDecimal totalMileage;
+
+    /** 浠诲姟閲岀▼(鍏噷) */
+    @Excel(name = "浠诲姟閲岀▼(鍏噷)")
+    private BigDecimal taskMileage;
+
+    /** 闈炰换鍔¢噷绋�(鍏噷) */
+    @Excel(name = "闈炰换鍔¢噷绋�(鍏噷)")
+    private BigDecimal nonTaskMileage;
+
+    /** 浠诲姟閲岀▼鍗犳瘮(%) */
+    @Excel(name = "浠诲姟閲岀▼鍗犳瘮(%)")
+    private BigDecimal taskMileageRatio;
+
+    /** GPS鐐规暟 */
+    @Excel(name = "GPS鐐规暟")
+    private Integer gpsCount;
+
+    public void setStatsId(Long statsId) 
+    {
+        this.statsId = statsId;
+    }
+
+    public Long getStatsId() 
+    {
+        return statsId;
+    }
+    public void setVehicleId(Long vehicleId) 
+    {
+        this.vehicleId = vehicleId;
+    }
+
+    public Long getVehicleId() 
+    {
+        return vehicleId;
+    }
+    public void setStatsDate(Date statsDate) 
+    {
+        this.statsDate = statsDate;
+    }
+
+    public Date getStatsDate() 
+    {
+        return statsDate;
+    }
+    public void setTotalMileage(BigDecimal totalMileage) 
+    {
+        this.totalMileage = totalMileage;
+    }
+
+    public BigDecimal getTotalMileage() 
+    {
+        return totalMileage;
+    }
+    public void setTaskMileage(BigDecimal taskMileage) 
+    {
+        this.taskMileage = taskMileage;
+    }
+
+    public BigDecimal getTaskMileage() 
+    {
+        return taskMileage;
+    }
+    public void setNonTaskMileage(BigDecimal nonTaskMileage) 
+    {
+        this.nonTaskMileage = nonTaskMileage;
+    }
+
+    public BigDecimal getNonTaskMileage() 
+    {
+        return nonTaskMileage;
+    }
+    public void setTaskMileageRatio(BigDecimal taskMileageRatio) 
+    {
+        this.taskMileageRatio = taskMileageRatio;
+    }
+
+    public BigDecimal getTaskMileageRatio() 
+    {
+        return taskMileageRatio;
+    }
+    public void setGpsCount(Integer gpsCount) 
+    {
+        this.gpsCount = gpsCount;
+    }
+
+    public Integer getGpsCount() 
+    {
+        return gpsCount;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("statsId", getStatsId())
+            .append("vehicleId", getVehicleId())
+            .append("statsDate", getStatsDate())
+            .append("totalMileage", getTotalMileage())
+            .append("taskMileage", getTaskMileage())
+            .append("nonTaskMileage", getNonTaskMileage())
+            .append("taskMileageRatio", getTaskMileageRatio())
+            .append("gpsCount", getGpsCount())
+            .append("createTime", getCreateTime())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleMileageStatsMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleMileageStatsMapper.java
index e69de29..ad784f7 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleMileageStatsMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleMileageStatsMapper.java
@@ -0,0 +1,72 @@
+package com.ruoyi.system.mapper;
+
+import java.util.Date;
+import java.util.List;
+import com.ruoyi.system.domain.VehicleMileageStats;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 杞﹁締閲岀▼缁熻Mapper鎺ュ彛
+ * 
+ * @author ruoyi
+ * @date 2025-01-15
+ */
+public interface VehicleMileageStatsMapper 
+{
+    /**
+     * 鏌ヨ杞﹁締閲岀▼缁熻
+     * 
+     * @param statsId 杞﹁締閲岀▼缁熻涓婚敭
+     * @return 杞﹁締閲岀▼缁熻
+     */
+    public VehicleMileageStats selectVehicleMileageStatsByStatsId(Long statsId);
+
+    /**
+     * 鏌ヨ杞﹁締閲岀▼缁熻鍒楄〃
+     * 
+     * @param vehicleMileageStats 杞﹁締閲岀▼缁熻
+     * @return 杞﹁締閲岀▼缁熻闆嗗悎
+     */
+    public List<VehicleMileageStats> selectVehicleMileageStatsList(VehicleMileageStats vehicleMileageStats);
+
+    /**
+     * 鏂板杞﹁締閲岀▼缁熻
+     * 
+     * @param vehicleMileageStats 杞﹁締閲岀▼缁熻
+     * @return 缁撴灉
+     */
+    public int insertVehicleMileageStats(VehicleMileageStats vehicleMileageStats);
+
+    /**
+     * 淇敼杞﹁締閲岀▼缁熻
+     * 
+     * @param vehicleMileageStats 杞﹁締閲岀▼缁熻
+     * @return 缁撴灉
+     */
+    public int updateVehicleMileageStats(VehicleMileageStats vehicleMileageStats);
+
+    /**
+     * 鍒犻櫎杞﹁締閲岀▼缁熻
+     * 
+     * @param statsId 杞﹁締閲岀▼缁熻涓婚敭
+     * @return 缁撴灉
+     */
+    public int deleteVehicleMileageStatsByStatsId(Long statsId);
+
+    /**
+     * 鎵归噺鍒犻櫎杞﹁締閲岀▼缁熻
+     * 
+     * @param statsIds 闇�瑕佸垹闄ょ殑鏁版嵁涓婚敭闆嗗悎
+     * @return 缁撴灉
+     */
+    public int deleteVehicleMileageStatsByStatsIds(Long[] statsIds);
+
+    /**
+     * 鏌ヨ鎸囧畾杞﹁締鍜屾棩鏈熺殑缁熻璁板綍
+     * 
+     * @param vehicleId 杞﹁締ID
+     * @param statsDate 缁熻鏃ユ湡
+     * @return 缁熻璁板綍
+     */
+    public VehicleMileageStats selectByVehicleIdAndDate(@Param("vehicleId") Long vehicleId, @Param("statsDate") Date statsDate);
+}
diff --git a/ruoyi-system/src/main/resources/mapper/system/VehicleMileageStatsMapper.xml b/ruoyi-system/src/main/resources/mapper/system/VehicleMileageStatsMapper.xml
index e69de29..1dd8199 100644
--- a/ruoyi-system/src/main/resources/mapper/system/VehicleMileageStatsMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/VehicleMileageStatsMapper.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.system.mapper.VehicleMileageStatsMapper">
+    
+    <resultMap type="VehicleMileageStats" id="VehicleMileageStatsResult">
+        <result property="statsId"    column="stats_id"    />
+        <result property="vehicleId"    column="vehicle_id"    />
+        <result property="statsDate"    column="stats_date"    />
+        <result property="totalMileage"    column="total_mileage"    />
+        <result property="taskMileage"    column="task_mileage"    />
+        <result property="nonTaskMileage"    column="non_task_mileage"    />
+        <result property="taskMileageRatio"    column="task_mileage_ratio"    />
+        <result property="gpsCount"    column="gps_count"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectVehicleMileageStatsVo">
+        select stats_id, vehicle_id, stats_date, total_mileage, task_mileage, non_task_mileage, 
+               task_mileage_ratio, gps_count, create_time, update_time
+        from vehicle_mileage_stats
+    </sql>
+
+    <select id="selectVehicleMileageStatsList" parameterType="VehicleMileageStats" resultMap="VehicleMileageStatsResult">
+        <include refid="selectVehicleMileageStatsVo"/>
+        <where>  
+            <if test="vehicleId != null "> and vehicle_id = #{vehicleId}</if>
+            <if test="statsDate != null "> and stats_date = #{statsDate}</if>
+        </where>
+        order by stats_date desc, vehicle_id
+    </select>
+    
+    <select id="selectVehicleMileageStatsByStatsId" parameterType="Long" resultMap="VehicleMileageStatsResult">
+        <include refid="selectVehicleMileageStatsVo"/>
+        where stats_id = #{statsId}
+    </select>
+    
+    <select id="selectByVehicleIdAndDate" resultMap="VehicleMileageStatsResult">
+        <include refid="selectVehicleMileageStatsVo"/>
+        where vehicle_id = #{vehicleId} and stats_date = #{statsDate}
+    </select>
+        
+    <insert id="insertVehicleMileageStats" parameterType="VehicleMileageStats" useGeneratedKeys="true" keyProperty="statsId">
+        insert into vehicle_mileage_stats
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="vehicleId != null">vehicle_id,</if>
+            <if test="statsDate != null">stats_date,</if>
+            <if test="totalMileage != null">total_mileage,</if>
+            <if test="taskMileage != null">task_mileage,</if>
+            <if test="nonTaskMileage != null">non_task_mileage,</if>
+            <if test="taskMileageRatio != null">task_mileage_ratio,</if>
+            <if test="gpsCount != null">gps_count,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="vehicleId != null">#{vehicleId},</if>
+            <if test="statsDate != null">#{statsDate},</if>
+            <if test="totalMileage != null">#{totalMileage},</if>
+            <if test="taskMileage != null">#{taskMileage},</if>
+            <if test="nonTaskMileage != null">#{nonTaskMileage},</if>
+            <if test="taskMileageRatio != null">#{taskMileageRatio},</if>
+            <if test="gpsCount != null">#{gpsCount},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateVehicleMileageStats" parameterType="VehicleMileageStats">
+        update vehicle_mileage_stats
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="vehicleId != null">vehicle_id = #{vehicleId},</if>
+            <if test="statsDate != null">stats_date = #{statsDate},</if>
+            <if test="totalMileage != null">total_mileage = #{totalMileage},</if>
+            <if test="taskMileage != null">task_mileage = #{taskMileage},</if>
+            <if test="nonTaskMileage != null">non_task_mileage = #{nonTaskMileage},</if>
+            <if test="taskMileageRatio != null">task_mileage_ratio = #{taskMileageRatio},</if>
+            <if test="gpsCount != null">gps_count = #{gpsCount},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where stats_id = #{statsId}
+    </update>
+
+    <delete id="deleteVehicleMileageStatsByStatsId" parameterType="Long">
+        delete from vehicle_mileage_stats where stats_id = #{statsId}
+    </delete>
+
+    <delete id="deleteVehicleMileageStatsByStatsIds" parameterType="String">
+        delete from vehicle_mileage_stats where stats_id in 
+        <foreach item="statsId" collection="array" open="(" separator="," close=")">
+            #{statsId}
+        </foreach>
+    </delete>
+</mapper>
diff --git a/sql/vehicle_mileage_stats.sql b/sql/vehicle_mileage_stats.sql
index e69de29..b059dec 100644
--- a/sql/vehicle_mileage_stats.sql
+++ b/sql/vehicle_mileage_stats.sql
@@ -0,0 +1,37 @@
+-- 杞﹁締閲岀▼缁熻琛�
+DROP TABLE IF EXISTS `vehicle_mileage_stats`;
+CREATE TABLE `vehicle_mileage_stats` (
+  `stats_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '缁熻ID',
+  `vehicle_id` bigint(20) NOT NULL COMMENT '杞﹁締ID',
+  `stats_date` date NOT NULL COMMENT '缁熻鏃ユ湡',
+  `total_mileage` decimal(10,2) DEFAULT '0.00' COMMENT '鎬婚噷绋�(鍏噷)',
+  `task_mileage` decimal(10,2) DEFAULT '0.00' COMMENT '浠诲姟閲岀▼(鍏噷)',
+  `non_task_mileage` decimal(10,2) DEFAULT '0.00' COMMENT '闈炰换鍔¢噷绋�(鍏噷)',
+  `task_mileage_ratio` decimal(5,2) DEFAULT '0.00' COMMENT '浠诲姟閲岀▼鍗犳瘮(%)',
+  `gps_count` int(11) DEFAULT '0' COMMENT 'GPS鐐规暟',
+  `create_time` datetime DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `update_time` datetime DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  PRIMARY KEY (`stats_id`),
+  UNIQUE KEY `uk_vehicle_date` (`vehicle_id`,`stats_date`),
+  KEY `idx_stats_date` (`stats_date`),
+  KEY `idx_vehicle_id` (`vehicle_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='杞﹁締閲岀▼缁熻琛�';
+
+-- 杞﹁締閲岀▼缁熻鏄庣粏琛�
+DROP TABLE IF EXISTS `vehicle_mileage_stats_detail`;
+CREATE TABLE `vehicle_mileage_stats_detail` (
+  `detail_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '鏄庣粏ID',
+  `stats_id` bigint(20) NOT NULL COMMENT '缁熻ID',
+  `vehicle_id` bigint(20) NOT NULL COMMENT '杞﹁締ID',
+  `task_id` bigint(20) DEFAULT NULL COMMENT '浠诲姟ID(浠诲姟鏃舵)',
+  `start_time` datetime NOT NULL COMMENT '寮�濮嬫椂闂�',
+  `end_time` datetime NOT NULL COMMENT '缁撴潫鏃堕棿',
+  `mileage` decimal(10,2) DEFAULT '0.00' COMMENT '閲岀▼(鍏噷)',
+  `is_task_period` char(1) DEFAULT '0' COMMENT '鏄惁浠诲姟鏃舵(0鍚� 1鏄�)',
+  `gps_count` int(11) DEFAULT '0' COMMENT 'GPS鐐规暟',
+  `create_time` datetime DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  PRIMARY KEY (`detail_id`),
+  KEY `idx_stats_id` (`stats_id`),
+  KEY `idx_vehicle_id` (`vehicle_id`),
+  KEY `idx_task_id` (`task_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='杞﹁締閲岀▼缁熻鏄庣粏琛�';

--
Gitblit v1.9.1