Просмотр исходного кода

feat:登录页/首页样式修改

颜琼丽 недель назад: 3
Родитель
Сommit
4ef63e4e18

+ 2 - 2
jd-logistics-ui-v3/.env.development

@@ -1,5 +1,5 @@
 # 页面标题
-VITE_APP_TITLE = 瑞鲸速达平台
+VITE_APP_TITLE = 瑞鲸速达平台管理系统
 
 # 开发环境配置
 VITE_APP_ENV = 'development'
@@ -7,4 +7,4 @@ VITE_APP_ENV = 'development'
 # 瑞鲸速达平台/开发环境
 VITE_APP_BASE_API = '/dev-api'
 
-VITE_APP_API_BASE_URL = 'http://192.168.101.77:8080'
+VITE_APP_API_BASE_URL = 'http://192.168.100.246:8080'

+ 1 - 1
jd-logistics-ui-v3/.env.production

@@ -1,5 +1,5 @@
 # 页面标题
-VITE_APP_TITLE = 瑞鲸速达平台
+VITE_APP_TITLE = 瑞鲸速达平台管理系统
 
 # 生产环境配置
 VITE_APP_ENV = 'production'

+ 1 - 1
jd-logistics-ui-v3/.env.staging

@@ -1,5 +1,5 @@
 # 页面标题
-VITE_APP_TITLE = 瑞鲸速达平台
+VITE_APP_TITLE = 瑞鲸速达平台管理系统
 
 # 生产环境配置
 VITE_APP_ENV = 'production'

BIN
jd-logistics-ui-v3/src/assets/images/login-background.png


jd-logistics-ui-v3/src/assets/images/login-background.jpg → jd-logistics-ui-v3/src/assets/images/login-background1.jpg


BIN
jd-logistics-ui-v3/src/assets/images/login-logo.png


BIN
jd-logistics-ui-v3/src/assets/images/login-pwd.png


BIN
jd-logistics-ui-v3/src/assets/images/login-username.png


+ 1 - 1
jd-logistics-ui-v3/src/settings.js

@@ -7,7 +7,7 @@ export default {
   /**
    * 侧边栏主题 深色主题theme-dark,浅色主题theme-light
    */
-  sideTheme: 'theme-dark',
+  sideTheme: 'theme-light',
 
   /**
    * 是否系统布局配置

+ 1 - 1
jd-logistics-ui-v3/src/views/dashboard/BarChart.vue

@@ -91,7 +91,7 @@ const initChart = () => {
       }
     },
     grid: {
-      top: 10,
+      top: '10%',
       left: '2%',
       right: '2%',
       bottom: '3%',

+ 2 - 7
jd-logistics-ui-v3/src/views/dashboard/LineChart.vue

@@ -17,7 +17,7 @@ const props = defineProps({
   },
   height: {
     type: String,
-    default: '350px'
+    default: '300px'
   },
   autoResize: {
     type: Boolean,
@@ -137,14 +137,9 @@ const setOptions = ({ expectedData, actualData } = {}) => {
 
   try {
     chartInstance.setOption({
-      title: {
-        text: '用户访问数据',
-        left: "3%",
-        top: "0%"
-      },
       tooltip: {
         trigger: 'axis',
-        z: 60,
+        z: 30,
         show: true,
         showContent: true
       },

+ 18 - 12
jd-logistics-ui-v3/src/views/dashboard/PanelGroup.vue

@@ -2,15 +2,16 @@
   <el-row :gutter="40" class="panel-group">
     <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
       <div class="card-panel" @click="handleSetLineChartData('newVisitis')">
-        <div class="card-panel-icon-wrapper icon-people">
-          <svg-icon icon-class="peoples" class-name="card-panel-icon" />
-        </div>
         <div class="card-panel-description">
           <div class="card-panel-text">
             访客
           </div>
           <CountTo :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
         </div>
+        <div class="card-panel-icon-wrapper icon-people">
+          <svg-icon icon-class="peoples" class-name="card-panel-icon" />
+        </div>
+
       </div>
     </el-col>
     <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
@@ -68,14 +69,19 @@ const handleSetLineChartData = (type) => {
 
 <style lang="scss" scoped>
 .panel-group {
-  margin-top: 18px;
+  margin-top: 16px;
+  padding: 0px 20px 0px 0px;
 
   .card-panel-col {
-    margin-bottom: 32px;
+    padding:0px !important;
+    padding-left: 20px !important;
+    margin-bottom: 16px;
+
   }
 
   .card-panel {
-    height: 108px;
+    border-radius: 8px;
+    height: 138px;
     cursor: pointer;
     font-size: 12px;
     position: relative;
@@ -124,23 +130,22 @@ const handleSetLineChartData = (type) => {
     }
 
     .card-panel-icon-wrapper {
-      float: left;
-      margin: 14px 0 0 14px;
+      float: right;
+      margin: 16px 16px 0 0px;
       padding: 16px;
       transition: all 0.38s ease-out;
       border-radius: 6px;
     }
 
     .card-panel-icon {
-      float: left;
+      float: right;
       font-size: 48px;
     }
 
     .card-panel-description {
-      float: right;
+      float: left;
       font-weight: bold;
       margin: 26px;
-      margin-left: 0px;
 
       .card-panel-text {
         line-height: 18px;
@@ -150,7 +155,8 @@ const handleSetLineChartData = (type) => {
       }
 
       .card-panel-num {
-        font-size: 20px;
+        font-size: 36px;
+        color: #333;
       }
     }
   }

+ 153 - 0
jd-logistics-ui-v3/src/views/dashboard/PieChart-one.vue

@@ -0,0 +1,153 @@
+<template>
+  <div ref="chartRef" :class="className" :style="{height:height,width:width}" />
+</template>
+
+<script setup>
+import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
+import * as echarts from 'echarts'
+
+const animationDuration = 6000
+
+const props = defineProps({
+  className: {
+    type: String,
+    default: 'chart'
+  },
+  width: {
+    type: String,
+    default: '100%'
+  },
+  height: {
+    type: String,
+    default: '300px'
+  }
+})
+
+const chartRef = ref(null)
+let chartInstance = null
+let resizeObserver = null
+let resizeTimer = null
+
+const handleResize = () => {
+  if (resizeTimer) {
+    clearTimeout(resizeTimer)
+  }
+
+  resizeTimer = setTimeout(() => {
+    if (chartInstance) {
+      try {
+        chartInstance.resize()
+      } catch (error) {
+        console.error('图表重绘失败:', error)
+      }
+    }
+  }, 200)
+}
+
+const initResizeListener = () => {
+  // 监听窗口大小变化
+  window.addEventListener('resize', handleResize)
+
+  // 使用 ResizeObserver 监听容器自身大小变化
+  if (typeof ResizeObserver !== 'undefined' && chartRef.value) {
+    resizeObserver = new ResizeObserver((entries) => {
+      handleResize()
+    })
+    resizeObserver.observe(chartRef.value)
+  }
+}
+
+const removeResizeListener = () => {
+  // 清理定时器
+  if (resizeTimer) {
+    clearTimeout(resizeTimer)
+    resizeTimer = null
+  }
+
+  // 移除窗口监听
+  window.removeEventListener('resize', handleResize)
+
+  // 断开 ResizeObserver
+  if (resizeObserver) {
+    resizeObserver.disconnect()
+    resizeObserver = null
+  }
+}
+
+const initChart = () => {
+  if (!chartRef.value) return
+
+  if (chartInstance) {
+    chartInstance.dispose()
+  }
+
+  chartInstance = echarts.init(chartRef.value, 'macarons')
+
+  chartInstance.setOption({
+    tooltip: {
+      trigger: 'item',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    legend: {
+      orient: 'horizontal',
+      left: 'right'
+    },
+    series: [
+      {
+        name: 'Access From',
+        type: 'pie',
+        radius: '50%',
+        data: [
+          { value: 1048, name: 'Search Engine' },
+          { value: 735, name: 'Direct' },
+          { value: 580, name: 'Email' },
+          { value: 484, name: 'Union Ads' },
+          { value: 300, name: 'Video Ads' }
+        ],
+        labelLine: {
+          show: false
+        },
+        label:{
+          show:false
+        },
+        animationEasing: 'cubicInOut',
+        animationDuration: 2600,
+        emphasis: {
+          itemStyle: {
+            shadowBlur: 10,
+            shadowOffsetX: 0,
+            shadowColor: 'rgba(0, 0, 0, 0.5)'
+          }
+        }
+      }
+    ]
+  })
+
+  // 图表初始化后立即重绘一次,确保尺寸正确
+  nextTick(() => {
+    chartInstance.resize()
+  })
+}
+
+onMounted(() => {
+  nextTick(() => {
+    initChart()
+    initResizeListener()
+  })
+})
+
+onBeforeUnmount(() => {
+  removeResizeListener()
+  if (chartInstance) {
+    chartInstance.dispose()
+    chartInstance = null
+  }
+})
+
+// 暴露方法给父组件
+defineExpose({
+  resizeChart: handleResize
+})
+</script>

+ 6 - 0
jd-logistics-ui-v3/src/views/dashboard/PieChart.vue

@@ -59,6 +59,12 @@ const initChart = () => {
           { value: 100, name: 'Gold' },
           { value: 59, name: 'Forecasts' }
         ],
+        labelLine: {
+          show: false
+        },
+        label:{
+          show:false
+        },
         animationEasing: 'cubicInOut',
         animationDuration: 2600
       }

+ 602 - 16
jd-logistics-ui-v3/src/views/index.vue

@@ -1,25 +1,106 @@
 <template>
   <div class="dashboard-editor-container">
-    <panel-group @handle-set-line-chart-data="handleSetLineChartData" />
+    <!-- 新增Banner区域 - 轮播图 -->
+    <el-row class="banner-section" >
+      <el-col :span="24">
+        <div class="carousel-container">
+          <!-- 轮播图 -->
+          <div class="carousel-wrapper">
+            <!-- 图片列表 -->
+            <div
+                class="carousel-slide"
+                :style="{ transform: `translateX(-${currentIndex * 100}%)` }"
+            >
+              <div
+                  v-for="(item, index) in bannerList"
+                  :key="index"
+                  class="carousel-item"
+                  @click="handleBannerClick(item)"
+              >
+                <!-- 背景图片 -->
+                <img
+                    :src="item.image"
+                    :alt="item.title"
+                    class="carousel-bg-img"
+                />
+                <!-- 遮罩层 -->
+                <div class="carousel-overlay"></div>
+
+                <!-- 内容 -->
+                <div class="carousel-content">
+                  <h2 class="carousel-title">{{ item.title }}</h2>
+                  <p class="carousel-desc">{{ item.desc }}</p>
+                  <el-button
+                      type="primary"
+                      size="large"
+                      class="carousel-button"
+                      @click.stop="handleQueryClick(item)"
+                  >
+                    <span style="font-weight: 500;">立即查询</span>
+                    <el-icon style="margin-left: 8px;">
+                      <ArrowRight />
+                    </el-icon>
+                  </el-button>
+                </div>
+              </div>
+            </div>
 
-    <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
-      <line-chart :chart-data="lineChartData" />
+            <!-- 导航箭头 -->
+            <div class="carousel-nav">
+              <el-button
+                  circle
+                  class="nav-btn prev-btn"
+                  @click="prevSlide"
+              >
+                <el-icon><ArrowLeft /></el-icon>
+              </el-button>
+              <el-button
+                  circle
+                  class="nav-btn next-btn"
+                  @click="nextSlide"
+              >
+                <el-icon><ArrowRight /></el-icon>
+              </el-button>
+            </div>
+
+            <!-- 指示器 -->
+            <div class="carousel-indicators">
+              <div
+                  v-for="(item, index) in bannerList"
+                  :key="index"
+                  class="indicator-item"
+                  :class="{ active: currentIndex === index }"
+                  @click="goToSlide(index)"
+              >
+                <div class="indicator-dot"></div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </el-col>
     </el-row>
 
-    <el-row :gutter="32">
-      <el-col :xs="24" :sm="24" :lg="8">
+    <panel-group @handle-set-line-chart-data="handleSetLineChartData" />
+
+    <el-row :gutter="32" class="chart-continer">
+      <el-col :xs="24" :sm="24" :lg="8" class="chart-section">
         <div class="chart-wrapper">
-          <raddar-chart />
+          <div class="chart-title">123</div>
+<!--          <raddar-chart />-->
+          <pie-chart-one />
         </div>
       </el-col>
-      <el-col :xs="24" :sm="24" :lg="8">
+      <el-col :xs="24" :sm="24" :lg="8" class="chart-section">
         <div class="chart-wrapper">
+          <div class="chart-title">123</div>
           <pie-chart />
         </div>
       </el-col>
-      <el-col :xs="24" :sm="24" :lg="8">
+      <el-col :xs="24" :sm="24" :lg="8" class="chart-section">
         <div class="chart-wrapper">
-          <bar-chart />
+          <div class="chart-title">123</div>
+<!--          <bar-chart />-->
+          <line-chart :chart-data="lineChartData"/>
         </div>
       </el-col>
     </el-row>
@@ -27,13 +108,67 @@
 </template>
 
 <script setup>
-import { ref } from 'vue'
+import { ref, onMounted, onUnmounted } from 'vue'
+import { ArrowRight, ArrowLeft } from '@element-plus/icons-vue'
 import PanelGroup from './dashboard/PanelGroup.vue'
 import LineChart from './dashboard/LineChart.vue'
 import RaddarChart from './dashboard/RaddarChart.vue'
 import PieChart from './dashboard/PieChart.vue'
+import PieChartOne from "./dashboard/PieChart-one.vue";
 import BarChart from './dashboard/BarChart.vue'
 
+// 轮播图数据
+const bannerList = ref([
+  {
+    id: 1,
+    image: 'https://images.unsplash.com/photo-1586528116311-ad8dd3c8310d?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=80',
+    title: '全程货物跟踪',
+    desc: '查询不限口岸,节点提醒、ETA/ETD延误,微信实时推送',
+    link: '/tracking',
+    queryType: 'all'
+  },
+  {
+    id: 2,
+    image: 'https://images.unsplash.com/photo-1562887189-e5d078343de4?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=80',
+    title: '海运货物跟踪',
+    desc: '海运货物实时位置查询,ETA准确率高达99%',
+    link: '/tracking?type=sea',
+    queryType: 'sea'
+  },
+  {
+    id: 3,
+    image: 'https://images.unsplash.com/photo-1518548419970-58e3b4079ab2?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=80',
+    title: '空运货物跟踪',
+    desc: '空运货物快速查询,航班动态实时更新',
+    link: '/tracking?type=air',
+    queryType: 'air'
+  },
+  {
+    id: 4,
+    image: 'https://images.unsplash.com/photo-1542744094-3a31f272c490?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=80',
+    title: '多式联运跟踪',
+    desc: '支持海运、空运、铁路、公路多式联运全程跟踪',
+    link: '/tracking?type=multimodal',
+    queryType: 'multimodal'
+  },
+  {
+    id: 5,
+    image: 'https://images.unsplash.com/photo-1601584115197-04ecc0da31d7?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=80',
+    title: '跨境电商物流',
+    desc: '专为跨境电商打造的物流跟踪解决方案',
+    link: '/tracking?type=ecommerce',
+    queryType: 'ecommerce'
+  }
+])
+
+// 当前轮播索引
+const currentIndex = ref(0)
+// 轮播定时器
+let autoPlayTimer = null
+// 轮播间隔(毫秒)
+const interval = 5000
+
+// 图表数据
 const lineChartDataMap = {
   newVisitis: {
     expectedData: [100, 120, 161, 134, 105, 160, 165],
@@ -60,24 +195,475 @@ const handleSetLineChartData = (type) => {
     lineChartData.value = lineChartDataMap[type]
   }
 }
+
+// 轮播图方法
+const nextSlide = () => {
+  currentIndex.value = (currentIndex.value + 1) % bannerList.value.length
+  resetAutoPlay()
+}
+
+const prevSlide = () => {
+  currentIndex.value = (currentIndex.value - 1 + bannerList.value.length) % bannerList.value.length
+  resetAutoPlay()
+}
+
+const goToSlide = (index) => {
+  currentIndex.value = index
+  resetAutoPlay()
+}
+
+const startAutoPlay = () => {
+  stopAutoPlay()
+  autoPlayTimer = setInterval(nextSlide, interval)
+}
+
+const stopAutoPlay = () => {
+  if (autoPlayTimer) {
+    clearInterval(autoPlayTimer)
+    autoPlayTimer = null
+  }
+}
+
+const resetAutoPlay = () => {
+  stopAutoPlay()
+  startAutoPlay()
+}
+
+// 点击事件
+const handleBannerClick = (item) => {
+  console.log('Banner clicked:', item)
+  // 这里可以添加跳转逻辑
+  // window.location.href = item.link
+}
+
+const handleQueryClick = (item) => {
+  console.log('Query button clicked:', item)
+  // 这里可以触发查询事件
+  // 例如:emit('query', item.queryType)
+}
+
+// 生命周期
+onMounted(() => {
+  startAutoPlay()
+})
+
+onUnmounted(() => {
+  stopAutoPlay()
+})
 </script>
 
 <style lang="scss" scoped>
 .dashboard-editor-container {
-  padding: 32px;
+  padding: 16px;
   background-color: rgb(240, 242, 245);
   position: relative;
 
+  .banner-section {
+    .carousel-container {
+      position: relative;
+      border-radius: 8px;
+      overflow: hidden;
+      box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
+
+      .carousel-wrapper {
+        position: relative;
+        overflow: hidden;
+        min-height: 230px;
+
+        .carousel-slide {
+          display: flex;
+          transition: transform 0.5s ease-in-out;
+          height: 100%;
+
+          .carousel-item {
+            flex: 0 0 100%;
+            position: relative;
+            cursor: pointer;
+            min-height: 230px;
+
+            .carousel-bg-img {
+              width: 100%;
+              height: 100%;
+              object-fit: cover;
+              position: absolute;
+              top: 0;
+              left: 0;
+            }
+
+            .carousel-overlay {
+              position: absolute;
+              top: 0;
+              left: 0;
+              width: 100%;
+              height: 100%;
+              background: linear-gradient(
+                      135deg,
+                      rgba(0, 0, 0, 0.7) 0%,
+                      rgba(0, 0, 0, 0.4) 50%,
+                      rgba(0, 0, 0, 0.2) 100%
+              );
+            }
+
+            .carousel-content {
+              position: relative;
+              z-index: 2;
+              padding: 20px;
+              height: 100%;
+              display: flex;
+              flex-direction: column;
+              justify-content: center;
+              color: white;
+
+              .carousel-title {
+                font-size: 42px;
+                font-weight: 700;
+                margin-bottom: 20px;
+                line-height: 1.2;
+                text-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
+                background: linear-gradient(135deg, #fff 0%, #e6f7ff 100%);
+                -webkit-background-clip: text;
+                -webkit-text-fill-color: transparent;
+                background-clip: text;
+              }
+
+              .carousel-desc {
+                font-size: 20px;
+                margin-bottom: 36px;
+                line-height: 1.6;
+                color: rgba(255, 255, 255, 0.95);
+                max-width: 600px;
+                text-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
+              }
+
+              .carousel-button {
+                background: linear-gradient(135deg, #409EFF 0%, #66b1ff 100%);
+                color: white;
+                border: none;
+                padding: 16px 42px;
+                font-size: 18px;
+                transition: all 0.3s ease;
+                box-shadow: 0 6px 20px rgba(64, 158, 255, 0.4);
+                border-radius: 10px;
+                border: 2px solid rgba(255, 255, 255, 0.3);
+                align-self: flex-start;
+
+                &:hover {
+                  background: linear-gradient(135deg, #66b1ff 0%, #409EFF 100%);
+                  transform: translateY(-3px);
+                  box-shadow: 0 10px 25px rgba(64, 158, 255, 0.5);
+                }
+
+                &:active {
+                  transform: translateY(-1px);
+                }
+              }
+            }
+
+            &:hover {
+              .carousel-bg-img {
+                transform: scale(1.05);
+                transition: transform 0.8s ease;
+              }
+            }
+          }
+        }
+
+        .carousel-nav {
+          position: absolute;
+          top: 50%;
+          left: 0;
+          right: 0;
+          transform: translateY(-50%);
+          display: flex;
+          justify-content: space-between;
+          padding: 0 20px;
+          z-index: 3;
+
+          .nav-btn {
+            background: rgba(255, 255, 255, 0.2);
+            border: 2px solid rgba(255, 255, 255, 0.3);
+            color: white;
+            width: 48px;
+            height: 48px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+
+            &:hover {
+              background: rgba(255, 255, 255, 0.3);
+              border-color: rgba(255, 255, 255, 0.5);
+            }
+
+            .el-icon {
+              font-size: 20px;
+              font-weight: bold;
+            }
+          }
+        }
+
+        .carousel-indicators {
+          position: absolute;
+          bottom: 24px;
+          left: 0;
+          right: 0;
+          display: flex;
+          justify-content: center;
+          gap: 12px;
+          z-index: 3;
+
+          .indicator-item {
+            cursor: pointer;
+            padding: 8px;
+
+            .indicator-dot {
+              width: 12px;
+              height: 12px;
+              border-radius: 50%;
+              background: rgba(255, 255, 255, 0.4);
+              transition: all 0.3s ease;
+            }
+
+            &.active {
+              .indicator-dot {
+                background: white;
+                width: 32px;
+                border-radius: 6px;
+                box-shadow: 0 0 8px rgba(64, 158, 255, 0.6);
+              }
+            }
+
+            &:hover:not(.active) {
+              .indicator-dot {
+                background: rgba(255, 255, 255, 0.7);
+                transform: scale(1.2);
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  .chart-continer{
+    padding: 0px 20px 0px 0px;
+
+    .chart-title{
+      height: 26px;
+      font-weight: 400;
+      font-size: 18px;
+      color: #333333;
+      line-height: 26px;
+
+      &::before{
+        content: ''; /* 必须设置content,否则伪元素不会显示 */
+        display: inline-block; /* 伪元素默认是行内,设置为块级以控制宽高 */
+        width: 4px;
+        height: 16px;
+        line-height: 26px;
+        background: #2D71FF;
+        border-radius: 2px 2px 2px 2px;
+        margin-right: 6px;
+      }
+    }
+
+    .chart-section{
+      marging:0px !important;
+      padding:0px !important;
+      padding-left: 20px !important;
+    }
+
+  }
+
+
   .chart-wrapper {
     background: #fff;
-    padding: 16px 16px 0;
-    margin-bottom: 32px;
+    padding: 16px;
+    margin-bottom: 16px;
+    border-radius: 8px;
+    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
   }
 }
 
-@media (max-width:1024px) {
-  .chart-wrapper {
-    padding: 8px;
+@media (max-width: 1200px) {
+  .dashboard-editor-container {
+    .banner-section {
+      .carousel-container {
+        .carousel-wrapper {
+          min-height: 190px;
+
+          .carousel-slide {
+            .carousel-item {
+              min-height: 190px;
+
+              .carousel-content {
+                padding: 10px;
+
+                .carousel-title {
+                  font-size: 36px;
+                }
+
+                .carousel-desc {
+                  font-size: 18px;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+@media (max-width: 1024px) {
+  .dashboard-editor-container {
+    padding: 20px;
+
+    .banner-section {
+      .carousel-container {
+        .carousel-wrapper {
+          min-height: 240px;
+
+          .carousel-slide {
+            .carousel-item {
+              min-height: 240px;
+
+              .carousel-content {
+                padding: 32px;
+
+                .carousel-title {
+                  font-size: 32px;
+                }
+
+                .carousel-desc {
+                  font-size: 16px;
+                  margin-bottom: 30px;
+                }
+
+                .carousel-button {
+                  padding: 14px 36px;
+                  font-size: 16px;
+                }
+              }
+            }
+          }
+
+          .carousel-nav {
+            .nav-btn {
+              width: 40px;
+              height: 40px;
+            }
+          }
+        }
+      }
+    }
+
+    .chart-wrapper {
+      padding: 12px;
+    }
+  }
+}
+
+@media (max-width: 768px) {
+  .dashboard-editor-container {
+    .banner-section {
+      .carousel-container {
+        .carousel-wrapper {
+          min-height: 200px;
+
+          .carousel-slide {
+            .carousel-item {
+              min-height: 200px;
+
+              .carousel-content {
+                padding: 24px;
+
+                .carousel-title {
+                  font-size: 28px;
+                  margin-bottom: 16px;
+                }
+
+                .carousel-desc {
+                  font-size: 15px;
+                  margin-bottom: 24px;
+                }
+
+                .carousel-button {
+                  padding: 12px 32px;
+                  font-size: 15px;
+                }
+              }
+            }
+          }
+
+          .carousel-nav {
+            padding: 0 12px;
+
+            .nav-btn {
+              width: 36px;
+              height: 36px;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+@media (max-width: 480px) {
+  .dashboard-editor-container {
+    padding: 16px;
+
+    .banner-section {
+      .carousel-container {
+        .carousel-wrapper {
+          min-height: 180px;
+
+          .carousel-slide {
+            .carousel-item {
+              min-height: 180px;
+
+              .carousel-content {
+                padding: 20px;
+
+                .carousel-title {
+                  font-size: 24px;
+                }
+
+                .carousel-desc {
+                  font-size: 14px;
+                }
+
+                .carousel-button {
+                  padding: 10px 28px;
+                  font-size: 14px;
+                }
+              }
+            }
+          }
+
+          .carousel-nav {
+            display: none; /* 小屏幕隐藏导航箭头 */
+          }
+
+          .carousel-indicators {
+            bottom: 16px;
+
+            .indicator-item {
+              .indicator-dot {
+                width: 8px;
+                height: 8px;
+              }
+
+              &.active {
+                .indicator-dot {
+                  width: 24px;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
   }
 }
 </style>

+ 90 - 67
jd-logistics-ui-v3/src/views/login.vue

@@ -1,62 +1,65 @@
 <template>
   <div class="login">
-    <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
-      <h3 class="title">{{ title }}</h3>
-      <el-form-item prop="username">
-        <el-input
-          v-model="loginForm.username"
-          type="text"
-          size="large"
-          auto-complete="off"
-          placeholder="账号"
-        >
-          <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
-        </el-input>
-      </el-form-item>
-      <el-form-item prop="password">
-        <el-input
-          v-model="loginForm.password"
-          type="password"
-          size="large"
-          auto-complete="off"
-          placeholder="密码"
-          @keyup.enter="handleLogin"
-        >
-          <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
-        </el-input>
-      </el-form-item>
-      <el-form-item prop="code" v-if="captchaEnabled">
-        <el-input
-          v-model="loginForm.code"
-          size="large"
-          auto-complete="off"
-          placeholder="验证码"
-          style="width: 63%"
-          @keyup.enter="handleLogin"
-        >
-          <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
-        </el-input>
-        <div class="login-code">
-          <img :src="codeUrl" @click="getCode" class="login-code-img"/>
-        </div>
-      </el-form-item>
-      <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
-      <el-form-item style="width:100%;">
-        <el-button
-          :loading="loading"
-          size="large"
-          type="primary"
-          style="width:100%;"
-          @click.prevent="handleLogin"
-        >
-          <span v-if="!loading">登 录</span>
-          <span v-else>登 录 中...</span>
-        </el-button>
-        <div style="float: right;" v-if="register">
-          <router-link class="link-type" :to="'/register'">立即注册</router-link>
-        </div>
-      </el-form-item>
-    </el-form>
+    <div class="login-container">
+      <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
+        <img class="title-logo" src="../assets/images/login-logo.png" alt="瑞鲸科技"/>
+        <h3 class="title">{{ title }}</h3>
+        <el-form-item prop="username">
+          <el-input
+              v-model="loginForm.username"
+              type="text"
+              size="large"
+              auto-complete="off"
+              placeholder="账号"
+          >
+            <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
+          </el-input>
+        </el-form-item>
+        <el-form-item prop="password">
+          <el-input
+              v-model="loginForm.password"
+              type="password"
+              size="large"
+              auto-complete="off"
+              placeholder="密码"
+              @keyup.enter="handleLogin"
+          >
+            <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
+          </el-input>
+        </el-form-item>
+        <el-form-item prop="code" v-if="captchaEnabled">
+          <el-input
+              v-model="loginForm.code"
+              size="large"
+              auto-complete="off"
+              placeholder="验证码"
+              style="width: 63%"
+              @keyup.enter="handleLogin"
+          >
+            <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
+          </el-input>
+          <div class="login-code">
+            <img :src="codeUrl" @click="getCode" class="login-code-img"/>
+          </div>
+        </el-form-item>
+        <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
+        <el-form-item style="width:100%;">
+          <el-button
+              :loading="loading"
+              size="large"
+              type="primary"
+              style="width:100%;"
+              @click.prevent="handleLogin"
+          >
+            <span v-if="!loading">登 录</span>
+            <span v-else>登 录 中...</span>
+          </el-button>
+          <div style="float: right;" v-if="register">
+            <router-link class="link-type" :to="'/register'">立即注册</router-link>
+          </div>
+        </el-form-item>
+      </el-form>
+    </div>
     <!--  底部  -->
     <div class="el-login-footer">
       <span>{{ footerContent }}</span>
@@ -171,21 +174,42 @@ getCookie()
   justify-content: center;
   align-items: center;
   height: 100%;
-  background-image: url("../assets/images/login-background.jpg");
+  background-image: url("../assets/images/login-background.png");
   background-size: cover;
 }
-.title {
-  margin: 0px auto 30px auto;
-  text-align: center;
-  color: #707070;
+.login-container{
+  background: #ffffff;
+  width: 40%;
+  height: 100%;
+  position: absolute;
+  right: 0;
+  padding-top: 5%;
+
+
+  .title-logo {
+    margin: 30px auto;
+    color: #333;
+    font-size: 24px;
+    width: 100%;
+    height: 100%;
+    font-weight: bold;
+  }
+
+  .title {
+    margin: 0px auto 30px auto;
+    text-align: center;
+    color: #333;
+    font-size: 24rpx;
+    line-height: 32rpx;
+  }
+
 }
 
 .login-form {
-  border-radius: 6px;
-  background: #ffffff;
-  width: 400px;
-  padding: 25px 25px 5px 25px;
   z-index: 1;
+  display: flex;
+  flex-direction: column;
+  margin: 0px 30%;
   .el-input {
     height: 40px;
     input {
@@ -226,6 +250,5 @@ getCookie()
 }
 .login-code-img {
   height: 40px;
-  padding-left: 12px;
 }
 </style>

+ 1 - 1
jd-logistics-ui-v3/src/views/register.vue

@@ -163,7 +163,7 @@ getCode()
   justify-content: center;
   align-items: center;
   height: 100%;
-  background-image: url("../assets/images/login-background.jpg");
+  background-image: url("../assets/images/login-background.png");
   background-size: cover;
 }
 .title {