Parcourir la source

底部导航栏+资料+我的资料完成

谢杰标 il y a 2 ans
Parent
commit
f4d596a371

+ 1 - 0
App.vue

@@ -2,6 +2,7 @@
 import plv from "./pages3/static/polyv-sdk/index";
 export default {
   onLaunch: function (option) {
+    uni.hideTabBar()
     let inviteCode = option.inviteCode;
     if (inviteCode && inviteCode != "") {
       uni.setStorageSync("inviteCode", inviteCode);

+ 8 - 0
common/httpList/course.js

@@ -85,6 +85,14 @@ export default {
 			data: data
 		})
 	},
+	// 购买讲义列表
+	goodsHandoutsList(data) {
+		return myRequest({
+			url: '/course/goodsHandoutsList',
+			method: 'get',
+			data: data
+		})
+	},
 	courseCourseList(data) {
 		return myRequest({
 			url: '/course/courseList',

+ 95 - 0
components/tabbar/index.vue

@@ -0,0 +1,95 @@
+<template>
+  <u-tabbar
+    v-model="current"
+    :before-switch="beforeSwitch"
+    :list="list"
+    @change="change"
+  ></u-tabbar>
+  <!-- <tabbar
+    v-model="current"
+    :before-switch="beforeSwitch"
+    :list="list"
+    @change="change"
+  ></tabbar> -->
+</template>
+
+<script>
+import tabbar from "./tabbar.vue";
+export default {
+  name: "myTabbar",
+  options: { styleIsolation: "shared" },
+  data() {
+    return {
+      list: [
+        {
+          pagePath: "/pages/index/index",
+          iconPath: "./../../static/nav1.png",
+          selectedIconPath: "./../../static/nav1_on.png",
+          text: "首页",
+        },
+        {
+          pagePath: "/pages/course/index",
+          iconPath: "./../../static/nav2.png",
+          selectedIconPath: "./../../static/nav2_on.png",
+          text: "选课",
+        },
+        {
+          pagePath: "/pages/learn/index",
+          iconPath: "/../../static/nav6.png",
+          selectedIconPath: "/../../static/nav6_on.png",
+          text: "学习",
+        },
+        {
+          pagePath: "/pages/questionBank/index",
+          iconPath: "/../../static/nav3.png",
+          selectedIconPath: "/../../static/nav3_on.png",
+          text: "题库",
+        },
+        {
+          pagePath: "/pages/information/index",
+          iconPath: "/../../static/nav4.png",
+          selectedIconPath: "/../../static/nav4_on.png",
+          text: "资料",
+        },
+        {
+          pagePath: "/pages/wd/index",
+          iconPath: "/../../static/nav5.png",
+          selectedIconPath: "/../../static/nav5_on.png",
+          text: "我的",
+        },
+      ],
+      current: 0,
+    };
+  },
+
+  mounted() {},
+
+  methods: {
+    beforeSwitch(index) {
+      return true; // 或者根据逻辑返回false
+    },
+    change(index) {
+      this.current = index;
+      if (index === 4) {
+        this.toInformation();
+      }
+    },
+    toInformation() {
+      uni.reLaunch({
+        url: "/pages/information/index",
+      });
+    },
+  },
+  components: {
+    tabbar,
+  },
+};
+</script>
+
+<style lang="scss">
+.u-tabbar {
+  ::v-deep &__content {
+    z-index: 10000 !important;
+  }
+}
+</style>

+ 375 - 0
components/tabbar/tabbar.vue

@@ -0,0 +1,375 @@
+<template>
+  <view v-if="show" class="u-tabbar" @touchmove.stop.prevent="() => {}">
+    <view
+      class="u-tabbar__content safe-area-inset-bottom"
+      :style="{
+        height: $u.addUnit(height),
+        backgroundColor: bgColor,
+      }"
+      :class="{
+        'u-border-top': borderTop,
+      }"
+    >
+      <view
+        class="u-tabbar__content__item"
+        v-for="(item, index) in list"
+        :key="index"
+        :class="{
+          'u-tabbar__content__circle': midButton && item.midButton,
+        }"
+        @tap.stop="clickHandler(index)"
+        :style="{
+          backgroundColor: bgColor,
+        }"
+      >
+        <view
+          :class="[
+            midButton && item.midButton
+              ? 'u-tabbar__content__circle__button'
+              : 'u-tabbar__content__item__button',
+          ]"
+        >
+          <u-icon
+            :size="midButton && item.midButton ? midButtonSize : iconSize"
+            :name="elIconPath(index)"
+            img-mode="scaleToFill"
+            :color="elColor(index)"
+            :custom-prefix="item.customIcon ? 'custom-icon' : 'uicon'"
+          ></u-icon>
+          <u-badge
+            :count="item.count"
+            :is-dot="item.isDot"
+            v-if="item.count"
+            :offset="[-2, getOffsetRight(item.count, item.isDot)]"
+          ></u-badge>
+        </view>
+        <view
+          class="u-tabbar__content__item__text"
+          :style="{
+            color: elColor(index),
+          }"
+        >
+          <text class="u-line-1">{{ item.text }}</text>
+        </view>
+      </view>
+      <view
+        v-if="midButton"
+        class="u-tabbar__content__circle__border"
+        :class="{
+          'u-border': borderTop,
+        }"
+        :style="{
+          backgroundColor: bgColor,
+          left: midButtonLeft,
+        }"
+      >
+      </view>
+    </view>
+    <!-- 这里加上一个48rpx的高度,是为了增高有凸起按钮时的防塌陷高度(也即按钮凸出来部分的高度) -->
+    <view
+      class="u-fixed-placeholder safe-area-inset-bottom"
+      :style="{
+        height: `calc(${$u.addUnit(height)} + ${midButton ? 48 : 0}rpx)`,
+      }"
+    ></view>
+  </view>
+</template>
+
+<script>
+export default {
+  props: {
+    // 显示与否
+    show: {
+      type: Boolean,
+      default: true,
+    },
+    // 通过v-model绑定current值
+    value: {
+      type: [String, Number],
+      default: 0,
+    },
+    // 整个tabbar的背景颜色
+    bgColor: {
+      type: String,
+      default: "#ffffff",
+    },
+    // tabbar的高度,默认50px,单位任意,如果为数值,则为rpx单位
+    height: {
+      type: [String, Number],
+      default: "50px",
+    },
+    // 非凸起图标的大小,单位任意,数值默认rpx
+    iconSize: {
+      type: [String, Number],
+      default: 40,
+    },
+    // 凸起的图标的大小,单位任意,数值默认rpx
+    midButtonSize: {
+      type: [String, Number],
+      default: 90,
+    },
+    // 激活时的演示,包括字体图标,提示文字等的演示
+    activeColor: {
+      type: String,
+      default: "#303133",
+    },
+    // 未激活时的颜色
+    inactiveColor: {
+      type: String,
+      default: "#606266",
+    },
+    // 是否显示中部的凸起按钮
+    midButton: {
+      type: Boolean,
+      default: false,
+    },
+    // 配置参数
+    list: {
+      type: Array,
+      default() {
+        return [];
+      },
+    },
+    // 切换前的回调
+    beforeSwitch: {
+      type: Function,
+      default: null,
+    },
+    // 是否显示顶部的横线
+    borderTop: {
+      type: Boolean,
+      default: true,
+    },
+    // 是否隐藏原生tabbar
+    hideTabBar: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {
+      // 由于安卓太菜了,通过css居中凸起按钮的外层元素有误差,故通过js计算将其居中
+      midButtonLeft: "50%",
+      pageUrl: "", // 当前页面URL
+    };
+  },
+  created() {
+    // 是否隐藏原生tabbar
+    if (this.hideTabBar) uni.hideTabBar();
+    // 获取引入了u-tabbar页面的路由地址,该地址没有路径前面的"/"
+    let pages = getCurrentPages();
+    // 页面栈中的最后一个即为项为当前页面,route属性为页面路径
+    this.pageUrl = pages[pages.length - 1].route;
+  },
+  computed: {
+    elIconPath() {
+      return (index) => {
+        return "photo";
+        // 历遍u-tabbar的每一项item时,判断是否传入了pagePath参数,如果传入了
+        // 和data中的pageUrl参数对比,如果相等,即可判断当前的item对应当前的tabbar页面,设置高亮图标
+        // 采用这个方法,可以无需使用v-model绑定的value值
+        let pagePath = this.list[index].pagePath;
+        // 如果定义了pagePath属性,意味着使用系统自带tabbar方案,否则使用一个页面用几个组件模拟tabbar页面的方案
+        // 这两个方案对处理tabbar item的激活与否方式不一样
+        if (pagePath) {
+          if (pagePath == this.pageUrl || pagePath == "/" + this.pageUrl) {
+            return this.list[index].selectedIconPath;
+          } else {
+            return this.list[index].iconPath;
+          }
+        } else {
+          // 普通方案中,索引等于v-model值时,即为激活项
+          return index == this.value
+            ? this.list[index].selectedIconPath
+            : this.list[index].iconPath;
+        }
+      };
+    },
+    elColor() {
+      return (index) => {
+        // 判断方法同理于elIconPath
+        let pagePath = this.list[index].pagePath;
+        if (pagePath) {
+          if (pagePath == this.pageUrl || pagePath == "/" + this.pageUrl)
+            return this.activeColor;
+          else return this.inactiveColor;
+        } else {
+          return index == this.value ? this.activeColor : this.inactiveColor;
+        }
+      };
+    },
+  },
+  mounted() {
+    this.midButton && this.getMidButtonLeft();
+  },
+  methods: {
+    clickTip(val) {
+      console.log(val);
+    },
+    async clickHandler(index) {
+      console.log(index, 789);
+      if (this.beforeSwitch && typeof this.beforeSwitch === "function") {
+        // 执行回调,同时传入索引当作参数
+        // 在微信,支付宝等环境(H5正常),会导致父组件定义的customBack()函数体中的this变成子组件的this
+        // 通过bind()方法,绑定父组件的this,让this.customBack()的this为父组件的上下文
+        let beforeSwitch = this.beforeSwitch.bind(this.$u.$parent.call(this))(
+          index
+        );
+        console.log(beforeSwitch, "beforeSwitch");
+        // 判断是否返回了promise
+        if (!!beforeSwitch && typeof beforeSwitch.then === "function") {
+          await beforeSwitch
+            .then((res) => {
+              // promise返回成功,
+              this.switchTab(index);
+            })
+            .catch((err) => {});
+        } else if (beforeSwitch === true) {
+          // 如果返回true
+          this.switchTab(index);
+        }
+      } else {
+        this.switchTab(index);
+      }
+    },
+    // 切换tab
+    switchTab(index) {
+      console.log(this.list[index].pagePath, "pagePath");
+      // 发出事件和修改v-model绑定的值
+      this.$emit("change", index);
+      // 如果有配置pagePath属性,使用uni.switchTab进行跳转
+      if (this.list[index].pagePath) {
+        console.log("跳转")
+        uni.switchTab({
+          url: this.list[index].pagePath,
+        });
+      } else {
+        // 如果配置了papgePath属性,将不会双向绑定v-model传入的value值
+        // 因为这个模式下,不再需要v-model绑定的value值了,而是通过getCurrentPages()适配
+        this.$emit("input", index);
+      }
+    },
+    // 计算角标的right值
+    getOffsetRight(count, isDot) {
+      // 点类型,count大于9(两位数),分别设置不同的right值,避免位置太挤
+      if (isDot) {
+        return -20;
+      } else if (count > 9) {
+        return -40;
+      } else {
+        return -30;
+      }
+    },
+    // 获取凸起按钮外层元素的left值,让其水平居中
+    getMidButtonLeft() {
+      let windowWidth = this.$u.sys().windowWidth;
+      // 由于安卓中css计算left: 50%的结果不准确,故用js计算
+      this.midButtonLeft = windowWidth / 2 + "px";
+    },
+  },
+};
+</script>
+
+<style scoped lang="scss">
+@mixin vue-flex($direction: row) {
+  /* #ifndef APP-NVUE */
+  display: flex;
+  flex-direction: $direction;
+  /* #endif */
+}
+.u-fixed-placeholder {
+  /* #ifndef APP-NVUE */
+  box-sizing: content-box;
+  /* #endif */
+}
+
+.u-tabbar {
+  &__content {
+    @include vue-flex;
+    align-items: center;
+    position: relative;
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    z-index: 1998;
+    /* #ifndef APP-NVUE */
+    box-sizing: content-box;
+    /* #endif */
+
+    &__circle__border {
+      border-radius: 100%;
+      width: 110rpx;
+      height: 110rpx;
+      top: -48rpx;
+      position: absolute;
+      z-index: 4;
+      background-color: #ffffff;
+      // 由于安卓的无能,导致只有3个tabbar item时,此css计算方式有误差
+      // 故使用js计算的形式来定位,此处不注释,是因为js计算有延后,避免出现位置闪动
+      left: 50%;
+      transform: translateX(-50%);
+
+      &:after {
+        border-radius: 100px;
+      }
+    }
+
+    &__item {
+      flex: 1;
+      justify-content: center;
+      height: 100%;
+      padding: 12rpx 0;
+      @include vue-flex;
+      flex-direction: column;
+      align-items: center;
+      position: relative;
+
+      &__button {
+        position: absolute;
+        top: 14rpx;
+        left: 50%;
+        transform: translateX(-50%);
+      }
+
+      &__text {
+        color: $u-content-color;
+        font-size: 26rpx;
+        line-height: 28rpx;
+        position: absolute;
+        bottom: 14rpx;
+        left: 50%;
+        transform: translateX(-50%);
+        width: 100%;
+        text-align: center;
+      }
+    }
+
+    &__circle {
+      position: relative;
+      @include vue-flex;
+      flex-direction: column;
+      justify-content: space-between;
+      z-index: 10;
+      /* #ifndef APP-NVUE */
+      height: calc(100% - 1px);
+      /* #endif */
+
+      &__button {
+        width: 90rpx;
+        height: 90rpx;
+        border-radius: 100%;
+        @include vue-flex;
+        justify-content: center;
+        align-items: center;
+        position: absolute;
+        background-color: #ffffff;
+        top: -40rpx;
+        left: 50%;
+        z-index: 6;
+        transform: translateX(-50%);
+      }
+    }
+  }
+}
+</style>

+ 2 - 0
main.js

@@ -27,6 +27,8 @@ Vue.use(uView);
 import navLogo from "@/components/nav-bar/nav-logo.vue";
 Vue.component('navLogo', navLogo)
 
+import myTabbar from "@/components/tabbar/index.vue";
+Vue.component('myTabbar', myTabbar)
 // 全局过滤器
 Vue.filter('formate', filters['formDate'])
 

+ 28 - 21
pages.json

@@ -82,6 +82,17 @@
           "bounce": "none"
         }
       }
+    },
+    {
+      "path": "pages/information/index",
+      "style": {
+        "navigationBarTitleText": "资料",
+        "navigationStyle": "custom", // 隐藏系统导航栏
+        "app-plus": {
+          "titleNView": false, //禁用原生导航栏
+          "bounce": "none"
+        }
+      }
     }
   ],
   "subPackages": [
@@ -268,6 +279,17 @@
             }
           }
         },
+        {
+          "path": "wd/stuff",
+          "style": {
+            "navigationBarTitleText": "我的资料",
+            "navigationStyle": "custom", // 隐藏系统导航栏
+            "app-plus": {
+              "titleNView": false, //禁用原生导航栏
+              "bounce": "none"
+            }
+          }
+        },
         {
           "path": "bank/my_question",
           "style": {
@@ -1127,39 +1149,24 @@
   },
   "tabBar": {
     "color": "#AAAAAA",
-    "selectedColor": "#222", //007AFF
+    "selectedColor": "#222",
     "borderStyle": "black",
     "backgroundColor": "#fff",
     "list": [
       {
-        "pagePath": "pages/index/index",
-        "iconPath": "static/nav1.png",
-        "selectedIconPath": "static/nav1_on.png",
-        "text": "首页"
+        "pagePath": "pages/index/index"
       },
       {
-        "pagePath": "pages/course/index",
-        "iconPath": "static/nav2.png",
-        "selectedIconPath": "static/nav2_on.png",
-        "text": "选课"
+        "pagePath": "pages/course/index"
       },
       {
-        "pagePath": "pages/learn/index",
-        "iconPath": "static/nav6.png",
-        "selectedIconPath": "static/nav6_on.png",
-        "text": "学习"
+        "pagePath": "pages/learn/index"
       },
       {
-        "pagePath": "pages/questionBank/index",
-        "iconPath": "static/nav3.png",
-        "selectedIconPath": "static/nav3_on.png",
-        "text": "题库"
+        "pagePath": "pages/questionBank/index"
       },
       {
-        "pagePath": "pages/wd/index",
-        "iconPath": "static/nav5.png",
-        "selectedIconPath": "static/nav5_on.png",
-        "text": "我的"
+        "pagePath": "pages/wd/index"
       }
     ]
   },

+ 4 - 1
pages/course/index.vue

@@ -373,6 +373,8 @@
         </view>
       </view>
     </u-popup>
+    <!-- tabbar -->
+    <myTabbar></myTabbar>
   </view>
 </template>
 
@@ -450,6 +452,7 @@ export default {
     }, 500);
   },
   onLoad(option) {
+    uni.hideTabBar()
     let eduStr = null;
     // 小程序分享跳转
     if (option.scene) {
@@ -719,7 +722,7 @@ page {
 .contents {
   position: relative;
   left: 0;
-  top: 320rpx;
+  top: 300rpx;
 }
 .emptyTip {
   color: #999999;

+ 11 - 4
pages/index/index.vue

@@ -327,6 +327,12 @@
       </view>
     </view>
     <!-- #endif -->
+    <view class="u-page">
+      <!-- 所有内容的容器 -->
+    </view>
+
+    <!-- tabbar -->
+    <myTabbar></myTabbar>
   </view>
 </template>
 
@@ -342,7 +348,7 @@ export default {
       tabCurrent: 0,
       date: ["日", "一", "二", "三", "四", "五", "六"],
       date_num: [],
-      current: 0,
+      current: 2,
       indicatorDots: true,
       autoplay: true,
       interval: 2000,
@@ -407,6 +413,7 @@ export default {
     };
   },
   async onLoad(option) {
+    uni.hideTabBar()
     // #ifdef H5
     uni.setNavigationBarTitle({
       title: this.config.companyName,
@@ -618,13 +625,12 @@ export default {
           "pages/course/index",
           "pages/learn/index",
           "pages/questionBank/index",
+          "pages/wd/index",
+          "pages/information/index"
         ];
         const isSwitch = map.find((e) => jumpUrl.includes(e));
         // tab页
         if (isSwitch) {
-          // uni.switchTab({
-          //   url: jumpUrl,
-          // });
           // 解决携带参数问题
           uni.reLaunch({
             url: jumpUrl,
@@ -1077,6 +1083,7 @@ page {
   white-space: nowrap;
 }
 .index {
+  padding-bottom: 110rpx;
   .swiper {
     width: 100%;
     position: relative;

+ 298 - 0
pages/information/index.vue

@@ -0,0 +1,298 @@
+<template>
+  <view>
+    <nav-logo title="资料"></nav-logo>
+    <view class="goods-warp">
+      <view class="search-box fl">
+        <u-search
+          bg-color="#ffffff"
+          placeholder="搜索"
+          v-model="goodsName"
+          @custom="comfirmSearch"
+          @search="comfirmSearch"
+        ></u-search>
+      </view>
+      <view class="goods-list">
+        <template v-if="goodsList.length">
+          <!-- hover-class="none" -->
+          <view
+            class="list_item"
+            v-for="(item, index) in goodsList"
+            :key="index"
+            @click="tobuy(item)"
+          >
+            <view class="list_item_content">
+              <view class="c_title">{{ item.goodsName }}</view>
+              <view class="c_downs">
+                <view class="img">
+                  <image
+                    :src="$method.splitImgHost(item.coverUrl, true)"
+                  ></image>
+                  <view class="time" v-if="item.year">{{
+                    item.year ? item.year : ""
+                  }}</view>
+                </view>
+                <view class="text">
+                  <view class="desc">
+                    <view class="left">
+                      <view
+                        class="mon_t"
+                        :class="item.standPrice === 0 ? 'free' : ''"
+                        v-if="
+                          !item.specTemplateId ||
+                          (!item.maxPrice && !item.minPrice)
+                        "
+                      >
+                        {{
+                          item.standPrice === 0
+                            ? "免费"
+                            : `¥${item.standPrice}`
+                        }}
+                      </view>
+                      <!-- 范围价格 -->
+                      <view v-else class="mon_t">
+                        <view>{{ item.minPrice }}</view>
+                        <template v-if="item.minPrice != item.maxPrice">
+                          <text>-</text>
+                          <view>{{ item.maxPrice }}</view>
+                        </template>
+                      </view>
+                      <text v-if="item.linePrice" class="sale"> ¥ </text>
+                      <text v-if="item.linePrice" class="price_line"
+                        >&nbsp;{{ item.linePrice }}</text
+                      >
+                    </view>
+                    <view class="right">
+                      <view v-if="!hideBuyState" class="regiser_row"
+                        >立即购买</view
+                      >
+                    </view>
+                  </view>
+                  <view v-if="item.buyUserNum" class="joins">
+                    <!-- <image class="people" src="/static/index/people.png"></image> -->
+                    <!-- 为0时,不显示 -->
+                    <view class="people">{{ item.buyUserNum }}人参与</view>
+                  </view>
+                </view>
+              </view>
+            </view>
+          </view>
+        </template>
+        <template v-else>
+          <u-empty text="暂无资料" mode="list" margin-top="100"></u-empty>
+        </template>
+      </view>
+    </view>
+    <!-- tabbar -->
+    <myTabbar></myTabbar>
+  </view>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+export default {
+  name: "SaasMiniprogramIndex",
+
+  data() {
+    return {
+      goodsName: "",
+      goodsList: [],
+      param: {},
+      total: 0,
+    };
+  },
+  onLoad(option) {
+    uni.hideTabBar();
+    this.init();
+  },
+  onPullDownRefresh() {
+    this.init();
+  },
+  onReachBottom() {
+    if (this.goodsList.length < this.total) {
+      this.param.pageNum++;
+      this.getGoodsList();
+    }
+  },
+  methods: {
+    init(goodsName = "") {
+      this.param = {
+        pageNum: 1,
+        pageSize: 10,
+        goodsType: 8,
+        goodsName,
+      };
+      this.goodsList = [];
+      this.getGoodsList();
+    },
+    comfirmSearch() {
+      this.param.goodsName = this.goodsName;
+      this.init(this.goodsName);
+    },
+    getGoodsList() {
+      this.$api.goodsList(this.param).then((res) => {
+        this.goodsList.push(...res.data.rows);
+        this.total = res.data.total;
+      });
+    },
+    tobuy(item) {
+      uni.navigateTo({
+        url:
+          "/pages3/course/detail?id=" +
+          item.goodsId +
+          "&goodsType=" +
+          item.goodsType,
+      });
+    },
+  },
+  computed: {
+    ...mapGetters(["userInfo", "hideBuyState"]),
+  },
+};
+</script>
+<style>
+page {
+  background: #eaeef1;
+}
+</style>
+<style lang="scss" scoped>
+.goods-warp {
+  padding: 16rpx;
+  position: relative;
+  .search-box {
+    height: 96rpx;
+    width: calc(100% - 32rpx);
+    position: fixed;
+    background: #eaeef1;
+    z-index: 10;
+    margin-top: -16rpx;
+  }
+}
+.goods-list {
+  margin-top: 40px;
+  .list_item {
+    padding: 24rpx;
+    // height: 278rpx;
+    background: #ffffff;
+    box-shadow: 0rpx 0rpx 20rpx 1rpx rgba(1, 99, 235, 0.1);
+    border-radius: 24rpx;
+    background: #fff;
+    margin-bottom: 32rpx;
+    display: flex;
+    align-items: center;
+    .list_item_content {
+      width: 100%;
+    }
+    .c_title {
+      font-size: 32rpx;
+      font-weight: bold;
+      margin-bottom: 24rpx;
+      font-weight: bold;
+      color: #222222;
+    }
+    .c_downs {
+      display: flex;
+    }
+    .img {
+      position: relative;
+      margin-right: 24rpx;
+      border-radius: 16rpx;
+      overflow: hidden;
+      width: 204rpx;
+      height: 120rpx;
+      image {
+        width: 100%;
+        height: 100%;
+      }
+
+      .time {
+        position: absolute;
+        bottom: 0;
+        right: 0;
+        width: 80rpx;
+        height: 32rpx;
+        background: rgba(1, 25, 45, 0.4);
+        color: #fff;
+        text-align: center;
+        line-height: 32rpx;
+        font-size: 24rpx;
+        border-radius: 10rpx 0px 10rpx 0px;
+      }
+    }
+
+    .text {
+      flex: 1;
+      position: relative;
+      display: flex;
+      flex-direction: column;
+      justify-content: space-between;
+      height: 120rpx;
+      .joins {
+        .people {
+          width: 160rpx;
+          font-size: 20rpx;
+          color: #999999;
+          padding: 0rpx 8rpx;
+          text-align: center;
+          height: 36rpx;
+          line-height: 36rpx;
+          background: #f6f7fb;
+          border-radius: 4px;
+        }
+      }
+      .desc {
+        margin-top: 10rpx;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        width: 100%;
+        .left {
+          flex: 1;
+          color: #333;
+          font-size: 26rpx;
+          .mon_t {
+            display: flex;
+            font-weight: bold;
+            color: #fc3f3f;
+            font-size: 36rpx;
+            view::before {
+              content: "¥";
+              font-size: 24rpx;
+              font-weight: bold;
+            }
+          }
+          .free {
+            font-size: 24rpx;
+          }
+          .sale {
+            color: #999999;
+            font-size: 24rpx;
+            margin-left: 8rpx;
+          }
+          .price_line {
+            color: #999999;
+            font-size: 24rpx;
+            text-decoration: line-through;
+            font-weight: 400;
+          }
+        }
+
+        .right {
+          font-size: 24rpx;
+          font-weight: bold;
+          .regiser_row {
+            width: 144rpx;
+            height: 52rpx;
+            line-height: 52rpx;
+            text-align: center;
+            border-radius: 16rpx;
+            background-color: #fc3f3f;
+            color: #fff;
+            font-weight: 500;
+            font-size: 26rpx;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 3 - 0
pages/learn/index.vue

@@ -581,6 +581,8 @@
         </view>
       </view>
     </u-popup>
+    <!-- tabbar -->
+    <myTabbar></myTabbar>
   </view>
 </template>
 
@@ -698,6 +700,7 @@ export default {
     },
   },
   onLoad() {
+    uni.hideTabBar()
     // 1668873600 ,2022.11.20的时间戳
     this.leftDays = 1668873600 - parseInt(curTime / 1000);
     this.sysTime = +this.$method.timest();

+ 3 - 0
pages/questionBank/index.vue

@@ -122,6 +122,8 @@
       <text class="word_tip">暂无题库</text>
       <view class="choose" @click="toChoose()">立即去选购</view>
     </view>
+    <!-- tabbar -->
+    <myTabbar></myTabbar>
   </view>
 </template>
 
@@ -144,6 +146,7 @@ export default {
     ...mapGetters(["userInfo", "config"]),
   },
   onLoad(options) {
+    uni.hideTabBar()
     this.options = options;
     if (this.options.isAct && !this.$method.isLogin()) {
       uni.navigateTo({

+ 12 - 0
pages/wd/index.vue

@@ -140,9 +140,20 @@
             <u-icon name="arrow-right" color="#999" size="24"></u-icon>
           </view>
         </navigator>
+        <navigator hover-class="none" url="/pages2/wd/stuff" class="menu_box">
+          <view class="box_left">
+            <image src="/static/icon/my_icon14.png" class="my_icon"></image>
+            <view>讲义资料</view>
+          </view>
+          <view class="box_right">
+            <u-icon name="arrow-right" color="#999" size="24"></u-icon>
+          </view>
+        </navigator>
       </view>
       <view class="logout" @click="logout">退出</view>
     </view>
+    <!-- tabbar -->
+    <myTabbar></myTabbar>
   </view>
 </template>
 
@@ -163,6 +174,7 @@ export default {
     };
   },
   onLoad(option) {
+    uni.hideTabBar()
     // console.log(option,987)
   },
   onShow() {

+ 438 - 0
pages2/wd/stuff.vue

@@ -0,0 +1,438 @@
+<template>
+  <view>
+    <nav-logo title="我的资料"></nav-logo>
+    <view v-if="goodsList.length" class="my_courses">
+      <view v-for="(item, index) in goodsList" :key="index" class="course_item">
+        <view class="c_downs">
+          <view class="lefts">
+            <image
+              class="lefet_img"
+              :src="$method.splitImgHost(item.coverUrl, true)"
+              mode=""
+            ></image>
+          </view>
+          <view class="rights">
+            <view class="learn_progress">
+              <view class="progress_up">
+                <view class="cou_titles line2">{{ item.goodsName }}</view>
+              </view>
+            </view>
+          </view>
+        </view>
+        <view class="course_item_info" v-if="item.goodsType !== 6">
+          <view>
+            <text>商品有效期:</text>
+            <template v-if="item.validityEndTime">
+              <text
+                :class="{
+                  'line-through':
+                    sysTime <= item.validityStartTime ||
+                    sysTime >= item.validityEndTime,
+                }"
+              >
+                {{ $method.formDate(item.validityStartTime, "yyyy/mm/dd") }}至{{
+                  $method.formDate(item.validityEndTime, "yyyy/mm/dd")
+                }}</text
+              >
+            </template>
+            <text v-else>——</text>
+          </view>
+        </view>
+        <view class="study_btns">
+          <view @click="studyIn(item)" class="exam_word intos">进入学习</view>
+        </view>
+      </view>
+    </view>
+    <view v-else class="no_datas">
+      <image class="courses" src="/static/learn/no_course.png" mode=""></image>
+      <view class="no_learns">您目前没有可学习的课程</view>
+      <view class="choose" @click="toChoose()">立即去选购</view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  name: "SaasMiniprogramStuff",
+
+  data() {
+    return {
+      param: {},
+      goodsList: [],
+      total: 0,
+      sysTime: "",
+    };
+  },
+
+  onLoad() {
+    this.init();
+  },
+  onReachBottom() {
+    if (this.goodsList.length < this.total) {
+      this.param.pageNum++;
+      this.getGoodsHandoutsList();
+    }
+  },
+  methods: {
+    init() {
+      this.param = {
+        pageNum: 1,
+        pageSize: 10,
+      };
+      this.sysTime = +this.$method.timest();
+      this.goodsList = [];
+      this.getGoodsHandoutsList();
+    },
+    getGoodsHandoutsList() {
+      this.$api.goodsHandoutsList(this.param).then((res) => {
+        this.goodsList.push(...res.data.rows);
+        this.total = res.data.total;
+      });
+    },
+    studyIn(item) {
+      if (
+        item.validityStartTime &&
+        (this.sysTime <= item.validityStartTime ||
+          this.sysTime >= item.validityEndTime)
+      ) {
+        uni.showToast({
+          icon: "none",
+          title: "不在商品有效期,不能进入学习",
+        });
+        return;
+      }
+    },
+    toChoose() {
+      uni.reLaunch({
+        url: "/pages/information/index",
+      });
+    },
+  },
+};
+</script>
+<style>
+page {
+  background: #eaeef1;
+}
+</style>
+<style lang="scss" scoped>
+.my_courses {
+  padding: 24rpx;
+  .titles {
+    font-size: 32rpx;
+    color: #333333;
+    margin: 44rpx 0rpx 24rpx 43rpx;
+    font-weight: bold;
+    display: block;
+  }
+  .course_item {
+    width: 100%;
+    // height: 278rpx;
+    background: #ffffff;
+    box-shadow: 0rpx 0rpx 20rpx 1rpx rgba(1, 99, 235, 0.1);
+    border-radius: 24rpx;
+    padding: 29rpx 29rpx 20rpx 24rpx;
+    margin-bottom: 20rpx;
+    .course_item_info {
+      border-radius: 16rpx;
+      background: #f8f8f8;
+      padding: 24rpx 24rpx 10rpx;
+      margin-top: 24rpx;
+      & > view {
+        margin-bottom: 10rpx;
+      }
+      view {
+        text {
+          font-size: 24rpx;
+          &:nth-of-type(1) {
+            color: #969696;
+          }
+          &:nth-of-type(2) {
+            color: #4b4b4b;
+          }
+        }
+        .eb {
+          color: #eb5757 !important;
+        }
+      }
+    }
+    .titlews {
+      padding-bottom: 24rpx;
+    }
+    .cou_titles {
+      color: #222222;
+      font-size: 28rpx;
+      font-weight: bold;
+      width: 100%;
+    }
+    .learn_ranges {
+      color: #666;
+      font-size: 24rpx;
+      .l_range {
+        width: 20rpx;
+        height: 24rpx;
+        margin-right: 9rpx;
+      }
+      .l_time {
+        color: #333;
+      }
+    }
+    .c_downs {
+      display: flex;
+      align-items: center;
+    }
+    // 状态
+    .all_status {
+      width: 654rpx;
+      background: #f8f8f8;
+      border-radius: 16rpx;
+    }
+    .class-warm {
+      display: flex;
+      align-items: flex-start;
+
+      &__icon {
+        margin-right: 10rpx;
+      }
+
+      &__text {
+        .date {
+          color: #ff3b30;
+          font-size: 22rpx;
+          font-weight: 400;
+        }
+      }
+    }
+    .box_progress {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-top: 20rpx;
+      // .disabled {
+      // 	opacity: 0.6;
+      // }
+    }
+    .study_tips {
+      color: #eb5757;
+      font-size: 24rpx;
+      margin-top: 20rpx;
+    }
+    .study_btns {
+      width: 100%;
+      margin-top: 40rpx;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+      .exam_btns {
+        // width: 64%;
+        display: flex;
+        justify-content: flex-end;
+        align-items: center;
+      }
+    }
+    .box_appoint {
+      // width: 35%;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+      .img {
+        width: 32rpx;
+        height: 32rpx;
+        margin-right: 10rpx;
+      }
+    }
+    .exam_word {
+      font-size: 24rpx;
+      font-weight: 500;
+      width: 144rpx;
+      height: 56rpx;
+      line-height: 56rpx;
+      text-align: center;
+      background: #ffffff;
+      border-radius: 66rpx;
+      margin-left: 32rpx;
+    }
+    .ones {
+      color: #484848;
+      border: 2rpx solid #b9b9b9;
+    }
+    .intos {
+      color: #498afe;
+      border: 2rpx solid #498afe;
+    }
+  }
+  .lefts {
+    width: 204rpx;
+    height: 120rpx;
+    border-radius: 12rpx;
+    margin-right: 26rpx;
+    position: relative;
+    top: 0;
+    left: 0;
+    .lefet_img {
+      width: 100%;
+      height: 100%;
+      display: block;
+      border-radius: 16rpx;
+    }
+    .live_icon {
+      width: 65rpx;
+      height: 35rpx;
+      line-height: 35rpx;
+      border-radius: 12rpx 0rpx 12rpx 0rpx;
+      background-color: #ffb102;
+      color: #fff;
+      font-size: 20rpx;
+      text-align: center;
+      position: absolute;
+      top: 0;
+      left: 0;
+    }
+  }
+  .rights {
+    width: 400rpx;
+    height: 120rpx;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+
+    .learn_progress {
+      width: 100%;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+    }
+    .progress_up {
+      width: 100%;
+      .classHour {
+        padding-top: 16rpx;
+        font-size: 24rpx;
+        color: #666666;
+      }
+      .scheduling {
+        display: flex;
+        align-items: center;
+      }
+      .sche_bar {
+        font-size: 24rpx;
+        color: #999999;
+        margin-right: 20rpx;
+      }
+      .progress_bar {
+        flex: 1;
+      }
+    }
+    .progress_down {
+      // width: 100%;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+    }
+    .enter_into {
+      width: 144rpx;
+      height: 52rpx;
+      line-height: 52rpx;
+      background: #ffb102;
+      border-radius: 16rpx;
+      font-size: 26rpx;
+      font-weight: 500;
+      color: #ffffff;
+      text-align: center;
+    }
+  }
+  // 收藏集,做题记录
+  .bottoms {
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 32rpx;
+    .item {
+      width: 335rpx;
+      &.collect {
+        position: relative;
+        font-size: 32rpx;
+        color: #ffffff;
+        height: 240rpx;
+        border-radius: 24rpx;
+        padding: 32rpx;
+
+        .text {
+          position: relative;
+          z-index: 10;
+          font-size: 32rpx;
+          font-weight: bold;
+          color: #ffffff;
+        }
+
+        .img {
+          position: absolute;
+          left: 0;
+          top: 0;
+          width: 100%;
+          height: 100%;
+        }
+      }
+
+      &.list {
+        .list-in {
+          position: relative;
+          width: 335rpx;
+          height: 112rpx;
+          background: #007aff;
+          border-radius: 24rpx;
+          display: flex;
+          align-items: center;
+          font-size: 32rpx;
+          color: #fff;
+
+          &:first-of-type {
+            margin-bottom: 16rpx;
+          }
+
+          .text {
+            padding-left: 91rpx;
+            position: relative;
+            z-index: 10;
+            font-size: 32rpx;
+            font-weight: bold;
+            color: #ffffff;
+          }
+
+          .img {
+            position: absolute;
+            left: 0;
+            top: 0;
+            width: 100%;
+            height: 100%;
+          }
+        }
+      }
+    }
+  }
+}
+.no_datas {
+  margin-top: 70rpx;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .courses {
+    width: 360rpx;
+    height: 349rpx;
+  }
+  .no_learns {
+    font-size: 32rpx;
+    color: #999;
+    margin: 46rpx 0rpx 56rpx;
+  }
+  .choose {
+    width: 280rpx;
+    height: 64rpx;
+    line-height: 62rpx;
+    border-radius: 32rpx;
+    background-color: #007aff;
+    color: #fff;
+    font-size: 30rpx;
+    text-align: center;
+  }
+}
+</style>

+ 22 - 21
pages3/course/detail.vue

@@ -74,7 +74,7 @@
               {{ detail.linePrice }}</text
             >
           </view>
-          <view class="noteTag">
+          <view class="noteTag" v-if="!isJx">
             <text class="blackFont"
               >{{ courseList.length }} 课程 {{ detail.classHours || "-" }}</text
@@ -85,7 +85,7 @@
       </view>
       <!-- </view> -->
     </view>
-    <view class="contents">
+    <view class="contents" v-if="list.length">
       <!-- <u-line color="#D6D6DB" /> -->
       <!-- <view style="height: 80rpx;">
 				<view><u-tabs :list="list" :item-width="itemWidth()" font-size="30" bar-width="24"  :current="current" @change="change" active-color="#007AFF"></u-tabs></view>
@@ -95,11 +95,8 @@
           v-for="(item, index) in list"
           :key="index"
           class="tab_item"
-          :class="[
-            list.length == 2 ? 'twoBtn' : list.length == 3 ? 'threeBtn' : '',
-            { nactive: current == index },
-          ]"
-          @click="change(index)"
+          :class="[{ nactive: current == item.value }]"
+          @click="change(item.value)"
           >{{ item.name }}</view
         >
       </view>
@@ -257,7 +254,6 @@
         style="padding: 20rpx; padding-bottom: 100rpx; position: relative"
         v-show="current == 2"
       >
-        <!-- <view > -->
         <view v-for="(item, index) in freeMenuList" :key="index">
           <view class="courseItemBox">
             <view class="courseItem">
@@ -265,8 +261,9 @@
             </view>
           </view>
         </view>
-        <!-- </view> -->
       </view>
+      <!-- 讲义资料 -->
+      <view v-show="current == 3">123</view>
     </view>
 
     <view class="bottomBox" v-if="!hideBuyState">
@@ -485,6 +482,10 @@ export default {
     disCode() {
       return this.options.distributionCode;
     },
+    isJx() {
+      // 8 讲义资料商品
+      return this.goodsType == 8;
+    },
   },
   onLoad(option) {
     if (option.scene) {
@@ -518,8 +519,12 @@ export default {
       }
     }
     this.disCode ? this.getFxDetail() : this.getDetail();
-    this.goodsCourseList();
-    this.appCommonGoodsCourseModuleFreeExamList();
+    // 非讲义商品
+    if (!this.isJx) {
+      this.goodsCourseList();
+      this.appCommonGoodsCourseModuleFreeExamList();
+    }
+
     // #ifdef MP-WEIXIN
     wx.showShareMenu({
       withShareTicket: true,
@@ -603,7 +608,6 @@ export default {
     },
     // 修改用户活动邀请码
     editShareActivityCode() {
-      goodsIds;
       console.log("修改用户活动邀请码");
       this.$http({
         url: "/app/user/edit/shareActivityCode",
@@ -624,21 +628,26 @@ export default {
           this.list = [
             {
               name: "课程介绍",
+              value: 0,
             },
             {
               name: "课程目录",
+              value: 1,
             },
             {
               name: "赠送",
+              value: 2,
             },
           ];
         } else {
           this.list = [
             {
               name: "课程介绍",
+              value: 0,
             },
             {
               name: "课程目录",
+              value: 1,
             },
           ];
         }
@@ -1454,7 +1463,7 @@ page {
   padding: 0rpx 5rpx;
 
   .tab_item {
-    width: 345rpx;
+    flex: 1;
     height: 65rpx;
     line-height: 65rpx;
     font-size: 28rpx;
@@ -1467,14 +1476,6 @@ page {
       color: #fff;
       background-color: #3577e8;
     }
-
-    &.twoBtn {
-      width: 50%;
-    }
-
-    &.threeBtn {
-      width: 33%;
-    }
   }
 
   // /deep/  .u-tabs {

BIN
static/icon/my_icon14.png


BIN
static/nav4.png


BIN
static/nav4_on.png


+ 5 - 1
static/style/index.scss

@@ -27,4 +27,8 @@
   text-overflow: ellipsis; /* 可以用来多行文本的情况下,用省略号“…”隐藏超出范围的文本 。*/
   -webkit-line-clamp: 2;
   overflow: hidden;
-}
+}
+.line-through {
+  text-decoration: line-through;
+  color: #999999 !important;
+}