Browse Source

```
feat(router): 修改菜单导航方式并优化路由跳转逻辑

将工作流交易菜单项的点击事件从直接路由跳转改为调用方法 `goMyLearning`,
以增强路由控制能力。同时引入 `useRouter` 并实现对应的跳转函数。

此外,调整了部分页面容器样式,统一使用 `.container` 类来限制内容宽度,
并移除了冗余的内联样式,使布局更加一致和易于维护。
```

zhangningning 2 weeks ago
parent
commit
0adc1c16ac
5 changed files with 586 additions and 56 deletions
  1. 10 4
      src/App.vue
  2. 1 6
      src/pages/CourseDetail.vue
  3. 17 22
      src/pages/Home.vue
  4. 9 16
      src/pages/MyLearning.vue
  5. 549 8
      src/styles/index.scss

+ 10 - 4
src/App.vue

@@ -7,7 +7,8 @@
           <div class="logo" @click="$router.push('/')">{{ $t('common.title') }}</div>
           <el-menu :default-active="activeIndex" mode="horizontal" :ellipsis="false">
             <el-menu-item index="1" @click="$router.push('/')">AI工作流</el-menu-item>
-            <el-menu-item index="2" @click="$router.push('/my-learning')">工作流交易</el-menu-item>
+            <!-- <el-menu-item index="2" @click="$router.push('/my-learning')">工作流交易</el-menu-item> -->
+            <el-menu-item index="2" @click="goMyLearning">工作流交易</el-menu-item>
             <el-menu-item index="3" @click="$router.push('/my-learning')">学习教程系统</el-menu-item>
             <el-menu-item index="4" @click="$router.push('/my-learning')">学习笔记</el-menu-item>
             <el-menu-item index="5" @click="$router.push('/my-learning')">积分商城</el-menu-item>
@@ -20,7 +21,7 @@
         </div>
       </el-header>
       
-      <el-main>
+      <el-main >
         <router-view />
       </el-main>
       
@@ -38,15 +39,20 @@
 import { computed,ref } from 'vue'
 import LangSwitch from './components/LangSwitch.vue'
 import { ElConfigProvider } from 'element-plus'
-import { useRoute } from 'vue-router'
+import { useRoute, useRouter } from 'vue-router'
 // 在Pinia安装后再设置初始语言
 import { useLangStore } from '@/pinia/langStore'
 const langStore = useLangStore()
 $i18n.global.locale.value = langStore.currentLang
 
 const route = useRoute()
+const router = useRouter()
+
 
 const activeIndex = ref('1')
+function goMyLearning() {
+  router.push('/my-learning')
+}
 </script>
 
 <style lang="scss">
@@ -96,6 +102,6 @@ const activeIndex = ref('1')
 }
 
 .el-main {
-  padding: 20px 0;
+  padding: 0;
 }
 </style>

+ 1 - 6
src/pages/CourseDetail.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="course-detail-page" v-if="currentCourse">
+  <div class="course-detail-page container" v-if="currentCourse">
     <!-- <el-page-header @back="goBack">
       <template #content>{{ currentCourse.title }}</template>
     </el-page-header> -->
@@ -76,11 +76,6 @@ const goBack = () => {
 </script>
 
 <style scoped lang="scss">
-.course-detail-page {
-  max-width: 1200px;
-  margin: 0 auto;
-  padding: 20px;
-}
 
 .course-detail {
   .course-video {

+ 17 - 22
src/pages/Home.vue

@@ -1,8 +1,8 @@
 <template>
-  <div class="home-page">
+  <div class="home-page container">
     <!-- 使用 BlockNote 编辑器 -->
     <BlockNoteEditor v-model="editorContent" @getHtml="getHtml" :editable="true"/>
-    <div v-html="editorContent_html"></div>
+    <!-- <div v-html="editorContent_html"></div> -->
     <div class="banner">
       <h1>欢迎来到视频学习平台</h1>
       <p>发现优质课程,提升你的技能</p>
@@ -46,21 +46,21 @@ import BlockNoteEditor from '@/components/BlockNoteEditor.vue';
 // ]
 
 const editorContent = ref(
-  // [
-  //   {
-  //     type: "paragraph",
-  //     content: [{ type: "text", text: "只读模式" }]
-  //   },
-  //   {
-  //   "id": "378ce968-02c2-4856-888b-c35a355aa84b",
-  //   "type": "codeBlock",
-  //   "props": {
-  //       "language": "text"
-  //   },
-  //   "content": [],
-  //   "children": []
-  //   }
-  // ]
+  [
+    {
+      type: "paragraph",
+      content: [{ type: "text", text: "只读模式" }]
+    },
+    {
+    "id": "378ce968-02c2-4856-888b-c35a355aa84b",
+    "type": "codeBlock",
+    "props": {
+        "language": "text"
+    },
+    "content": [],
+    "children": []
+    }
+  ]
 );
 const editorContent_html = ref();
 
@@ -91,11 +91,6 @@ const goToCourseDetail = (id,title) => {
 </script>
 
 <style scoped lang="scss">
-.home-page {
-  max-width: 1200px;
-  margin: 0 auto;
-  padding: 20px;
-}
 
 .banner {
   background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

+ 9 - 16
src/pages/MyLearning.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="my-learning-page">
+  <div class="my-learning-page container">
     <!-- <el-page-header content="我的学习"></el-page-header> -->
     <Breadcrumb />
     
@@ -40,7 +40,6 @@
     <!-- 已购课程列表 -->
     <div class="my-courses">
       <h2>我的课程</h2>
-      
       <div v-if="myCourses.length === 0" class="no-courses">
         <el-empty description="你还没有购买任何课程"></el-empty>
         <el-button type="primary" @click="$router.push('/')">去选课</el-button>
@@ -58,12 +57,11 @@
               <h3>{{ course.title }}</h3>
               <p>讲师:{{ course.teacher }}</p>
               <div class="progress-container">
-                <el-progress 
+                <el-progress class="flex_1 gap10"
                   :percentage="course.progress" 
-                  :status="course.progress === 100 ? 'success' : 'processing'"
-                  size="small"
+                  :status="course.progress === 100 ? 'success' : ''"
                 ></el-progress>
-                <span class="progress-text">{{ course.progress }}%</span>
+                <!-- <span class="progress-text">{{ course.progress }}%</span> -->
               </div>
             </div>
           </div>
@@ -71,16 +69,16 @@
           <div class="course-actions">
             <el-button 
               type="primary" 
-              icon="el-icon-play-circle"
               @click="continueLearning(course.id)"
             >
+              <el-icon><VideoPlay /></el-icon>
               继续学习
             </el-button>
             <el-button 
               type="text" 
-              icon="el-icon-star-off"
               @click="toggleCollect(course.id)"
             >
+              <el-icon><StarFilled /></el-icon>
               {{ course.isCollected ? '取消收藏' : '收藏' }}
             </el-button>
           </div>
@@ -111,8 +109,8 @@
 </template>
 
 <script setup>
-  // import { VideoPlay, Clock, Check } from '@element-plus/icons-vue'
-  import { ElProgress } from 'element-plus'
+// import { VideoPlay, Clock, Check,StarFilled } from '@element-plus/icons-vue'
+// import { ElProgress } from 'element-plus'
 import { ref, computed } from 'vue'
 import { useRouter } from 'vue-router'
 
@@ -183,11 +181,6 @@ const toggleCollect = (courseId) => {
 </script>
 
 <style scoped lang="scss">
-.my-learning-page {
-  max-width: 1200px;
-  margin: 0 auto;
-  padding: 20px;
-}
 
 // 学习统计卡片
 .learning-stats {
@@ -287,7 +280,7 @@ const toggleCollect = (courseId) => {
         .progress-container {
           display: flex;
           align-items: center;
-          gap: 10px;
+          // gap: 10px;
           
           .progress-text {
             font-size: 0.8rem;

+ 549 - 8
src/styles/index.scss

@@ -11,16 +11,24 @@ $danger-color: #e63946; // 危险色(价格、警告等)
 
 // 2. 全局重置样式(统一浏览器默认样式)
 * {
-  margin: 0;
-  padding: 0;
   box-sizing: border-box;
 }
+H1,
+H2,
+H3,
+H4,
+H5,
+H6,
+P {
+  margin: 0;
+}
 
-body {
+body ,htm{
   font-family: "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
   color: $text-color;
-  background-color: #ffffff;
+  background-color: #f5f5f5;
   line-height: 1.6;
+  margin: 0;
 }
 
 // 3. 公共样式类(全局可复用)
@@ -46,8 +54,14 @@ body {
 
 // 4. 全局组件样式覆盖(可选,如需调整 Element Plus 组件默认样式)
 // 例如:调整按钮圆角
-.el-button {
-  border-radius: 4px;
+// .el-button {
+//   border-radius: 4px;
+// }
+.container {
+  max-width: 1200px;
+  margin: 0 auto;
+  padding: 20px;
+  background-color: #ffffff;
 }
 
 // 调整折叠面板样式
@@ -59,13 +73,540 @@ body {
 // 小屏幕(手机)
 @media (max-width: 768px) {
   .container {
-    padding: 0 10px;
+    // padding: 0 10px;
   }
 }
 
 // 中屏幕(平板)
 @media (min-width: 769px) and (max-width: 1024px) {
   .container {
-    padding: 0 15px;
+    // padding: 0 15px;
+  }
+}
+
+@charset "UTF-8";
+wx-image{
+	height: auto;
+}
+.padding12 {
+	padding: 12px
+}
+.padding20 {
+	padding: 20px
+}
+.paddingTB20 {
+	padding: 20px 0
+}
+.paddingTB30 {
+	padding: 30px 0
+}
+.paddingTB10 {
+	padding: 10px 0
+}
+
+.pad20 {
+	padding: 0 20px
+}
+
+.padding15 {
+	padding: 15px
+}
+.padding30 {
+	padding: 30px
+}
+
+.pad30 {
+	padding: 0 30px
+}
+.pt20 {
+	padding-top: 20px
+}
+.pb15 {
+	padding-bottom: 15px
+}
+.pb20 {
+	padding-bottom: 20px
+}
+.pb30 {
+	padding-bottom: 30px
+}
+
+.mb30 {
+	margin-bottom: 30px;
+}
+.mr20 {
+	margin-right: 20px;
+}
+.mr30 {
+	margin-right: 30px;
+}
+.mr10 {
+	margin-right: 10px;
+}
+.ml10 {
+	margin-left: 10px;
+}
+.ml20 {
+	margin-left: 20px;
+}
+.mt20 {
+	margin-top: 20px;
+}
+.mt30 {
+	margin-top: 30px;
+}
+.mt16 {
+	margin-top: 16px;
+}
+.mt10 {
+	margin-top: 10px;
+}
+.mt5 {
+	margin-top: 5px;
+}
+.mb20 {
+	margin-bottom: 20px;
+}
+.ellipsis {
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap
+}
+
+.line1 {
+	word-break: break-all;
+	display: -webkit-box;
+	-webkit-line-clamp: 1;
+	-webkit-box-orient: vertical;
+	overflow: hidden;
+	/* height: 84px; */
+}
+.line2 {
+	word-break: break-all;
+	display: -webkit-box;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+	overflow: hidden;
+	/* height: 84px; */
+}
+
+.mask {
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	background-color: #000;
+	opacity: .5;
+	z-index: 5
+}
+
+@keyframes load {
+	from {
+		transform: rotate(0)
+	}
+
+	to {
+		transform: rotate(360deg)
+	}
+}
+
+@-webkit-keyframes load {
+	from {
+		transform: rotate(0)
+	}
+
+	to {
+		transform: rotate(360deg)
+	}
+}
+
+.loadingpic {
+	animation: load 3s linear 1s infinite;
+	--webkit-animation: load 3s linear 1s infinite
+}
+
+.loading-list {
+	animation: load linear 1s infinite;
+	-webkit-animation: load linear 1s infinite;
+	font-size: 40px;
+	margin-right: 22px
+}
+
+.loading {
+	width: 100%;
+	height: 100px;
+	line-height: 100px;
+	align-items: center;
+	justify-content: center;
+	position: relative;
+	text-align: center
+}
+
+.loading .line {
+	position: absolute;
+	width: 450px;
+	left: 150px;
+	top: 50px;
+	height: 1px;
+	border-top: 1px solid #eee
+}
+
+.loading .text {
+	position: relative;
+	display: inline-block;
+	padding: 0 20px;
+	background: #fff;
+	z-index: 2;
+	color: #777
+}
+
+.loadingicon .loading {
+	animation: load linear 1s infinite;
+	font-size: 45px;
+	color: #000
+}
+
+.loadingicon {
+	width: 100%;
+	height: 80px;
+	overflow: hidden
+}
+.bg-color-huic{
+	background: #F1F1F1!important;
+	border: 1px solid #ccc!important;
+	color: #ccc!important;
+}
+.nowrap{
+	white-space: nowrap;
+}
+.gap10{
+  gap: 10px;
+}
+/*flex样式*/
+.flex_1{
+  flex:1;
+}
+.flex{
+  display: flex;
+}
+.flex_2{
+  flex: 2;
+}
+.flex-between{/*两边对齐*/
+  display: flex;
+  justify-content: space-between;
+}
+.flex-align-center{/*垂直居中*/
+  display: flex !important;
+  align-items: center;
+}
+.flex-center{/*水平垂直居中*/
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.flex-center-flex-end{/*水平垂直居中-尾部对齐*/
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+}
+.flex-center-box-end{/*水平垂直居中-铺满盒内*/
+  display: -webkit-inline-box;
+  justify-content: flex-end;
+  align-items: center;
+}
+.flex-center-flex-start{/*水平垂直居中-首部对齐*/
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+}
+.flex-center-around{/*水平垂直居中-平均对齐*/
+  display: flex;
+  justify-content: space-around;
+  align-items: center;
+}
+.flex-center-between{/*水平垂直居中-两边对齐*/
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+.flex-column{/*竖直方向*/
+  display: flex;
+  flex-direction: column;
+}
+.flex-column-center{/*竖直方向水平居中 两端对齐*/
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  align-items: center;
+}
+.flex-column-start{/*竖直方向水平居中 首部对齐*/
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  align-items: self-start;
+}
+.flex-column-start-between{/*竖直方向-首部对齐-两端对齐*/
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  align-items: self-start;
+}
+.flex-column-align{/*竖直方向水平居中*/
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+.flex-center-flex-start-warp{/*水平垂直居中-首部对齐*/
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+   flex-wrap:wrap ;
+}
+.order_btn{
+	font-size: 25px;
+	color: #ffffff;
+	border-radius:10px;
+	background-color: primary-color;
+	&.error{
+		background-color: #E93323;
+	}
+	&.plain{
+		border:1px solid #cccccc;
+		color: #000000;
+		background-color: #ffffff;
+	}
+}
+.border{
+	border: 1px solid #eeeeee;
+}
+.border-bottom{
+	border-bottom: 1px solid #eeeeee;
+}
+.gray{
+	color: #666666;
+}
+.link{
+	color: #007aff;
+}
+.bg_color_f5{
+	background-color: #f5f5f5;
+}
+.edit_gary {
+	background: #EBEBEB;
+}
+.bg_color_fff{
+	background-color: #ffffff;
+}
+.bg_color_primary{
+	background-color: primary-color;
+}
+.bg_gradient_primary{
+	background: linear-gradient(180deg, #0089FF 0%, #F5F7FA  50%);
+	background-size: 200% 100vh; 
+	background-repeat: no-repeat;
+}
+.bg_gradient_primary_toright{
+	//从左到右渐变色
+  background: linear-gradient(to right, rgba(73, 171, 255, 1), rgba(0, 137, 255, 1));
+}
+.border_radius_10{
+	border-radius: 10px;
+}
+.border_radius_20{
+	border-radius: 20px;
+}
+.border_radius_30{
+	border-radius: 30px;
+}
+.bold{
+	font-weight: bold;
+}
+.font_size40{
+	font-size: 40px;
+}
+.font_size36{
+	font-size: 36px;
+}
+.font_size35{
+	font-size: 35px;
+}
+.font_size32{
+	font-size: 32px;
+}
+.font_size30{
+	font-size: 30px;
+}
+.font_size28{ 
+	font-size: 28px;
+}
+.font_size20{
+	font-size: 20px;
+}
+.font_size25{
+	font-size: 25px;
+}
+.font_size24{
+	font-size: 24px;
+}
+.line_vertical{
+	width: 8px;
+	height: 30px;
+	background-color: primary-color;
+	border-radius: 4px;
+}
+.color_price{
+	color: #fc4f1d;
+}
+.color_vip{
+	color: #fee189;
+}
+.color_fff{
+	color: #ffffff;
+}
+.color_000{
+	color: #000000;
+}
+.color_theme{
+	color: primary-color;
+}
+
+.text_align_center{
+	text-align: center;
+}
+.text_align_right{
+	text-align: right;
+}
+.foot{
+	padding: 20px 30px;
+	width: 100%;
+	position: fixed;
+	bottom: 0;
+	left: 0;
+	box-shadow: 0 -4px 6px -1px rgba(0, 0, 0, 0.1);
+	z-index: 10;
+}
+.box_shadow{
+	box-shadow: 0 -4px 6px -1px rgba(0, 0, 0, 0.1);
+}
+.ellipsis{
+	overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+.bg_img{
+	width: 100%;
+	position: absolute;
+	top: 0;
+	left: 0;;
+	z-index: -1;
+}
+.line_through{
+	text-decoration: line-through;
+}
+
+.required{
+	color: #E93323;
+}
+.u_popup_bottom{
+	border-radius: 30px 30px 0 0;
+}
+.overflow_hidden{
+	overflow: hidden;
+}
+
+
+.payment-radio {
+  width: 40px;
+  height: 40px;
+
+  .radio-circle {
+    width: 100%;
+    height: 100%;
+    border: 3px solid #ddd;
+    border-radius: 50%;
+    position: relative;
+    transition: all 0.3s;
+
+    &.checked {
+      border-color: primary-color;
+
+      &::after {
+        content: "";
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+        width: 20px;
+        height: 20px;
+        background: primary-color;
+        border-radius: 50%;
+      }
+    }
+  }
+}
+.noData{
+	text-align: center;
+	padding: 30px 0;
+	color: #c8c7cc;
+}
+.serviceLabel{
+	background-color: #ffe8e6;
+	font-size: 25px;
+	color: #E93323;
+	border-radius: 10px;
+	padding: 5px 10px;
+	display: inline-block;
+	// margin-top: 20px;
+	&:not(:last-child){ 
+		margin-right: 10px;
+	}
+}
+
+
+.status_bar {
+    height: var(--height);
+    width: 100%;
+  }
+  .hover-view {
+	  opacity: 0.7;
   }
+  .p_certification {
+	  width: 124px;
+	  height: 40px;
+	  display: flex;
+	  align-items: center;
+	  justify-content: center;
+	  background: #E9EFFF;
+	  border-radius: 20px;
+	  image {
+		  width: 32px;
+		  height: 32px;
+	  }
+	  view {
+		  color: #0089FF;
+		  font-size: 24px;
+		  margin-left: 4px;
+	  }
+  }
+  
+  .truncate {
+	  white-space: nowrap;
+	  /* 禁止换行 */
+	  overflow: hidden;
+	  /* 隐藏溢出内容 */
+	  text-overflow: ellipsis;
+	  /* 显示省略号 */
+  }
+.tabbar_height{
+	height: calc(120px + constant(safe-area-inset-bottom));
+	height: calc(120px + env(safe-area-inset-bottom));
+}
+.zp-empty-view,.zp-l-container{
+	background-color: #F5F7FA;
+}
+.close_img{
+	width: 32px;
+	height: 32px;
 }