rk
2026-04-23 3696830fbaf2fd97d98020087abf20917e491bdc
Merge remote-tracking branch 'origin/master'
已添加94个文件
已修改13个文件
已删除46个文件
52552 ■■■■ 文件已修改
app/.hbuilderx/uni-agent/uni-agent.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/main.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/manifest.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages.json 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/certification-details/certification-details.vue 297 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/change-password/change-password.vue 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/driver-certification/driver-certification.vue 549 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/guide-page/guide-page.vue 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/index/index.vue 2118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/login/login.vue 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/message/message.vue 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/mine/mine.vue 437 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/order-detail/order-detail.vue 1042 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/order/order.vue 532 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/settings/settings.vue 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/static/bg_a.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/bg_b.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/background.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/btn_upload2@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/default_nodata_grey@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_biaosuda@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_c1all@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_call@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_camera@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_cancle@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_clock@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_close2@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_close@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_daohang@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_fail@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_jiangpai@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_jisuda@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_pass@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_photo@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_pic@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_renzhengzhong@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_shaixuan@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ic_shaixuan_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/login_bg@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/login_ic_account@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/login_ic_account_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/login_ic_code@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/login_ic_code_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/map_marker_end.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/map_marker_start.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/mine_ar2@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/image/ming_bg@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_gongdan@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_gongdan_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_home_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_home_sel@2x1.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_jiancha@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_jiancha_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_mine@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_mine@2x1.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_order@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_order@2x1.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_shangbao@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_shangbao_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_tubiao@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_tubiao_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_xiaoxi@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/static/tabbar/nav_xiaoxi@2x1.png 补丁 | 查看 | 原始文档 | blame | 历史
app/uni_modules/native-tts/android/.gradle/8.9/checksums/checksums.lock 补丁 | 查看 | 原始文档 | blame | 历史
app/uni_modules/native-tts/android/.gradle/8.9/dependencies-accessors/gc.properties 补丁 | 查看 | 原始文档 | blame | 历史
app/uni_modules/native-tts/android/.gradle/8.9/fileChanges/last-build.bin 补丁 | 查看 | 原始文档 | blame | 历史
app/uni_modules/native-tts/android/.gradle/8.9/fileHashes/fileHashes.lock 补丁 | 查看 | 原始文档 | blame | 历史
app/uni_modules/native-tts/android/.gradle/8.9/gc.properties 补丁 | 查看 | 原始文档 | blame | 历史
app/uni_modules/native-tts/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock 补丁 | 查看 | 原始文档 | blame | 历史
app/uni_modules/native-tts/android/.gradle/buildOutputCleanup/cache.properties 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/uni_modules/native-tts/android/.gradle/vcs-1/gc.properties 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/app-config-service.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/app-service.js 13699 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/app-view.js 9977 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/manifest.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/bg_a.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/bg_b.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/background.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/btn_upload2@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/default_nodata_grey@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_biaosuda@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_c1all@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_call@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_camera@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_cancle@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_clock@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_close2@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_close@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_daohang@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_fail@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_jiangpai@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_jisuda@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_pass@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_photo@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_pic@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_renzhengzhong@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_shaixuan@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ic_shaixuan_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/login_bg@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/login_ic_account@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/login_ic_account_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/login_ic_code@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/login_ic_code_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/map_marker_end.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/map_marker_start.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/mine_ar2@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/image/ming_bg@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_gongdan@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_gongdan_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_home_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_home_sel@2x1.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_jiancha@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_jiancha_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_mine@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_mine@2x1.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_order@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_order@2x1.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_shangbao@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_shangbao_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_tubiao@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_tubiao_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_xiaoxi@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/app-plus/static/tabbar/nav_xiaoxi@2x1.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/app.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/app.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/app.wxss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/common/main.js 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/common/main.wxss 291 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/common/runtime.js 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/common/vendor.js 21099 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/pages/index/index.js 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/pages/index/index.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/pages/index/index.wxml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/pages/index/index.wxss 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/pages/mine/mine.js 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/pages/mine/mine.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/pages/mine/mine.wxml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/pages/mine/mine.wxss 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/static/bg_a.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/static/bg_b.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/static/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_gongdan@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_gongdan_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_jiancha@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_jiancha_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_shangbao@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_shangbao_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_tubiao@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_tubiao_sel@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
small-program/pages/delivery-order-detail/delivery-order-detail.vue 398 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
small-program/pages/evaluate/evaluate.vue 192 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
small-program/pages/itinerary/itinerary.vue 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
small-program/utils/http.api.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/.hbuilderx/uni-agent/uni-agent.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
{
  "permission": {
    "edit": {
      "*": "allow"
    }
  }
}
app/main.js
@@ -3,7 +3,6 @@
import uView from "uview-ui";
import store from './store/index.js'
import './uni.promisify.adaptor'
// import Vconsole from 'vconsole'
Vue.config.productionTip = false
App.mpType = 'app'
@@ -11,7 +10,6 @@
 
Vue.prototype.$baseUrl = 'http://192.168.1.54:10011/'
Vue.prototype.$store = store;
// Vue.prototype.$vConsole= new Vconsole()
const app = new Vue({
    store,
app/manifest.json
@@ -50,6 +50,13 @@
            },
            /* SDK配置 */
            "sdkConfigs" : {
                "maps" : {
                    "amap" : {
                        "name" : "",
                        "appkey_ios" : "e4d46c87adf151dca20060317592b1b6",
                        "appkey_android" : "e4d46c87adf151dca20060317592b1b6"
                    }
                },
                "push" : {
                    "unipush" : {
                        "version" : "2",
app/pages.json
@@ -4,17 +4,88 @@
    },
    "pages": [
        {
            "path": "pages/guide-page/guide-page",
            "style": {
                "app-plus": {
                    "titleNView": false
                }
            }
        },
        {
            "path": "pages/index/index",
            "style": {
                "navigationBarTitleText": "首页",
                "navigationBarBackgroundColor": "#ffffff"
                "navigationStyle": "custom",
                "app-plus": {
                    "titleNView": false
                }
            }
        },
        {
            "path": "pages/mine/mine",
            "style": {
                "navigationBarTitleText": "我的",
                "navigationBarBackgroundColor": "#ffffff"
                "navigationStyle": "custom",
                "app-plus": {
                    "titleNView": false
                }
            }
        },
        {
            "path": "pages/order/order",
            "style": {
                "navigationStyle": "custom",
                "app-plus": {
                    "titleNView": false
                }
            }
        },
        {
            "path": "pages/order-detail/order-detail",
            "style": {
                "navigationStyle": "custom",
                "app-plus": {
                    "titleNView": false
                }
            }
        },
        {
            "path": "pages/message/message",
            "style": {
                "navigationStyle": "custom",
                "app-plus": {
                    "titleNView": false
                }
            }
        },
        {
            "path": "pages/login/login",
            "style": {
                "app-plus": {
                    "titleNView": false
                }
            }
        },
        {
            "path": "pages/settings/settings",
            "style": {
                "navigationBarTitleText": "设置"
            }
        },
        {
            "path": "pages/change-password/change-password",
            "style": {
                "navigationBarTitleText": "修改密码"
            }
        },
        {
            "path": "pages/driver-certification/driver-certification",
            "style": {
                "navigationBarTitleText": "司机认证"
            }
        },
        {
            "path": "pages/certification-details/certification-details",
            "style": {
                "navigationBarTitleText": "司机认证"
            }
        }
    ],
@@ -32,14 +103,26 @@
        "list": [
            {
                "pagePath": "pages/index/index",
                "iconPath": "static/tabbar/nav_jiancha@2x.png",
                "selectedIconPath": "static/tabbar/nav_jiancha_sel@2x.png",
                "text": "首页"
                "iconPath": "static/tabbar/nav_home_sel@2x.png",
                "selectedIconPath": "static/tabbar/nav_home_sel@2x1.png",
                "text": "大厅"
            },
            {
                "pagePath": "pages/order/order",
                "iconPath": "static/tabbar/nav_order@2x.png",
                "selectedIconPath": "static/tabbar/nav_order@2x1.png",
                "text": "订单"
            },
            {
                "pagePath": "pages/message/message",
                "iconPath": "static/tabbar/nav_xiaoxi@2x.png",
                "selectedIconPath": "static/tabbar/nav_xiaoxi@2x1.png",
                "text": "消息"
            },
            {
                "pagePath": "pages/mine/mine",
                "iconPath": "static/tabbar/nav_jiancha@2x.png",
                "selectedIconPath": "static/tabbar/nav_jiancha_sel@2x.png",
                "iconPath": "static/tabbar/nav_mine@2x.png",
                "selectedIconPath": "static/tabbar/nav_mine@2x1.png",
                "text": "我的"
            }
        ]
app/pages/certification-details/certification-details.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,297 @@
<template>
    <view class="cert-details-page">
        <view class="cert-details-page__status-card" :class="'cert-details-page__status-card--' + statusType">
            <view class="cert-details-page__status-head">
                <image class="cert-details-page__status-icon" :src="statusIcon" mode="aspectFit"></image>
                <text class="cert-details-page__status-title" :class="'cert-details-page__status-title--' + statusType">{{ statusTitle }}</text>
            </view>
            <text v-if="statusDesc" class="cert-details-page__status-desc">{{ statusDesc }}</text>
        </view>
        <view class="cert-details-page__section">
            <text class="cert-details-page__section-title">基本信息</text>
            <view class="cert-details-page__info-list">
                <view v-for="item in basicInfo" :key="item.label" class="cert-details-page__info-item">
                    <text class="cert-details-page__info-label">{{ item.label }}</text>
                    <text class="cert-details-page__info-value">{{ item.value }}</text>
                </view>
            </view>
            <view class="cert-details-page__upload-group">
                <text class="cert-details-page__upload-title">身份证正反面</text>
                <view class="cert-details-page__upload-list">
                    <view class="cert-details-page__upload-card">
                    </view>
                    <view class="cert-details-page__upload-card">
                    </view>
                </view>
            </view>
        </view>
        <view class="cert-details-page__section cert-details-page__section--last">
            <text class="cert-details-page__section-title">车辆信息</text>
            <view class="cert-details-page__info-list">
                <view v-for="item in vehicleInfo" :key="item.label" class="cert-details-page__info-item">
                    <text class="cert-details-page__info-label">{{ item.label }}</text>
                    <text class="cert-details-page__info-value">{{ item.value }}</text>
                </view>
            </view>
            <view class="cert-details-page__upload-group">
                <text class="cert-details-page__upload-title">车辆照片</text>
                <view class="cert-details-page__upload-list">
                    <view class="cert-details-page__upload-img">
                    </view>
                    <view class="cert-details-page__upload-img">
                    </view>
                </view>
            </view>
            <view class="cert-details-page__upload-group">
                <text class="cert-details-page__upload-title">驾驶证照片</text>
                <view class="cert-details-page__upload-list cert-details-page__upload-list--single">
                    <view class="cert-details-page__upload-img">
                    </view>
                </view>
            </view>
        </view>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                statusType: 'review',
                basicInfo: [
                    { label: '注册手机号', value: '18155114565' },
                    { label: '司机姓名', value: '苏熙熙' },
                    { label: '婚姻状况', value: '未婚' },
                    { label: '居住城市', value: '安徽省/合肥市/庐阳区' },
                    { label: '详细地址', value: '九华山路201号' },
                    { label: '支付宝账号', value: '18155114565' },
                    { label: '身份证号', value: '3482938472937838902' }
                ],
                vehicleInfo: [
                    { label: '车牌号', value: '皖BD23189' },
                    { label: '车辆类型', value: '面包车' },
                    { label: '车辆颜色', value: '白色' },
                    { label: '驾驶证有效期', value: '2016å¹´1月1日至2036å¹´1月1日' }
                ]
            }
        },
        computed: {
            statusTitle() {
                const titleMap = {
                    review: '平台审核中',
                    approved: '司机认证已通过',
                    rejected: '司机认证已拒绝'
                }
                return titleMap[this.statusType] || titleMap.review
            },
            statusDesc() {
                const descMap = {
                    review: '审核结果将通过短信/订单消息通知您',
                    approved: '',
                    rejected: '驾驶证过期,请重新提交审核'
                }
                return descMap[this.statusType] || ''
            },
            statusIcon() {
                const iconMap = {
                    review: '/static/image/ic_renzhengzhong@2x.png',
                    approved: '/static/image/ic_pass@2x.png',
                    rejected: '/static/image/ic_fail@2x.png'
                }
                return iconMap[this.statusType] || iconMap.review
            }
        },
        onLoad(options) {
            this.statusType = options && options.status ? options.status : 'review'
        }
    }
</script>
<style lang="scss" scoped>
    .cert-details-page {
        background: #ffffff;
        &__status-card {
            width: 100%;
            height: 248rpx;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
            background: linear-gradient(180deg, #fff3e7 0%, #fff7f0 100%);
            text-align: center;
            &--approved {
                background: linear-gradient(180deg, #ecfff3 0%, #f5fff9 100%);
            }
            &--rejected {
                background: linear-gradient(180deg, #fff1f1 0%, #fff7f7 100%);
            }
        }
        &__status-head {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 12rpx;
        }
        &__status-icon {
            width: 60rpx;
            height: 60rpx;
            flex-shrink: 0;
        }
        &__status-title {
            font-weight: 600;
            font-size: 40rpx;
            color: #FA8010;
            &--approved {
                color: #18c86d;
            }
            &--rejected {
                color: #ff2f2f;
            }
        }
        &__status-desc {
            display: block;
            margin-top: 14rpx;
            font-weight: 400;
            font-size: 28rpx;
            color: #333333;
        }
        &__section {
            padding: 24rpx 30rpx;
            box-sizing: border-box;
            &--last {
                padding-bottom: calc(env(safe-area-inset-bottom) + 28rpx);
            }
        }
        &__section-title {
            display: block;
            font-weight: 600;
            font-size: 36rpx;
            color: #222222;
        }
        &__info-list {
            margin-top: 14rpx;
        }
        &__info-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            gap: 20rpx;
            padding: 30rpx 0;
            box-sizing: border-box;
            border-bottom: 1rpx solid #E5E5E5;
        }
        &__info-label {
            font-weight: 400;
            font-size: 30rpx;
            color: #777777;
            flex-shrink: 0;
        }
        &__info-value {
            font-weight: 400;
            font-size: 30rpx;
            color: #222222;
            text-align: right;
        }
        &__upload-group {
            padding-top: 24rpx;
        }
        &__upload-title {
            display: block;
            font-weight: 400;
            font-size: 30rpx;
            color: #777777;
        }
        &__upload-list {
            display: flex;
            flex-wrap: wrap;
            gap: 20rpx;
            margin-top: 30rpx;
            &--single {
                justify-content: flex-start;
            }
        }
        &__upload-card {
            flex: 1;
            height: 216rpx;
            border-radius: 10rpx;
            overflow: hidden;
            background: #f7f8fa;
            border: 1rpx solid #eef1f5;
            &--license {
                height: 124rpx;
            }
        }
        &__upload-img {
            width: 144rpx;
            height: 144rpx;
            background-color: #333333;
        }
        &__id-avatar {
            width: 36rpx;
            height: 42rpx;
            margin-left: auto;
            margin-top: -34rpx;
            border-radius: 8rpx;
            background: linear-gradient(180deg, #ffd39a 0%, #ffc56d 100%);
        }
        &__id-emblem,
        &__id-emblem-sub {
            display: block;
            font-size: 14rpx;
            font-weight: 700;
            color: #9b6e67;
        }
        &__id-emblem-sub {
            margin-top: 6rpx;
            letter-spacing: 2rpx;
        }
        &__car-photo {
            position: relative;
            width: 144rpx;
            height: 144rpx;
            background: linear-gradient(180deg, #f5f7fa 0%, #eff2f7 100%);
        }
    }
</style>
app/pages/change-password/change-password.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,99 @@
<template>
    <view class="change-password-page">
        <view class="change-password-page__form">
            <view class="change-password-page__item">
                <text class="change-password-page__label">新密码</text>
                <input v-model="form.password" class="change-password-page__input" password placeholder="请输入新密码" placeholder-style="color: #c2c7d0;" />
            </view>
            <view class="change-password-page__item">
                <text class="change-password-page__label">确认密码</text>
                <input v-model="form.confirmPassword" class="change-password-page__input" password placeholder="请再次输入新密码" placeholder-style="color: #c2c7d0;" />
            </view>
            <text class="change-password-page__rule">密码规则:字母、数字组合,不少于8个字符</text>
        </view>
        <button class="change-password-page__submit" hover-class="change-password-page__submit--hover">确认修改</button>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                form: {
                    password: '',
                    confirmPassword: ''
                }
            }
        }
    }
</script>
<style lang="scss" scoped>
    .change-password-page {
        min-height: 100vh;
        background: #ffffff;
        padding-top: 2rpx;
        &__form {
            background: #ffffff;
        }
        &__item {
            display: flex;
            align-items: center;
            height: 100rpx;
            padding: 0 30rpx;
            border-bottom: 1rpx solid #eceff4;
        }
        &__label {
            width: 150rpx;
            font-size: 32rpx;
            font-weight: 500;
            color: #333333;
            flex-shrink: 0;
        }
        &__input {
            flex: 1;
            height: 100rpx;
            text-align: right;
            font-size: 30rpx;
            color: #333333;
            background: transparent;
        }
        &__rule {
            display: block;
            padding: 20rpx 30rpx 0;
            font-size: 24rpx;
            line-height: 1.6;
            color: #b3b8c1;
        }
        &__submit {
            width: calc(100% - 60rpx);
            height: 78rpx;
            line-height: 78rpx;
            margin: 110rpx auto 0;
            border-radius: 999rpx;
            background: #2476f6;
            font-size: 30rpx;
            font-weight: 500;
            color: #ffffff;
            border: 0;
            padding: 0;
            &::after {
                border: 0;
            }
            &--hover {
                opacity: 0.92;
            }
        }
    }
</style>
app/pages/driver-certification/driver-certification.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,549 @@
<template>
    <view class="driver-cert-page">
        <view class="driver-cert-page__steps">
            <view class="driver-cert-page__step"
                :class="{ 'driver-cert-page__step--active': currentStep === 1, 'driver-cert-page__step--done': currentStep > 1 }">
                <view class="driver-cert-page__step-circle">
                    <view class="driver-cert-page__step-circle-inner">
                        <u-icon v-if="currentStep > 1" name="checkbox-mark" color="#ffffff" size="10"></u-icon>
                    </view>
                </view>
                <text class="driver-cert-page__step-text"
                    :class="{ 'driver-cert-page__step-text--active': currentStep === 1, 'driver-cert-page__step-text--done': currentStep > 1 }">基本信息</text>
            </view>
            <view class="driver-cert-page__step-line"></view>
            <view class="driver-cert-page__step" :class="{ 'driver-cert-page__step--active': currentStep === 2 }">
                <view class="driver-cert-page__step-circle"
                    :class="{ 'driver-cert-page__step-circle--inactive': currentStep !== 2 }">
                    <view class="driver-cert-page__step-circle-inner">{{ currentStep === 2 ? '' : '2' }}</view>
                </view>
                <text class="driver-cert-page__step-text"
                    :class="{ 'driver-cert-page__step-text--active': currentStep === 2 }">车辆信息</text>
            </view>
        </view>
        <view class="driver-cert-page__scroll">
            <view v-if="currentStep === 1" class="driver-cert-card">
                <text class="driver-cert-card__title">基本信息</text>
                <text class="driver-cert-card__mobile">注册手机号:18155114565</text>
                <view class="driver-cert-card__field">
                    <text class="driver-cert-card__label">司机姓名</text>
                    <text class="driver-cert-card__required">*</text>
                    <input v-model="form.name" class="driver-cert-card__input" placeholder="请输入司机姓名"
                        placeholder-style="color: #b9bfc8;" />
                </view>
                <view class="driver-cert-card__field">
                    <text class="driver-cert-card__label">身份证号</text>
                    <text class="driver-cert-card__required">*</text>
                    <input v-model="form.idCard" class="driver-cert-card__input" placeholder="请输入司机身份证号码"
                        placeholder-style="color: #b9bfc8;" />
                </view>
                <view class="driver-cert-card__field driver-cert-card__field--select">
                    <view class="driver-cert-card__field-head">
                        <text class="driver-cert-card__label">婚姻状况</text>
                        <text class="driver-cert-card__required">*</text>
                    </view>
                    <view class="driver-cert-card__selector">
                        <text class="driver-cert-card__selector-text">请选择</text>
                        <text class="driver-cert-card__arrow">›</text>
                    </view>
                </view>
                <view class="driver-cert-card__field driver-cert-card__field--select">
                    <view class="driver-cert-card__field-head">
                        <text class="driver-cert-card__label">居住城市</text>
                        <text class="driver-cert-card__required">*</text>
                    </view>
                    <view class="driver-cert-card__selector">
                        <text class="driver-cert-card__selector-text">请选择省市区</text>
                        <text class="driver-cert-card__arrow">›</text>
                    </view>
                </view>
                <view class="driver-cert-card__field">
                    <text class="driver-cert-card__label">详细地址</text>
                    <text class="driver-cert-card__required">*</text>
                    <input v-model="form.address" class="driver-cert-card__input" placeholder="请输入详细居住地址"
                        placeholder-style="color: #b9bfc8;" />
                </view>
                <view class="driver-cert-card__field">
                    <text class="driver-cert-card__label">支付宝账号</text>
                    <text class="driver-cert-card__required">*</text>
                    <input v-model="form.alipay" class="driver-cert-card__input" placeholder="请输入收款支付宝账号"
                        placeholder-style="color: #b9bfc8;" />
                </view>
                <view class="driver-cert-card__upload-block">
                    <view class="driver-cert-card__upload-title-row">
                        <text class="driver-cert-card__label">身份证正反面</text>
                        <text class="driver-cert-card__required">*</text>
                    </view>
                    <view class="driver-cert-card__upload-list">
                        <view class="driver-cert-card__upload-item">
                            <image class="driver-cert-card__upload-icon" src="/static/image/ic_camera@2x.png"
                                mode="aspectFit"></image>
                            <text class="driver-cert-card__upload-text">上传人像面</text>
                        </view>
                        <view class="driver-cert-card__upload-item">
                            <image class="driver-cert-card__upload-icon" src="/static/image/ic_camera@2x.png"
                                mode="aspectFit"></image>
                            <text class="driver-cert-card__upload-text">上传国徽面</text>
                        </view>
                    </view>
                </view>
            </view>
            <view v-else class="driver-cert-card driver-cert-card--vehicle">
                <text class="driver-cert-card__title">车辆信息</text>
                <view class="driver-cert-card__field">
                    <text class="driver-cert-card__label">车牌号</text>
                    <text class="driver-cert-card__required">*</text>
                    <input v-model="vehicleForm.plateNumber" class="driver-cert-card__input" placeholder="请输入车牌号"
                        placeholder-style="color: #b9bfc8;" />
                </view>
                <view class="driver-cert-card__field driver-cert-card__field--select">
                    <view class="driver-cert-card__field-head">
                        <text class="driver-cert-card__label">车辆类型</text>
                        <text class="driver-cert-card__required">*</text>
                    </view>
                    <view class="driver-cert-card__selector">
                        <text class="driver-cert-card__selector-text">请选择</text>
                        <text class="driver-cert-card__arrow">›</text>
                    </view>
                </view>
                <view class="driver-cert-card__field">
                    <text class="driver-cert-card__label">车辆颜色</text>
                    <text class="driver-cert-card__required">*</text>
                    <input v-model="vehicleForm.color" class="driver-cert-card__input" placeholder="请输入车辆颜色"
                        placeholder-style="color: #b9bfc8;" />
                </view>
                <view class="driver-cert-card__field driver-cert-card__field--select">
                    <view class="driver-cert-card__field-head">
                        <text class="driver-cert-card__label">驾驶证有效期</text>
                        <text class="driver-cert-card__required">*</text>
                    </view>
                    <view class="driver-cert-card__selector">
                        <text class="driver-cert-card__selector-text">请选择</text>
                        <text class="driver-cert-card__arrow">›</text>
                    </view>
                </view>
                <view class="driver-cert-card__upload-block driver-cert-card__upload-block--stacked">
                    <view class="driver-cert-card__upload-title-row">
                        <text class="driver-cert-card__label">车辆照片</text>
                        <text class="driver-cert-card__required">*</text>
                        <text class="driver-cert-card__upload-tip">最多上传3张照片</text>
                    </view>
                    <view class="driver-cert-card__upload-list driver-cert-card__upload-list--single">
                        <view class="driver-cert-card__upload-item driver-cert-card__upload-item--single">
                            <image class="driver-cert-card__upload-image" src="/static/image/btn_upload2@2x.png"
                                mode="aspectFit"></image>
                        </view>
                    </view>
                </view>
                <view class="driver-cert-card__upload-block driver-cert-card__upload-block--stacked">
                    <view class="driver-cert-card__upload-title-row">
                        <text class="driver-cert-card__label">驾驶证照片</text>
                        <text class="driver-cert-card__required">*</text>
                        <text class="driver-cert-card__upload-tip">最多上传3张照片</text>
                    </view>
                    <view class="driver-cert-card__upload-list driver-cert-card__upload-list--single">
                        <view class="driver-cert-card__upload-item driver-cert-card__upload-item--single">
                            <image class="driver-cert-card__upload-image" src="/static/image/btn_upload2@2x.png"
                                mode="aspectFit"></image>
                        </view>
                    </view>
                </view>
                <view class="driver-cert-card__upload-block driver-cert-card__upload-block--stacked">
                    <view class="driver-cert-card__upload-title-row">
                        <text class="driver-cert-card__label">其他材料</text>
                        <text class="driver-cert-card__upload-tip">最多上传3张照片</text>
                    </view>
                    <view class="driver-cert-card__upload-list driver-cert-card__upload-list--single">
                        <view class="driver-cert-card__upload-item driver-cert-card__upload-item--single">
                            <image class="driver-cert-card__upload-image" src="/static/image/btn_upload2@2x.png"
                                mode="aspectFit"></image>
                        </view>
                    </view>
                </view>
            </view>
        </view>
        <view class="driver-cert-page__bottom-bar">
            <label v-if="currentStep === 2" class="driver-cert-page__agreement">
                <radio class="driver-cert-page__agreement-radio" :checked="true" color="#2D7CFF" />
                <text class="driver-cert-page__agreement-text">我已阅读并同意《风险声明》、《行李寄存员须知》及《服务协议》</text>
            </label>
            <view class="driver-cert-page__actions" :class="{ 'driver-cert-page__actions--dual': currentStep === 2 }">
                <button v-if="currentStep === 2" class="driver-cert-page__submit driver-cert-page__submit--ghost"
                    hover-class="driver-cert-page__submit--hover" @click="goPrevStep">上一步</button>
                <button class="driver-cert-page__submit" hover-class="driver-cert-page__submit--hover"
                    @click="handlePrimaryAction">{{ currentStep === 1 ? '下一步' : '提交认证申请' }}</button>
            </view>
        </view>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                currentStep: 1,
                form: {
                    name: '',
                    idCard: '',
                    address: '',
                    alipay: ''
                },
                vehicleForm: {
                    plateNumber: '',
                    color: ''
                }
            }
        },
        methods: {
            handlePrimaryAction() {
                if (this.currentStep === 1) {
                    this.scrollToTop()
                    this.currentStep = 2
                }
            },
            goPrevStep() {
                this.scrollToTop()
                this.currentStep = 1
            },
            scrollToTop() {
                uni.pageScrollTo({
                    scrollTop: 0,
                    duration: 0
                })
            }
        }
    }
</script>
<style lang="scss" scoped>
    .driver-cert-page {
        min-height: 100vh;
        padding: 18rpx 16rpx 32rpx;
        background: linear-gradient(180deg, #d7f0ff 0%, #f6fbff 28%, #ffffff 100%);
        box-sizing: border-box;
        overflow: hidden;
        &__scroll {
            width: 100%;
        }
        &__steps {
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 10rpx 20rpx 24rpx;
        }
        &__step {
            display: flex;
            flex-direction: column;
            align-items: center;
            min-width: 150rpx;
            &--active {
                .driver-cert-page__step-circle {
                    background: #b9e9ff;
                }
                .driver-cert-page__step-circle-inner {
                    background: #106efa;
                    color: #ffffff;
                    box-shadow: 0 8rpx 18rpx rgba(16, 110, 250, 0.24);
                }
            }
            &--done {
                .driver-cert-page__step-circle {
                    background: #b9e9ff;
                }
                .driver-cert-page__step-circle-inner {
                    background: #106efa;
                    color: #ffffff;
                }
            }
        }
        &__step-circle {
            width: 52rpx;
            height: 52rpx;
            border-radius: 50%;
            background: #b9e9ff;
            display: flex;
            align-items: center;
            justify-content: center;
            &--inactive {
                background: #8c939f;
                .driver-cert-page__step-circle-inner {
                    width: 100%;
                    height: 100%;
                    background: transparent;
                    box-shadow: none;
                }
            }
        }
        &__step-circle-inner {
            width: 32rpx;
            height: 32rpx;
            border-radius: 50%;
            background: #106efa;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 22rpx;
            font-weight: 700;
            color: #ffffff;
        }
        &__step-text {
            margin-top: 12rpx;
            font-size: 30rpx;
            font-weight: 500;
            color: #7f8693;
            &--active {
                color: #2b3139;
                font-weight: 700;
            }
            &--done {
                color: #106efa;
                font-weight: 700;
            }
        }
        &__step-line {
            width: 160rpx;
            height: 2rpx;
            margin: 0 12rpx 30rpx;
            background: #b4c7ea;
        }
        &__bottom-bar {
            margin-top: 30rpx;
            padding: 18rpx 0 calc(env(safe-area-inset-bottom) + 18rpx);
            background: #ffffff;
            box-sizing: border-box;
        }
        &__actions {
            display: flex;
            justify-content: center;
            &--dual {
                gap: 18rpx;
            }
        }
        &__submit {
            width: 100%;
            height: 78rpx;
            line-height: 78rpx;
            border-radius: 999rpx;
            background: #2476f6;
            font-size: 30rpx;
            font-weight: 500;
            color: #ffffff;
            border: 0;
            padding: 0;
            &::after {
                border: 0;
            }
            &--hover {
                opacity: 0.92;
            }
            &--ghost {
                width: 220rpx;
                background: #f3f8ff;
                border: 1rpx solid #7db0ff;
                color: #2d7cff;
            }
        }
        &__agreement {
            display: flex;
            align-items: flex-start;
            margin-bottom: 18rpx;
        }
        &__agreement-radio {
            transform: scale(0.9);
            transform-origin: left top;
            margin-right: 6rpx;
        }
        &__agreement-text {
            font-size: 22rpx;
            line-height: 1.6;
            color: #98a0ad;
        }
    }
    .driver-cert-card {
        padding: 24rpx 24rpx 22rpx;
        border-radius: 22rpx;
        background: #ffffff;
        overflow: hidden;
        box-shadow: 0rpx 2rpx 20rpx 0rpx rgba(0, 0, 0, 0.08);
        &__title {
            display: block;
            font-size: 40rpx;
            font-weight: 700;
            color: #2b3139;
        }
        &__mobile {
            display: block;
            margin-top: 14rpx;
            font-size: 28rpx;
            color: #9aa1ad;
        }
        &--vehicle {
            margin-bottom: 30rpx;
        }
        &__field {
            padding: 28rpx 0 24rpx;
            border-bottom: 1rpx solid #eef1f5;
            &--select {
                padding-bottom: 20rpx;
            }
        }
        &__field-head,
        &__upload-title-row {
            display: flex;
            align-items: center;
        }
        &__label {
            font-size: 32rpx;
            font-weight: 600;
            color: #2b3139;
        }
        &__required {
            margin-left: 4rpx;
            font-size: 32rpx;
            line-height: 1;
            color: #ff4a3d;
        }
        &__input {
            width: 100%;
            height: 78rpx;
            margin-top: 10rpx;
            font-size: 30rpx;
            color: #333333;
            background: transparent;
        }
        &__selector {
            display: flex;
            justify-content: space-between;
            align-items: center;
            height: 78rpx;
            margin-top: 10rpx;
        }
        &__selector-text {
            font-size: 30rpx;
            color: #b9bfc8;
        }
        &__arrow {
            font-size: 34rpx;
            line-height: 1;
            color: #9aa1ad;
        }
        &__upload-block {
            padding-top: 28rpx;
            &--stacked {
                border-top: 1rpx solid #eef1f5;
                margin-top: 2rpx;
            }
        }
        &__upload-list {
            display: flex;
            gap: 20rpx;
            margin-top: 22rpx;
            &--single {
                gap: 0;
            }
        }
        &__upload-item {
            flex: 1;
            height: 144rpx;
            border-radius: 16rpx;
            background: #f7f8fa;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            &--single {
                flex: none;
                width: 144rpx;
            }
        }
        &__upload-image {
            width: 144rpx;
            height: 144rpx;
        }
        &__upload-icon {
            width: 52rpx;
            height: 52rpx;
            opacity: 0.5;
        }
        &__upload-text {
            margin-top: 16rpx;
            font-size: 28rpx;
            color: #8f96a3;
        }
        &__upload-tip {
            margin-left: 10rpx;
            font-size: 22rpx;
            color: #b7bdc7;
        }
    }
</style>
app/pages/guide-page/guide-page.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,136 @@
<template>
    <view class="guide-page">
        <swiper class="guide-page__swiper" :current="current" circular @change="handleSwiperChange">
            <swiper-item v-for="(item, index) in guideList" :key="index">
                <view class="guide-page__slide">
                    <image class="guide-page__image" :src="item.url" mode="heightFix"></image>
                </view>
            </swiper-item>
        </swiper>
        <view class="guide-page__dots">
            <view
                v-for="(item, index) in guideList"
                :key="item.id"
                class="guide-page__dot"
                :class="{ 'guide-page__dot--active': current === index }"
            ></view>
        </view>
        <view class="guide-page__footer">
            <view class="guide-page__action">
                <button class="guide-page__button" hover-class="guide-page__button--hover" @click="jump">立即体验</button>
            </view>
        </view>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                current: 0,
                guideList: [
                    { id: 1, background: '#d9d9d9', url: '/static/image/background.png' },
                    { id: 2, background: '#d9d9d9', url: '/static/image/background.png' },
                    { id: 3, background: '#d9d9d9', url: '/static/image/background.png' },
                    { id: 4, background: '#d9d9d9', url: '/static/image/background.png' }
                ]
            };
        },
        methods: {
            handleSwiperChange(event) {
                this.current = event.detail.current;
            },
            jump() {
                uni.navigateTo({
                    url: '/pages/login/login'
                })
            }
        }
    };
</script>
<style lang="scss" scoped>
    .guide-page {
        position: relative;
        min-height: 100vh;
        background: #d9d9d9;
        &__swiper {
            height: 100vh;
        }
        &__slide {
            height: 100vh;
        }
        &__image {
            display: block;
            width: 100%;
            height: 100%;
        }
        &__footer {
            position: absolute;
            left: 0;
            right: 0;
            bottom: 0;
            padding: 24rpx 0 calc(env(safe-area-inset-bottom) + 30rpx);
            background: #ffffff;
        }
        &__dots {
            position: absolute;
            left: 0;
            right: 0;
            bottom: calc(env(safe-area-inset-bottom) + 154rpx);
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 18rpx;
        }
        &__dot {
            width: 14rpx;
            height: 14rpx;
            border-radius: 50%;
            background: rgba(255, 255, 255, 0.58);
            transition: all 0.2s ease;
            &--active {
                width: 18rpx;
                height: 18rpx;
                background: #ffffff;
                box-shadow: 0 0 0 4rpx rgba(255, 255, 255, 0.18);
            }
        }
        &__action {
            padding: 0 0 8rpx;
        }
        &__button {
            width: 330rpx;
            height: 74rpx;
            line-height: 74rpx;
            border: 0;
            border-radius: 999rpx;
            background: linear-gradient(180deg, #2d7fff 0%, #2369f3 100%);
            box-shadow: 0 16rpx 32rpx rgba(35, 105, 243, 0.24);
            font-size: 30rpx;
            font-weight: 600;
            color: #ffffff;
            padding: 0;
            &::after {
                border: 0;
            }
            &--hover {
                opacity: 0.92;
                transform: translateY(2rpx);
            }
        }
    }
</style>
app/pages/index/index.vue
@@ -1,6 +1,367 @@
<template>
    <view style="padding: 40rpx;">
        <button @click="speak('订单已收到,开始播报')">开始播报</button>
        <view class="hall-page">
            <view v-if="showOrderDetail && isStatusDetail" class="order-detail-map-layer" :style="{ top: statusBarHeight + 'px' }">
                <map
                    class="order-detail-map-layer__map"
                    :latitude="detailMap.center.latitude"
                    :longitude="detailMap.center.longitude"
                    :markers="detailMap.markers"
                    :polyline="detailMap.polyline"
                    :include-points="detailMap.includePoints"
                    :scale="detailMap.scale"
                    :enable-zoom="true"
                    :enable-scroll="true"
                ></map>
            </view>
            <view class="hall-page__header" :style="{ paddingTop: statusBarHeight + 'px' }">
            <view class="hall-page__user-row">
                <view class="hall-page__user">
                    <image class="hall-page__avatar" src="/static/image/login_bg@2x.png" mode="aspectFill"></image>
                    <text class="hall-page__name">汤子新</text>
                </view>
                <view class="hall-page__status">
                    <view class="hall-page__status-dot"></view>
                    <text class="hall-page__status-text">接单中</text>
                    <text class="hall-page__status-arrow">▼</text>
                </view>
                <view class="hall-page__user" style="opacity: 0;">
                    <image class="hall-page__avatar" src="/static/image/login_bg@2x.png" mode="aspectFill"></image>
                    <text class="hall-page__name">汤子新</text>
                </view>
            </view>
            <view class="hall-page__stats">
                <view v-for="item in stats" :key="item.label" class="hall-page__stat-item">
                    <text class="hall-page__stat-value">{{ item.value }}</text>
                    <text class="hall-page__stat-label">{{ item.label }}</text>
                </view>
            </view>
            <view class="hall-page__tabs">
                <view v-for="tab in tabs" :key="tab.value" class="hall-page__tab" :class="{ 'hall-page__tab--active': activeTab === tab.value }" @click="activeTab = tab.value">
                    <text class="hall-page__tab-text">{{ tab.label }}</text>
                    <text v-if="tab.count" class="hall-page__tab-count">{{ tab.count }}</text>
                    <view v-if="activeTab === tab.value" class="hall-page__tab-line"></view>
                </view>
                <view class="hall-page__filter" @click="toggleFilterPopup(true)">
                    <text class="hall-page__filter-text" :class="{ 'hall-page__filter-text--active': showFilterPopup }">筛选</text>
                    <image :src="showFilterPopup ? '/static/image/ic_shaixuan_sel@2x.png' : '/static/image/ic_shaixuan@2x.png'" mode="widthFix" class="hall-page__filter-icon"></image>
                </view>
            </view>
        </view>
        <view v-if="showFilterPopup" class="filter-popup" :style="{ top: headerHeight + 'px', bottom: tabbarHeight + 'px' }" @click="toggleFilterPopup(false)">
            <view class="filter-popup__panel" @click.stop>
                <view v-for="section in filterSections" :key="section.key" class="filter-popup__section">
                    <text class="filter-popup__title">{{ section.title }}</text>
                    <view class="filter-popup__options">
                        <view
                            v-for="option in section.options"
                            :key="option"
                            class="filter-popup__option"
                            :class="{ 'filter-popup__option--active': selectedFilters[section.key] === option }"
                            @click="selectFilter(section.key, option)"
                        >
                            <text class="filter-popup__option-text">{{ option }}</text>
                        </view>
                    </view>
                </view>
                <view class="filter-popup__actions">
                    <button class="filter-popup__button filter-popup__button--reset" hover-class="filter-popup__button--hover" @click="resetFilters">重置</button>
                    <button class="filter-popup__button filter-popup__button--confirm" hover-class="filter-popup__button--hover" @click="confirmFilters">确认</button>
                </view>
            </view>
        </view>
        <scroll-view class="hall-page__body" scroll-y :style="bodyStyle">
            <view v-if="currentOrderList.length" class="hall-page__list">
                <view v-for="item in currentOrderList" :key="item.id" class="order-card" @click="openDetailPopup(item)">
                    <view class="order-card__head">
                        <view class="order-card__time">
                            <text class="order-card__time-main">{{ item.time }}</text>
                            <text class="order-card__time-sub">送达</text>
                        </view>
                        <view v-if="activeTab === 'hall'" class="order-card__price-wrap">
                            <text v-if="item.serialNo" class="order-card__serial">#{{ item.serialNo }}</text>
                            <text class="order-card__price">{{ item.price }}</text>
                        </view>
                        <view v-else class="order-card__price-wrap order-card__price-wrap--serial-only">
                            <text v-if="item.serialNo" class="order-card__serial">#{{ item.serialNo }}</text>
                        </view>
                    </view>
                    <view class="order-card__meta">
                        <view class="order-card__tags">
                            <view v-for="tag in item.tags" :key="tag.text" class="order-card__tag-wrap">
                                <image
                                    v-if="getTagImage(tag.text)"
                                    class="order-card__tag-icon"
                                    :src="getTagImage(tag.text)"
                                    mode="widthFix"
                                ></image>
                                <text v-else class="order-card__tag" :class="tag.type ? 'order-card__tag--' + tag.type : ''">{{ tag.text }}</text>
                            </view>
                        </view>
                        <text v-if="activeTab === 'hall'" class="order-card__extra">含加急¥{{ item.extra }}</text>
                    </view>
                    <view class="order-card__route">
                        <view class="order-card__route-side">
                            <text class="order-card__distance-top">{{ item.distanceTop }}</text>
                            <view class="order-card__line"></view>
                            <text class="order-card__distance-bottom">{{ item.distanceBottom }}</text>
                        </view>
                        <view class="order-card__route-main">
                            <view class="order-card__route-item">
                                <view class="order-card__route-texts">
                                    <text class="order-card__route-title">{{ item.fromName }}</text>
                                    <text class="order-card__route-desc">{{ item.fromAddress }}</text>
                                </view>
                                <image src="/static/image/ic_daohang@2x.png" mode="widthFix" class="order-card__nav"></image>
                            </view>
                            <view class="order-card__route-item order-card__route-item--destination">
                                <view class="order-card__route-texts">
                                    <text class="order-card__route-title">{{ item.toName }}</text>
                                    <text class="order-card__route-desc">{{ item.toAddress }}</text>
                                </view>
                                <image src="/static/image/ic_daohang@2x.png" mode="widthFix" class="order-card__nav"></image>
                            </view>
                        </view>
                    </view>
                    <view class="order-card__goods">
                        <text class="order-card__goods-text">{{ item.goods }}</text>
                        <text class="order-card__goods-arrow">⌄</text>
                    </view>
                    <view class="order-card__actions" :class="'order-card__actions--' + activeTab">
                        <template v-if="activeTab === 'pickup'">
                            <view class="order-card__icon-actions">
                                <view class="order-card__icon-action" @click.stop="show = true">
                                <image class="order-card__action-icon" src="/static/image/ic_cancle@2x.png" mode="aspectFit"></image>
                                    <text class="order-card__action-text">取消</text>
                                </view>
                                <view class="order-card__icon-action" @click.stop>
                                    <image class="order-card__action-icon" src="/static/image/ic_call@2x.png" mode="aspectFit"></image>
                                    <text class="order-card__action-text">联系</text>
                                </view>
                            </view>
                            <button class="order-card__button order-card__button--code" hover-class="order-card__button--hover" @click.stop="show1 = true">取货码</button>
                        </template>
                        <template v-else-if="activeTab === 'delivering'">
                            <view class="order-card__icon-actions order-card__icon-actions--single">
                                <view class="order-card__icon-action" @click.stop>
                                    <image class="order-card__action-icon" src="/static/image/ic_call@2x.png" mode="aspectFit"></image>
                                    <text class="order-card__action-text">联系</text>
                                </view>
                            </view>
                            <button class="order-card__button order-card__button--code" hover-class="order-card__button--hover" @click.stop>存件码</button>
                        </template>
                        <button v-else class="order-card__button" hover-class="order-card__button--hover" @click.stop="openDetailPopup(item)">立即抢单</button>
                    </view>
                </view>
            </view>
            <view v-else class="hall-page__empty">
                <image class="hall-page__empty-icon" src="/static/image/default_nodata_grey@2x.png" mode="aspectFit"></image>
            </view>
        </scroll-view>
        <!-- å–消订单 -->
        <u-modal
            :show="show"
            showCancelButton
            @cancel="show = false"
            cancelColor="#666666"
            confirmColor="#0055FF"
            title="取消订单确认">
            <view style="text-align: center;color: #333333;font-size: 28rpx;font-weight: 400;">
                æ‚¨ä»Šæ—¥è¿˜å¯å–消 X æ¬¡è®¢å•,次数用尽后今日将无法接单,是否确认取消?
            </view>
        </u-modal>
        <!-- å–货码 -->
        <u-popup :show="show1" round="20" mode="bottom">
            <view class="qrcode">
                <view class="qrcode-title">
                    <image src="/static/image/ic_close@2x.png" mode="widthFix" style="opacity: 0;"></image>
                    <text>取货码</text>
                    <image src="/static/image/ic_close@2x.png" mode="widthFix" @click="show1 = false"></image>
                </view>
                <view class="qrcode-image">
                    <image src="/static/logo.png" mode="widthFix"></image>
                </view>
                <view class="qrcode-btn" hover-class="qrcode-btn--hover" @click="show1 = false">关闭</view>
            </view>
        </u-popup>
        <!-- è®¢å•详情 -->
        <u-popup :show="showOrderDetail" round="20" mode="bottom" :overlayStyle="{ background: 'rgba(0, 0, 0, 0.32)' }" @close="showOrderDetail = false">
            <view class="order-detail" :style="{ height: 'calc(100vh - ' + statusBarHeight + 'px)' }">
                <view v-if="isStatusDetail" class="order-detail__map-section">
                    <view class="order-detail__map">
                        <view class="order-detail__map-placeholder"></view>
                        <view class="order-detail__map-bubble">{{ detailMap.tips }}</view>
                    </view>
                    <view class="order-detail__status-bar">
                        <view class="order-detail__status-left">
                            <image class="order-detail__status-icon" mode="aspectFit"></image>
                            <text class="order-detail__status-name">{{ detailOrder.statusText }}</text>
                        </view>
                        <view class="order-detail__status-right">
                            <text v-if="detailOrder.showCancelTag" class="order-detail__cancel-tag">取消订单</text>
                            <text class="order-detail__status-no">#{{ detailOrder.serialNo }}</text>
                        </view>
                    </view>
                </view>
                <scroll-view class="order-detail__scroll" scroll-y>
                    <view class="order-detail__content">
                        <view class="order-detail__head">
                            <view class="order-detail__time-wrap">
                                <text class="order-detail__time">{{ detailOrder.time }}</text>
                                <text class="order-detail__time-sub">送达</text>
                            </view>
                            <view class="order-detail__price-wrap">
                                <text class="order-detail__price">{{ detailOrder.price }}</text>
                                <text class="order-detail__extra">含加急¥{{ detailOrder.extra }}</text>
                            </view>
                        </view>
                        <view v-if="isStatusDetail" class="order-detail__qrcode-section">
                            <view class="order-detail__qrcode-box">
                                <image class="order-detail__qrcode-image" src="/static/logo.png" mode="aspectFit"></image>
                            </view>
                            <text class="order-detail__qrcode-value">{{ detailOrder.qrcodeValue }}</text>
                            <text class="order-detail__qrcode-label">{{ detailOrder.qrcodeLabel }}</text>
                        </view>
                        <view class="order-detail__tags">
                            <view v-for="tag in detailOrder.tags" :key="tag.text" class="order-detail__tag-wrap">
                                <image
                                    v-if="getTagImage(tag.text)"
                                    class="order-detail__tag-icon"
                                    :src="getTagImage(tag.text)"
                                    mode="widthFix"
                                ></image>
                                <text v-else class="order-detail__tag" :class="tag.type ? 'order-detail__tag--' + tag.type : ''">{{ tag.text }}</text>
                            </view>
                        </view>
                        <view class="order-detail__route">
                            <view class="order-detail__route-side">
                                <text class="order-detail__distance-top">{{ detailOrder.distanceTop }}</text>
                                <view class="order-detail__line"></view>
                                <text class="order-detail__distance-bottom">{{ detailOrder.distanceBottom }}</text>
                            </view>
                            <view class="order-detail__route-main">
                                <view class="order-detail__route-item">
                                    <view class="order-detail__route-texts">
                                        <text class="order-detail__route-title">{{ detailOrder.fromName }}</text>
                                        <text class="order-detail__route-desc">{{ detailOrder.fromAddress }}</text>
                                    </view>
                                    <view class="order-detail__route-actions">
                                        <image class="order-detail__route-icon" src="/static/image/ic_c1all@2x.png" mode="aspectFit"></image>
                                        <image class="order-detail__route-icon" src="/static/image/ic_daohang@2x.png" mode="aspectFit"></image>
                                    </view>
                                </view>
                                <view class="order-detail__route-item order-detail__route-item--destination">
                                    <view class="order-detail__route-texts">
                                        <text class="order-detail__route-title">{{ detailOrder.toName }}</text>
                                        <text class="order-detail__route-desc">{{ detailOrder.toAddress }}</text>
                                    </view>
                                    <view class="order-detail__route-actions">
                                        <image class="order-detail__route-icon order-detail__route-icon--phone" src="/static/image/ic_c1all@2x.png" mode="aspectFit"></image>
                                        <image class="order-detail__route-icon" src="/static/image/ic_daohang@2x.png" mode="aspectFit"></image>
                                    </view>
                                </view>
                            </view>
                        </view>
                        <view class="order-detail__section">
                            <text class="order-detail__section-title">客户信息</text>
                            <view class="order-detail__customer">
                                <text class="order-detail__customer-text">{{ detailOrder.customer.name }}(手机号{{ detailOrder.customer.phone }})</text>
                                <image class="order-detail__customer-icon" src="/static/image/ic_c1all@2x.png" mode="aspectFit"></image>
                            </view>
                        </view>
                        <view class="order-detail__section">
                            <text class="order-detail__section-title">物品清单(共{{ detailOrder.goodsList.length }}件)</text>
                            <view class="order-detail__goods-list">
                                <view v-for="goods in detailOrder.goodsList" :key="goods.name" class="order-detail__goods-item">
                                    <text class="order-detail__goods-name">{{ goods.name }}</text>
                                    <text class="order-detail__goods-count">x{{ goods.count }}</text>
                                </view>
                            </view>
                        </view>
                        <view class="order-detail__section order-detail__section--photos">
                            <text class="order-detail__section-title">物品信息</text>
                            <text class="order-detail__goods-category">{{ detailOrder.goodsCategory }}</text>
                            <view class="order-detail__photos">
                                <view v-for="(photo, index) in detailOrder.photos" :key="index" class="order-detail__photo-item">
                                    <image class="order-detail__photo" :src="photo" mode="aspectFill"></image>
                                </view>
                            </view>
                        </view>
                    </view>
                </scroll-view>
                <view class="order-detail__footer">
                    <view class="order-detail__cancel" @click="showOrderDetail = false">
                        <image class="order-detail__cancel-icon" src="/static/image/ic_close2@2x.png" mode="aspectFit"></image>
                    </view>
                    <button v-if="!isStatusDetail" class="order-detail__confirm" hover-class="order-detail__confirm--hover">确认抢单</button>
                    <button v-else class="order-detail__confirm order-detail__confirm--status" hover-class="order-detail__confirm--hover" @click="handleStatusAction">
                        <image class="order-detail__confirm-icon" src="/static/image/ic_photo@2x.png" mode="aspectFit"></image>
                        <text>{{ detailPopupType === 'pickup' ? '拍照取货' : '拍照送达' }}</text>
                    </button>
                </view>
            </view>
        </u-popup>
        <u-popup :show="showPhotoDeliverPopup" round="20" mode="bottom">
            <view class="photo-deliver">
                <view class="photo-deliver__header">
                    <image class="photo-deliver__close-placeholder" mode="aspectFit"></image>
                    <text class="photo-deliver__title">拍照送达</text>
                    <image class="photo-deliver__close" mode="aspectFit" @click="showPhotoDeliverPopup = false"></image>
                </view>
                <view class="photo-deliver__section">
                    <view class="photo-deliver__label-row">
                        <text class="photo-deliver__label">拍摄送达照片</text>
                        <text class="photo-deliver__required">*</text>
                        <text class="photo-deliver__hint">最多3张照片</text>
                    </view>
                    <view class="photo-deliver__photos">
                        <view class="photo-deliver__upload-card">
                            <image class="photo-deliver__upload-icon" mode="aspectFit"></image>
                            <text class="photo-deliver__upload-text">点击拍照</text>
                        </view>
                        <view class="photo-deliver__preview-card">
                            <image class="photo-deliver__preview-image" mode="aspectFill"></image>
                            <view class="photo-deliver__preview-mask">
                                <text class="photo-deliver__preview-delete">删除</text>
                            </view>
                        </view>
                    </view>
                </view>
                <view class="photo-deliver__section photo-deliver__section--remark">
                    <text class="photo-deliver__remark-title">备注信息</text>
                    <textarea class="photo-deliver__textarea" maxlength="200" placeholder="请输入" placeholder-style="color: #c7cbd3;" />
                </view>
                <button class="photo-deliver__submit" hover-class="photo-deliver__submit--hover" @click="showPhotoDeliverPopup = false">确认送达</button>
            </view>
        </u-popup>
    </view>
</template>
@@ -8,7 +369,315 @@
    export default {
        data() {
            return {
                tts: null // åŽŸç”ŸTTS对象
                tts: null,
                show: false,
                show1: false,
                showPhotoDeliverPopup: false,
                showOrderDetail: false,
                detailPopupType: 'hall',
                routeInfo: null,
                statusBarHeight: 0,
                headerHeight: 0,
                tabbarHeight: 0,
                scrollHeight: 0,
                showFilterPopup: false,
                activeTab: 'hall',
                filterSections: [
                    { key: 'sort', title: '排序', options: ['综合排序', '离我最近'] },
                    { key: 'level', title: '物品等级', options: ['不限', '普通物品', '贵重物品', '大件物品', '特殊物品', '其他物品'] },
                    { key: 'distance', title: '位置范围', options: ['不限', '500m', '1km', '2km', '3km', '4km', '5km', '6km', '7km'] }
                ],
                selectedFilters: {
                    sort: '综合排序',
                    level: '不限',
                    distance: '不限'
                },
                detailOrder: {
                    time: '45分钟内',
                    price: 'Â¥20.5',
                    extra: '3.0',
                    serialNo: 1,
                    statusText: '抢单大厅',
                    qrcodeValue: '767889',
                    qrcodeLabel: '取货码',
                    mapTips: '',
                    showCancelTag: false,
                    startPoint: {
                        latitude: 31.8269,
                        longitude: 117.2334
                    },
                    endPoint: {
                        latitude: 31.8435,
                        longitude: 117.2852
                    },
                    tags: [
                        { text: '标速达', type: 'blue' },
                        { text: '贵重物品', type: 'orange' }
                    ],
                    distanceTop: '349m',
                    distanceBottom: '12.5km',
                    fromName: '中铁快运南站旗舰店',
                    fromAddress: '莲花路200号莲花产业园F栋401',
                    toName: '佳苑巴黎都市3期10栋301室',
                    toAddress: '洞庭湖路与湖北路交叉口西150ç±³',
                    customer: {
                        name: '刘先生',
                        phone: '2878'
                    },
                    goodsList: [
                        { name: '大件行李', count: 1 },
                        { name: '中件行李', count: 2 },
                        { name: '小件行李', count: 3 },
                        { name: '背包', count: 2 }
                    ],
                    goodsCategory: '文件',
                    photos: ['/static/logo.png', '/static/logo.png', '/static/logo.png']
                },
                stats: [
                    { value: '4.2', label: '服务分' },
                    { value: '234.3', label: '今日预计佣金' },
                    { value: '13', label: '今日接单' }
                ],
                tabs: [
                    { label: '抢单大厅', value: 'hall' },
                    { label: '待取货', value: 'pickup', count: 2 },
                    { label: '配送中', value: 'delivering', count: 2 }
                ],
                orderList: [
                    {
                        id: 1,
                        time: '45分钟内',
                        price: 'Â¥20.5',
                        extra: '3.0',
                        startPoint: {
                            latitude: 31.829512,
                            longitude: 117.239211
                        },
                        endPoint: {
                            latitude: 31.841268,
                            longitude: 117.278695
                        },
                        tags: [
                            { text: '极速达', type: 'blue' },
                            { text: '贵重物品', type: 'orange' }
                        ],
                        distanceTop: '349m',
                        distanceBottom: '12.5km',
                        fromName: '中铁快运南站旗舰店',
                        fromAddress: '莲花路200号莲花产业园F栋401',
                        toName: '佳苑巴黎都市3期10栋301室',
                        toAddress: '洞庭湖路与湖北路交叉口西150ç±³',
                        goods: '大件行李*1、中件行李*2、小件行李*3、背包*1'
                    },
                    {
                        id: 2,
                        time: '45分钟内',
                        price: 'Â¥20.5',
                        extra: '3.0',
                        startPoint: {
                            latitude: 31.827106,
                            longitude: 117.232884
                        },
                        endPoint: {
                            latitude: 31.847331,
                            longitude: 117.289762
                        },
                        tags: [
                            { text: '极速达', type: 'red' },
                            { text: '大件物品', type: 'blue-light' }
                        ],
                        distanceTop: '349m',
                        distanceBottom: '12.5km',
                        fromName: '中铁快运南站旗舰店(合肥南站北广场',
                        fromAddress: '莲花路200号莲花产业园F栋401',
                        toName: '佳苑巴黎都市3期10栋301室',
                        toAddress: '洞庭湖路与湖北路交叉口西150ç±³',
                        goods: '大件行李*1'
                    },
                    {
                        id: 3,
                        time: '45分钟内',
                        price: 'Â¥20.5',
                        extra: '3.0',
                        startPoint: {
                            latitude: 31.823761,
                            longitude: 117.228947
                        },
                        endPoint: {
                            latitude: 31.838473,
                            longitude: 117.272513
                        },
                        tags: [
                            { text: '极速达', type: 'red' },
                            { text: '大件物品', type: 'blue-light' }
                        ],
                        distanceTop: '349m',
                        distanceBottom: '12.5km',
                        fromName: '中铁快运南站旗舰店(合肥南站北广场',
                        fromAddress: '莲花路200号莲花产业园F栋401',
                        toName: '佳苑巴黎都市3期10栋301室',
                        toAddress: '洞庭湖路与湖北路交叉口西150ç±³',
                        goods: '大件行李*1'
                    }
                ],
                pickupOrderList: [
                    {
                        id: 101,
                        serialNo: 1,
                        statusText: '待取货',
                        qrcodeValue: '767889',
                        qrcodeLabel: '取货码',
                        mapTips: '',
                        showCancelTag: true,
                        startPoint: {
                            latitude: 31.829512,
                            longitude: 117.239211
                        },
                        endPoint: {
                            latitude: 31.841268,
                            longitude: 117.278695
                        },
                        time: '45分钟内',
                        price: 'Â¥20.5',
                        extra: '3.0',
                        tags: [
                            { text: '标速达', type: 'blue' },
                            { text: '贵重物品', type: 'orange' }
                        ],
                        distanceTop: '349m',
                        distanceBottom: '12.5km',
                        fromName: '中铁快运南站旗舰店',
                        fromAddress: '莲花路200号莲花产业园F栋401',
                        toName: '小铁无忧存',
                        toAddress: '洞庭湖路与湖北路交叉口西150ç±³',
                        goods: '大件行李*1、中件行李*2、小件行李*3、背包*1'
                    }
                ],
                deliveringOrderList: [
                    {
                        id: 201,
                        serialNo: 1,
                        statusText: '配送中',
                        qrcodeValue: '767889',
                        qrcodeLabel: '存件码',
                        mapTips: '',
                        showCancelTag: false,
                        startPoint: {
                            latitude: 31.827106,
                            longitude: 117.232884
                        },
                        endPoint: {
                            latitude: 31.847331,
                            longitude: 117.289762
                        },
                        time: '45分钟内',
                        price: 'Â¥20.5',
                        extra: '3.0',
                        tags: [
                            { text: '标速达', type: 'blue' },
                            { text: '贵重物品', type: 'orange' }
                        ],
                        distanceTop: '349m',
                        distanceBottom: '12.5km',
                        fromName: '中铁快运南站旗舰店',
                        fromAddress: '莲花路200号莲花产业园F栋401',
                        toName: '小铁无忧存',
                        toAddress: '洞庭湖路与湖北路交叉口西150ç±³',
                        goods: '大件行李*1、中件行李*2、小件行李*3、背包*1'
                    }
                ]
            }
        },
        onLoad() {
            const systemInfo = uni.getSystemInfoSync()
            const safeBottom = systemInfo.safeAreaInsets ? systemInfo.safeAreaInsets.bottom || 0 : 0
            const windowHeight = systemInfo.windowHeight || 0
            this.statusBarHeight = systemInfo.statusBarHeight || 0
            this.headerHeight = this.statusBarHeight + uni.upx2px(308)
            this.tabbarHeight = uni.upx2px(100) + safeBottom
            this.scrollHeight = Math.max(windowHeight - this.headerHeight, 0)
        },
        computed: {
            isStatusDetail() {
                return this.detailPopupType === 'pickup' || this.detailPopupType === 'delivering'
            },
            detailMap() {
                const fallbackPoint = {
                    latitude: 31.8269,
                    longitude: 117.2334
                }
                const startPoint = this.detailOrder.startPoint || fallbackPoint
                const endPoint = this.detailOrder.endPoint || fallbackPoint
                const routePoints = this.routeInfo && this.routeInfo.points && this.routeInfo.points.length ? this.routeInfo.points : []
                const center = {
                    latitude: (startPoint.latitude + endPoint.latitude) / 2,
                    longitude: (startPoint.longitude + endPoint.longitude) / 2
                }
                const distanceKm = this.routeInfo && this.routeInfo.distanceKm ? this.routeInfo.distanceKm : 0
                const durationMinutes = this.routeInfo && this.routeInfo.durationMinutes ? this.routeInfo.durationMinutes : 0
                const tips = this.detailOrder.mapTips || (distanceKm ? `剩余${distanceKm.toFixed(1)}km,约${durationMinutes}分钟` : '路线规划中...')
                return {
                    center,
                    markers: [
                        {
                            id: 1,
                            latitude: startPoint.latitude,
                            longitude: startPoint.longitude,
                            iconPath: '/static/image/map_marker_start.svg',
                            width: 32,
                            height: 38,
                            anchor: {
                                x: 0.5,
                                y: 1
                            }
                        },
                        {
                            id: 2,
                            latitude: endPoint.latitude,
                            longitude: endPoint.longitude,
                            iconPath: '/static/image/map_marker_end.svg',
                            width: 32,
                            height: 38,
                            anchor: {
                                x: 0.5,
                                y: 1
                            }
                        }
                    ],
                    polyline: [
                        ...(routePoints.length ? [{
                            points: routePoints,
                            color: '#2A7FFF',
                            width: 8,
                            dottedLine: false,
                            arrowLine: true
                        }] : [])
                    ],
                    includePoints: routePoints.length ? routePoints : [startPoint, endPoint],
                    scale: 12,
                    tips
                }
            },
            currentOrderList() {
                const orderMap = {
                    hall: this.orderList,
                    pickup: this.pickupOrderList,
                    delivering: this.deliveringOrderList
                }
                return orderMap[this.activeTab] || []
            },
            bodyStyle() {
                return {
                    marginTop: this.headerHeight + 'px',
                    height: this.scrollHeight + 'px'
                }
            }
        },
@@ -17,7 +686,193 @@
        },
        methods: {
            // ========== åˆå§‹åŒ–安卓原生语音 ==========
            calculateDistance(startPoint, endPoint) {
                if (!startPoint || !endPoint) {
                    return 0
                }
                const toRad = (value) => value * Math.PI / 180
                const earthRadius = 6371
                const deltaLat = toRad(endPoint.latitude - startPoint.latitude)
                const deltaLng = toRad(endPoint.longitude - startPoint.longitude)
                const lat1 = toRad(startPoint.latitude)
                const lat2 = toRad(endPoint.latitude)
                const a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(deltaLng / 2) * Math.sin(deltaLng / 2)
                const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
                return earthRadius * c
            },
            estimateDuration(distanceKm) {
                if (!distanceKm) {
                    return 1
                }
                const averageSpeedKmPerHour = 35
                return Math.max(1, Math.round(distanceKm / averageSpeedKmPerHour * 60))
            },
            handleStatusAction() {
                if (this.detailPopupType === 'delivering') {
                    this.showOrderDetail = false
                    this.showPhotoDeliverPopup = true
                }
            },
            openDetailPopup(item) {
                this.detailPopupType = this.activeTab
                this.routeInfo = null
                this.detailOrder = {
                    ...this.detailOrder,
                    ...item,
                    customer: item.customer || this.detailOrder.customer,
                    goodsList: item.goodsList || this.detailOrder.goodsList,
                    goodsCategory: item.goodsCategory || this.detailOrder.goodsCategory,
                    photos: item.photos || this.detailOrder.photos
                }
                this.showOrderDetail = true
                if (this.activeTab === 'pickup' || this.activeTab === 'delivering') {
                    this.fetchDrivingRoute(this.detailOrder)
                }
            },
            fetchDrivingRoute(order) {
                if (!order || !order.startPoint || !order.endPoint) {
                    return
                }
                const origin = `${order.startPoint.longitude},${order.startPoint.latitude}`
                const destination = `${order.endPoint.longitude},${order.endPoint.latitude}`
                uni.request({
                    url: 'https://restapi.amap.com/v3/direction/driving',
                    method: 'GET',
                    data: {
                        key: 'e4d46c87adf151dca20060317592b1b6',
                        origin,
                        destination,
                        extensions: 'all',
                        strategy: 0,
                        output: 'json'
                    },
                    success: (response) => {
                        const path = response.data && response.data.route && response.data.route.paths && response.data.route.paths[0]
                        if (!path) {
                            this.routeInfo = this.buildMockRouteInfo(order.startPoint, order.endPoint)
                            return
                        }
                        const points = this.parseRoutePoints(path.steps || [], order.startPoint, order.endPoint)
                        const distanceKm = Number(path.distance || 0) / 1000
                        const durationMinutes = Math.max(1, Math.round(Number(path.duration || 0) / 60))
                        this.routeInfo = {
                            points,
                            distanceKm: distanceKm || this.calculateDistance(order.startPoint, order.endPoint),
                            durationMinutes
                        }
                    },
                    fail: () => {
                        this.routeInfo = this.buildMockRouteInfo(order.startPoint, order.endPoint)
                    }
                })
            },
            buildMockRouteInfo(startPoint, endPoint) {
                const middleLatitude = (startPoint.latitude + endPoint.latitude) / 2
                const middleLongitude = (startPoint.longitude + endPoint.longitude) / 2
                const points = [
                    startPoint,
                    {
                        latitude: startPoint.latitude + (middleLatitude - startPoint.latitude) * 0.65,
                        longitude: startPoint.longitude + 0.008
                    },
                    {
                        latitude: middleLatitude + 0.004,
                        longitude: middleLongitude + 0.012
                    },
                    {
                        latitude: endPoint.latitude - 0.003,
                        longitude: endPoint.longitude - 0.008
                    },
                    endPoint
                ]
                const distanceKm = this.calculatePathDistance(points)
                const durationMinutes = this.estimateDuration(distanceKm)
                return {
                    points,
                    distanceKm,
                    durationMinutes
                }
            },
            parseRoutePoints(steps, startPoint, endPoint) {
                const points = []
                steps.forEach((step) => {
                    const polyline = step.polyline || ''
                    polyline.split(';').forEach((pointText) => {
                        const [longitude, latitude] = pointText.split(',').map(Number)
                        if (!Number.isNaN(latitude) && !Number.isNaN(longitude)) {
                            points.push({ latitude, longitude })
                        }
                    })
                })
                if (!points.length) {
                    return [startPoint, endPoint]
                }
                return points
            },
            calculatePathDistance(points) {
                if (!points || points.length < 2) {
                    return 0
                }
                let totalDistance = 0
                for (let index = 1; index < points.length; index += 1) {
                    totalDistance += this.calculateDistance(points[index - 1], points[index])
                }
                return totalDistance
            },
            toggleFilterPopup(show) {
                this.showFilterPopup = show
            },
            selectFilter(key, option) {
                this.selectedFilters = {
                    ...this.selectedFilters,
                    [key]: option
                }
            },
            resetFilters() {
                this.selectedFilters = {
                    sort: '综合排序',
                    level: '不限',
                    distance: '不限'
                }
            },
            confirmFilters() {
                this.showFilterPopup = false
            },
            getTagImage(tagText) {
                const tagImageMap = {
                    '极速达': '/static/image/ic_jisuda@2x.png',
                    '标速达': '/static/image/ic_biaosuda@2x.png'
                }
                return tagImageMap[tagText] || ''
            },
            initTTS() {
                if (uni.getSystemInfoSync().platform !== 'android') {
                    console.log('仅支持安卓')
@@ -44,7 +899,6 @@
                }
            },
            // ========== è¯­éŸ³æ’­æŠ¥ï¼ˆæ ¸å¿ƒæ–¹æ³•) ==========
            speak(text) {
                if (!this.tts) {
                    uni.showToast({
@@ -62,13 +916,11 @@
                }
            },
            // åœæ­¢æ’­æŠ¥
            stopSpeak() {
                if (this.tts) this.tts.stop()
            }
        },
        // é¡µé¢é”€æ¯æ—¶å…³é—­è¯­éŸ³
        onUnload() {
            if (this.tts) {
                this.tts.stop()
@@ -76,4 +928,1254 @@
            }
        }
    }
</script>
</script>
<style lang="scss" scoped>
    .hall-page {
        position: relative;
        height: 100vh;
        background: #f5f6f8;
        overflow: hidden;
        .order-detail-map-layer {
            position: fixed;
            left: 0;
            right: 0;
            height: 330rpx;
            z-index: 10081;
            overflow: hidden;
            border-top-left-radius: 28rpx;
            border-top-right-radius: 28rpx;
            &__map {
                width: 100%;
                height: 100%;
            }
        }
        .qrcode {
            padding: 36rpx 30rpx;
            box-sizing: border-box;
            .qrcode-title {
                width: 100%;
                display: flex;
                align-items: center;
                justify-content: space-between;
                image {
                    width: 28rpx;
                    height: 28rpx;
                }
                text {
                    font-weight: 600;
                    font-size: 32rpx;
                    color: #111111;
                }
            }
            .qrcode-image {
                width: 100%;
                display: flex;
                align-items: center;
                justify-content: center;
                margin-top: 60rpx;
                image {
                    width: 400rpx;
                    height: 400rpx;
                }
            }
            .qrcode-btn {
                width: 100%;
                height: 88rpx;
                line-height: 88rpx;
                text-align: center;
                background: #106EFA;
                border-radius: 50rpx;
                font-weight: bold;
                font-size: 32rpx;
                color: #FFFFFF;
                margin-top: 68rpx;
                &--hover {
                    opacity: 0.92;
                    transform: translateY(2rpx);
                }
            }
        }
        .photo-deliver {
            padding: 32rpx 28rpx calc(env(safe-area-inset-bottom) + 28rpx);
            background: #ffffff;
            box-sizing: border-box;
            border-top-left-radius: 20rpx;
            border-top-right-radius: 20rpx;
            overflow: hidden;
            &__header {
                display: flex;
                align-items: center;
                justify-content: space-between;
            }
            &__title {
                font-size: 34rpx;
                font-weight: 700;
                color: #111111;
            }
            &__close,
            &__close-placeholder {
                width: 36rpx;
                height: 36rpx;
                flex-shrink: 0;
            }
            &__close-placeholder {
                opacity: 0;
            }
            &__section {
                margin-top: 56rpx;
                &--remark {
                    margin-top: 46rpx;
                }
            }
            &__label-row {
                display: flex;
                align-items: center;
                flex-wrap: wrap;
            }
            &__label,
            &__remark-title {
                font-size: 28rpx;
                font-weight: 700;
                color: #23262d;
            }
            &__required {
                margin-left: 4rpx;
                font-size: 28rpx;
                font-weight: 700;
                color: #ff3b30;
            }
            &__hint {
                margin-left: 12rpx;
                font-size: 24rpx;
                color: #a8adb7;
            }
            &__photos {
                display: flex;
                gap: 18rpx;
                margin-top: 30rpx;
            }
            &__upload-card,
            &__preview-card {
                position: relative;
                width: 160rpx;
                height: 160rpx;
                border-radius: 8rpx;
                overflow: hidden;
            }
            &__upload-card {
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                border: 2rpx dashed #c9ced6;
                background: #ffffff;
                box-sizing: border-box;
            }
            &__upload-icon {
                width: 52rpx;
                height: 52rpx;
            }
            &__upload-text {
                margin-top: 14rpx;
                font-size: 26rpx;
                color: #9da3ae;
            }
            &__preview-card {
                background: #eef1f5;
            }
            &__preview-image {
                width: 100%;
                height: 100%;
            }
            &__preview-mask {
                position: absolute;
                left: 0;
                right: 0;
                bottom: 0;
                display: flex;
                justify-content: center;
                align-items: center;
                height: 48rpx;
                background: rgba(0, 0, 0, 0.46);
            }
            &__preview-delete {
                font-size: 26rpx;
                color: #ffffff;
            }
            &__textarea {
                width: 100%;
                height: 110rpx;
                margin-top: 24rpx;
                padding: 28rpx 24rpx;
                border-radius: 12rpx;
                background: #f7f8fa;
                box-sizing: border-box;
                font-size: 30rpx;
                color: #2c3139;
            }
            &__submit {
                width: 100%;
                height: 88rpx;
                line-height: 88rpx;
                margin-top: 86rpx;
                border-radius: 50rpx;
                background: #106efa;
                font-size: 32rpx;
                font-weight: 700;
                color: #ffffff;
                border: 0;
                padding: 0;
                &::after {
                    border: 0;
                }
                &--hover {
                    opacity: 0.92;
                }
            }
        }
        .order-detail {
            display: flex;
            flex-direction: column;
            background: #ffffff;
            border-top-left-radius: 28rpx;
            border-top-right-radius: 28rpx;
            overflow: hidden;
            &__scroll {
                flex: 1;
                min-height: 0;
            }
            &__map-section {
                background: #ffffff;
            }
            &__map {
                position: relative;
                height: 330rpx;
                background: #eef5ff;
                overflow: hidden;
            }
            &__map-view {
                width: 100%;
                height: 100%;
            }
            &__map-placeholder {
                width: 100%;
                height: 100%;
            }
            &__map-bubble {
                position: absolute;
                left: 26rpx;
                bottom: 44rpx;
                padding: 12rpx 18rpx;
                border-radius: 12rpx;
                background: rgba(255, 255, 255, 0.96);
                box-shadow: 0 10rpx 20rpx rgba(33, 92, 182, 0.08);
                font-size: 26rpx;
                font-weight: 500;
                color: #2f6ff2;
            }
            &__status-bar {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 0 24rpx;
                height: 92rpx;
                background: #d9e8ff;
            }
            &__status-left,
            &__status-right {
                display: flex;
                align-items: center;
            }
            &__status-icon {
                width: 28rpx;
                height: 28rpx;
                margin-right: 12rpx;
                border-radius: 6rpx;
                background: #7ea7ef;
            }
            &__status-name,
            &__status-no {
                font-size: 34rpx;
                font-weight: 700;
                color: #2b3139;
            }
            &__cancel-tag {
                padding: 8rpx 16rpx;
                margin-right: 18rpx;
                border: 2rpx solid #6ea6ff;
                border-radius: 999rpx;
                font-size: 24rpx;
                color: #1d73ff;
                background: rgba(255, 255, 255, 0.72);
            }
            &__content {
                padding: 28rpx 24rpx 36rpx;
            }
            &__head {
                display: flex;
                justify-content: space-between;
                align-items: flex-start;
            }
            &__time-wrap {
                display: flex;
                align-items: center;
            }
            &__time {
                font-size: 42rpx;
                font-weight: 700;
                color: #ff8d27;
            }
            &__time-sub {
                margin-left: 8rpx;
                font-size: 28rpx;
                color: #a4a9b2;
            }
            &__price-wrap {
                display: flex;
                flex-direction: column;
                align-items: flex-end;
            }
            &__price {
                font-size: 44rpx;
                font-weight: 700;
                color: #ff3b30;
            }
            &__extra {
                margin-top: 6rpx;
                font-size: 24rpx;
                color: #a0a5af;
            }
            &__tags {
                display: flex;
                align-items: center;
                flex-wrap: wrap;
                gap: 10rpx;
                margin-top: 14rpx;
            }
            &__tag-wrap {
                display: flex;
                align-items: center;
            }
            &__tag-icon {
                width: 108rpx;
                height: 40rpx;
            }
            &__tag {
                padding: 4rpx 10rpx;
                border-radius: 8rpx;
                font-size: 22rpx;
                line-height: 1.2;
                border: 1rpx solid #2473f5;
                color: #2473f5;
                &--orange {
                    border-color: #ff9c45;
                    background: #ff9c45;
                    color: #ffffff;
                }
            }
            &__route {
                display: flex;
                margin-top: 20rpx;
                padding-bottom: 26rpx;
                border-bottom: 1rpx solid #edf0f3;
            }
            &__route-side {
                width: 64rpx;
                display: flex;
                flex-direction: column;
                align-items: center;
                flex-shrink: 0;
            }
            &__distance-top,
            &__distance-bottom {
                font-size: 22rpx;
                font-weight: 600;
                color: #555b66;
                text-align: center;
            }
            &__line {
                position: relative;
                width: 4rpx;
                flex: 1;
                min-height: 92rpx;
                margin: 10rpx 0;
                border-radius: 999rpx;
                background: #d8dbe1;
                &::before,
                &::after {
                    content: '';
                    position: absolute;
                    left: 50%;
                    transform: translateX(-50%);
                    width: 14rpx;
                    height: 14rpx;
                    border-radius: 50%;
                    background: #6a6f79;
                }
                &::before {
                    top: -4rpx;
                }
                &::after {
                    bottom: -4rpx;
                }
            }
            &__route-main {
                flex: 1;
            }
            &__route-item {
                display: flex;
                justify-content: space-between;
                align-items: flex-start;
                gap: 18rpx;
                &--destination {
                    margin-top: 24rpx;
                }
            }
            &__route-texts {
                flex: 1;
                min-width: 0;
            }
            &__route-title {
                display: block;
                font-size: 40rpx;
                font-weight: 700;
                color: #2d3139;
                line-height: 1.3;
            }
            &__route-desc {
                display: block;
                margin-top: 8rpx;
                font-size: 28rpx;
                color: #9ea4ae;
                line-height: 1.4;
            }
            &__route-actions {
                display: flex;
                align-items: center;
                gap: 12rpx;
                flex-shrink: 0;
            }
            &__route-icon,
            &__customer-icon {
                width: 48rpx;
                height: 48rpx;
                border: 2rpx dashed #c9ced6;
                border-radius: 8rpx;
                background: #f7f8fa;
            }
            &__cancel-icon {
                width: 40rpx;
                height: 40rpx;
            }
            &__qrcode-section {
                display: flex;
                flex-direction: column;
                align-items: center;
                padding: 34rpx 0 8rpx;
                border-bottom: 1rpx solid #edf0f3;
            }
            &__qrcode-box {
                width: 260rpx;
                height: 260rpx;
                padding: 16rpx;
                border: 2rpx solid #edf0f3;
                border-radius: 12rpx;
                box-sizing: border-box;
            }
            &__qrcode-image {
                width: 100%;
                height: 100%;
            }
            &__qrcode-value {
                margin-top: 18rpx;
                font-size: 44rpx;
                font-weight: 700;
                color: #31363f;
            }
            &__qrcode-label {
                margin-top: 8rpx;
                font-size: 26rpx;
                color: #b0b4bc;
            }
            &__section {
                padding: 28rpx 0;
                border-bottom: 1rpx solid #edf0f3;
                &--photos {
                    border-bottom: 0;
                }
            }
            &__section-title {
                display: block;
                font-size: 32rpx;
                font-weight: 700;
                color: #2b3139;
            }
            &__customer {
                margin-top: 28rpx;
                display: flex;
                justify-content: space-between;
                align-items: center;
                gap: 20rpx;
            }
            &__customer-text {
                flex: 1;
                font-size: 32rpx;
                color: #41464f;
                line-height: 1.5;
            }
            &__goods-list {
                margin-top: 22rpx;
            }
            &__goods-item {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 10rpx 0;
            }
            &__goods-name {
                font-size: 32rpx;
                color: #41464f;
            }
            &__goods-count {
                font-size: 30rpx;
                color: #a1a6af;
            }
            &__goods-category {
                display: block;
                margin-top: 24rpx;
                font-size: 32rpx;
                color: #41464f;
            }
            &__photos {
                display: flex;
                gap: 16rpx;
                margin-top: 22rpx;
            }
            &__photo-item {
                width: 120rpx;
                height: 120rpx;
                border-radius: 12rpx;
                overflow: hidden;
                background: #f3f5f8;
            }
            &__photo {
                width: 100%;
                height: 100%;
            }
            &__footer {
                display: flex;
                align-items: center;
                gap: 18rpx;
                padding: 18rpx 24rpx calc(env(safe-area-inset-bottom) + 18rpx);
                background: #ffffff;
                box-shadow: 0 -8rpx 24rpx rgba(16, 27, 49, 0.04);
            }
            &__cancel {
                width: 176rpx;
                height: 100rpx;
                border-radius: 50rpx;
                background: #E5E5E5;
                display: flex;
                justify-content: center;
                align-items: center;
                flex-shrink: 0;
            }
            &__confirm {
                flex: 1;
                display: flex;
                justify-content: center;
                align-items: center;
                gap: 14rpx;
                height: 100rpx;
                line-height: 100rpx;
                border-radius: 50rpx;
                background: #106EFA;
                font-size: 36rpx;
                font-weight: 600;
                color: #ffffff;
                border: 0;
                padding: 0;
                &::after {
                    border: 0;
                }
                &--hover {
                    opacity: 0.92;
                }
            }
            &__confirm-icon {
                width: 44rpx;
                height: 44rpx;
                flex-shrink: 0;
            }
        }
        &__header {
            position: fixed;
            left: 0;
            top: 0;
            right: 0;
            z-index: 10;
            background: linear-gradient(180deg, #2473f5 0%, #1e6fef 100%);
            box-shadow: 0 12rpx 24rpx rgba(36, 115, 245, 0.08);
        }
        &__user-row {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 20rpx 24rpx 0;
        }
        &__user {
            display: flex;
            align-items: center;
            gap: 14rpx;
        }
        &__avatar {
            width: 42rpx;
            height: 42rpx;
            border-radius: 50%;
            border: 2rpx solid rgba(255, 255, 255, 0.7);
        }
        &__name {
            font-size: 28rpx;
            font-weight: 500;
            color: #ffffff;
        }
        &__status {
            display: flex;
            align-items: center;
            padding: 10rpx 16rpx;
            border-radius: 999rpx;
            background: rgba(255, 255, 255, 0.16);
            backdrop-filter: blur(10rpx);
        }
        &__status-dot {
            width: 14rpx;
            height: 14rpx;
            border-radius: 50%;
            background: #32d74b;
            margin-right: 10rpx;
        }
        &__status-text,
        &__status-arrow {
            font-size: 24rpx;
            color: #ffffff;
        }
        &__status-arrow {
            font-size: 18rpx;
            margin-left: 8rpx;
        }
        &__stats {
            display: flex;
            justify-content: space-between;
            padding: 34rpx 36rpx 28rpx;
        }
        &__stat-item {
            display: flex;
            flex-direction: column;
            align-items: center;
            min-width: 160rpx;
        }
        &__stat-value {
            font-size: 52rpx;
            line-height: 1;
            font-weight: 700;
            color: #ffffff;
        }
        &__stat-label {
            margin-top: 12rpx;
            font-size: 26rpx;
            color: rgba(255, 255, 255, 0.86);
        }
        &__tabs {
            display: flex;
            align-items: center;
            height: 88rpx;
            padding: 0 18rpx;
            background: #ffffff;
        }
        &__tab {
            position: relative;
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100%;
            padding: 0 18rpx;
            font-size: 32rpx;
            color: #8b9099;
        }
        &__tab--active {
            color: #242933;
            font-weight: 700;
        }
        &__tab-text {
            font-size: inherit;
            color: inherit;
        }
        &__tab-count {
            margin-left: 6rpx;
            font-size: 28rpx;
            color: #8b9099;
        }
        &__tab-line {
            position: absolute;
            left: 18rpx;
            right: 18rpx;
            bottom: 0;
            height: 5rpx;
            border-radius: 999rpx;
            background: #2473f5;
        }
        &__filter {
            margin-left: auto;
            display: flex;
            align-items: center;
            gap: 6rpx;
            padding-right: 10rpx;
        }
        &__filter-text {
            font-size: 28rpx;
            color: #9aa1ab;
            &--active {
                color: #106efa;
            }
        }
        &__filter-icon {
            width: 28rpx;
            height: 28rpx;
        }
        &__body {
            box-sizing: border-box;
            background-color: #F6F9FF;
        }
        &__list {
            padding: 22rpx 30rpx calc(22rpx + env(safe-area-inset-bottom)) 30rpx;
        }
        &__empty {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100%;
            padding-bottom: env(safe-area-inset-bottom);
            box-sizing: border-box;
        }
        &__empty-icon {
            width: 320rpx;
            height: 320rpx;
        }
    }
    .filter-popup {
        position: fixed;
        left: 0;
        right: 0;
        z-index: 20;
        background: rgba(0, 0, 0, 0.24);
        &__panel {
            height: 100%;
            padding: 22rpx 0 26rpx;
            background: #ffffff;
            border-bottom-left-radius: 28rpx;
            border-bottom-right-radius: 28rpx;
            box-sizing: border-box;
            overflow-y: auto;
        }
        &__section {
            padding: 0 18rpx;
            margin-bottom: 28rpx;
        }
        &__title {
            display: block;
            margin-bottom: 20rpx;
            font-size: 28rpx;
            font-weight: 700;
            color: #252b33;
        }
        &__options {
            display: flex;
            flex-wrap: wrap;
            gap: 18rpx 20rpx;
        }
        &__option {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 226rpx;
            height: 74rpx;
            border-radius: 10rpx;
            background: #f5f5f5;
            border: 2rpx solid transparent;
            box-sizing: border-box;
            &--active {
                background: #edf5ff;
                border-color: #3d8cff;
            }
        }
        &__option-text {
            font-size: 28rpx;
            color: #4b515a;
            .filter-popup__option--active & {
                font-weight: 600;
                color: #2678ff;
            }
        }
        &__actions {
            display: flex;
            gap: 24rpx;
            padding: 8rpx 18rpx 0;
        }
        &__button {
            flex: 1;
            height: 92rpx;
            line-height: 92rpx;
            border-radius: 999rpx;
            font-size: 34rpx;
            font-weight: 700;
            border: 0;
            padding: 0;
            &::after {
                border: 0;
            }
            &--reset {
                background: #ebebeb;
                color: #777d86;
            }
            &--confirm {
                background: linear-gradient(180deg, #2d82ff 0%, #206ef6 100%);
                color: #ffffff;
            }
            &--hover {
                opacity: 0.92;
            }
        }
    }
    .order-card {
        margin-bottom: 20rpx;
        padding: 20rpx;
        border-radius: 24rpx;
        background: #ffffff;
        box-shadow: 0 10rpx 24rpx rgba(26, 44, 81, 0.04);
        &__head {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
        }
        &__time-main {
            font-size: 42rpx;
            font-weight: 700;
            color: #ff8d27;
        }
        &__time-sub {
            margin-left: 8rpx;
            font-size: 28rpx;
            color: #a3a8b2;
        }
        &__price-wrap {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 8rpx;
            &--serial-only {
                justify-content: flex-start;
                min-width: 54rpx;
            }
        }
        &__serial {
            font-size: 38rpx;
            font-weight: 700;
            line-height: 1;
            color: #2c3139;
        }
        &__price {
            font-size: 44rpx;
            font-weight: 700;
            color: #ff3b30;
        }
        &__meta {
            display: flex;
            justify-content: space-between;
            align-items: center;
            gap: 16rpx;
            margin-top: 12rpx;
        }
        &__extra {
            flex-shrink: 0;
            font-size: 24rpx;
            color: #a0a5af;
        }
        &__tags {
            display: flex;
            flex: 1;
            flex-wrap: wrap;
            gap: 10rpx;
        }
        &__tag-wrap {
            display: flex;
            align-items: center;
        }
        &__tag-icon {
            width: 108rpx;
            height: 40rpx;
        }
        &__tag {
            padding: 4rpx 10rpx;
            border-radius: 8rpx;
            font-size: 22rpx;
            line-height: 1.2;
            border: 1rpx solid #2473f5;
            color: #2473f5;
            &--orange {
                border-color: #ff9c45;
                background: #ff9c45;
                color: #ffffff;
            }
            &--red {
                border-color: #ff6c57;
                color: #ff6c57;
            }
            &--blue-light {
                border-color: #74a9ff;
                color: #74a9ff;
            }
        }
        &__route {
            display: flex;
            margin-top: 20rpx;
        }
        &__route-side {
            width: 64rpx;
            display: flex;
            flex-direction: column;
            align-items: center;
            flex-shrink: 0;
        }
        &__distance-top,
        &__distance-bottom {
            font-size: 22rpx;
            font-weight: 600;
            color: #555b66;
            text-align: center;
        }
        &__line {
            position: relative;
            width: 4rpx;
            flex: 1;
            min-height: 86rpx;
            margin: 10rpx 0;
            border-radius: 999rpx;
            background: #d8dbe1;
            &::before,
            &::after {
                content: '';
                position: absolute;
                left: 50%;
                transform: translateX(-50%);
                width: 14rpx;
                height: 14rpx;
                border-radius: 50%;
                background: #6a6f79;
            }
            &::before {
                top: -4rpx;
            }
            &::after {
                bottom: -4rpx;
            }
        }
        &__route-main {
            flex: 1;
        }
        &__route-item {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            gap: 16rpx;
            &--destination {
                margin-top: 20rpx;
            }
        }
        &__route-texts {
            flex: 1;
            min-width: 0;
        }
        &__route-title {
            display: block;
            font-size: 40rpx;
            font-weight: 700;
            color: #2d3139;
            line-height: 1.3;
        }
        &__route-desc {
            display: block;
            margin-top: 8rpx;
            font-size: 28rpx;
            color: #9ea4ae;
            line-height: 1.4;
        }
        &__nav {
            width: 48rpx;
            height: 48rpx;
            flex-shrink: 0;
        }
        &__goods {
            display: flex;
            justify-content: space-between;
            align-items: center;
            height: 70rpx;
            padding: 0 20rpx;
            margin-top: 20rpx;
            border-radius: 16rpx;
            background: #f4f5f7;
        }
        &__goods-text {
            flex: 1;
            font-size: 28rpx;
            color: #7a818d;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        &__goods-arrow {
            margin-left: 12rpx;
            font-size: 24rpx;
            color: #a4a9b1;
        }
        &__button {
            margin-top: 24rpx;
            width: 100%;
            height: 88rpx;
            line-height: 88rpx;
            border-radius: 999rpx;
            background: linear-gradient(180deg, #2b7fff 0%, #1f6ff3 100%);
            font-size: 34rpx;
            font-weight: 700;
            color: #ffffff;
            border: 0;
            padding: 0;
            &::after {
                border: 0;
            }
            &--hover {
                opacity: 0.92;
            }
        }
        &__actions {
            margin-top: 24rpx;
            &--pickup,
            &--delivering {
                display: flex;
                align-items: center;
                gap: 22rpx;
            }
        }
        &__icon-actions {
            display: flex;
            align-items: center;
            gap: 20rpx;
            flex-shrink: 0;
            &--single {
                gap: 0;
            }
        }
        &__icon-action {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            width: 74rpx;
        }
        &__action-icon {
            width: 40rpx;
            height: 40rpx;
            border-radius: 8rpx;
            background: #f7f8fa;
        }
        &__action-text {
            margin-top: 8rpx;
            font-size: 26rpx;
            line-height: 1;
            color: #5b616b;
        }
        &__button--code {
            flex: 1;
            margin-top: 0;
        }
    }
</style>
app/pages/login/login.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,288 @@
<template>
    <view class="login-page">
        <image class="login-page__bg" src="/static/image/login_bg@2x.png" mode="aspectFill"></image>
        <view></view>
        <view class="login-page__content">
            <view class="login-card">
                <view class="login-card__tabs">
                    <view
                        v-for="item in tabs"
                        :key="item.value"
                        class="login-card__tab"
                        :style="{
                            backgroundImage: returnBackgroundImg(item.value, activeTab === item.value)
                        }"
                        :class="{ 'login-card__tab--active': activeTab === item.value }"
                        @click="activeTab = item.value"
                    >
                        <text class="login-card__tab-text">{{ item.label }}</text>
                        <view v-if="activeTab === item.value" class="login-card__tab-line"></view>
                    </view>
                </view>
                <view class="login-card__form">
                    <view v-if="activeTab === 'account'" class="login-card__group">
                        <view class="login-card__field">
                            <input v-model="form.mobile" class="login-card__input" type="number" placeholder="请输入手机号" placeholder-style="color: #c5cad4;" />
                        </view>
                        <view class="login-card__field">
                            <input v-model="form.password" class="login-card__input" password placeholder="请输入密码" placeholder-style="color: #c5cad4;" />
                        </view>
                    </view>
                    <view v-else class="login-card__group">
                        <view class="login-card__field">
                            <input v-model="form.mobile" class="login-card__input" type="number" placeholder="请输入手机号" placeholder-style="color: #c5cad4;" />
                        </view>
                        <view class="login-card__field login-card__field--code">
                            <input v-model="form.code" class="login-card__input" type="number" placeholder="请输入验证码" placeholder-style="color: #c5cad4;" />
                            <text class="login-card__code-btn">获取验证码</text>
                        </view>
                    </view>
                    <button class="login-card__submit" hover-class="login-card__submit--hover" @click="login">登录</button>
                </view>
                <view class="login-card__agreement">
                    <view class="login-card__agreement-icon"></view>
                    <text class="login-card__agreement-text">登录即代表您同意<text>《用户协议》</text>及<text>《用户隐私政策》</text></text>
                </view>
            </view>
        </view>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                activeTab: 'account',
                tabs: [
                    { label: '账号登录', value: 'account' },
                    { label: '验证码登录', value: 'code' }
                ],
                form: {
                    mobile: '',
                    password: '',
                    code: ''
                }
            };
        },
        methods: {
            returnBackgroundImg(value, active) {
                if (value === 'account' && !active) {
                    return "url('/static/image/login_ic_account@2x.png')"
                } else if (value === 'account' && active) {
                    return "url('/static/image/login_ic_account_sel@2x.png')"
                } else if (value === 'code' && !active) {
                    return "url('/static/image/login_ic_code@2x.png')"
                } else if (value === 'code' && active) {
                    return "url('/static/image/login_ic_code_sel@2x.png')"
                }
            },
            login() {
                uni.switchTab({
                    url: '/pages/index/index'
                })
            }
        }
    };
</script>
<style lang="scss" scoped>
    .login-page {
        position: relative;
        height: 100vh;
        background: linear-gradient(180deg, #cfe6ff 0%, #a7c6ff 100%);
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        &__bg {
            position: absolute;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            width: 100vw;
            height: 100vh;
        }
        &__content {
            position: relative;
            z-index: 1;
            height: 88vh;
            box-sizing: border-box;
            padding: 180rpx 40rpx 20rpx 40rpx;
        }
    }
    .login-card {
        position: relative;
        height: calc(100% - 15rpx);
        box-sizing: border-box;
        border-radius: 40rpx;
        background: rgba(255, 255, 255, 0.95);
        box-shadow: 0 24rpx 70rpx rgba(69, 124, 219, 0.16);
        overflow: hidden;
        &__tabs {
            display: flex;
            align-items: stretch;
            background: rgba(228, 236, 247, 0.8);
        }
        &__tab {
            flex: 1;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100rpx;
            border-bottom-left-radius: 28rpx;
            border-bottom-right-radius: 28rpx;
            background-repeat: no-repeat;
            background-size: 100% 100%;
            position: relative;
            &--active {
                flex: 1.3;
                // background: #ffffff;
            }
            .login-card__tab-line {
                position: absolute;
                bottom: 10rpx;
                left: 50%;
                transform: translate(0, -55%);
                width: 36rpx;
                height: 8rpx;
                margin-top: 10rpx;
                border-radius: 999rpx;
                background: #1f74ff;
                z-index: 999;
            }
        }
        &__tab-text {
            font-size: 34rpx;
            font-weight: 400;
            color: #666666;
            .login-card__tab--active & {
                color: #222222;
            }
        }
        &__tab-line {
            width: 36rpx;
            height: 8rpx;
            margin-top: 10rpx;
            border-radius: 999rpx;
            background: #1f74ff;
        }
        &__form {
            padding: 46rpx 36rpx 0;
        }
        &__group {
            display: flex;
            flex-direction: column;
            gap: 26rpx;
        }
        &__field {
            display: flex;
            align-items: center;
            height: 96rpx;
            padding: 0 34rpx;
            border-radius: 48rpx;
            background: #f3f6fb;
            &--code {
                justify-content: space-between;
                gap: 20rpx;
            }
        }
        &__input {
            flex: 1;
            height: 98rpx;
            font-size: 30rpx;
            color: #31343a;
            background: transparent;
        }
        &__code-btn {
            flex-shrink: 0;
            font-size: 26rpx;
            font-weight: 600;
            color: #1f74ff;
        }
        &__submit {
            margin-top: 40rpx;
            width: 100%;
            height: 98rpx;
            line-height: 98rpx;
            border: 0;
            border-radius: 50rpx;
            background: #106EFA;
            font-size: 32rpx;
            font-weight: 600;
            color: #ffffff;
            padding: 0;
            &::after {
                border: 0;
            }
            &--hover {
                opacity: 0.94;
            }
        }
        &__agreement {
            position: absolute;
            left: 36rpx;
            right: 36rpx;
            bottom: calc(env(safe-area-inset-bottom) + 40rpx);
            display: flex;
            align-items: flex-start;
            gap: 10rpx;
        }
        &__agreement-icon {
            position: relative;
            flex-shrink: 0;
            width: 28rpx;
            height: 28rpx;
            margin-top: 8rpx;
            border-radius: 50%;
            background: #1f74ff;
            &::after {
                content: '';
                position: absolute;
                left: 8rpx;
                top: 4rpx;
                width: 9rpx;
                height: 13rpx;
                border-right: 3rpx solid #ffffff;
                border-bottom: 3rpx solid #ffffff;
                transform: rotate(38deg);
            }
        }
        &__agreement-text {
            font-size: 24rpx;
            line-height: 1.6;
            color: #555555;
            text {
                color: #106EFA;
            }
        }
    }
</style>
app/pages/message/message.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,211 @@
<template>
    <view class="message-page">
        <view class="message-page__nav" :style="{ paddingTop: statusBarHeight + 'px' }">
            <view class="message-page__nav-inner">
                <text class="message-page__nav-title">消息</text>
            </view>
        </view>
        <scroll-view class="message-page__body" scroll-y :style="bodyStyle">
            <view class="message-page__list">
                <view v-for="item in messageList" :key="item.id" class="message-card">
                    <view class="message-card__icon-wrap">
                        <view class="message-card__icon-bg">
                            <text class="message-card__icon">🔔</text>
                        </view>
                        <view v-if="item.unread" class="message-card__dot"></view>
                    </view>
                    <view class="message-card__content">
                        <text class="message-card__title">{{ item.title }}</text>
                        <text class="message-card__desc">{{ item.desc }}</text>
                        <text class="message-card__time">{{ item.time }}</text>
                    </view>
                </view>
            </view>
        </scroll-view>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                statusBarHeight: 0,
                navHeight: 0,
                messageList: [
                    {
                        id: 1,
                        title: '订单待配送',
                        desc: '您已抢单成功,订单:32728367487367,请按时到【中铁快运南站旗舰店】取货',
                        time: '2026-04-12 20:00',
                        unread: true
                    },
                    {
                        id: 2,
                        title: '配送中',
                        desc: '订单:32728367487367已取货,请按时送达',
                        time: '2026-04-12 20:00',
                        unread: true
                    },
                    {
                        id: 3,
                        title: '已送达',
                        desc: '订单:32728367487367已送达,请联系用户确认签收',
                        time: '2026-04-12 20:00',
                        unread: false
                    },
                    {
                        id: 4,
                        title: '订单已完成',
                        desc: '订单:32728367487367已完成,相关订单结算会在3个工作日内完成',
                        time: '2026-04-12 20:00',
                        unread: false
                    },
                    {
                        id: 5,
                        title: '订单已评价',
                        desc: '订单:32728367487367,用户已评价,可查看评价内容',
                        time: '2026-04-12 20:00',
                        unread: false
                    },
                    {
                        id: 6,
                        title: '退款中',
                        desc: '订单:32728367487367,用户已提交退款申请,该订单任务已取消,请勿前往。',
                        time: '2026-04-12 20:00',
                        unread: false
                    },
                    {
                        id: 7,
                        title: '订单已结算',
                        desc: '行李订单:3729378487987 å¹³å°å·²å®Œæˆç»“算,金额为XX元,请注意查收',
                        time: '2026-04-12 20:00',
                        unread: false
                    }
                ]
            }
        },
        computed: {
            bodyStyle() {
                return {
                    marginTop: this.navHeight + 'px',
                    height: `calc(100vh - ${this.navHeight}px)`
                }
            }
        },
        onLoad() {
            const systemInfo = uni.getSystemInfoSync()
            this.statusBarHeight = systemInfo.statusBarHeight || 0
            this.navHeight = this.statusBarHeight + uni.upx2px(88)
        }
    }
</script>
<style lang="scss" scoped>
    .message-page {
        height: 100vh;
        background: #f6f8fc;
        overflow: hidden;
        &__nav {
            position: fixed;
            left: 0;
            top: 0;
            right: 0;
            z-index: 10;
            background: linear-gradient(180deg, #1f73f6 0%, #1b6df2 100%);
        }
        &__nav-inner {
            height: 88rpx;
            display: flex;
            align-items: center;
            padding: 0 24rpx;
        }
        &__nav-title {
            font-size: 36rpx;
            font-weight: 700;
            color: #ffffff;
        }
        &__body {
            box-sizing: border-box;
        }
        &__list {
            padding: 18rpx 18rpx calc(env(safe-area-inset-bottom) + 24rpx);
        }
    }
    .message-card {
        display: flex;
        align-items: flex-start;
        gap: 18rpx;
        padding: 24rpx 20rpx;
        margin-bottom: 18rpx;
        border-radius: 18rpx;
        background: #ffffff;
        box-shadow: 0 8rpx 20rpx rgba(28, 55, 106, 0.04);
        &__icon-wrap {
            position: relative;
            flex-shrink: 0;
        }
        &__icon-bg {
            width: 52rpx;
            height: 52rpx;
            border-radius: 50%;
            background: #fff7e3;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        &__icon {
            font-size: 26rpx;
            line-height: 1;
        }
        &__dot {
            position: absolute;
            right: 0;
            top: 0;
            width: 14rpx;
            height: 14rpx;
            border-radius: 50%;
            background: #ff3b30;
            border: 2rpx solid #ffffff;
        }
        &__content {
            flex: 1;
            min-width: 0;
        }
        &__title {
            display: block;
            font-size: 36rpx;
            font-weight: 700;
            color: #2b3139;
            line-height: 1.35;
        }
        &__desc {
            display: block;
            margin-top: 10rpx;
            font-size: 28rpx;
            line-height: 1.55;
            color: #8c95a3;
        }
        &__time {
            display: block;
            margin-top: 16rpx;
            font-size: 26rpx;
            color: #b1b7c1;
        }
    }
</style>
app/pages/mine/mine.vue
@@ -1,56 +1,143 @@
<template>
    <view class="index">
        <view class="index_list">
            <view class="index_list_item">
                <view class="index_list_item_info">
                    <text>SHE事件上报</text>
                    <text>FAC/NM</text>
                </view>
                <image src="/static/bg_a.png" mode="widthFix"></image>
    <view class="mine-page">
        <view class="mine-page__nav" :style="{ paddingTop: statusBarHeight + 'px' }">
            <view class="mine-page__nav-inner">
                <text class="mine-page__nav-title">我的</text>
            </view>
            <view class="index_list_item">
                <view class="index_list_item_info">
                    <text>跌绊滑风险上报</text>
                    <text>TAG</text>
        </view>
        <scroll-view class="mine-page__body" scroll-y :style="bodyStyle">
            <view class="mine-page__content">
                <view class="mine-page__profile">
                    <image class="mine-page__avatar" src="/static/image/ic_pic@2x.png" mode="aspectFill"></image>
                    <view class="mine-page__profile-info">
                        <view class="mine-page__name-row">
                            <text class="mine-page__name">{{ currentProfile.name }}</text>
                            <view v-if="currentProfile.levelTag" class="mine-page__level-tag">
                                <!-- <text class="mine-page__level-dot"></text> -->
                                <image src="/static/image/ic_jiangpai@2x.png" mode="widthFix" class="mine-page__level-dot"></image>
                                <text class="mine-page__level-text">{{ currentProfile.levelTag }}</text>
                            </view>
                        </view>
                        <text class="mine-page__phone">{{ currentProfile.phone }}</text>
                    </view>
                </view>
                <image src="/static/bg_b.png" mode="widthFix"></image>
                <view class="income-card">
                    <view class="income-card__left">
                        <text class="income-card__label">累计佣金(元)</text>
                        <text class="income-card__value">{{ currentProfile.totalIncome }}</text>
                    </view>
                    <view class="income-card__right">
                        <view class="income-card__stat">
                            <text class="income-card__stat-label">待结算(元):</text>
                            <text class="income-card__stat-value">{{ currentProfile.pendingIncome }}</text>
                        </view>
                        <view class="income-card__stat">
                            <text class="income-card__stat-label">订单总数:</text>
                            <text class="income-card__stat-value">{{ currentProfile.orderCount }}</text>
                        </view>
                    </view>
                </view>
                <view class="menu-panel">
                    <view v-for="item in menuList" :key="item.title" class="menu-panel__item" @click="jump(item)">
                        <text class="menu-panel__title">{{ item.title }}</text>
                        <view class="menu-panel__right">
                            <template v-if="item.key === 'wallet'">
                                <text class="menu-panel__sub menu-panel__sub--muted">余额:{{ currentProfile.walletBalance }}</text>
                            </template>
                            <template v-else-if="item.key === 'driver' && !currentProfile.verified">
                                <text class="menu-panel__sub menu-panel__sub--danger">完成认证后即可接单</text>
                            </template>
                            <template v-else-if="item.key === 'driver' && currentProfile.verified">
                                <text class="menu-panel__sub menu-panel__sub--warning">审核中</text>
                                <text class="menu-panel__sub menu-panel__sub--primary">已认证</text>
                            </template>
                            <template v-else-if="item.key === 'setting'">
                                <text class="menu-panel__sub menu-panel__sub--muted">当前版本V1.0.0</text>
                            </template>
                            <view class="menu-panel__arrow">
                                <image src="/static/image/mine_ar2@2x.png" mode="widthFix"></image>
                            </view>
                        </view>
                    </view>
                </view>
            </view>
        </scroll-view>
        <view class="mine-page__footer">
            <button class="mine-page__logout" hover-class="mine-page__logout--hover">退出登录</button>
        </view>
    </view>
</template>
<script>
    import { mapState } from 'vuex'
    export default {
        computed: {
            ...mapState(['userInfo'])
        },
        data() {
            return {
                title: 'Hello'
                statusBarHeight: 0,
                navHeight: 0,
                useVerifiedState: true,
                menuList: [
                    { key: 'wallet', title: '我的钱包' },
                    { key: 'driver', title: '司机认证' },
                    { key: 'guide', title: '规范须知' },
                    { key: 'help', title: '帮助与客服' },
                    { key: 'setting', title: '设置' }
                ],
                profileStates: {
                    guest: {
                        name: '汤子新',
                        phone: '18166565677',
                        levelTag: '',
                        totalIncome: '-',
                        pendingIncome: '-',
                        orderCount: '-',
                        walletBalance: 'Â¥0',
                        verified: false
                    },
                    verified: {
                        name: '汤子新',
                        phone: '18166565677(皖BD23189)',
                        levelTag: 'S级',
                        totalIncome: '8,314.90',
                        pendingIncome: '2000.00',
                        orderCount: '329',
                        walletBalance: 'Â¥1500.00',
                        verified: true
                    }
                }
            }
        },
        computed: {
            currentProfile() {
                return this.useVerifiedState ? this.profileStates.verified : this.profileStates.guest
            },
            bodyStyle() {
                const footerHeight = uni.upx2px(124)
                return {
                    marginTop: this.navHeight + 'px',
                    height: `calc(100vh - ${this.navHeight + footerHeight}px)`
                }
            }
        },
        onLoad() {
            const systemInfo = uni.getSystemInfoSync()
            this.statusBarHeight = systemInfo.statusBarHeight || 0
            this.navHeight = this.statusBarHeight + uni.upx2px(88)
        },
        methods: {
            jump(type) {
                switch (type) {
                    case 1:
                        uni.navigateTo({
                            url: '/pages/reporting_she/reporting_she'
                        })
                        break;
                    case 2:
                        uni.navigateTo({
                            url: '/pages/riskReporting/riskReporting'
                        })
                        break;
                    case 3:
                        uni.navigateTo({
                            url: '/pages/report_dca/report_dca'
                        })
                        break;
            jump(item) {
                console.log(item)
                if (item.key === 'setting') {
                    uni.navigateTo({
                        url: '/pages/settings/settings'
                    })
                } else if (item.key === 'driver') {
                    uni.navigateTo({
                        url: '/pages/certification-details/certification-details'
                    })
                }
            }
        }
@@ -58,53 +145,245 @@
</script>
<style lang="scss" scoped>
    .index {
        width: 100vw;
        padding: 30rpx;
    .mine-page {
        height: 100vh;
        background: #f6f8fc;
        overflow: hidden;
        &__nav {
            position: fixed;
            left: 0;
            top: 0;
            right: 0;
            z-index: 10;
            background: #ffffff;
        }
        &__nav-inner {
            height: 88rpx;
            display: flex;
            align-items: center;
            padding: 0 26rpx;
        }
        &__nav-title {
            font-size: 36rpx;
            font-weight: 700;
            color: #2b3139;
        }
        &__body {
            box-sizing: border-box;
        }
        &__content {
            padding: 28rpx 20rpx 20rpx;
        }
        &__profile {
            display: flex;
            align-items: center;
            gap: 20rpx;
            padding: 8rpx 0 24rpx;
        }
        &__avatar {
            width: 92rpx;
            height: 92rpx;
            border-radius: 50%;
            background: #e8f1ff;
            flex-shrink: 0;
        }
        &__profile-info {
            flex: 1;
            min-width: 0;
        }
        &__name-row {
            display: flex;
            align-items: center;
            gap: 12rpx;
        }
        &__name {
            font-size: 40rpx;
            font-weight: 700;
            color: #2b3139;
        }
        &__level-tag {
            display: flex;
            align-items: center;
            gap: 6rpx;
            padding: 4rpx 10rpx;
            border-radius: 999rpx;
            background: linear-gradient(180deg, #ff9e68 0%, #ff7d34 100%);
        }
        &__level-dot {
            width: 20rpx;
            height: 24rpx;
        }
        &__level-text {
            font-size: 22rpx;
            font-weight: 700;
            color: #ffffff;
        }
        &__phone {
            display: block;
            margin-top: 10rpx;
            font-size: 28rpx;
            color: #8f96a3;
        }
        &__footer {
            position: fixed;
            left: 0;
            right: 0;
            bottom: 0;
            padding: 16rpx 0 calc(env(safe-area-inset-bottom) + 20rpx);
            background: #f6f8fc;
            display: flex;
            justify-content: center;
        }
        &__logout {
            width: 186rpx;
            height: 70rpx;
            line-height: 70rpx;
            border-radius: 999rpx;
            background: #ffffff;
            border: 1rpx solid #d8dde5;
            font-size: 28rpx;
            font-weight: 500;
            color: #7e8794;
            padding: 0;
            &::after {
                border: 0;
            }
            &--hover {
                opacity: 0.92;
            }
        }
    }
    .income-card {
        position: relative;
        display: flex;
        justify-content: space-between;
        gap: 20rpx;
        padding: 10rpx 30rpx 40rpx 30rpx;
        box-sizing: border-box;
        height: calc(100vh - 44px - 50px);
        background: linear-gradient( 180deg, #B5D2FF 0%, #FFFFFF 100%);
        .index_list {
            width: 100%;
        background-image: url('../../static/image/ming_bg@2x.png');
        background-repeat: no-repeat;
        background-size: 100% 100%;
        overflow: hidden;
        &__left,
        &__right {
            position: relative;
            z-index: 1;
        }
        &__left {
            flex: 1;
        }
        &__label,
        &__stat-label,
        &__stat-value {
            font-size: 24rpx;
            color: rgba(255, 255, 255, 0.78);
        }
        &__value {
            display: block;
            margin-top: 20rpx;
            font-size: 52rpx;
            line-height: 1;
            font-weight: normal;
            color: #ffffff;
        }
        &__right {
            display: flex;
            flex-direction: column;
            margin-top: 12rpx;
            .index_list_item {
            align-items: flex-end;
            justify-content: flex-end;
            gap: 18rpx;
            padding-top: 12rpx;
        }
        &__stat {
            display: flex;
            align-items: center;
            gap: 10rpx;
        }
    }
    .menu-panel {
        margin-top: 20rpx;
        border-radius: 22rpx;
        background: #ffffff;
        overflow: hidden;
        &__item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            height: 102rpx;
            padding: 0 24rpx;
            box-sizing: border-box;
            border-bottom: 1rpx solid #eef1f5;
            &:last-child {
                border-bottom: 0;
            }
        }
        &__title {
            font-size: 34rpx;
            font-weight: 600;
            color: #2b3139;
        }
        &__right {
            display: flex;
            align-items: flex-start;
            gap: 10rpx;
        }
        &__sub {
            font-size: 26rpx;
            white-space: nowrap;
            &--muted {
                color: #b2b8c1;
            }
            &--danger {
                color: #ff5a4f;
            }
            &--warning {
                color: #ff7b38;
            }
            &--primary {
                color: #2b7cff;
            }
        }
        &__arrow {
            width: 16rpx;
            height: 28rpx;
            image {
                width: 100%;
                height: 200rpx;
                margin-bottom: 30rpx;
                position: relative;
                .index_list_item_info {
                    width: 100%;
                    height: 100%;
                    padding: 0 48rpx;
                    box-sizing: border-box;
                    display: flex;
                    justify-content: center;
                    flex-direction: column;
                    position: relative;
                    z-index: 99;
                    text {
                        &:nth-child(1) {
                            font-weight: bold;
                            font-size: 34rpx;
                            color: #FFFFFF;
                        }
                        &:nth-child(2) {
                            font-weight: 400;
                            font-size: 26rpx;
                            color: rgba(255,255,255,0.6);
                            margin-top: 10rpx;
                        }
                    }
                }
                image {
                    width: 100%;
                    height: 100%;
                    position: absolute;
                    top: 0;
                    left: 0;
                }
            }
        }
    }
app/pages/order-detail/order-detail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1042 @@
<template>
    <view class="order-detail-page">
        <view v-if="!showMapStatus" class="order-detail-page__simple-nav" :style="{ paddingTop: statusBarHeight + 'px' }">
            <view class="order-detail-page__simple-nav-inner">
                <text class="order-detail-page__simple-nav-title">{{ detailStatus === 'rated' ? '订单已评价' : '订单已完成' }}</text>
            </view>
        </view>
        <view v-if="showMapStatus" class="order-detail-page__fixed-top">
            <view class="order-detail-page__map-wrap">
                <map
                    class="order-detail-page__map"
                    :latitude="mapData.center.latitude"
                    :longitude="mapData.center.longitude"
                    :markers="mapData.markers"
                    :polyline="mapData.polyline"
                    :include-points="mapData.includePoints"
                    :scale="mapData.scale"
                    :enable-zoom="true"
                    :enable-scroll="true"
                ></map>
                <view class="order-detail-page__map-bubble">
                    <text class="order-detail-page__map-bubble-text">剩余3.2km,约4分钟</text>
                </view>
            </view>
            <view class="order-detail-page__status-bar">
                <view class="order-detail-page__status-left">
                    <view class="order-detail-page__status-dot"></view>
                    <text class="order-detail-page__status-title">{{ statusTextMap[detailStatus] || '待取货' }}</text>
                </view>
                <view class="order-detail-page__status-right">
                    <text v-if="detailStatus === 'pickup'" class="order-detail-page__status-cancel">取消订单</text>
                    <text class="order-detail-page__status-no">#1</text>
                </view>
            </view>
        </view>
        <scroll-view class="order-detail-page__body" scroll-y :style="bodyStyle">
            <view class="order-detail-page__content">
                <view class="order-detail-page__section order-detail-page__section--main">
                    <view v-if="showMapStatus" class="order-detail-page__summary">
                        <view class="order-detail-page__summary-left">
                            <view class="order-detail-page__head-left">
                                <text class="order-detail-page__time">35分钟内</text>
                                <text class="order-detail-page__time-sub">送达</text>
                            </view>
                            <view class="order-detail-page__tags">
                                <image class="order-detail-page__tag-icon" src="/static/image/ic_biaosuda@2x.png" mode="widthFix"></image>
                                <text class="order-detail-page__tag-text">贵重物品</text>
                            </view>
                        </view>
                        <view class="order-detail-page__summary-right">
                            <text class="order-detail-page__price">Â¥20.5</text>
                            <text class="order-detail-page__extra">含加急¥3.0</text>
                        </view>
                    </view>
                    <view v-else class="order-detail-page__done-summary">
                        <view class="order-detail-page__done-summary-left">
                            <text class="order-detail-page__done-title">{{ detailStatus === 'rated' ? '订单已评价' : '订单已完成' }}</text>
                            <view class="order-detail-page__tags order-detail-page__tags--done">
                                <image class="order-detail-page__tag-icon" src="/static/image/ic_biaosuda@2x.png" mode="widthFix"></image>
                                <text class="order-detail-page__tag-text">贵重物品</text>
                            </view>
                        </view>
                        <view class="order-detail-page__done-summary-right">
                            <view class="order-detail-page__done-price-row">
                                <text v-if="detailStatus === 'rated'" class="order-detail-page__settled-tag">已结算</text>
                                <text class="order-detail-page__price">Â¥20.5</text>
                            </view>
                            <text class="order-detail-page__extra">含加急¥3.0</text>
                        </view>
                    </view>
                    <view class="order-detail-page__route-list">
                        <view class="order-detail-page__route-item">
                            <view class="order-detail-page__route-left">
                                <text class="order-detail-page__distance-top">349</text>
                                <text class="order-detail-page__distance-unit">m</text>
                                <view class="order-detail-page__route-divider"></view>
                            </view>
                            <view class="order-detail-page__route-main">
                                <view class="order-detail-page__route-texts">
                                    <text class="order-detail-page__route-title">中铁快运南站旗舰店</text>
                                    <text class="order-detail-page__route-desc">莲花路200号莲花产业园F栋401</text>
                                </view>
                                <view class="order-detail-page__route-actions">
                                    <image class="order-detail-page__route-icon" src="/static/image/ic_c1all@2x.png" mode="aspectFit"></image>
                                    <image class="order-detail-page__route-icon" src="/static/image/ic_daohang@2x.png" mode="aspectFit"></image>
                                </view>
                            </view>
                        </view>
                        <view class="order-detail-page__route-item order-detail-page__route-item--end">
                            <view class="order-detail-page__route-left">
                                <view class="order-detail-page__route-pin"></view>
                                <view class="order-detail-page__route-divider order-detail-page__route-divider--light"></view>
                                <text class="order-detail-page__distance-top">12.5</text>
                                <text class="order-detail-page__distance-unit">km</text>
                            </view>
                            <view class="order-detail-page__route-main">
                                <view class="order-detail-page__route-texts">
                                    <text class="order-detail-page__route-title">佳苑巴黎都市3期10栋301室</text>
                                    <text class="order-detail-page__route-desc">洞庭湖路与湖北路交叉口西150ç±³</text>
                                </view>
                                <view class="order-detail-page__route-actions">
                                    <image class="order-detail-page__route-icon" src="/static/image/ic_c1all@2x.png" mode="aspectFit"></image>
                                    <image class="order-detail-page__route-icon" src="/static/image/ic_daohang@2x.png" mode="aspectFit"></image>
                                </view>
                            </view>
                        </view>
                    </view>
                    <view v-if="showMapStatus" class="order-detail-page__qrcode-wrap">
                        <view class="order-detail-page__qrcode-box">
                            <image class="order-detail-page__qrcode-image" src="/static/logo.png" mode="aspectFit"></image>
                        </view>
                        <text class="order-detail-page__qrcode-value">767889</text>
                        <text class="order-detail-page__qrcode-label">取货码</text>
                    </view>
                </view>
                <view class="order-detail-page__section">
                    <text class="order-detail-page__section-title">客户信息</text>
                    <view class="order-detail-page__row-info">
                        <text class="order-detail-page__row-text">刘先生(手机号2878)</text>
                        <image class="order-detail-page__row-icon" src="/static/image/ic_call@2x.png" mode="aspectFit"></image>
                    </view>
                    <view v-if="detailStatus === 'rated'" class="order-detail-page__comment-card">
                        <text class="order-detail-page__comment-title">客户已评价:</text>
                        <view class="order-detail-page__comment-score">
                            <text class="order-detail-page__comment-star">★</text>
                            <text class="order-detail-page__comment-score-text">4.5</text>
                        </view>
                        <text class="order-detail-page__comment-content">送的很快,东西完好无损</text>
                        <image class="order-detail-page__comment-image" src="/static/logo.png" mode="aspectFill"></image>
                    </view>
                </view>
                <view class="order-detail-page__section">
                    <text class="order-detail-page__section-title">物品清单(共8件)</text>
                    <view class="order-detail-page__goods-list">
                        <view v-for="item in goodsList" :key="item.name" class="order-detail-page__goods-item">
                            <text class="order-detail-page__goods-name">{{ item.name }}</text>
                            <text class="order-detail-page__goods-count">x{{ item.count }}</text>
                        </view>
                    </view>
                </view>
                <view class="order-detail-page__section">
                    <text class="order-detail-page__section-title">物品信息</text>
                    <text class="order-detail-page__goods-category">文件</text>
                    <view class="order-detail-page__photos">
                        <image v-for="(item, index) in photos" :key="index" class="order-detail-page__photo" :src="item" mode="aspectFill"></image>
                    </view>
                </view>
                <view class="order-detail-page__section order-detail-page__section--last">
                    <text class="order-detail-page__section-title">订单信息</text>
                    <view class="order-detail-page__detail-list">
                        <view class="order-detail-page__detail-item">
                            <text class="order-detail-page__detail-label">订单编号:</text>
                            <text class="order-detail-page__detail-value">202107131749250001</text>
                        </view>
                        <view class="order-detail-page__detail-item">
                            <text class="order-detail-page__detail-label">下单时间:</text>
                            <text class="order-detail-page__detail-value">2026-04-12 12:00:00</text>
                        </view>
                        <view class="order-detail-page__detail-item">
                            <text class="order-detail-page__detail-label">接单时间:</text>
                            <text class="order-detail-page__detail-value">2026-04-12 12:00:00</text>
                        </view>
                        <view class="order-detail-page__detail-item">
                            <text class="order-detail-page__detail-label">订单备注:</text>
                            <text class="order-detail-page__detail-value">-</text>
                        </view>
                    </view>
                </view>
            </view>
        </scroll-view>
        <view v-if="footerButtons.length" class="order-detail-page__footer">
            <button
                v-for="button in footerButtons"
                :key="button.text"
                class="order-detail-page__footer-btn"
                :class="button.primary ? 'order-detail-page__footer-btn--primary' : 'order-detail-page__footer-btn--ghost'"
                hover-class="order-detail-page__footer-btn--hover"
                @click="handleFooterAction(button)"
            >
                {{ button.text }}
            </button>
        </view>
        <u-popup :show="showPhotoPopup" round="20" mode="bottom" @close="closePhotoPopup">
            <view class="photo-popup">
                <view class="photo-popup__header">
                    <view class="photo-popup__placeholder"></view>
                    <text class="photo-popup__title">{{ photoPopupTitle }}</text>
                    <image class="photo-popup__close" src="/static/image/ic_close2@2x.png" mode="aspectFit" @click="closePhotoPopup"></image>
                </view>
                <view class="photo-popup__section">
                    <view class="photo-popup__label-row">
                        <text class="photo-popup__label">{{ photoPopupLabel }}</text>
                        <text class="photo-popup__required">*</text>
                        <text class="photo-popup__hint">最多3张照片</text>
                    </view>
                    <view class="photo-popup__photos">
                        <view class="photo-popup__upload-card">
                            <image class="photo-popup__upload-icon" src="/static/image/ic_photo@2x.png" mode="aspectFit"></image>
                            <text class="photo-popup__upload-text">点击拍照</text>
                        </view>
                        <view class="photo-popup__preview-card">
                            <image class="photo-popup__preview-image" src="/static/logo.png" mode="aspectFill"></image>
                            <view class="photo-popup__preview-mask">
                                <text class="photo-popup__preview-delete">删除</text>
                            </view>
                        </view>
                    </view>
                </view>
                <view class="photo-popup__section photo-popup__section--remark">
                    <text class="photo-popup__remark-title">备注信息</text>
                    <textarea v-model="photoRemark" class="photo-popup__textarea" maxlength="200" placeholder="请输入" placeholder-style="color: #c7cbd3;" />
                </view>
                <button class="photo-popup__submit" hover-class="photo-popup__submit--hover" @click="submitPhotoPopup">{{ photoPopupSubmitText }}</button>
            </view>
        </u-popup>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                detailStatus: 'pickup',
                statusBarHeight: 0,
                topFixedHeight: 0,
                showPhotoPopup: false,
                photoPopupMode: '',
                photoRemark: '',
                statusTextMap: {
                    pickup: '待取货',
                    delivering: '配送中',
                    finished: '已完成',
                    rated: '已评价',
                    cancelled: '已取消'
                },
                goodsList: [
                    { name: '大件行李', count: 1 },
                    { name: '中件行李', count: 2 },
                    { name: '小件行李', count: 3 },
                    { name: '背包', count: 2 }
                ],
                photos: ['/static/logo.png', '/static/logo.png', '/static/logo.png']
            }
        },
        computed: {
            showMapStatus() {
                return this.detailStatus === 'pickup' || this.detailStatus === 'delivering'
            },
            mapData() {
                const startPoint = { latitude: 31.829512, longitude: 117.239211 }
                const endPoint = { latitude: 31.841268, longitude: 117.278695 }
                const routePoints = [
                    startPoint,
                    { latitude: 31.831624, longitude: 117.247836 },
                    { latitude: 31.834918, longitude: 117.255467 },
                    { latitude: 31.838214, longitude: 117.265358 },
                    { latitude: 31.840126, longitude: 117.272481 },
                    endPoint
                ]
                return {
                    center: { latitude: 31.83539, longitude: 117.258953 },
                    markers: [
                        { id: 1, latitude: startPoint.latitude, longitude: startPoint.longitude, iconPath: '/static/image/map_marker_start.svg', width: 32, height: 38, anchor: { x: 0.5, y: 1 } },
                        { id: 2, latitude: endPoint.latitude, longitude: endPoint.longitude, iconPath: '/static/image/map_marker_end.svg', width: 32, height: 38, anchor: { x: 0.5, y: 1 } }
                    ],
                    polyline: [
                        { points: routePoints, color: '#00c67a', width: 20, arrowLine: true, dottedLine: true, borderColor: '#469972', borderWidth: 10 }
                    ],
                    includePoints: routePoints,
                    scale: 12
                }
            },
            bodyStyle() {
                const footerHeight = uni.upx2px(116)
                const simpleNavHeight = this.statusBarHeight + uni.upx2px(88)
                return {
                    paddingTop: (this.showMapStatus ? this.topFixedHeight : simpleNavHeight) + 'px',
                    height: `calc(100vh - ${this.footerButtons.length ? footerHeight : 0}px)`
                }
            },
            footerButtons() {
                const buttonMap = {
                    pickup: [
                        { text: '取消订单', primary: false },
                        { text: '拍照取货', primary: true }
                    ],
                    delivering: [
                        { text: '拍照送达', primary: true }
                    ],
                    finished: [],
                    rated: [],
                    cancelled: []
                }
                return buttonMap[this.detailStatus] || []
            },
            photoPopupTitle() {
                return this.photoPopupMode === 'delivering' ? '拍照送达' : '拍照取货'
            },
            photoPopupLabel() {
                return this.photoPopupMode === 'delivering' ? '拍摄送达照片' : '拍摄取货照片'
            },
            photoPopupSubmitText() {
                return this.photoPopupMode === 'delivering' ? '确认送达' : '确认取货'
            }
        },
        onLoad() {
            const pages = getCurrentPages()
            const currentPage = pages[pages.length - 1]
            const options = currentPage && currentPage.options ? currentPage.options : {}
            const systemInfo = uni.getSystemInfoSync()
            this.statusBarHeight = systemInfo.statusBarHeight || 0
            this.detailStatus = options.status || 'pickup'
            this.topFixedHeight = uni.upx2px(500 + 92)
        },
        methods: {
            handleFooterAction(button) {
                if (!button.primary) {
                    return
                }
                this.photoPopupMode = this.detailStatus === 'delivering' ? 'delivering' : 'pickup'
                this.showPhotoPopup = true
            },
            closePhotoPopup() {
                this.showPhotoPopup = false
            },
            submitPhotoPopup() {
                this.showPhotoPopup = false
            }
        }
    }
</script>
<style lang="scss" scoped>
    .order-detail-page {
        height: 100vh;
        background: #f6f8fc;
        overflow: hidden;
        &__simple-nav {
            position: fixed;
            left: 0;
            top: 0;
            right: 0;
            z-index: 11;
            background: #106EFA;
        }
        &__simple-nav-inner {
            height: 88rpx;
            display: flex;
            align-items: center;
            padding: 0 24rpx;
        }
        &__simple-nav-title {
            font-size: 36rpx;
            font-weight: 700;
            color: #ffffff;
        }
        &__fixed-top {
            position: fixed;
            left: 0;
            top: 0;
            right: 0;
            z-index: 10;
            background: #ffffff;
        }
        &__map-wrap {
            position: relative;
            margin: 0;
            height: 500rpx;
            border-radius: 0;
            overflow: hidden;
            background: #dbe8ff;
        }
        &__map {
            width: 100%;
            height: 100%;
        }
        &__map-bubble {
            position: absolute;
            left: 34rpx;
            bottom: 32rpx;
            padding: 12rpx 18rpx;
            border-radius: 14rpx;
            background: rgba(255, 255, 255, 0.96);
            box-shadow: 0 8rpx 18rpx rgba(23, 74, 163, 0.12);
        }
        &__map-bubble-text {
            font-size: 24rpx;
            font-weight: 600;
            color: #2f6ff2;
        }
        &__status-bar {
            display: flex;
            justify-content: space-between;
            align-items: center;
            height: 92rpx;
            padding: 0 24rpx;
            background: #d9e8ff;
        }
        &__status-left,
        &__status-right {
            display: flex;
            align-items: center;
        }
        &__status-dot {
            width: 18rpx;
            height: 18rpx;
            border-radius: 6rpx;
            background: #2b7cff;
            margin-right: 12rpx;
        }
        &__status-title,
        &__status-no {
            font-size: 34rpx;
            font-weight: 700;
            color: #2b3139;
        }
        &__status-cancel {
            padding: 8rpx 18rpx;
            margin-right: 18rpx;
            border: 2rpx solid #72a8ff;
            border-radius: 999rpx;
            font-size: 24rpx;
            color: #2b7cff;
            background: rgba(255, 255, 255, 0.7);
        }
        &__body {
            box-sizing: border-box;
        }
        &__content {
            padding: 16rpx 0 calc(env(safe-area-inset-bottom) + 26rpx);
        }
        &__section {
            margin: 16rpx 20rpx 0;
            padding: 26rpx 22rpx;
            border-radius: 20rpx;
            background: #ffffff;
            &--main {
                margin-top: 0;
            }
            &--last {
                margin-bottom: calc(env(safe-area-inset-bottom) + 26rpx);
            }
        }
        &__summary {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
        }
        &__done-summary {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            gap: 20rpx;
        }
        &__done-summary-left {
            flex: 1;
            min-width: 0;
        }
        &__done-summary-right {
            display: flex;
            flex-direction: column;
            align-items: flex-end;
            flex-shrink: 0;
        }
        &__done-title {
            font-size: 38rpx;
            font-weight: 700;
            color: #2b3139;
        }
        &__done-price-row {
            display: flex;
            align-items: center;
            gap: 10rpx;
        }
        &__settled-tag {
            padding: 4rpx 10rpx;
            border-radius: 8rpx;
            border: 1rpx solid #ff8f8f;
            font-size: 22rpx;
            font-weight: 600;
            color: #ff6a6a;
            background: #fff4f4;
        }
        &__summary-left {
            flex: 1;
            min-width: 0;
        }
        &__summary-right {
            display: flex;
            flex-direction: column;
            align-items: flex-end;
            margin-left: 20rpx;
            flex-shrink: 0;
        }
        &__head-left {
            display: flex;
            align-items: baseline;
        }
        &__time {
            font-size: 42rpx;
            font-weight: 700;
            color: #ff972c;
        }
        &__time-sub,
        &__extra,
        &__route-desc,
        &__qrcode-label,
        &__detail-label,
        &__detail-value,
        &__goods-count,
        &__row-text,
        &__goods-category {
            font-size: 24rpx;
            color: #adb3bd;
        }
        &__time-sub {
            margin-left: 8rpx;
        }
        &__price {
            font-size: 44rpx;
            font-weight: 700;
            color: #ff4132;
        }
        &__extra {
            margin-top: 6rpx;
        }
        &__tags {
            display: flex;
            align-items: center;
            flex-wrap: wrap;
            gap: 12rpx;
            margin-top: 14rpx;
            &--done {
                margin-top: 12rpx;
            }
        }
        &__tag-icon {
            width: 108rpx;
            height: 40rpx;
        }
        &__tag-text {
            padding: 5rpx 12rpx;
            border-radius: 8rpx;
            background: #ff9c45;
            font-size: 22rpx;
            font-weight: 600;
            color: #ffffff;
        }
        &__route-list {
            margin-top: 22rpx;
        }
        &__route-item {
            display: flex;
            align-items: flex-start;
            &--end {
                margin-top: 24rpx;
            }
        }
        &__route-left {
            width: 60rpx;
            display: flex;
            flex-direction: column;
            align-items: center;
            flex-shrink: 0;
        }
        &__distance-top {
            font-size: 28rpx;
            font-weight: 600;
            color: #515866;
        }
        &__distance-unit {
            font-size: 22rpx;
            color: #939aa6;
        }
        &__route-divider {
            width: 4rpx;
            height: 42rpx;
            margin-top: 8rpx;
            border-radius: 999rpx;
            background: #d7dbe2;
            &--light {
                height: 18rpx;
                margin: 8rpx 0;
            }
        }
        &__route-pin {
            width: 18rpx;
            height: 18rpx;
            margin-top: 4rpx;
            border-radius: 50%;
            background: #888f9b;
        }
        &__route-main {
            flex: 1;
            display: flex;
            justify-content: space-between;
            gap: 18rpx;
        }
        &__route-texts {
            flex: 1;
            min-width: 0;
        }
        &__route-title {
            display: block;
            font-size: 38rpx;
            font-weight: 700;
            line-height: 1.3;
            color: #2b3139;
        }
        &__route-desc {
            display: block;
            margin-top: 8rpx;
            line-height: 1.5;
        }
        &__route-actions {
            display: flex;
            align-items: center;
            gap: 12rpx;
            flex-shrink: 0;
        }
        &__route-icon,
        &__row-icon {
            width: 40rpx;
            height: 40rpx;
        }
        &__qrcode-wrap {
            display: flex;
            flex-direction: column;
            align-items: center;
            padding-top: 30rpx;
        }
        &__qrcode-box {
            width: 360rpx;
            height: 360rpx;
            padding: 16rpx;
            border-radius: 8rpx;
            border: 2rpx solid #EEEEEE;
            box-sizing: border-box;
        }
        &__qrcode-image {
            width: 100%;
            height: 100%;
        }
        &__qrcode-value {
            margin-top: 16rpx;
            font-size: 40rpx;
            font-weight: 700;
            color: #303640;
        }
        &__qrcode-label {
            margin-top: 6rpx;
        }
        &__section-title {
            display: block;
            font-size: 32rpx;
            font-weight: 700;
            color: #2b3139;
        }
        &__row-info {
            display: flex;
            justify-content: space-between;
            align-items: center;
            gap: 16rpx;
            margin-top: 26rpx;
        }
        &__row-text {
            flex: 1;
            font-size: 28rpx;
            color: #4d5562;
        }
        &__comment-card {
            margin-top: 20rpx;
            padding: 22rpx 20rpx;
            border-radius: 16rpx;
            background: #f7f8fa;
        }
        &__comment-title,
        &__comment-content,
        &__comment-score-text {
            font-size: 28rpx;
            color: #4d5562;
        }
        &__comment-score {
            display: flex;
            align-items: center;
            margin-top: 10rpx;
        }
        &__comment-star {
            font-size: 28rpx;
            color: #ffb323;
            margin-right: 8rpx;
        }
        &__comment-content {
            display: block;
            margin-top: 12rpx;
            line-height: 1.5;
        }
        &__comment-image {
            width: 92rpx;
            height: 92rpx;
            border-radius: 10rpx;
            margin-top: 14rpx;
        }
        &__goods-list,
        &__detail-list {
            margin-top: 22rpx;
        }
        &__goods-item,
        &__detail-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 8rpx 0;
        }
        &__goods-name {
            font-size: 28rpx;
            color: #4d5562;
        }
        &__goods-category {
            display: block;
            margin-top: 24rpx;
            font-size: 28rpx;
            color: #4d5562;
        }
        &__photos {
            display: flex;
            gap: 16rpx;
            margin-top: 18rpx;
        }
        &__photo {
            width: 92rpx;
            height: 92rpx;
            border-radius: 10rpx;
        }
        &__detail-label {
            color: #aeb4be;
        }
        &__detail-value {
            color: #666d79;
        }
        &__footer {
            position: fixed;
            left: 0;
            right: 0;
            bottom: 0;
            display: flex;
            justify-content: flex-end;
            gap: 20rpx;
            padding: 14rpx 20rpx calc(env(safe-area-inset-bottom) + 14rpx);
            background: #ffffff;
            box-shadow: 0 -8rpx 20rpx rgba(30, 46, 80, 0.06);
        }
        &__footer-btn {
            width: 182rpx;
            height: 68rpx;
            line-height: 68rpx;
            padding: 0;
            border-radius: 999rpx;
            font-size: 28rpx;
            font-weight: 500;
            border: 1rpx solid transparent;
            &::after {
                border: 0;
            }
            &--ghost {
                background: #ffffff;
                border-color: #d8dde5;
                color: #959daa;
            }
            &--primary {
                background: #2d7cff;
                color: #ffffff;
            }
            &--hover {
                opacity: 0.92;
            }
        }
    }
    .photo-popup {
        padding: 30rpx 28rpx calc(env(safe-area-inset-bottom) + 28rpx);
        background: #ffffff;
        border-top-left-radius: 20rpx;
        border-top-right-radius: 20rpx;
        overflow: hidden;
        &__header {
            display: flex;
            align-items: center;
            justify-content: space-between;
        }
        &__placeholder,
        &__close {
            width: 36rpx;
            height: 36rpx;
            flex-shrink: 0;
        }
        &__placeholder {
            opacity: 0;
        }
        &__title {
            font-size: 34rpx;
            font-weight: 700;
            color: #111111;
        }
        &__section {
            margin-top: 54rpx;
            &--remark {
                margin-top: 48rpx;
            }
        }
        &__label-row {
            display: flex;
            align-items: center;
            flex-wrap: wrap;
        }
        &__label,
        &__remark-title {
            font-size: 28rpx;
            font-weight: 700;
            color: #23262d;
        }
        &__required {
            margin-left: 4rpx;
            font-size: 28rpx;
            font-weight: 700;
            color: #ff3b30;
        }
        &__hint {
            margin-left: 12rpx;
            font-size: 24rpx;
            color: #a8adb7;
        }
        &__photos {
            display: flex;
            gap: 18rpx;
            margin-top: 28rpx;
        }
        &__upload-card,
        &__preview-card {
            position: relative;
            width: 160rpx;
            height: 160rpx;
            border-radius: 8rpx;
            overflow: hidden;
        }
        &__upload-card {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            border: 2rpx solid #ebedf2;
            background: #f8f9fb;
        }
        &__upload-icon {
            width: 48rpx;
            height: 48rpx;
            opacity: 0.55;
        }
        &__upload-text {
            margin-top: 12rpx;
            font-size: 26rpx;
            color: #a0a6b0;
        }
        &__preview-card {
            background: #eef1f5;
        }
        &__preview-image {
            width: 100%;
            height: 100%;
        }
        &__preview-mask {
            position: absolute;
            left: 0;
            right: 0;
            bottom: 0;
            height: 48rpx;
            display: flex;
            align-items: center;
            justify-content: center;
            background: rgba(0, 0, 0, 0.42);
        }
        &__preview-delete {
            font-size: 26rpx;
            color: #ffffff;
        }
        &__textarea {
            width: 100%;
            height: 110rpx;
            margin-top: 24rpx;
            padding: 28rpx 24rpx;
            border-radius: 12rpx;
            background: #f7f8fa;
            font-size: 30rpx;
            color: #2c3139;
        }
        &__submit {
            width: 100%;
            height: 88rpx;
            line-height: 88rpx;
            margin-top: 86rpx;
            border-radius: 50rpx;
            background: #106efa;
            font-size: 32rpx;
            font-weight: 700;
            color: #ffffff;
            border: 0;
            padding: 0;
            &::after {
                border: 0;
            }
            &--hover {
                opacity: 0.92;
            }
        }
    }
</style>
app/pages/order/order.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,532 @@
<template>
    <view class="order-page">
        <view class="order-page__nav" :style="{ paddingTop: statusBarHeight + 'px' }">
            <view class="order-page__nav-inner">
                <text class="order-page__nav-title">我的订单</text>
            </view>
        </view>
        <view class="order-page__tabs" :style="{ top: navHeight + 'px' }">
            <view v-for="tab in displayTabs" :key="tab.value" class="order-page__tab" :class="{ 'order-page__tab--active': activeTab === tab.value }" @click="activeTab = tab.value">
                <text class="order-page__tab-text">{{ tab.label }}</text>
                <view v-if="activeTab === tab.value" class="order-page__tab-line"></view>
            </view>
        </view>
        <scroll-view class="order-page__body" scroll-y :style="bodyStyle">
            <view class="order-page__list">
                <view v-for="item in currentOrders" :key="item.id" class="order-card" @click="goToOrderDetail(item)">
                    <view class="order-card__head">
                    <view class="order-card__head-left">
                        <image class="order-card__badge-icon" :src="getBadgeIcon(item.badge)" mode="widthFix"></image>
                        <text class="order-card__time-text">下单时间: {{ item.orderTime }}</text>
                    </view>
                        <text class="order-card__status" :class="{ 'order-card__status--highlight': item.actions && item.actions.length }">{{ item.statusText }}</text>
                    </view>
                    <view class="order-card__route-item">
                        <view class="order-card__point order-card__point--pickup">取</view>
                        <view class="order-card__route-texts">
                            <text class="order-card__route-title">{{ item.pickupName }}</text>
                            <text class="order-card__route-desc">{{ item.pickupAddress }}</text>
                        </view>
                    </view>
                    <view class="order-card__route-item order-card__route-item--delivery">
                        <view class="order-card__point order-card__point--delivery">送</view>
                        <view class="order-card__route-texts">
                            <text class="order-card__route-title">{{ item.deliveryName }}</text>
                            <text class="order-card__route-desc">{{ item.deliveryAddress }}</text>
                        </view>
                    </view>
                    <view class="order-card__footer">
                        <view class="order-card__arrival">
                            <image class="order-card__clock" src="/static/image/ic_clock@2x.png" mode="aspectFit"></image>
                            <text class="order-card__arrival-text">{{ item.arriveLabel || '送达时间:' }}{{ item.arriveTime }}</text>
                        </view>
                        <view class="order-card__price-wrap">
                            <text v-if="item.priceTag" class="order-card__price-tag">{{ item.priceTag }}</text>
                            <text class="order-card__price">{{ item.price }}</text>
                        </view>
                    </view>
                    <view v-if="item.actions && item.actions.length" class="order-card__actions">
                        <button
                            v-for="action in item.actions"
                            :key="action.text"
                            class="order-card__action-btn"
                            :class="['order-card__action-btn--' + action.type, { 'order-card__action-btn--primary-fill': action.fill }]"
                            hover-class="order-card__action-btn--hover"
                        >
                            {{ action.text }}
                        </button>
                    </view>
                </view>
            </view>
        </scroll-view>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                statusBarHeight: 0,
                navHeight: 0,
                activeTab: 'all',
                tabs: [
                    { label: '全部', value: 'all' },
                    { label: '待取货', value: 'pickup' },
                    { label: '配送中', value: 'delivering' },
                    { label: '已完成', value: 'finished' }
                ],
                orders: [
                    {
                        id: 1,
                        type: 'pickup',
                        badge: '标速达',
                        badgeType: 'blue',
                        orderTime: '2026-04-12 12:09',
                        statusText: '待取货',
                        pickupName: '中铁快运南站旗舰店',
                        pickupAddress: '莲花路200号莲花产业园F栋401',
                        deliveryName: '佳苑巴黎都市3期10栋301室',
                        deliveryAddress: '洞庭湖路与湖北路交叉口西150ç±³',
                        arriveLabel: '',
                        arriveTime: '45分钟内送达',
                        priceTag: '',
                        price: 'Â¥20.5',
                        actions: [
                            { text: '取消订单', type: 'light', fill: false },
                            { text: '取货码', type: 'primary', fill: false },
                            { text: '拍照取货', type: 'primary', fill: true }
                        ]
                    },
                    {
                        id: 4,
                        type: 'pickup',
                        badge: '极速达',
                        badgeType: 'red',
                        orderTime: '2026-04-12 12:33',
                        statusText: '待取货',
                        pickupName: '中铁快运南站旗舰店',
                        pickupAddress: '莲花路200号莲花产业园F栋401',
                        deliveryName: '佳苑巴黎都市3期10栋301室',
                        deliveryAddress: '洞庭湖路与湖北路交叉口西150ç±³',
                        arriveLabel: '',
                        arriveTime: '50分钟内送达',
                        priceTag: '',
                        price: 'Â¥20.5',
                        actions: [
                            { text: '取消订单', type: 'light', fill: false },
                            { text: '取货码', type: 'primary', fill: false },
                            { text: '拍照取货', type: 'primary', fill: true }
                        ]
                    },
                    {
                        id: 2,
                        type: 'delivering',
                        badge: '极速达',
                        badgeType: 'red',
                        orderTime: '2026-04-12 12:33',
                        statusText: '配送中',
                        pickupName: '中铁快运南站旗舰店',
                        pickupAddress: '莲花路200号莲花产业园F栋401',
                        deliveryName: '佳苑巴黎都市3期10栋301室',
                        deliveryAddress: '洞庭湖路与湖北路交叉口西150ç±³',
                        arriveLabel: '送达时间:',
                        arriveTime: '04-12 12:58',
                        priceTag: '',
                        price: 'Â¥20.5'
                    },
                    {
                        id: 5,
                        type: 'rated',
                        badge: '极速达',
                        badgeType: 'red',
                        orderTime: '2026-04-12 13:08',
                        statusText: '已评价',
                        pickupName: '中铁快运南站旗舰店',
                        pickupAddress: '莲花路200号莲花产业园F栋401',
                        deliveryName: '佳苑巴黎都市3期10栋301室',
                        deliveryAddress: '洞庭湖路与湖北路交叉口西150ç±³',
                        arriveLabel: '送达时间:',
                        arriveTime: '04-12 13:36',
                        priceTag: '',
                        price: 'Â¥18.8'
                    },
                    {
                        id: 6,
                        type: 'cancelled',
                        badge: '标速达',
                        badgeType: 'blue',
                        orderTime: '2026-04-12 13:18',
                        statusText: '已取消',
                        pickupName: '中铁快运南站旗舰店',
                        pickupAddress: '莲花路200号莲花产业园F栋401',
                        deliveryName: '佳苑巴黎都市3期10栋301室',
                        deliveryAddress: '洞庭湖路与湖北路交叉口西150ç±³',
                        arriveLabel: '送达时间:',
                        arriveTime: '04-12 13:52',
                        priceTag: '',
                        price: 'Â¥16.5'
                    },
                    {
                        id: 3,
                        type: 'finished',
                        badge: '极速达',
                        badgeType: 'red',
                        orderTime: '2026-04-12 12:33',
                        statusText: '已完成',
                        pickupName: '中铁快运南站旗舰店',
                        pickupAddress: '莲花路200号莲花产业园F栋401',
                        deliveryName: '佳苑巴黎都市3期10栋301室',
                        deliveryAddress: '洞庭湖路与湖北路交叉口西150ç±³',
                        arriveLabel: '送达时间:',
                        arriveTime: '04-12 12:58',
                        priceTag: '已结算',
                        price: 'Â¥20.5'
                    }
                ]
            }
        },
        computed: {
            displayTabs() {
                const countMap = {
                    pickup: this.orders.filter((item) => item.type === 'pickup').length,
                    delivering: this.orders.filter((item) => item.type === 'delivering').length,
                    finished: this.orders.filter((item) => item.type === 'finished').length
                }
                return this.tabs.map((tab) => {
                    if (!countMap[tab.value]) {
                        return tab
                    }
                    return {
                        ...tab,
                        label: `${tab.label} ${countMap[tab.value]}`
                    }
                })
            },
            bodyStyle() {
                return {
                    marginTop: this.navHeight + uni.upx2px(88) + 'px',
                    height: `calc(100vh - ${this.navHeight + uni.upx2px(88)}px)`
                }
            },
            currentOrders() {
                if (this.activeTab === 'all') {
                    return this.orders
                }
                return this.orders.filter((item) => item.type === this.activeTab)
            }
        },
        onLoad() {
            const systemInfo = uni.getSystemInfoSync()
            this.statusBarHeight = systemInfo.statusBarHeight || 0
            this.navHeight = this.statusBarHeight + uni.upx2px(88)
        },
        methods: {
            getBadgeIcon(badge) {
                const badgeMap = {
                    '极速达': '/static/image/ic_jisuda@2x.png',
                    '标速达': '/static/image/ic_biaosuda@2x.png'
                }
                return badgeMap[badge] || ''
            },
            goToOrderDetail(item) {
                uni.navigateTo({
                    url: `/pages/order-detail/order-detail?id=${item.id}&status=${item.type === 'delivering' ? 'delivering' : item.type === 'finished' ? 'finished' : item.type === 'cancelled' ? 'cancelled' : item.type === 'rated' ? 'rated' : 'pickup'}`
                })
            }
        }
    }
</script>
<style lang="scss" scoped>
    .order-page {
        height: 100vh;
        background: #f5f7fb;
        overflow: hidden;
        &__nav {
            position: fixed;
            left: 0;
            top: 0;
            right: 0;
            z-index: 10;
            background: linear-gradient(180deg, #1f73f6 0%, #1b6cf2 100%);
        }
        &__nav-inner {
            height: 88rpx;
            display: flex;
            align-items: center;
            padding: 0 28rpx;
        }
        &__nav-title {
            font-size: 38rpx;
            font-weight: 700;
            color: #ffffff;
        }
        &__tabs {
            position: fixed;
            left: 0;
            right: 0;
            z-index: 9;
            height: 88rpx;
            display: flex;
            align-items: center;
            background: #ffffff;
            box-shadow: 0 10rpx 20rpx rgba(40, 72, 128, 0.04);
        }
        &__tab {
            position: relative;
            flex: 1;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            &--active {
                .order-page__tab-text {
                    color: #272b33;
                    font-weight: 700;
                }
            }
        }
        &__tab-text {
            font-size: 30rpx;
            color: #8f96a3;
        }
        &__tab-line {
            position: absolute;
            left: 26rpx;
            right: 26rpx;
            bottom: 0;
            height: 4rpx;
            border-radius: 999rpx;
            background: #1a73f8;
        }
        &__body {
            box-sizing: border-box;
        }
        &__list {
            padding: 18rpx 22rpx calc(env(safe-area-inset-bottom) + 26rpx);
        }
    }
    .order-card {
        margin-bottom: 18rpx;
        padding: 20rpx 18rpx 18rpx;
        border-radius: 20rpx;
        background: #ffffff;
        box-shadow: 0 8rpx 20rpx rgba(43, 65, 106, 0.05);
        &__head {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        &__head-left {
            display: flex;
            align-items: center;
            gap: 12rpx;
            min-width: 0;
        }
        &__badge {
            padding: 4rpx 10rpx;
            border-radius: 10rpx;
            font-size: 22rpx;
            line-height: 1.2;
            font-weight: 600;
            &--blue {
                border: 1rpx solid #75cfff;
                color: #27a8f8;
                background: #eefaff;
            }
            &--red {
                border: 1rpx solid #ff8f8f;
                color: #ff5d5d;
                background: #fff1f1;
            }
        }
        &__badge-icon {
            width: 108rpx;
            height: 40rpx;
            flex-shrink: 0;
        }
        &__time-text,
        &__status,
        &__route-desc,
        &__arrival-text {
            font-size: 24rpx;
            color: #a1a7b2;
        }
        &__status {
            flex-shrink: 0;
            &--highlight {
                color: #ff4a3d;
                font-weight: 700;
            }
        }
        &__route-item {
            display: flex;
            align-items: flex-start;
            margin-top: 22rpx;
            &--delivery {
                margin-top: 20rpx;
            }
        }
        &__point {
            width: 34rpx;
            height: 34rpx;
            line-height: 34rpx;
            text-align: center;
            border-radius: 50%;
            font-size: 22rpx;
            font-weight: 700;
            color: #ffffff;
            flex-shrink: 0;
            margin-right: 16rpx;
            &--pickup {
                background: #2ab8ff;
            }
            &--delivery {
                background: #ff9d2e;
            }
        }
        &__route-texts {
            flex: 1;
            min-width: 0;
        }
        &__route-title {
            display: block;
            font-size: 34rpx;
            font-weight: 700;
            color: #2d3139;
            line-height: 1.3;
        }
        &__route-desc {
            display: block;
            margin-top: 8rpx;
            line-height: 1.4;
        }
        &__footer {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-top: 22rpx;
            padding-top: 16rpx;
            border-top: 1rpx solid #f0f2f6;
        }
        &__arrival {
            display: flex;
            align-items: center;
            gap: 10rpx;
        }
        &__clock {
            width: 24rpx;
            height: 24rpx;
            flex-shrink: 0;
        }
        &__price-wrap {
            display: flex;
            align-items: center;
            gap: 10rpx;
        }
        &__price-tag {
            padding: 3rpx 8rpx;
            border-radius: 8rpx;
            border: 1rpx solid #ff8f8f;
            font-size: 22rpx;
            font-weight: 600;
            color: #ff6a6a;
            background: #fff4f4;
        }
        &__price {
            font-size: 40rpx;
            font-weight: 700;
            color: #ff4030;
        }
        &__actions {
            display: flex;
            justify-content: flex-end;
            gap: 20rpx;
            margin-top: 18rpx;
            padding-top: 18rpx;
            border-top: 1rpx solid #f0f2f6;
        }
        &__action-btn {
            width: 160rpx;
            height: 64rpx;
            line-height: 64rpx;
            padding: 0;
            border-radius: 34rpx;
            font-size: 28rpx;
            font-weight: 500;
            border: 1rpx solid transparent;
            background: #ffffff;
            box-sizing: border-box;
            &::after {
                border: 0;
            }
            &--light {
                border-color: #d7dbe3;
                color: #8f96a3;
            }
            &--primary {
                border-color: #2c7cff;
                color: #2c7cff;
            }
            &--primary-fill {
                background: #2c7cff;
                color: #ffffff;
            }
            &--hover {
                opacity: 0.92;
            }
        }
    }
</style>
app/pages/settings/settings.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
<template>
    <view class="box">
        <view class="box-item" @click="jump">
            <text>修改密码</text>
            <image src="/static/image/mine_ar2@2x.png" mode="widthFix"></image>
        </view>
    </view>
</template>
<script>
    export default {
        data() {
            return {
            };
        },
        methods: {
            jump() {
                uni.navigateTo({
                    url: '/pages/change-password/change-password'
                })
            }
        }
    }
</script>
<style lang="scss" scoped>
    .box {
        width: 100%;
        padding: 0 30rpx;
        box-sizing: border-box;
        .box-item {
            width: 100%;
            height: 104rpx;
            display: flex;
            align-items: center;
            justify-content: space-between;
            border-bottom: 1rpx solid #E5E5E5;
            text {
                font-weight: 400;
                font-size: 30rpx;
                color: #222222;
            }
            image {
                width: 14rpx;
                height: 28rpx;
            }
        }
    }
</style>
app/static/bg_a.png
Binary files differ
app/static/bg_b.png
Binary files differ
app/static/image/background.png
app/static/image/btn_upload2@2x.png
app/static/image/default_nodata_grey@2x.png
app/static/image/ic_biaosuda@2x.png
app/static/image/ic_c1all@2x.png
app/static/image/ic_call@2x.png
app/static/image/ic_camera@2x.png
app/static/image/ic_cancle@2x.png
app/static/image/ic_clock@2x.png
app/static/image/ic_close2@2x.png
app/static/image/ic_close@2x.png
app/static/image/ic_daohang@2x.png
app/static/image/ic_fail@2x.png
app/static/image/ic_jiangpai@2x.png
app/static/image/ic_jisuda@2x.png
app/static/image/ic_pass@2x.png
app/static/image/ic_photo@2x.png
app/static/image/ic_pic@2x.png
app/static/image/ic_renzhengzhong@2x.png
app/static/image/ic_shaixuan@2x.png
app/static/image/ic_shaixuan_sel@2x.png
app/static/image/login_bg@2x.png
app/static/image/login_ic_account@2x.png
app/static/image/login_ic_account_sel@2x.png
app/static/image/login_ic_code@2x.png
app/static/image/login_ic_code_sel@2x.png
app/static/image/map_marker_end.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
<svg width="64" height="76" viewBox="0 0 64 76" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M32 75C31.1 75 30.2 74.6 29.6 73.8C24.9 68.2 8 47.2 8 31C8 17.7 18.7 7 32 7C45.3 7 56 17.7 56 31C56 47.2 39.1 68.2 34.4 73.8C33.8 74.6 32.9 75 32 75Z" fill="#FF5A5A"/>
<circle cx="32" cy="31" r="19" fill="white"/>
<text x="32" y="37" text-anchor="middle" font-size="24" font-family="Arial, sans-serif" font-weight="700" fill="#FF5A5A">终</text>
</svg>
app/static/image/map_marker_start.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
<svg width="64" height="76" viewBox="0 0 64 76" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M32 75C31.1 75 30.2 74.6 29.6 73.8C24.9 68.2 8 47.2 8 31C8 17.7 18.7 7 32 7C45.3 7 56 17.7 56 31C56 47.2 39.1 68.2 34.4 73.8C33.8 74.6 32.9 75 32 75Z" fill="#15BF74"/>
<circle cx="32" cy="31" r="19" fill="white"/>
<text x="32" y="37" text-anchor="middle" font-size="24" font-family="Arial, sans-serif" font-weight="700" fill="#15BF74">èµ·</text>
</svg>
app/static/image/mine_ar2@2x.png
app/static/image/ming_bg@2x.png
app/static/tabbar/nav_gongdan@2x.png
Binary files differ
app/static/tabbar/nav_gongdan_sel@2x.png
Binary files differ
app/static/tabbar/nav_home_sel@2x.png
app/static/tabbar/nav_home_sel@2x1.png
app/static/tabbar/nav_jiancha@2x.png
Binary files differ
app/static/tabbar/nav_jiancha_sel@2x.png
Binary files differ
app/static/tabbar/nav_mine@2x.png
app/static/tabbar/nav_mine@2x1.png
app/static/tabbar/nav_order@2x.png
app/static/tabbar/nav_order@2x1.png
app/static/tabbar/nav_shangbao@2x.png
Binary files differ
app/static/tabbar/nav_shangbao_sel@2x.png
Binary files differ
app/static/tabbar/nav_tubiao@2x.png
Binary files differ
app/static/tabbar/nav_tubiao_sel@2x.png
Binary files differ
app/static/tabbar/nav_xiaoxi@2x.png
app/static/tabbar/nav_xiaoxi@2x1.png
app/uni_modules/native-tts/android/.gradle/8.9/checksums/checksums.lock
Binary files differ
app/uni_modules/native-tts/android/.gradle/8.9/dependencies-accessors/gc.properties
app/uni_modules/native-tts/android/.gradle/8.9/fileChanges/last-build.bin
Binary files differ
app/uni_modules/native-tts/android/.gradle/8.9/fileHashes/fileHashes.lock
Binary files differ
app/uni_modules/native-tts/android/.gradle/8.9/gc.properties
app/uni_modules/native-tts/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock
Binary files differ
app/uni_modules/native-tts/android/.gradle/buildOutputCleanup/cache.properties
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,2 @@
#Wed Apr 22 17:09:11 CST 2026
gradle.version=8.9
app/uni_modules/native-tts/android/.gradle/vcs-1/gc.properties
app/unpackage/dist/dev/app-plus/app-config-service.js
@@ -1,8 +1,8 @@
var isReady=false;var onReadyCallbacks=[];
var isServiceReady=false;var onServiceReadyCallbacks=[];
var __uniConfig = {"pages":["pages/index/index","pages/mine/mine"],"window":{"navigationBarTextStyle":"black","navigationBarTitleText":"uni-app","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8"},"tabBar":{"color":"#999999","selectedColor":"#222222","borderStyle":"black","backgroundColor":"#fff","list":[{"pagePath":"pages/index/index","iconPath":"static/tabbar/nav_jiancha@2x.png","selectedIconPath":"static/tabbar/nav_jiancha_sel@2x.png","text":"首页"},{"pagePath":"pages/mine/mine","iconPath":"static/tabbar/nav_jiancha@2x.png","selectedIconPath":"static/tabbar/nav_jiancha_sel@2x.png","text":"我的"}]},"darkmode":false,"nvueCompiler":"uni-app","nvueStyleCompiler":"uni-app","renderer":"auto","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":false},"appname":"高铁站行李寄存","compilerVersion":"5.06","entryPagePath":"pages/index/index","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000}};
var __uniRoutes = [{"path":"/pages/index/index","meta":{"isQuit":true,"isTabBar":true},"window":{"navigationBarTitleText":"首页","navigationBarBackgroundColor":"#ffffff"}},{"path":"/pages/mine/mine","meta":{"isQuit":true,"isTabBar":true},"window":{"navigationBarTitleText":"我的","navigationBarBackgroundColor":"#ffffff"}}];
var __uniConfig = {"pages":["pages/guide-page/guide-page","pages/index/index","pages/mine/mine","pages/order/order","pages/order-detail/order-detail","pages/message/message","pages/login/login","pages/settings/settings","pages/change-password/change-password","pages/driver-certification/driver-certification","pages/certification-details/certification-details"],"window":{"navigationBarTextStyle":"black","navigationBarTitleText":"uni-app","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8"},"tabBar":{"color":"#999999","selectedColor":"#222222","borderStyle":"black","backgroundColor":"#fff","list":[{"pagePath":"pages/index/index","iconPath":"static/tabbar/nav_home_sel@2x.png","selectedIconPath":"static/tabbar/nav_home_sel@2x1.png","text":"大厅"},{"pagePath":"pages/order/order","iconPath":"static/tabbar/nav_order@2x.png","selectedIconPath":"static/tabbar/nav_order@2x1.png","text":"订单"},{"pagePath":"pages/message/message","iconPath":"static/tabbar/nav_xiaoxi@2x.png","selectedIconPath":"static/tabbar/nav_xiaoxi@2x1.png","text":"消息"},{"pagePath":"pages/mine/mine","iconPath":"static/tabbar/nav_mine@2x.png","selectedIconPath":"static/tabbar/nav_mine@2x1.png","text":"我的"}]},"darkmode":false,"nvueCompiler":"uni-app","nvueStyleCompiler":"uni-app","renderer":"auto","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":false},"appname":"高铁站行李寄存","compilerVersion":"5.07","entryPagePath":"pages/guide-page/guide-page","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000}};
var __uniRoutes = [{"path":"/pages/guide-page/guide-page","meta":{"isQuit":true},"window":{"titleNView":false}},{"path":"/pages/index/index","meta":{"isQuit":true,"isTabBar":true},"window":{"navigationStyle":"custom","titleNView":false}},{"path":"/pages/mine/mine","meta":{"isQuit":true,"isTabBar":true},"window":{"navigationStyle":"custom","titleNView":false}},{"path":"/pages/order/order","meta":{"isQuit":true,"isTabBar":true},"window":{"navigationStyle":"custom","titleNView":false}},{"path":"/pages/order-detail/order-detail","meta":{},"window":{"navigationStyle":"custom","titleNView":false}},{"path":"/pages/message/message","meta":{"isQuit":true,"isTabBar":true},"window":{"navigationStyle":"custom","titleNView":false}},{"path":"/pages/login/login","meta":{},"window":{"titleNView":false}},{"path":"/pages/settings/settings","meta":{},"window":{"navigationBarTitleText":"设置"}},{"path":"/pages/change-password/change-password","meta":{},"window":{"navigationBarTitleText":"修改密码"}},{"path":"/pages/driver-certification/driver-certification","meta":{},"window":{"navigationBarTitleText":"司机认证"}},{"path":"/pages/certification-details/certification-details","meta":{},"window":{"navigationBarTitleText":"司机认证"}}];
__uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
__uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:Math.round(f/20)})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,global:void 0,window:void 0,document:void 0,frames:void 0,self:void 0,location:void 0,navigator:void 0,localStorage:void 0,history:void 0,Caches:void 0,screen:void 0,alert:void 0,confirm:void 0,prompt:void 0,fetch:void 0,XMLHttpRequest:void 0,WebSocket:void 0,webkit:void 0,print:void 0}}}});
app/unpackage/dist/dev/app-plus/app-service.js
ÎļþÌ«´ó
app/unpackage/dist/dev/app-plus/app-view.js
ÎļþÌ«´ó
app/unpackage/dist/dev/app-plus/manifest.json
@@ -1 +1 @@
{"@platforms":["android","iPhone","iPad"],"id":"__UNI__965A7DA","name":"高铁站行李寄存","version":{"name":"1.0.0","code":"100"},"description":"","launch_path":"__uniappview.html","developer":{"name":"","email":"","url":""},"permissions":{"Push":{},"UniNView":{"description":"UniNView原生渲染"}},"plus":{"useragent":{"value":"uni-app","concatenate":true},"splashscreen":{"target":"id:1","autoclose":true,"waiting":true,"delay":0},"popGesture":"close","launchwebview":{"id":"1","kernel":"WKWebview"},"statusbar":{"immersed":"supportedDevice","style":"dark","background":"#F8F8F8"},"usingComponents":true,"nvueStyleCompiler":"uni-app","compilerVersion":3,"distribute":{"icons":{"android":{"hdpi":""}},"google":{"permissions":["<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>","<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>","<uses-permission android:name=\"android.permission.VIBRATE\"/>","<uses-permission android:name=\"android.permission.READ_LOGS\"/>","<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>","<uses-feature android:name=\"android.hardware.camera.autofocus\"/>","<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>","<uses-permission android:name=\"android.permission.CAMERA\"/>","<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>","<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>","<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>","<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>","<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>","<uses-feature android:name=\"android.hardware.camera\"/>","<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>","<uses-permission android:name=\"android.permission.INTERNET\"/>","<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>"]},"apple":{"dSYMs":false},"plugins":{"push":{"unipush":{"version":"2","offline":true,"honor":{},"meizu":{},"mi":{},"vivo":{},"oppo":{},"hms":{}}},"audio":{"mp3":{"description":"Android平台录音支持MP3格式文件"}}}},"uniStatistics":{"enable":false},"allowsInlineMediaPlayback":true,"safearea":{"background":"#fff","bottom":{"offset":"auto"}},"uni-app":{"compilerVersion":"5.06","control":"uni-v3","nvueCompiler":"uni-app","renderer":"auto","nvue":{"flex-direction":"column"},"nvueLaunchMode":"normal"},"tabBar":{"color":"#999999","selectedColor":"#222222","borderStyle":"rgba(0,0,0,0.4)","backgroundColor":"#fff","list":[{"pagePath":"pages/index/index","iconPath":"static/tabbar/nav_jiancha@2x.png","selectedIconPath":"static/tabbar/nav_jiancha_sel@2x.png","text":"首页"},{"pagePath":"pages/mine/mine","iconPath":"static/tabbar/nav_jiancha@2x.png","selectedIconPath":"static/tabbar/nav_jiancha_sel@2x.png","text":"我的"}],"height":"50px","child":["lauchwebview"],"selected":0},"launch_path":"__uniappview.html"},"locale":"zh-Hans"}
{"@platforms":["android","iPhone","iPad"],"id":"__UNI__965A7DA","name":"高铁站行李寄存","version":{"name":"1.0.0","code":"100"},"description":"","launch_path":"__uniappview.html","developer":{"name":"","email":"","url":""},"permissions":{"Push":{},"UniNView":{"description":"UniNView原生渲染"}},"plus":{"useragent":{"value":"uni-app","concatenate":true},"splashscreen":{"target":"id:1","autoclose":true,"waiting":true,"delay":0},"popGesture":"close","launchwebview":{"id":"1","kernel":"WKWebview"},"statusbar":{"immersed":"supportedDevice","style":"dark","background":"#F8F8F8"},"usingComponents":true,"nvueStyleCompiler":"uni-app","compilerVersion":3,"distribute":{"icons":{"android":{"hdpi":""}},"google":{"permissions":["<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>","<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>","<uses-permission android:name=\"android.permission.VIBRATE\"/>","<uses-permission android:name=\"android.permission.READ_LOGS\"/>","<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>","<uses-feature android:name=\"android.hardware.camera.autofocus\"/>","<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>","<uses-permission android:name=\"android.permission.CAMERA\"/>","<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>","<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>","<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>","<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>","<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>","<uses-feature android:name=\"android.hardware.camera\"/>","<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>","<uses-permission android:name=\"android.permission.INTERNET\"/>","<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>"]},"apple":{"dSYMs":false},"plugins":{"maps":{"amap":{"name":"","appkey_ios":"e4d46c87adf151dca20060317592b1b6","appkey_android":"e4d46c87adf151dca20060317592b1b6"}},"push":{"unipush":{"version":"2","offline":true,"honor":{},"meizu":{},"mi":{},"vivo":{},"oppo":{},"hms":{}}},"audio":{"mp3":{"description":"Android平台录音支持MP3格式文件"}}}},"uniStatistics":{"enable":false},"allowsInlineMediaPlayback":true,"safearea":{"background":"#fff","bottom":{"offset":"auto"}},"uni-app":{"compilerVersion":"5.07","control":"uni-v3","nvueCompiler":"uni-app","renderer":"auto","nvue":{"flex-direction":"column"},"nvueLaunchMode":"normal"},"tabBar":{"color":"#999999","selectedColor":"#222222","borderStyle":"rgba(0,0,0,0.4)","backgroundColor":"#fff","list":[{"pagePath":"pages/index/index","iconPath":"static/tabbar/nav_home_sel@2x.png","selectedIconPath":"static/tabbar/nav_home_sel@2x1.png","text":"大厅"},{"pagePath":"pages/order/order","iconPath":"static/tabbar/nav_order@2x.png","selectedIconPath":"static/tabbar/nav_order@2x1.png","text":"订单"},{"pagePath":"pages/message/message","iconPath":"static/tabbar/nav_xiaoxi@2x.png","selectedIconPath":"static/tabbar/nav_xiaoxi@2x1.png","text":"消息"},{"pagePath":"pages/mine/mine","iconPath":"static/tabbar/nav_mine@2x.png","selectedIconPath":"static/tabbar/nav_mine@2x1.png","text":"我的"}],"height":"50px"},"launch_path":"__uniappview.html"},"locale":"zh-Hans"}
app/unpackage/dist/dev/app-plus/static/bg_a.png
Binary files differ
app/unpackage/dist/dev/app-plus/static/bg_b.png
Binary files differ
app/unpackage/dist/dev/app-plus/static/image/background.png
app/unpackage/dist/dev/app-plus/static/image/btn_upload2@2x.png
app/unpackage/dist/dev/app-plus/static/image/default_nodata_grey@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_biaosuda@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_c1all@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_call@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_camera@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_cancle@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_clock@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_close2@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_close@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_daohang@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_fail@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_jiangpai@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_jisuda@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_pass@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_photo@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_pic@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_renzhengzhong@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_shaixuan@2x.png
app/unpackage/dist/dev/app-plus/static/image/ic_shaixuan_sel@2x.png
app/unpackage/dist/dev/app-plus/static/image/login_bg@2x.png
app/unpackage/dist/dev/app-plus/static/image/login_ic_account@2x.png
app/unpackage/dist/dev/app-plus/static/image/login_ic_account_sel@2x.png
app/unpackage/dist/dev/app-plus/static/image/login_ic_code@2x.png
app/unpackage/dist/dev/app-plus/static/image/login_ic_code_sel@2x.png
app/unpackage/dist/dev/app-plus/static/image/map_marker_end.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
<svg width="64" height="76" viewBox="0 0 64 76" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M32 75C31.1 75 30.2 74.6 29.6 73.8C24.9 68.2 8 47.2 8 31C8 17.7 18.7 7 32 7C45.3 7 56 17.7 56 31C56 47.2 39.1 68.2 34.4 73.8C33.8 74.6 32.9 75 32 75Z" fill="#FF5A5A"/>
<circle cx="32" cy="31" r="19" fill="white"/>
<text x="32" y="37" text-anchor="middle" font-size="24" font-family="Arial, sans-serif" font-weight="700" fill="#FF5A5A">终</text>
</svg>
app/unpackage/dist/dev/app-plus/static/image/map_marker_start.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
<svg width="64" height="76" viewBox="0 0 64 76" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M32 75C31.1 75 30.2 74.6 29.6 73.8C24.9 68.2 8 47.2 8 31C8 17.7 18.7 7 32 7C45.3 7 56 17.7 56 31C56 47.2 39.1 68.2 34.4 73.8C33.8 74.6 32.9 75 32 75Z" fill="#15BF74"/>
<circle cx="32" cy="31" r="19" fill="white"/>
<text x="32" y="37" text-anchor="middle" font-size="24" font-family="Arial, sans-serif" font-weight="700" fill="#15BF74">èµ·</text>
</svg>
app/unpackage/dist/dev/app-plus/static/image/mine_ar2@2x.png
app/unpackage/dist/dev/app-plus/static/image/ming_bg@2x.png
app/unpackage/dist/dev/app-plus/static/tabbar/nav_gongdan@2x.png
Binary files differ
app/unpackage/dist/dev/app-plus/static/tabbar/nav_gongdan_sel@2x.png
Binary files differ
app/unpackage/dist/dev/app-plus/static/tabbar/nav_home_sel@2x.png
app/unpackage/dist/dev/app-plus/static/tabbar/nav_home_sel@2x1.png
app/unpackage/dist/dev/app-plus/static/tabbar/nav_jiancha@2x.png
Binary files differ
app/unpackage/dist/dev/app-plus/static/tabbar/nav_jiancha_sel@2x.png
Binary files differ
app/unpackage/dist/dev/app-plus/static/tabbar/nav_mine@2x.png
app/unpackage/dist/dev/app-plus/static/tabbar/nav_mine@2x1.png
app/unpackage/dist/dev/app-plus/static/tabbar/nav_order@2x.png
app/unpackage/dist/dev/app-plus/static/tabbar/nav_order@2x1.png
app/unpackage/dist/dev/app-plus/static/tabbar/nav_shangbao@2x.png
Binary files differ
app/unpackage/dist/dev/app-plus/static/tabbar/nav_shangbao_sel@2x.png
Binary files differ
app/unpackage/dist/dev/app-plus/static/tabbar/nav_tubiao@2x.png
Binary files differ
app/unpackage/dist/dev/app-plus/static/tabbar/nav_tubiao_sel@2x.png
Binary files differ
app/unpackage/dist/dev/app-plus/static/tabbar/nav_xiaoxi@2x.png
app/unpackage/dist/dev/app-plus/static/tabbar/nav_xiaoxi@2x1.png
app/unpackage/dist/dev/mp-weixin/app.js
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/app.json
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/app.wxss
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/common/main.js
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/common/main.wxss
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/common/runtime.js
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/common/vendor.js
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/pages/index/index.js
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/pages/index/index.json
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/pages/index/index.wxml
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/pages/index/index.wxss
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/pages/mine/mine.js
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/pages/mine/mine.json
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/pages/mine/mine.wxml
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/pages/mine/mine.wxss
ÎļþÒÑɾ³ý
app/unpackage/dist/dev/mp-weixin/static/bg_a.png
Binary files differ
app/unpackage/dist/dev/mp-weixin/static/bg_b.png
Binary files differ
app/unpackage/dist/dev/mp-weixin/static/logo.png
Binary files differ
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_gongdan@2x.png
Binary files differ
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_gongdan_sel@2x.png
Binary files differ
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_jiancha@2x.png
Binary files differ
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_jiancha_sel@2x.png
Binary files differ
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_shangbao@2x.png
Binary files differ
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_shangbao_sel@2x.png
Binary files differ
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_tubiao@2x.png
Binary files differ
app/unpackage/dist/dev/mp-weixin/static/tabbar/nav_tubiao_sel@2x.png
Binary files differ
small-program/pages/delivery-order-detail/delivery-order-detail.vue
@@ -1,21 +1,21 @@
<template>
    <view class="detail">
        <view class="head" :style="{ height: statusbarHeight + navHeight + 'px' }">
        <view :class="info.type === 1?'head head1':'head head0'" :style="{ height: statusbarHeight + navHeight + 'px' }">
            <view :style="{width: '100%', height: statusbarHeight + 'px'}"></view>
            <view class="head-nav" :style="{width: '100%', height: navHeight + 'px'}">
                <image src="/static/icon/nav_ic_back.png" mode="widthFix"></image>
                <image src="/static/icon/nav_ic_back.png" mode="widthFix"  @click="goBack"></image>
                <text>寄存订单</text>
                <image src="/static/icon/nav_ic_back.png" mode="widthFix" style="opacity: 0;"></image>
                <image src="/static/icon/nav_ic_back.png" @click="goBack" mode="widthFix" style="opacity: 0;"></image>
            </view>
        </view>
        <view :style="{ width: '100%', height: statusbarHeight + navHeight + 'px' }"></view>
        <view class="nr">
        <view :class="info.type === 1?'nr head1':'nr head0'">
            <view class="nr-status">
                <text>待配送</text>
                <view class="nr-status-type">寄送</view>
                <view class="nr-status-type1">寄送</view>
                <text>{{info.statusName|| ''}}</text>
                <view class="nr-status-type1" v-if="info.type === 0">就地寄存</view>
                <view class="nr-status-type" v-else>同城寄送</view>
            </view>
            <view class="nr-desc">门店已接单,正在为您安排配送司机~</view>
            <view class="nr-desc" v-if="info.statusDesc">{{info.statusDesc || ''}}</view>
            <view class="item" style="padding: 10rpx;">
                <map name="mapAddr"></map>
            </view>
@@ -25,44 +25,44 @@
                        <view class="ji bg">寄</view>
                        <view class="xiantiao"></view>
                        <view class="addr-item-top">
                            <text>安徽省合肥市蜀山区莲花科技产业园F401</text>
                            <text>{{info.depositShopName || ''}}</text>
                            <image src="/static/icon/ar_jicundian@2x.png" mode="widthFix"></image>
                        </view>
                        <text>张海涛 18733987653</text>
                        <text>{{info.takeUser || ''}} {{info.takePhone || ''}}</text>
                    </view>
                    <view class="addr-item">
                        <view class="ji bg1">收</view>
                        <view class="addr-item-top">
                            <text>安徽省合肥市蜀山区莲花科技产业园F401</text>
                            <text>{{info.takeShopName || info.takeLocation || ''}}</text>
                            <image src="/static/icon/ar_jicundian@2x.png" mode="widthFix"></image>
                        </view>
                        <text>张海涛 18733987653</text>
                        <text>{{info.takeUser || ''}} {{info.takePhone || ''}}</text>
                    </view>
                </view>
                <view class="item-qrcode">
                    <image src="/static/image/btn_upload@2x.png" mode="widthFix"></image>
                    <text>767889</text>
                    <text>{{info.memberVerifyCode || ''}}</text>
                    <text>取件码</text>
                </view>
                <view class="item-x"></view>
                <view class="item-list">
                    <view class="item-list-row">
                        <view class="item-form-label">预计到店时间</view>
                        <view class="item-form-val">2026-04-12 12:00</view>
                        <view class="item-form-val">{{info.expectedDepositTime || ''}}</view>
                    </view>
                    <view class="item-list-row">
                        <view class="item-form-label">预计取件时间</view>
                        <view class="item-form-val">2026-04-14 12:00</view>
                        <view class="item-form-val">{{info.expectedTakeTime || ''}}</view>
                    </view>
                    <view class="item-list-row">
                        <view class="item-form-label">物品名称</view>
                        <view class="item-form-val">衣服</view>
                        <view class="item-form-val">{{info.typeName || ''}}</view>
                    </view>
                    <view class="item-list-row">
                        <view class="item-form-label">物品照片</view>
                        <view class="item-form-list">
                            <view class="item-form-list-row">
                                <image src="/static/image/tx@2x.png" mode="widthFix"></image>
                        <view class="item-form-list" v-if="info.orderImages && info.orderImages.length">
                            <view class="item-form-list-row" v-for="(item,index) in info.orderImages" key="item">
                                <image :src="item" mode="widthFix" @click="previewImage(info.orderImages,index)"></image>
                            </view>
                        </view>
                    </view>
@@ -72,60 +72,42 @@
                <view class="tuikuan">
                    <view class="tuikuan-top">
                        <text>退款金额</text>
                        <text>115.00</text>
                        <text>Â¥{{((info.refundAmount || 0)/100).toFixed(2)}}</text>
                    </view>
                    <view class="tuikuan-bottom">
                        <text>已退回您的支付账户</text>
                        <text>2026-04-12 12:32:00</text>
                        <text v-if="info.refundStatus === 0">退款中</text>
                        <text v-if="info.refundStatus === 1">已退回您的支付账户</text>
                        <text v-if="info.refundStatus === 2">退款失败</text>
                        <text>{{info.refundTime || ''}}</text>
                    </view>
                </view>
            </view>
            <view class="item">
            <view class="item" v-if="info.detailList">
                <view class="xl">
                    <view class="xl-item">
                    <view v-for="goods in info.detailList " :key="goods.luggageName" class="xl-item">
                        <view class="xl-item-top">
                            <text>大件行李箱</text>
                            <text>Â¥35</text>
                            <text>{{ goods.luggageName ||'' }}</text>
                            <text>Â¥{{((goods.subtotal || 0)/100).toFixed(2) }}</text>
                        </view>
                        <view class="xl-item-bottom">
                            <text>24-28寸</text>
                            <text>x1</text>
                            <text>{{ goods.luggageDetail || '' }}</text>
                            <text>x{{ goods.num || 1}}</text>
                        </view>
                    </view>
                    <view class="xl-item">
                        <view class="xl-item-top">
                            <text>中件行李箱</text>
                            <text>Â¥35</text>
                        </view>
                        <view class="xl-item-bottom">
                            <text>24-28寸</text>
                            <text>x1</text>
                        </view>
                    </view>
                    <view class="xl-item">
                        <view class="xl-item-top">
                            <text>小件行李箱</text>
                            <text>Â¥35</text>
                        </view>
                        <view class="xl-item-bottom">
                            <text>24-28寸</text>
                            <text>x1</text>
                        </view>
                    </view>
                    </view>
                </view>
                <view class="item-x"></view>
                <view class="item-list">
                    <view class="item-list-row">
                        <view class="item-form-label" style="color: #333333; font-size: 28rpx;">配送费</view>
                        <view class="item-form-val" style="color: #333333; font-size: 24rpx;">Â¥105.00</view>
                        <view class="item-form-label" style="color: #333333; font-size: 28rpx;">报价金额</view>
                        <view class="item-form-val" style="color: #333333; font-size: 24rpx;">Â¥{{((info.declaredAmount || 0)/100).toFixed(2)}}</view>
                    </view>
                    <view class="item-list-row">
                        <view class="item-form-label" style="color: #333333; font-size: 28rpx;">行李保费</view>
                        <view class="item-form-val" style="color: #333333; font-size: 24rpx;">Â¥10.00</view>
                        <view class="item-form-val" style="color: #333333; font-size: 24rpx;">Â¥{{((info.declaredFee || 0)/100).toFixed(2)}}</view>
                    </view>
                    <view class="item-list-row">
                        <view class="item-form-label" style="color: #222222; font-size: 30rpx; font-weight: 600;">实付款</view>
                        <view class="item-form-val price" style="color: #FE2C2E; font-size: 36rpx;">115.00</view>
                        <view class="item-form-val price" style="color: #FE2C2E; font-size: 36rpx;">{{((info.actualPayAmount || 0)/100).toFixed(2)}}</view>
                    </view>
                </view>
            </view>
@@ -135,20 +117,20 @@
                    <view class="item-infos-item">
                        <view class="item-infos-item-left">订单编号:</view>
                        <view class="item-infos-item-right">
                            <text>202107131742520001</text>
                            <text>{{info.code ||''}}</text>
                            <image src="/static/icon/ic_cppy@2x.png" mode="widthFix"></image>
                        </view>
                    </view>
                    <view class="item-infos-item">
                        <view class="item-infos-item-left">创建时间:</view>
                        <view class="item-infos-item-right">
                            <text>2026-04-12 12:00:00</text>
                            <text>{{info.createTime ||''}}</text>
                        </view>
                    </view>
                    <view class="item-infos-item">
                    <view class="item-infos-item" v-if="info.payTime">
                        <view class="item-infos-item-left">支付时间:</view>
                        <view class="item-infos-item-right">
                            <text>2026-04-12 12:00:00</text>
                            <text>{{info.payTime ||''}}</text>
                        </view>
                    </view>
                    <view class="item-infos-item">
@@ -157,51 +139,141 @@
                            <text>微信支付</text>
                        </view>
                    </view>
                    <view class="item-infos-item">
                    <view class="item-infos-item" v-if="info.outTradeNo">
                        <view class="item-infos-item-left">交易号:</view>
                        <view class="item-infos-item-right">
                            <text>2025080698723178237189237123</text>
                            <text>{{info.outTradeNo || ''}}</text>
                        </view>
                    </view>
                    <view class="item-infos-item">
                        <view class="item-infos-item-left">订单备注:</view>
                        <view class="item-infos-item-right">
                            <text>-</text>
                            <text>{{info.remark || ''}}</text>
                        </view>
                    </view>
                    <view class="item-infos-item">
                    <view class="item-infos-item" v-if="info.refundTime">
                        <view class="item-infos-item-left">申请退款:</view>
                        <view class="item-infos-item-right">
                            <text>2026-04-12 12:30:00</text>
                            <text>{{info.refundTime || ''}}</text>
                        </view>
                    </view>
                    <view class="item-infos-item">
                    <view class="item-infos-item" v-if="info.refundAmount">
                        <view class="item-infos-item-left">退款金额:</view>
                        <view class="item-infos-item-right">
                            <text>Â¥115.00</text>
                            <text>Â¥{{((info.refundAmount || 0)/100).toFixed(2)}}</text>
                        </view>
                    </view>
                    <view class="item-infos-item">
                    <view class="item-infos-item"  v-if="info.refundRemark">
                        <view class="item-infos-item-left">退款原因:</view>
                        <view class="item-infos-item-right">
                            <text>协商一致退款</text>
                            <text>{{info.refundRemark || ''}}</text>
                        </view>
                    </view>
                </view>
            </view>
            <view style="width: 100%; height: calc(210rpx + env(safe-area-inset-bottom));"></view>
        </view>
        <view class="tips">
        <view class="tips" v-if="info.overdue">
            <image src="/static/icon/ic_waring@2x.png" mode="widthFix"></image>
            <text>已超过取件时间,超时费用:¥10.00</text>
        </view>
        <view class="footer">
            <text>已超过取件时间,超时费用:¥{{((info.overdueFee || 0)/100).toFixed(2)}}元</text>
        </view>
        <view cclass="footer" v-if="info.type===0">
            <view class="footer-btns">
                <view class="btn kong">删除订单</view>
                <view class="btn you">评价订单</view>
                <view class="btn kong" @click="contactPhone(info,0)" v-if="info.status ===1 || info.status==2 || info.status===98">联系门店</view>
                <view class="btn kong" v-if="info.status ===0 || info.status ===1"  @click="cancelOrder(info)">取消订单</view>
                <view class="btn kong" @click="deleteOrder(info)" v-if="info.status ===7 || info.status===96 || info.status == 99">删除订单</view>
                <view class="btn you"  @click="payOrder(info)" v-if="info.status ===0">立即支付</view>
                <view class="btn you" v-if="info.status >=1 &&info.status <7 " @click="openQrcode(info)" >核销码</view>
                <view class="btn you" @click="evaluateOrder(info)" v-if="info.status ===7 && !info.commentStatus ">评价订单</view>
            </view>
            <view style="width: 100%; height: env(safe-area-inset-bottom);"></view>
        </view>
        <view class="footer" v-else>
            <view class="footer-btns">
                <view class="btn kong" @click="contactPhone(info,0)" v-if="info.status ===1 || info.status ==2">联系门店</view>
                <view class="btn kong" @click="contactPhone(info,2)" v-if="info.status ===3 || info.status ===4 ">联系骑手</view>
                <view class="btn kong" @click="contactPhone(info,1)" v-if="info.status ===5">联系门店</view>
                <view class="btn kong" v-if="info.status ===0"  @click="cancelOrder(info)">取消订单</view>
                <view class="btn you" @click="payOrder(info)" v-if="info.status ===0">立即支付</view>
                <view class="btn kong" @click="deleteOrder(info)" v-if="info.status ===7 || info.status===96 || info.status == 99">删除订单</view>
                <view class="btn you" @click="cancelOrder(info)" v-if="info.status ===1">申请退款</view>
                <view class="btn you" v-if="info.status ===1 || (info.takeShopId && info.status ===5)" @click="openQrcode(info)" >核销码</view>
                <view class="btn you"  @click="doneOrder(info)"  v-if="!info.takeShopId && info.status ===5">确认收货</view>
                <view class="btn you"  @click="evaluateOrder(info)" v-if="info.status ===7 && !info.commentStatus ">评价订单</view>
            </view>
        </view>
        <u-popup :show="showPhone" round="15" mode="bottom" :safeAreaInsetBottom="true"  @close="contactPhone()" :closeable="true" :closeOnClickOverlay="true">
            <view class="phone">
                <view class="phone-head">
                    <view></view>
                    <text>联系客户</text>
                </view>
                 <view class="phone-item" >
                     <view>
                        <image src="/static/icon/ic_call@2x.png" mode="widthFix" @click="contactPhoneDo()" ></image>
                        <text>{{linkinfo.linkname||''}} </text>
                        <text style="margin-left: 10px;"> {{linkinfo.linkphone||''}}</text>
                    </view>
                 </view>
                 <view style="width: 100%; height: 30rpx;"></view>
            </view>
        </u-popup>
        <!-- ç¡®è®¤æ”¶è´§ -->
        <u-popup :show="showDone" round="15" :safeAreaInsetBottom="false" mode="center">
            <view class="tc">
                <view class="tc-contemt">
                    <view class="tc-contemt-title">确认收货提醒</view>
                    <view class="tc-contemt-nr">
                        æ‚¨ç¡®è®¤å·²ç»æ”¶åˆ°æ‚¨çš„行李了吗?
                    </view>
                </view>
                <view class="tc-btn">
                    <view class="tc-btn-item" @click="showDone = false;currentOrder=null;">取消</view>
                    <view class="tc-btn-item" style="color: #004096;" @click="doneOrderDo()">确认收货</view>
                </view>
            </view>
        </u-popup>
        <u-popup :show="showCancel" round="15" :safeAreaInsetBottom="false" mode="center">
            <view class="tc">
                <view class="tc-contemt">
                    <view class="tc-contemt-title">确定取消提醒</view>
                    <view class="tc-contemt-nr">
                        æ‚¨ç¡®è®¤å–消该订单吗?
                    </view>
                </view>
                <view class="tc-btn">
                    <view class="tc-btn-item" @click="showCancel = false;currentOrder=null;">我再想想</view>
                    <view class="tc-btn-item" style="color: red;" @click="cancelOrderDo">确认取消</view>
                </view>
            </view>
        </u-popup>
        <!-- åˆ é™¤è®¢å• -->
        <u-popup :show="showDelete" round="15" :safeAreaInsetBottom="false" mode="center">
            <view class="tc">
                <view class="tc-contemt">
                    <view class="tc-contemt-title">确认删除提醒</view>
                    <view class="tc-contemt-nr">
                        æ‚¨ç¡®è®¤åˆ é™¤è¯¥è®¢å•吗?
                    </view>
                </view>
                <view class="tc-btn">
                    <view class="tc-btn-item" @click="showDelete = false;currentOrder=null;">我再想想</view>
                    <view class="tc-btn-item" style="color: red;" @click="deleteOrderDo">确认删除</view>
                </view>
            </view>
        </u-popup>
        <u-popup :show="showQrcode" round="15" @close="openQrcode()"   :safeAreaInsetBottom="false" mode="bottom"  :closeable="true" :closeOnClickOverlay="false">
            <view class="tc" style="height: 700rpx;width: 100%; ">
                <view class="tc-contemt" style="text-align: center;">
                    <view class="tc-contemt-title" style="text-align: center;">核销码</view>
                    <view class="qrcode-box">
                        <canvas canvas-id="qrcodeCanvas" id="qrcodeCanvas" style="width: 100px; height: 100px;"></canvas>
                        <image class="qrcode-image" :src="qrcodeImage" mode="widthFix"></image>
                    </view>
                    <text class="pickup-code">{{ currentOrder.memberVerifyCode||'' }}</text>
                    <text class="pickup-tip" @tap="copyCode">点击复制自提码</text>
                </view>
            </view>
        </u-popup>
    </view>
</template>
@@ -214,11 +286,172 @@
        },
        data() {
            return {
                id:null,
                info:{},
                showDone:false,
                showCancel:false,
                showDelete:false,
                showQrcode:false,
                showPay:false,
                showPhone:false
            }
        },
        methods: {
        onShow() {
            this.info={}
            this.showDone=false
            this.showCancel=false
            this.showDelete=false
            this.showQrcode=false
            this.showPay=false
            this.showPhone=false
            this.getUserDetail()
        },
        onLoad(options) {
            this.id = options.id
        },
        methods:{
            previewImage(images,index = 0) {
                uni.previewImage({
                    current: index,
                    urls: images
                });
            },
            payOrder(){
                var that = this;
                uni.showLoading({ title: '发起支付中...', mask: true })
                this.$u.api.continuePayOrder({
                    orderId: this.id
                }).then(res => {
                    uni.hideLoading()
                    if (res.code === 200 && res.data) {
                        let paymentData = res.data.response
                        uni.requestPayment({
                            provider: 'wxpay',
                            timeStamp: paymentData.timeStamp || '',
                            nonceStr: paymentData.nonceStr || '',
                            package: paymentData.package || '',
                            signType: paymentData.signType || 'MD5',
                            paySign: paymentData.paySign || '',
                            success: (res) => {
                                that.getUserDetail()
                            },
                            fail: (err) => {
                                if (err.errMsg.includes('cancel')) {
                                    uni.showToast({ title: '已取消支付', icon: 'none' })
                                } else {
                                    uni.showToast({ title: '支付失败', icon: 'none' })
                                }
                            }
                        })
                    } else {
                        uni.showToast({ title: res.msg || '支付失败', icon: 'none' })
                    }
                }).catch(err => {
                    uni.hideLoading()
                    uni.showToast({ title: '支付失败', icon: 'none' })
                })
            },
            doneOrder(item){
                this.showDone = !this.showDone
            },
            async  doneOrderDo(){
                var that =this
                let res = await this.$u.api.confirmReceipt({ orderId: this.id  });
                if (res.code === 200 ) {
                    that.showDone = false
                    that.getUserDetail()
                }
            },
            contactPhone(){
                 this.showPhone = !this.showPhone
            },
            contactPhoneDo(){
                if(this.info.linkphone !=null && this.info.linkphone!=''){
                    uni.makePhoneCall({
                       phoneNumber: this.info.linkphone
                    })
                }
            },
            cancelOrder(item){
                this.showCancel = !this.showCancel
            },
            deleteOrder(item){
                this.showDelete = !this.showDelete
            },
            async cancelOrderDo(){
                var that =this
                let res = await that.$u.api.cancelOrder({ orderId: this.id });
                if (res.code === 200 ) {
                    this.showCancel = false
                    uni.$emit('updateOrder',{info:this.info,delete:0})
                }
            },
            async deleteOrderDo(){
                if( this.currentOrder==null || this.currentOrder.id == null) {
                    return
                }
                var that =this
                let res = await that.$u.api.deleteOrder({ orderId: this.currentOrder.id  });
                if (res.code === 200 ) {
                    this.showDelete = false
                    uni.$emit('updateOrder',{info:this.info,delete:1})
                    this.goBack()
                }
            },
            copyCode() {
                if (!this.currentOrder || !this.info.memberVerifyCode) {
                    return
                }
                uni.setClipboardData({
                    data: this.info.memberVerifyCode,
                    success: () => {
                        uni.showToast({
                            title: '已复制自提码',
                            icon: 'none'
                        })
                    }
                })
            },
            async openQrcode(){
                this.qrcodeImage=null
                var that =this
                if(!this.showQrcode){
                    this.showQrcode =true
                    drawQrcode({
                        canvasId: 'qrcodeCanvas',
                        text: this.info.memberVerifyCode,
                        width: 100,
                        height: 100,
                        correctLevel: 2
                    })
                    setTimeout(() => {
                        uni.canvasToTempFilePath({
                            canvasId: 'qrcodeCanvas',
                            success: (res) => {
                                that.qrcodeImage = res.tempFilePath
                            }
                        }, this)
                    }, 100)
                }else{
                    this.showQrcode = false
                }
            },
            evaluateOrder(){
                uni.navigateTo({
                    url:"/pages/evaluate/evaluate?id="+this.info.id
                })
            },
            goBack(){
                uni.navigateBack({delta:-1})
            },
            async  getUserDetail(){
                var that =this
                let res = await this.$u.api.getOrderDetail( this.id  )
                if (res.code === 200) {
                    this.info = res.data
                    uni.$emit('updateOrder',{info:this.info,delete:0})
                }
            }
        }
    }
</script>
@@ -292,9 +525,14 @@
                }
            }
        }
        .head0{
            background: #1ba8fa;
        }
        .head1{
            background: #E4730B;
        }
        .head {
            width: 100%;
            background: #E4730B;
            padding: 0 30rpx;
            box-sizing: border-box;
            position: fixed;
@@ -322,7 +560,7 @@
            height: 264rpx;
            padding: 22rpx 30rpx;
            box-sizing: border-box;
            background-color: #E4730B;
            // background-color: #E4730B;
            .nr-status {
                display: flex;
                align-items: baseline;
@@ -333,7 +571,7 @@
                    margin-right: 16rpx;
                }
                .nr-status-type {
                    width: 64rpx;
                    width: 164rpx;
                    height: 38rpx;
                    display: flex;
                    align-items: center;
@@ -345,7 +583,7 @@
                    color: #FA8010;
                }
                .nr-status-type1 {
                    width: 88rpx;
                    width: 188rpx;
                    height: 38rpx;
                    display: flex;
                    align-items: center;
small-program/pages/evaluate/evaluate.vue
@@ -4,20 +4,19 @@
            <view class="rate-block">
                <view class="title-row">
                    <text class="title-label">寄件门店:</text>
                    <text class="title-value">中铁快运南站旗舰店</text>
                    <text class="title-value">{{info.depositShopName||''}}</text>
                </view>
                <view class="star-row">
                    <view class="star-list">
                        <!-- <view
                        <view
                            v-for="n in 5"
                            :key="'shop-' + n"
                            class="star-item"
                            :class="{ active: n <= shopRate, dashed: n === 1 || n === 3 }"
                            @tap="shopRate = n"
                        >★</view> -->
                        <u-rate :count="count" activeColor="#FFC331" v-model="value"></u-rate>
                            :class="{ active: n < form.depositScore, dashed: n === 1 || n === 3 }"
                            @tap="form.depositScore = n+1"
                        >★</view>
                    </view>
                    <text class="rate-text">{{ shopRate }}星</text>
                    <text class="rate-text">{{ form.depositScore }}星</text>
                </view>
            </view>
@@ -26,67 +25,67 @@
            <view class="rate-block">
                <view class="title-row">
                    <text class="title-label">配送司机:</text>
                    <text class="title-value">张伟</text>
                    <text class="title-value">{{info.driverName || ''}}</text>
                </view>
                <view class="star-row no-text-row">
                <view class="star-row">
                    <view class="star-list">
                        <!-- <view
                        <view
                            v-for="n in 5"
                            :key="'driver-' + n"
                            class="star-item"
                            :class="{ active: n <= driverRate, dashed: n === 1 }"
                            @tap="driverRate = n"
                        >★</view> -->
                        <u-rate :count="count" activeColor="#FFC331" v-model="value"></u-rate>
                            :class="{ active: n < form.driverScore, dashed: n === 1 }"
                            @tap=" form.driverScore = n+1"
                        >★</view>
                    </view>
                    <text class="rate-text">{{ form.driverScore }}星</text>
                </view>
            </view>
            <view class="divider"></view>
            <view class="rate-block">
            <view class="rate-block" v-if="info.type ===1 && info.takeShopId ">
                <view class="title-row">
                    <text class="title-label">收件门店:</text>
                    <text class="title-value">中铁快运合肥站旗舰店</text>
                    <text class="title-value">{{info.takeShopName || 0}}</text>
                </view>
                <view class="star-row no-text-row">
                <view class="star-row">
                    <view class="star-list">
                        <!-- <view
                        <view
                            v-for="n in 5"
                            :key="'receive-' + n"
                            class="star-item"
                            :class="{ active: n <= receiveRate, dashed: n === 1 }"
                            @tap="receiveRate = n"
                        >★</view> -->
                        <u-rate :count="count" activeColor="#FFC331" v-model="value"></u-rate>
                            :class="{ active: n < form.takeScore, dashed: n === 1 }"
                            @tap="form.takeScore = n+1"
                        >★</view>
                    </view>
                    <text class="rate-text">{{ form.takeScore }}星</text>
                </view>
            </view>
            <view class="divider"></view>
            <view class="upload-row">
                <view class="upload-box">
                <view class="upload-box" @click="chooseAndUploadImage(9)">
                    <view class="upload-plus">+</view>
                    <text class="upload-text">上传照片</text>
                </view>
                <view v-for="(item, index) in photoList" :key="index" class="photo-box">
                    <image class="photo-image" :src="item" mode="aspectFill"></image>
                    <text class="photo-delete">删除</text>
                    <image class="photo-image" :src="item.url" mode="aspectFill"></image>
                    <text class="photo-delete" @click="deleteImage(index)">删除</text>
                </view>
            </view>
            <view class="textarea-box">
                <view class="textarea-placeholder-wrap">
                    <view class="textarea-icon"></view>
                    <textarea v-model="content" class="textarea" maxlength="200" placeholder="请说说您对本次服务的感受" placeholder-class="textarea-placeholder"></textarea>
                    <textarea v-model="form.content" class="textarea" maxlength="200" placeholder="请说说您对本次服务的感受" placeholder-class="textarea-placeholder"></textarea>
                </view>
                <text class="textarea-count">{{ content.length }}/200</text>
                <text class="textarea-count">{{ form.content.length }}/200</text>
            </view>
        </view>
        <view class="submit-wrap">
            <view class="submit-btn">提交评价</view>
            <view class="submit-btn" @click="orderComment">提交评价</view>
        </view>
    </view>
</template>
@@ -95,16 +94,139 @@
    export default {
        data() {
            return {
                shopRate: 2,
                driverRate: 0,
                receiveRate: 0,
                content: '',
                id:null,
                info:{},
                form:{
                   content: "",
                   depositScore: 5,
                   driverScore: 5,
                   orderId: null,
                   takeScore: 5,
                   fileList:[]
                },
                photoList: [
                    '/static/icon/nav_home_sel@2x.png',
                    '/static/icon/nav_xingcheng_sel@2x.png'
                ],
                count: 5,
                value: 2
                ]
            }
        },
        onShow() {
            this.info={}
            this.getUserDetail()
        },
        onLoad(options) {
            this.id = options.id
            this.photoList=[]
            this.form={
               content: "",
               depositScore: 5,
               driverScore: 5,
               orderId: this.id,
               takeScore: 5,
               images:[]
            }
        },
        methods:{
            deleteImage(index) {
                this.photoList.splice(index, 1)
                this.form.images.splice(index, 1)
            },
            async uploadFiles(filePaths, maxCount = 9) {
                if (!filePaths || filePaths.length === 0) {
                    return []
                }
                const limitedPaths = filePaths.slice(0, maxCount)
                const uploadTasks = limitedPaths.map(filePath => {
                    return new Promise((resolve, reject) => {
                        uni.uploadFile({
                            url: this.$baseUrl + '/web/public/upload',
                            filePath: filePath,
                            name: 'file',
                            formData: {
                                folder: 'orders'
                            },
                            success: (res) => {
                                if (res.statusCode === 200) {
                                    const data = JSON.parse(res.data)
                                    if (data.code === 200) {
                                        resolve(data.data)
                                    } else {
                                        reject(new Error(data.msg || '上传失败'))
                                    }
                                } else {
                                    reject(new Error('上传失败'))
                                }
                            },
                            fail: (err) => {
                                reject(err)
                            }
                        })
                    })
                })
                try {
                    const results = await Promise.all(uploadTasks)
                    return results
                } catch (error) {
                    uni.showToast({
                        title: '上传失败',
                        icon: 'none'
                    })
                    throw error
                }
            },
            async chooseAndUploadImage(maxCount = 9) {
                const currentCount = this.form.images.length
                const remainingCount = maxCount - currentCount
                if (remainingCount <= 0) {
                    uni.showToast({
                        title: `最多上传${maxCount}张图片`,
                        icon: 'none'
                    })
                    return
                }
                var that = this
                uni.chooseImage({
                    count: remainingCount,
                    sizeType: ['compressed'],
                    sourceType: ['album', 'camera'],
                    success: async (res) => {
                        const tempFilePaths = res.tempFilePaths
                        uni.showLoading({
                            title: '上传中...',
                            mask: true
                        })
                        try {
                            const uploadResults = await that.uploadFiles(tempFilePaths, maxCount)
                            const fullPaths = uploadResults.map(item => item.url || item.path || item)
                            that.photoList = [...that.photoList, ...fullPaths.map(url => ({ url }))]
                            that.form.images = [...that.form.images, ...fullPaths]
                            uni.hideLoading()
                            uni.showToast({
                                title: '上传成功',
                                icon: 'success'
                            })
                        } catch (error) {
                            uni.hideLoading()
                        }
                    }
                })
            },
            async orderComment(){
                var that =this
                let res = await that.$u.api.orderComment(this.form);
                if (res.code === 200 ) {
                    this.info.commentStatus == 1
                    uni.$emit('updateOrder',{info:this.info,delete:0})
                    uni.navigateBack({delta:-1})
                }
            },
            async  getUserDetail(){
                var that =this
                let res = await this.$u.api.getOrderDetail( this.id  )
                if (res.code === 200) {
                    this.info = res.data
                    uni.$emit('updateOrder',{info:this.info,delete:0})
                }
            }
        }
    }
small-program/pages/itinerary/itinerary.vue
@@ -26,7 +26,7 @@
        <view class="content-wrap">
            <view class="page-padding card-list">
                <view v-for="(item, index) in dataList" :key="item.id" class="order-card">
                    <view class="order-head" :class="item.mode === 'city' ? 'city-head-bg' : 'local-head-bg'">
                    <view class="order-head" :class="item.mode === 'city' ? 'city-head-bg' : 'local-head-bg'"  @click="jumpOrderDetail(item.id)">
                        <view v-if="item.type === 0" class="head-local">
                            <view class="mode-tag local-tag">就地寄存</view>
                            <view class="head-copy single-copy">
@@ -34,7 +34,7 @@
                                <text class="head-user">{{ item.takeUser ||'' }}</text>
                            </view>
                            <text v-if="item.status < 7" class=" status-text status-orange">{{ item.statusName||'' }}</text>
                            <text v-else-if="item.status ===7" class=" status-text">{{ item.statusName||'' }}</text>
                            <text v-else-if="item.status ===7" class=" status-text  status-grey">{{ item.statusName||'' }}</text>
                            <text v-else-if="item.status >7" class=" status-text status-grey">{{ item.statusName||'' }}</text>
                        </view>    
                        <view v-else class="head-city">
@@ -49,15 +49,14 @@
                            </view>
                            <view class="head-copy city-right align-right">
                                <text v-if="item.status < 7" class=" status-text status-orange">{{ item.statusName||'' }}</text>
                                <text v-else-if="item.status ===7" class="status-text">{{ item.statusName||'' }}</text>
                                <text v-else-if="item.status ===7" class="status-text  status-grey" >{{ item.statusName||'' }}</text>
                                <text v-else-if="item.status >7" class=" status-text status-grey">{{ item.statusName||'' }}</text>
                                <text class="head-name text-ellipsis">{{ item.takeShopName||'对对对' }}</text>
                                <text class="head-name text-ellipsis">{{ item.takeShopName || item.takeLocation||'' }}</text>
                                <text class="head-user">{{ item.takeUser||'' }}</text>
                            </view>
                        </view>
                    </view>
                    <view class="goods-area" v-if="item.detailList">
                    <view class="goods-area" v-if="item.detailList" @click="jumpOrderDetail(item.id)">
                        <view v-for="goods in item.detailList " :key="goods.luggageName" class="goods-row">
                            <view class="goods-left">
                                <text class="goods-name">{{ goods.luggageName ||'' }}</text>
@@ -94,7 +93,7 @@
                            <view class="footer-btn contact-btn" @click="deleteOrder(item)" v-if="item.status ===7 || item.status===96 || item.status == 99">删除订单</view>
                            <view class="footer-btn primary-btn"  @click="payOrder(item)" v-if="item.status ===0">立即支付</view>
                            <view class="footer-btn primary-btn" v-if="item.status >=1 &&item.status <7 " @click="openQrcode(item)" >核销码</view>
                            <view class="footer-btn primary-btn" v-if="item.status ===7 && !commentStatus ">评价订单</view>
                            <view class="footer-btn primary-btn" @click="evaluateOrder(item)" v-if="item.status ===7 && !item.commentStatus ">评价订单</view>
                        </view>
                        <view class="footer-actions" v-else>
                            <view class="footer-btn contact-btn" @click="contactPhone(item,0)" v-if="item.status ===1 || item.status ==2">联系门店</view> 
@@ -106,7 +105,7 @@
                            <view class="footer-btn primary-btn" @click="cancelOrder(item)" v-if="item.status ===1">申请退款</view>
                            <view class="footer-btn primary-btn" v-if="item.status ===1 || (item.takeShopId && item.status ===5)" @click="openQrcode(item)" >核销码</view>
                            <view class="footer-btn primary-btn"  @click="doneOrder(item)"  v-if="!item.takeShopId && item.status ===5">确认收货</view>
                            <view class="footer-btn primary-btn" v-if="item.status ===7 && !commentStatus ">评价订单</view>
                            <view class="footer-btn primary-btn"  @click="evaluateOrder(item)" v-if="item.status ===7 && !item.commentStatus ">评价订单</view>
                        </view>
                    </view>
                </view>
@@ -197,11 +196,13 @@
                </view>
            </view>
        </u-popup>
        <custom-tabbar></custom-tabbar>
    </view>
</template>
<script>
    import { mapState } from 'vuex'
    import CustomTabbar from '@/components/custom-tabbar/custom-tabbar.vue'
    import drawQrcode from 'weapp-qrcode'
    export default {
        computed: {
@@ -261,6 +262,7 @@
                        if(item.id==data.info.orderId){
                             console.log('监听到事件来自 update 02:' ,data);
                            item.status = data.info.orderStatus
                            item.commentStatus = data.info.commentStatus
                        }
                    }) 
                }
@@ -473,7 +475,12 @@
            },
            jumpOrderDetail(id){
                uni.navigateTo({
                    url:'/pages/details-entry/details-entry?userType='+this.userType+'&id='+id
                    url:'/pages/delivery-order-detail/delivery-order-detail?userType=0&id='+id
                })
            },
            evaluateOrder(item){
                uni.navigateTo({
                    url:"/pages/evaluate/evaluate?id="+item.id
                })
            }
        }
@@ -675,9 +682,11 @@
    }
    .text-ellipsis {
        display: block;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        max-width: 100%;
    }
    .city-arrow {
small-program/utils/http.api.js
@@ -46,8 +46,10 @@
    let cancelOrder = (data = {}) => vm.$u.http.post('web/order/cancel', data);    // å–消订单
    let confirmReceipt = (data = {}) => vm.$u.http.post('web/order/confirmReceipt/'+data.orderId, data);    // ä¼šå‘˜ç¡®è®¤æ”¶è´§ 
    let continuePayOrder = (data = {}) => vm.$u.http.post('web/order/continuePay/'+data.orderId, data);    //继续发起支付
    let orderComment = (data = {}) => vm.$u.http.post('web/order/comment', data);    //订单评价
    
    vm.$u.api = {
        orderComment,
        confirmReceipt,
        cancelOrder,
        deleteOrder,