From 5abcde36961125cbf436f91b8c17610a6b5f8308 Mon Sep 17 00:00:00 2001
From: sen <sen@qq.com>
Date: 星期三, 15 四月 2026 12:15:08 +0800
Subject: [PATCH] 修改调度单必填校验

---
 ui/car_wx_app/pages/beReferred/index.vue |  816 ++++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 601 insertions(+), 215 deletions(-)

diff --git a/ui/car_wx_app/pages/beReferred/index.vue b/ui/car_wx_app/pages/beReferred/index.vue
index 8b6b9f2..13de592 100644
--- a/ui/car_wx_app/pages/beReferred/index.vue
+++ b/ui/car_wx_app/pages/beReferred/index.vue
@@ -1,262 +1,648 @@
 <template>
-    <view class="container">
-        <!-- 鏍囬鏍� -->
-          <u-navbar :placeholder="true" bgColor="#409effc1"  :titleStyle="{ color: '#fff'}" title="琚寚娲捐绋�">
-            <view slot="left" class="u-nav-slot" @click="leftClick">
-              <u-icon color="#fff" name="list" size="28"></u-icon>
+  <view class="container">
+    <!-- 鑷畾涔夊鑸爮 -->
+    <u-navbar
+      :placeholder="true"
+      bg-color="#409eff"
+      title="琚寚娲捐绋�"
+      :title-style="{ color: '#fff', fontSize: '16px', fontWeight: 500 }"
+    >
+      <view slot="left" class="nav-left-slot" @click="toggleSidebar">
+        <u-icon name="list" color="#fff" size="22" />
+      </view>
+    </u-navbar>
+
+    <!-- 涓昏鍐呭鍖� -->
+    <view class="main-content">
+      <!-- 涓嬫媺鍒锋柊瀹瑰櫒 -->
+      <scroll-view
+        class="task-scroll"
+        scroll-y
+        :refresher-enabled="true"
+        :refresher-triggered="isRefreshing"
+        @refresherrefresh="onRefresh"
+        @scrolltolower="onLoadMore"
+        :lower-threshold="100"
+      >
+        <view class="scroll-content">
+          <!-- 鍔犺浇楠ㄦ灦灞� -->
+          <view v-if="loading && !taskList.length">
+            <view v-for="i in 3" :key="i" class="skeleton-item">
+              <u-skeleton :rows="4" :title="false" avatar avatar-size="0" />
             </view>
-          </u-navbar>
-
-        <!-- 琛岀▼鍒楄〃-鍙笅鎷夋粴鍔� -->
-        <scroll-view class="task-scroll" scroll-y="true" style="height: calc(100vh - 120rpx);">
-            <view class="task-item" v-for="(item, index) in taskList" :key="index" @click="historyClick(item)">
-                <view class="task-field">
-                    <view class="field-label">璋冨害鍗曞彿</view>
-                    <view class="field-value">{{ item.dispatchNo }}</view>
-                </view>
-                <view class="task-field">
-                    <view class="field-label">杩愯緭宸ュ叿鍙风爜</view>
-                    <view class="field-value">{{ item.licensePlate }}</view>
-                </view>
-                <view class="task-field">
-                    <view class="field-label">璺嚎</view>
-                    <view class="field-value">{{ item.transportLine }}</view>
-                </view>
-                <view class="task-field">
-                    <view class="field-label">瀹㈡埛</view>
-                    <view class="field-value">{{ item.customerName }}</view>
-                </view>
-                <view class="task-field">
-                    <view class="field-label">褰撳墠鐘舵��</view>
-                    <view class="field-value status">{{ item.statusStr }}</view>
-                </view>
-                <view class="task-field">
-                    <view class="field-label">瑕佹眰鏈�鏅氬彂杞︽椂闂�</view>
-                    <view class="field-value">{{ item.latestDeparture }}</view>
-                </view>
-            </view>
-        </scroll-view>
-
-        <!-- 搴曢儴鎿嶄綔鏍� -->
-        <view class="bottom-bar">
-            <u-button class="bottom-btn" @click="goToURL" text="鍘嗗彶璋冨害鍗�"></u-button>
-            <!-- <view class="bottom-btn">鍨粯鍒楄〃</view> -->
-            <u-button class="bottom-btn" @click="goToURLDF" text="鍨粯鍒楄〃"></u-button>
-
-        </view>
-
-
-      <u-popup :zIndex="1000" :overlayZIndex="999" :show="show" mode="left" @close="close">
-        <view style="width: 250px">
-          <view class="logo-info">
-            <image src="/static/oss.png" style="width: 120px;height: 120px"></image>
-            <h3 class="company">鏅烘収鐗╂祦璋冨害骞冲彴</h3>
           </view>
-          <text class="lout" @click="goToUrl('/pages/login/index')">閫�鍑虹櫥褰�</text>
+
+          <!-- 绌虹姸鎬� -->
+          <view v-else-if="!taskList.length" class="empty-state">
+            <u-empty mode="list" text="鏆傛棤琚寚娲捐绋�" />
+          </view>
+
+          <!-- 琛岀▼鍒楄〃 -->
+          <view v-else>
+            <view
+              v-for="item in taskList"
+              :key="item.dispatchId"
+              class="task-card"
+              @click="handleTaskClick(item)"
+            >
+              <!-- 鍗$墖澶撮儴锛氬崟鍙峰拰鐘舵�� -->
+              <view class="card-header">
+                <view class="dispatch-no">
+                  <text class="label">璋冨害鍗曞彿</text>
+                  <text class="value">{{ item.dispatchNo }}</text>
+                </view>
+                <view class="status-tag" :class="item.statusClass">
+                  {{ item.statusStr }}
+                </view>
+              </view>
+
+              <!-- 鍗$墖涓讳綋 -->
+              <view class="card-body">
+                <view class="info-row">
+                  <u-icon name="car" size="16" color="#909399" />
+                  <text class="info-text">{{ item.licensePlate || '鏈垎閰嶈溅杈�' }}</text>
+                </view>
+
+                <view class="route-section">
+                  <view class="route-line">
+                    <view class="route-dot start" />
+                    <view class="route-path" />
+                    <view class="route-dot end" />
+                  </view>
+                  <view class="route-info">
+                    <text class="route-text">{{ item.transportLine || '鏆傛棤璺嚎淇℃伅' }}</text>
+                  </view>
+                </view>
+
+                <view class="info-row">
+                  <u-icon name="account" size="16" color="#909399" />
+                  <text class="info-text">{{ item.customerName || '鏈煡瀹㈡埛' }}</text>
+                </view>
+
+                <view class="info-row time-row">
+                  <u-icon name="clock" size="16" color="#f0ae2d" />
+                  <text class="time-text">鏈�鏅氬彂杞︼細{{ item.latestDeparture }}</text>
+                </view>
+              </view>
+            </view>
+
+            <!-- 鍔犺浇鏇村 -->
+            <view class="load-more">
+              <u-loading-icon v-if="loadingMore" size="16" text="鍔犺浇涓�..." />
+              <text v-else-if="!hasMore" class="no-more">娌℃湁鏇村浜�</text>
+            </view>
+          </view>
+        </view>
+      </scroll-view>
+    </view>
+
+    <!-- 搴曢儴鎿嶄綔鏍� -->
+    <view class="bottom-bar">
+      <view class="bottom-btn" @click="goToHistory">
+        <u-icon name="order" size="18" color="#409eff" />
+        <text>鍘嗗彶璋冨害鍗�</text>
+      </view>
+      <view class="divider" />
+      <view class="bottom-btn" @click="goToPaymentList">
+        <u-icon name="red-packet" size="18" color="#ff6b6b" />
+        <text>鍨粯鍒楄〃</text>
+      </view>
+    </view>
+
+    <!-- 渚ц竟鏍忓脊绐� -->
+    <u-popup
+      :show="showSidebar"
+      mode="left"
+      :overlay-opacity="0.3"
+      @close="closeSidebar"
+    >
+      <view class="sidebar-content">
+        <view class="sidebar-header">
+          <image src="/static/oss.png" class="logo" mode="aspectFit" />
+          <text class="company-name">鏅烘収鐗╂祦璋冨害骞冲彴</text>
         </view>
 
-      </u-popup>
-
-    </view>
+        <view class="sidebar-menu">
+          <view class="menu-item" @click="handleLogout">
+            <text class="menu-text">閫�鍑虹櫥褰�</text>
+          </view>
+        </view>
+      </view>
+    </u-popup>
+  </view>
 </template>
 
 <script>
+import { getSsignedItineraryList } from '@/common/beReferred'
+import { navigateTo, PAGES } from '@/common/router'
 
-import { getSsignedItineraryList } from "@/common/beReferred";
+// 鐘舵�佹槧灏勯厤缃�
+const STATUS_MAP = {
+  '寰呯敥鎸�': { class: 'status-pending', color: '#ff6b6b' },
+  '寰呮帴鎸�': { class: 'status-pending', color: '#ff6b6b' },
+  '杩愯緭涓�': { class: 'status-transporting', color: '#409eff' },
+  '宸插畬鎴�': { class: 'status-completed', color: '#67c23a' },
+  '宸插彇娑�': { class: 'status-cancelled', color: '#909399' }
+}
 
 export default {
-    data() {
-        return {
-            taskList: [
-
-            ],
-          show:false,
-        };
-    },
-    created() {
-        this.getList();
-    },
-    methods: {
-        getList() {
-            
-
-
-            getSsignedItineraryList().then((res1) => {
-				console.log(res1);
-                this.taskList = res1 || [];
-                // uni.$u.toast(res.message);
-            })
-        },
-        goToURL() {
-            setTimeout(function () {
-                uni.$u.route('/pages/history/index');
-            }, 1000)
-
-        },
-        goToURLDF() {
-            setTimeout(function () {
-                uni.$u.route('/pages/paymentList/index?name='+'鍨粯鍒楄〃'+'&router='+'pages/beReferred/index');
-            }, 1000)
-
-        },
-        historyClick(item) {
-               // wx.navigateTo({
-               //      url: '/pages/examine/index?id=' + item.dispatchId+'&name='+'涓婁紶琛岀▼'+'&router='+'pages/beReferred/index'
-               //  });
-              
-            if( ['寰呯敥鎸�', '寰呮帴鎸�'].includes(item.statusStr) ){
-                uni.$u.route('/pages/transportation/index?id=' + item.dispatchId+'&name='+'涓婁紶琛岀▼'+'&router='+'pages/beReferred/index'+'&statusStr='+item.statusStr);
-            }else {
-                wx.navigateTo({
-                    url: '/pages/examine/index?id=' + item.dispatchId+'&name='+'涓婁紶琛岀▼'+'&router='+'pages/beReferred/index'
-                });
-            }
-        },
-      leftClick(){
-          this.show = true;
-      },
-        goToUrl(){
-          this.show = false;
-          this.$u.vuex('sso_user_token',undefined);
-            uni.reLaunch({
-              url: '/pages/login/index'
-            })
-        },
-      close(){
-          this.show = false;
-      }
-
+  data() {
+    return {
+      taskList: [],
+      loading: false,
+      loadingMore: false,
+      isRefreshing: false,
+      showSidebar: false,
+      pageNum: 1,
+      pageSize: 10,
+      hasMore: true,
+      _isFirstLoad: true
     }
-};
+  },
+
+  onLoad() {
+    this._isFirstLoad = true
+    this.fetchTaskList()
+  },
+
+  onShow() {
+    // 棣栨鍔犺浇鏃惰烦杩囷紙onLoad 宸茬粡璋冪敤杩囦簡锛�
+    if (this._isFirstLoad) {
+      this._isFirstLoad = false
+      return
+    }
+    // 浠庡叾浠栭〉闈㈣繑鍥炴椂鍒锋柊鏁版嵁
+    this.pageNum = 1
+    this.fetchTaskList(true)
+  },
+
+  onPullDownRefresh() {
+    this.onRefresh()
+  },
+
+  onReachBottom() {
+    this.onLoadMore()
+  },
+
+  methods: {
+    // 鏍煎紡鍖栨椂闂�
+    formatTime(timeStr) {
+      if (!timeStr) return '鏆傛棤'
+
+      const date = new Date(timeStr.replace(/-/g, '/'))
+      if (isNaN(date.getTime())) return timeStr
+
+      const month = (date.getMonth() + 1).toString().padStart(2, '0')
+      const day = date.getDate().toString().padStart(2, '0')
+      const hours = date.getHours().toString().padStart(2, '0')
+      const minutes = date.getMinutes().toString().padStart(2, '0')
+
+      return `${month}-${day} ${hours}:${minutes}`
+    },
+
+    // 鍔犺浇鏁版嵁
+    async fetchTaskList(isRefresh = false) {
+      if (this.loading && !isRefresh) return
+
+      this.loading = true
+
+      try {
+        const res = await getSsignedItineraryList({
+          pageNum: this.pageNum,
+          pageSize: this.pageSize
+        })
+
+        const list = (res || []).map(item => ({
+          ...item,
+          statusClass: STATUS_MAP[item.statusStr]?.class || 'status-default'
+        }))
+
+        if (isRefresh) {
+          this.taskList = list
+          uni.stopPullDownRefresh()
+          this.isRefreshing = false
+        } else {
+          this.taskList = [...this.taskList, ...list]
+        }
+
+        this.hasMore = list.length === this.pageSize
+      } catch (error) {
+        console.error('鑾峰彇琛岀▼鍒楄〃澶辫触:', error)
+        uni.$u.toast('鑾峰彇鏁版嵁澶辫触锛岃閲嶈瘯')
+      } finally {
+        this.loading = false
+        this.loadingMore = false
+      }
+    },
+
+    // 涓嬫媺鍒锋柊
+    onRefresh() {
+      this.isRefreshing = true
+      this.pageNum = 1
+      this.fetchTaskList(true)
+    },
+
+    // 鍔犺浇鏇村
+    onLoadMore() {
+      if (!this.hasMore || this.loadingMore) return
+
+      this.loadingMore = true
+      this.pageNum++
+      this.fetchTaskList()
+    },
+
+    // 璺宠浆鍒板巻鍙茶褰�
+    goToHistory() {
+      navigateTo(PAGES.HISTORY)
+    },
+
+    // 璺宠浆鍒板灚浠樺垪琛�
+    goToPaymentList() {
+      navigateTo(PAGES.PAYMENT_LIST)
+    },
+
+    // 浠诲姟鐐瑰嚮
+    handleTaskClick(item) {
+      // 鏍规嵁鐘舵�佸喅瀹氳烦杞〉闈�
+      if (['寰呯敥鎸�', '寰呮帴鎸�'].includes(item.statusStr)) {
+        navigateTo(PAGES.TRANSPORTATION, {
+          id: item.dispatchId,
+          statusStr: item.statusStr,
+          name: '涓婁紶琛岀▼'
+        })
+      } else {
+        // 鐩存帴璺宠浆鍒版搷浣滈〉闈紝閬垮厤璺敱鍒嗗彂瀵艰嚧鐨勯棯鐑�
+        uni.navigateTo({
+          url: `/pages/examine/operate?id=${item.dispatchId}&name=涓婁紶琛岀▼`
+        })
+      }
+    },
+
+    // 鍒囨崲渚ц竟鏍�
+    toggleSidebar() {
+      this.showSidebar = !this.showSidebar
+    },
+
+    // 鍏抽棴渚ц竟鏍�
+    closeSidebar() {
+      this.showSidebar = false
+    },
+
+    // 閫�鍑虹櫥褰�
+    handleLogout() {
+      uni.showModal({
+        title: '鎻愮ず',
+        content: '纭畾瑕侀��鍑虹櫥褰曞悧锛�',
+        success: (res) => {
+          if (res.confirm) {
+            // 鏄剧ず鍔犺浇鎻愮ず
+            uni.showLoading({
+              title: '閫�鍑轰腑...',
+              mask: true
+            })
+
+            // 娓呴櫎鐧诲綍鐘舵��
+            uni.$u.vuex('sso_user_token', undefined)
+            uni.$u.vuex('user_info', undefined)
+
+            // 寤惰繜璺宠浆锛岄伩鍏嶇櫧灞�
+            setTimeout(() => {
+              uni.hideLoading()
+              uni.reLaunch({
+                url: '/pages/login/index'
+              })
+            }, 300)
+          }
+          this.closeSidebar()
+        }
+      })
+    }
+  }
+}
 </script>
 
+<style lang="scss" scoped>
+// 鍙橀噺瀹氫箟
+$primary-color: #409eff;
+$success-color: #67c23a;
+$warning-color: #e6a23c;
+$danger-color: #f56c6c;
+$info-color: #909399;
+$bg-color: #f5f7fa;
+$card-bg: #ffffff;
+$text-primary: #303133;
+$text-regular: #606266;
+$text-secondary: #909399;
 
-
-<style scoped>
+// 甯冨眬
 .container {
-    display: flex;
-    flex-direction: column;
-    height: 100vh;
-    background-color: #f7f7f7;
-    /* 缁欏簳閮ㄥ浐瀹氭爮棰勭暀绌洪棿锛岄伩鍏嶅唴瀹硅閬尅 */
-    padding-bottom: 100rpx;
-    box-sizing: border-box;
+  min-height: 100vh;
+  background-color: $bg-color;
+  display: flex;
+  flex-direction: column;
 }
 
-/* 鏍囬鏍� */
-.title-bar {
-    height: 80rpx;
-    line-height: 80rpx;
-    text-align: center;
-    font-size: 32rpx;
-    font-weight: 500;
-    background-color: #fff;
-    border-bottom: 1rpx solid #eee;
-    z-index: 10;
-    /* 纭繚鏍囬鏍忓湪婊氬姩鍖轰笂灞� */
+.main-content {
+  flex: 1;
+  overflow: hidden;
+  padding-bottom: 100rpx;
 }
 
-/* 琛岀▼婊氬姩鍖哄煙 */
+// 瀵艰埅鏍�
+.nav-left-slot {
+  padding: 0 20rpx;
+  display: flex;
+  align-items: center;
+}
+
+// 婊氬姩鍖哄煙
 .task-scroll {
-    flex: 1;
-    padding: 20rpx;
-    box-sizing: border-box;
-    z-index: 1;
-    /* 婊氬姩鍖哄眰绾т綆浜庢爣棰樻爮鍜屽簳閮ㄦ爮 */
+  height: calc(100vh - 44px - 100rpx); // 鍑忓幓瀵艰埅鏍忛珮搴�(44px)鍜屽簳閮ㄦ爮楂樺害(100rpx)
+  box-sizing: border-box;
 }
 
-/* 琛岀▼椤广�佸瓧娈垫牱寮忎繚鎸佷笉鍙� */
-.task-item {
-    background-color: #fff;
-    border-radius: 12rpx;
-    padding: 30rpx;
-    margin-bottom: 20rpx;
-    box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+.scroll-content {
+  padding: 20rpx;
+  min-height: 100%;
 }
 
-.task-field {
-    display: flex;
-    margin-bottom: 20rpx;
+// 楠ㄦ灦灞�
+.skeleton-item {
+  background: $card-bg;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  margin-bottom: 20rpx;
 }
 
-.field-label {
-    width: 180rpx;
-    color: #666;
-    font-size: 28rpx;
+// 绌虹姸鎬�
+.empty-state {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 60vh;
 }
 
-.field-value {
-    flex: 1;
-    color: #333;
-    font-size: 28rpx;
+// 浠诲姟鍗$墖
+.task-card {
+  background: $card-bg;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  margin-bottom: 20rpx;
+  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
+  transition: transform 0.2s, box-shadow 0.2s;
+
+  &:active {
+    transform: scale(0.98);
+    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
+  }
 }
 
-.status {
-    color: #ff6b6b;
-    font-weight: 500;
+// 鍗$墖澶撮儴
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-bottom: 20rpx;
+  border-bottom: 1rpx solid #ebeef5;
+  margin-bottom: 20rpx;
 }
 
-/* 搴曢儴鎿嶄綔鏍�-鍏抽敭淇敼锛氬浐瀹氬畾浣� */
-.bottom-bar {
-    /* 鍥哄畾鍦ㄥ睆骞曞簳閮紝涓嶉殢婊氬姩绉诲姩 */
-    position: fixed;
-    bottom: 0;
-    left: 0;
-    right: 0;
-    display: flex;
-    height: 100rpx;
-    border-top: 1rpx solid #eee;
-    background-color: #fff;
-    /* 椤堕儴闃村奖锛屽尯鍒嗗唴瀹瑰尯鍜屽簳閮ㄦ爮 */
-    box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
-    z-index: 999;
-    /* 纭繚鍦ㄦ墍鏈夊唴瀹逛笂灞� */
+.dispatch-no {
+  display: flex;
+  flex-direction: column;
+
+  .label {
+    font-size: 22rpx;
+    color: $text-secondary;
+    margin-bottom: 4rpx;
+  }
+
+  .value {
+    font-size: 30rpx;
+    font-weight: 600;
+    color: $text-primary;
+    font-family: 'Courier New', monospace;
+  }
 }
 
-.bottom-btn {
-    flex: 1;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    font-size: 28rpx;
-    color: #333;
-    border-right: 1rpx solid #eee;
-}
-
-.bottom-btn:last-child {
-    border-right: none;
-}
-
-
-.logo-info {
-  text-align: center;
-  position: absolute;
-  left: 50%;
-  top: 15%;
-  width: 100%;
-  transform: translateX(-50%);
-
-
-}
-.company {
-  font-size: 18px;
-  color: #5d6680;
+// 鐘舵�佹爣绛�
+.status-tag {
+  padding: 8rpx 20rpx;
+  border-radius: 8rpx;
+  font-size: 24rpx;
   font-weight: 500;
 }
 
-.user {
-  line-height: 40px;
-  color: #a2a2a2;
-  font-size: 14px;
+.status-pending {
+  background-color: rgba($danger-color, 0.1);
+  color: $danger-color;
 }
 
+.status-transporting {
+  background-color: rgba($primary-color, 0.1);
+  color: $primary-color;
+}
 
-.lout {
+.status-completed {
+  background-color: rgba($success-color, 0.1);
+  color: $success-color;
+}
+
+.status-cancelled {
+  background-color: rgba($info-color, 0.1);
+  color: $info-color;
+}
+
+.status-default {
+  background-color: rgba($info-color, 0.1);
+  color: $info-color;
+}
+
+// 鍗$墖涓讳綋
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: 16rpx;
+}
+
+.info-row {
+  display: flex;
+  align-items: center;
+  gap: 12rpx;
+}
+
+.info-text {
+  font-size: 28rpx;
+  color: $text-regular;
+}
+
+.time-row {
+  margin-top: 8rpx;
+  padding-top: 16rpx;
+  border-top: 1rpx dashed #ebeef5;
+}
+
+.time-text {
+  font-size: 26rpx;
+  color: $warning-color;
+  font-weight: 500;
+}
+
+// 璺嚎灞曠ず
+.route-section {
+  display: flex;
+  align-items: center;
+  gap: 20rpx;
+  padding: 16rpx 0;
+}
+
+.route-line {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  width: 24rpx;
+}
+
+.route-dot {
+  width: 16rpx;
+  height: 16rpx;
+  border-radius: 50%;
+
+  &.start {
+    background-color: $success-color;
+    box-shadow: 0 0 8rpx rgba($success-color, 0.4);
+  }
+
+  &.end {
+    background-color: $danger-color;
+    box-shadow: 0 0 8rpx rgba($danger-color, 0.4);
+  }
+}
+
+.route-path {
+  width: 2rpx;
+  height: 40rpx;
+  background: linear-gradient(to bottom, $success-color, $danger-color);
+  margin: 8rpx 0;
+}
+
+.route-info {
+  flex: 1;
+}
+
+.route-text {
+  font-size: 28rpx;
+  color: $text-primary;
+  font-weight: 500;
+  line-height: 1.5;
+}
+
+// 鍔犺浇鏇村
+.load-more {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding: 30rpx 0;
+
+  .no-more {
+    font-size: 24rpx;
+    color: $text-secondary;
+  }
+}
+
+// 搴曢儴鏍�
+.bottom-bar {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  height: 100rpx;
+  background: $card-bg;
+  display: flex;
+  align-items: center;
+  box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.08);
+  z-index: 100;
+}
+
+.bottom-btn {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  gap: 8rpx;
+  height: 100%;
+  transition: background-color 0.2s;
+
+  &:active {
+    background-color: rgba($primary-color, 0.05);
+  }
+
+  text {
+    font-size: 24rpx;
+    color: $text-regular;
+  }
+}
+
+.divider {
+  width: 1rpx;
+  height: 50rpx;
+  background-color: #ebeef5;
+}
+
+// 渚ц竟鏍�
+.sidebar-content {
+  width: 500rpx;
+  height: 100vh;
+  background: $card-bg;
+  display: flex;
+  flex-direction: column;
+}
+
+.sidebar-header {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 240rpx 40rpx 60rpx;
+
+  .logo {
+    width: 160rpx;
+    height: 160rpx;
+    border-radius: 20rpx;
+    margin-bottom: 24rpx;
+    box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.15);
+  }
+
+  .company-name {
+    font-size: 32rpx;
+    color: $primary-color;
+    font-weight: 600;
+    text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
+  }
+}
+
+.sidebar-menu {
+  flex: 1;
+  padding: 40rpx 0;
   position: absolute;
   bottom: 65px;
   left: 50%;
   transform: translateX(-50%);
-  color: #f0ae2d;
 }
+.menu-item {
+  display: flex;
+  align-items: center;
+  gap: 20rpx;
+  padding: 30rpx 40rpx;
+  transition: background-color 0.2s;
 
-</style>
\ No newline at end of file
+  &:active {
+    background-color: rgba($warning-color, 0.1);
+  }
+
+  .menu-text {
+    font-size: 30rpx;
+    color: $warning-color;
+  }
+}
+</style>

--
Gitblit v1.8.0