闫增涛
2024-04-11 bd3a3057169eb727728f8a322f51fd4fb4b6cf30
答题器听力题播放功能优化
9个文件已修改
336 ■■■■ 已修改文件
packageBookService/pages/bookServices/detail/components/tree/index.wxml 163 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/components/tree/index.wxss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/index.wxml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/index.wxss 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/examination/examination.js 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/examination/questionList/index.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/examination/questionList/index.wxml 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/examination/questionList/index.wxss 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/list/index.js 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/components/tree/index.wxml
@@ -1,52 +1,140 @@
<view class="tree">
  <t-collapse default-value="{{openIds}}" catchchange="handleChange">
    <t-collapse-panel wx:for="{{treeList}}" wx:for-item="item" wx:for-index="index" wx:key="id" value="{{item.id}}">
    <t-collapse-panel
      wx:for="{{treeList}}"
      wx:for-item="item"
      wx:for-index="index"
      wx:key="id"
      value="{{item.id}}"
    >
      <view slot="header" class="header-title">
        <view class="title-checkBox" catchtap="catchTap">
          <t-checkbox icon="rectangle" checked="{{item.checked}}" data-item="{{item}}" catchchange="checkResourceTitle" wx:if="{{isShowCheck}}" />
          <t-checkbox
            style="align-items: center"
            icon="rectangle"
            checked="{{item.checked}}"
            data-item="{{item}}"
            catchchange="checkResourceTitle"
            wx:if="{{isShowCheck}}"
          />
          <!-- 章节名 -->
          <view class="title-box">
            <text class="title-name">{{item.name}} </text>
            <view class="title-name">{{item.name}} </view>
            <view wx:if="{{item.sysType =='CmsFolder'}}" class="title-num">
              ({{item.children ? item.children.length : 0}})
            </view>
          </view>
        </view>
      </view>
      <view class="list" wx:for="{{item.children}}" wx:for-item="citem" wx:for-index="cindex" wx:key="cindex">
      <view
        class="list"
        wx:for="{{item.children}}"
        wx:for-item="citem"
        wx:for-index="cindex"
        wx:key="cindex"
      >
        <!-- // 判断 无子项 且为商品item 直接显示 -->
        <view class="listItems" wx:if="{{citem.childrenFolderCount <= 0 && citem.sysType == 'CmsItem'}}">
        <view
          class="listItems"
          wx:if="{{citem.childrenFolderCount <= 0 && citem.sysType == 'CmsItem'}}"
        >
          <view class="itemsInfo" data-item="{{citem}}" data-index="{{cindex}}">
            <view class="contentBox" bind:tap="goPlayer" data-item="{{citem}}" data-parent="{{item}}">
            <view
              class="contentBox"
              bind:tap="goPlayer"
              data-item="{{citem}}"
              data-parent="{{item}}"
            >
              <!-- 教学资源 云学习 图标 -->
              <view class="box-image" style="{{ tab == 'jsek_teachingResources' ? 'width: 350rpx;' : 'width: 450rpx;'}}">
                <view class="checkBox" wx:if="{{isShowCheck}}" catchtap="catchTap">
              <view
                class="box-image"
                style="{{ tab == 'jsek_teachingResources' ? 'width: 350rpx;' : 'width: 450rpx;'}}"
              >
                <view
                  class="checkBox"
                  wx:if="{{isShowCheck}}"
                  catchtap="catchTap"
                >
                  <!-- checked="{{citem.checked}}"  -->
                  <!-- <t-checkbox icon="rectangle" checked="{{citem.checked}}" disabled="{{citem.selectType=='webpage' || citem.isDownload != 1 || citem.fileMap[citem.file].protectType == 'Private'}}" catch:change="checkResource" data-item="{{citem}}" /> -->
                  <t-checkbox disabled="{{!citem.saleMethod[0].Id}}" icon="rectangle" checked="{{citem.checked}}" data-item="{{citem}}" data-parent="{{item}}" catch:change="checkResource" />
                  <t-checkbox
                    disabled="{{!citem.saleMethod[0].Id}}"
                    icon="rectangle"
                    checked="{{citem.checked}}"
                    data-item="{{citem}}"
                    data-parent="{{item}}"
                    catch:change="checkResource"
                  />
                </view>
                <!-- 教学资源图标 -->
                <view class="teach-icon">
                  <image wx:if="{{citem.selectType == 'audio' || citem.learnSelectType == 'audio'}}" src="/static/images/bookService/detail/audioIcon.png" mode="aspectFill" />
                  <image wx:elif="{{citem.selectType == 'video' || citem.learnSelectType == 'video'}}" src="/static/images/bookService/detail/video.png" mode="aspectFill" />
                  <image wx:elif="{{citem.selectType == 'pdf'}}" src="/static/images/bookService/detail/pdf.png" mode="aspectFill" />
                  <image wx:elif="{{citem.selectType == 'webpage'}}" src="/static/images/bookService/detail/net.png" mode="aspectFill" />
                  <image wx:elif="{{citem.selectType == 'picture'}}" src="/static/images/bookService/detail/picture.png" mode="aspectFill" />
                  <image wx:elif="{{citem.selectType == 'zip'}}" src="/static/images/bookService/detail/zip.png" mode="aspectFill" />
                  <image wx:elif="{{ citem.fileMap[citem.file].extension == 'doc' ||  citem.fileMap[citem.file].extension == 'docx'}}" src="/static/images/bookService/detail/word.png" mode="aspectFill" />
                  <image wx:elif="{{ citem.fileMap[citem.file].extension == 'xlsx' ||  citem.fileMap[citem.file].extension == 'xlsx'}}" src="/static/images/bookService/detail/excel.png" mode="aspectFill" />
                  <image wx:elif="{{ citem.fileMap[citem.file].extension == 'ppt' ||  citem.fileMap[citem.file].extension == 'pptx'}}" src="/static/images/bookService/detail/PPT.png" mode="aspectFill" />
                  <image
                    wx:if="{{citem.selectType == 'audio' || citem.learnSelectType == 'audio'}}"
                    src="/static/images/bookService/detail/audioIcon.png"
                    mode="aspectFill"
                  />
                  <image
                    wx:elif="{{citem.selectType == 'video' || citem.learnSelectType == 'video'}}"
                    src="/static/images/bookService/detail/video.png"
                    mode="aspectFill"
                  />
                  <image
                    wx:elif="{{citem.selectType == 'pdf'}}"
                    src="/static/images/bookService/detail/pdf.png"
                    mode="aspectFill"
                  />
                  <image
                    wx:elif="{{citem.selectType == 'webpage'}}"
                    src="/static/images/bookService/detail/net.png"
                    mode="aspectFill"
                  />
                  <image
                    wx:elif="{{citem.selectType == 'picture'}}"
                    src="/static/images/bookService/detail/picture.png"
                    mode="aspectFill"
                  />
                  <image
                    wx:elif="{{citem.selectType == 'zip'}}"
                    src="/static/images/bookService/detail/zip.png"
                    mode="aspectFill"
                  />
                  <image
                    wx:elif="{{ citem.fileMap[citem.file].extension == 'doc' ||  citem.fileMap[citem.file].extension == 'docx'}}"
                    src="/static/images/bookService/detail/word.png"
                    mode="aspectFill"
                  />
                  <image
                    wx:elif="{{ citem.fileMap[citem.file].extension == 'xlsx' ||  citem.fileMap[citem.file].extension == 'xlsx'}}"
                    src="/static/images/bookService/detail/excel.png"
                    mode="aspectFill"
                  />
                  <image
                    wx:elif="{{ citem.fileMap[citem.file].extension == 'ppt' ||  citem.fileMap[citem.file].extension == 'pptx'}}"
                    src="/static/images/bookService/detail/PPT.png"
                    mode="aspectFill"
                  />
                  <!-- 资源无文件内容图标 -->
                  <image wx:else src="/static/images/bookService/detail/word.png" mode="" />
                  <image
                    wx:else
                    src="/static/images/bookService/detail/word.png"
                    mode=""
                  />
                </view>
                <!-- 云学习图标 -->
                <view> </view>
                <!-- 名称 -->
                <text class="name" style="{{ tab == 'jsek_teachingResources' ? 'width: 300rpx;' : 'width: 400rpx;'}}">{{citem.name || '-'}}</text>
                <text
                  class="name"
                  style="{{ tab == 'jsek_teachingResources' ? 'width: 300rpx;' : 'width: 400rpx;'}}"
                  >{{citem.name || '-'}}</text
                >
              </view>
              <!-- 教学资源类型 -->
              <view class="teachClass"> {{citem.resourceClass}} </view>
              <view class="teach-btn" wx:if="{{tab == 'jsek_teachingResources'}}">
              <view
                class="teach-btn"
                wx:if="{{tab == 'jsek_teachingResources'}}"
              >
                <!--  下载按钮 -->
                <!-- <image
                  src="/static/images/bookService/detail/download-icon.png"
@@ -57,17 +145,42 @@
              </view>
              <view wx:if="{{tab == 'jsek_cloudLearning'}}">
                <!-- 云学习试看图标 -->
                <image src="/static/images/bookService/detail/shikan.png" class="testSee" wx:if="{{!citem.isbuy ? false : citem.freeFile ? true : false}}"></image>
                <image
                  src="/static/images/bookService/detail/shikan.png"
                  class="testSee"
                  wx:if="{{!citem.isbuy ? false : citem.freeFile ? true : false}}"
                ></image>
                <!-- 云学习加入购物车图标 -->
                <image src="/static/images/bookService/detail/cart@2x.png" wx:if="{{citem.isShopCar}}" class="shopCar" data-item="{{citem}}" catch:tap="onCloudShoppingCart"></image>
                <image
                  src="/static/images/bookService/detail/cart@2x.png"
                  wx:if="{{citem.isShopCar}}"
                  class="shopCar"
                  data-item="{{citem}}"
                  catch:tap="onCloudShoppingCart"
                ></image>
                <!-- 云学习购买图标 -->
                <image src="/static/images/bookService/detail/need-buy.png" class="need-buy" wx:if="{{citem.isbuy }}"></image>
                <image
                  src="/static/images/bookService/detail/need-buy.png"
                  class="need-buy"
                  wx:if="{{citem.isbuy }}"
                ></image>
              </view>
            </view>
          </view>
        </view>
        <!-- // 判断 不是商品 有子项 递归组件 -->
        <tree wx:if="{{citem.childrenCount > 0 && citem.sysType == 'CmsFolder' }}" isShowCheck="{{isShowCheck}}" bookInfo="{{bookInfo}}" treeList="{{[citem]}}" learnList="{{learnList}}" itemId="{{itemId}}" tab="{{tab}}" buyIds="{{buyIds}}" openTeachids="{{openTeachids}}" openLearnids="{{openLearnids}}"></tree>
        <tree
          wx:if="{{ citem.sysType == 'CmsFolder' }}"
          isShowCheck="{{isShowCheck}}"
          bookInfo="{{bookInfo}}"
          treeList="{{[citem]}}"
          learnList="{{learnList}}"
          itemId="{{itemId}}"
          tab="{{tab}}"
          buyIds="{{buyIds}}"
          openTeachids="{{openTeachids}}"
          openLearnids="{{openLearnids}}"
        ></tree>
      </view>
      <!-- 暂无数据 -->
      <view wx:if="{{!item.children || !item.children.length}}" class="noData">
packageBookService/pages/bookServices/detail/components/tree/index.wxss
@@ -1,8 +1,10 @@
.tree {
  --td-collapse-content-padding: 0rpx 12rpx 32rpx 12rpx;
  --td-collapse-header-text-color: #ff6C00;
  --td-collapse-icon-color: #ff6c00
  --td-collapse-icon-color: #ff6c00;
  --td-collapse-header-height: min-content;
}
.header-title {
  width: 100%;
@@ -15,7 +17,7 @@
.title-box {
  width: 100%;
  display: flex;
  align-items: flex-start;
  align-items: center;
}
.title-checkBox {
@@ -26,11 +28,7 @@
.title-name {
  display: inline-block;
  /* max-width: 60%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis; */
  height: min-content;
}
.t-class {
packageBookService/pages/bookServices/detail/index.wxml
@@ -30,7 +30,7 @@
            <image
              loading=""
              src="{{bookDetail.icon ? bookDetail.icon : '/static/images/default-book-img.png'}}"
              mode="aspectFill"
              mode="aspectFit"
              aria-label="{{bookDetail.name}}"
            />
          </view>
packageBookService/pages/bookServices/detail/index.wxss
@@ -1,5 +1,6 @@
/* pages/bookServices/detail/index.wxss */
@import "./index.skeleton.wxss";
.page-bookService {
  width: 100vw;
  height: 100%;
@@ -27,12 +28,18 @@
  background-color: #F2F3F8;
}
.book-img image {
.book-img {
  width: 240rpx;
  height: 340rpx;
  display: flex;
  align-items: center;
  box-shadow: 0px 3px 6px 1px rgba(0, 0, 0, 0.16);
}
.book-img image {
  height: 340rpx;
}
.book-detail {
  padding: 32rpx;
  display: flex;
packageBookService/pages/bookServices/examination/examination.js
@@ -182,7 +182,6 @@
  // 监听watch
  watch(context, variableName, callback) {
    let value = context.data[variableName]; // 获取被监听属性的当前值
    // 使用 Object.defineProperty 方法在数据对象上定义属性的 getter 和 setter
    Object.defineProperty(context.data, variableName, {
      configurable: true, // 可配置
@@ -197,6 +196,34 @@
      },
    });
  },
  // 正则找出听力src
  extractSourceSrc(htmlString) {
    // 正则表达式匹配<source>标签中的src属性值
    var srcRegex = /<source\s+src="([^"]+)"/i;
    var srcTwo = /<audio\s+src="([^"]+)"/i;
    // 执行正则匹配
    var match = srcRegex.exec(htmlString);
    const local = srcTwo.exec(htmlString)
    // 如果匹配成功,返回第一个捕获组的内容(src属性的值)
    if (match && match[1]) {
      return match[1];
    } else if (local && local[1]) {
      return local[1]
    } else {
      // 如果没有匹配到,返回null
      return null;
    }
  },
  // 拿到听力题除audio标签外其他内容
  removeVideoAndAudioTags(htmlString) {
    // 使用正则表达式匹配并移除所有的 <video> 和 <audio> 标签
    var cleanedHtml = htmlString.replace(/<video[^>]*>[\s\S]*?<\/video>|<audio[^>]*>[\s\S]*?<\/audio>/gi, '');
    return cleanedHtml;
  },
  // 改变loading状态
  changeLoadingState() {
    this.setData({
@@ -874,12 +901,13 @@
            );
          }
          // 听力题修改
          if (questionObj.questionType == 'singleChoiceArr') {
            questionObj.stem.stemTxt = questionObj.stem.stemTxt
              .replace(
                /\<audio/gi,
                '<audio @play="play" '
              )
          if (questionObj.questionType == 'singleChoice') {
            const src = this.extractSourceSrc(questionObj.stem.stemTxt)
            if (src) {
              questionObj.src = src
              questionObj.stem.stemTxt = this.removeVideoAndAudioTags(questionObj.stem.stemTxt)
              console.log('题干', questionObj.stem.stemTxt);
            }
          }
          // 获取图片
          if (
packageBookService/pages/bookServices/examination/questionList/index.js
@@ -1,4 +1,7 @@
// pages/bookServices/examination/questionList/index.js
const innerAudioContext = wx.createInnerAudioContext({
  useWebAudioImplement: false
})
Component({
  /**
   * 组件的属性列表
@@ -39,6 +42,10 @@
  created() {
    // console.log('组件传参', this.properties);
  },
  ready() {
    innerAudioContext.stop();
    innerAudioContext.destroy();
  },
  /**
   * 组件的初始数据
   */
@@ -55,12 +62,25 @@
      type: 'fraction'
    },
    showIndex: 0,
    isPlay: false
  },
  /**
   * 组件的方法列表
   */
  methods: {
    audioPlay(e) {
      const src = e.currentTarget.dataset.src
      innerAudioContext.src = src
      if (!this.data.isPlay) {
        innerAudioContext.play()
      } else {
        innerAudioContext.pause()
      }
      this.setData({
        isPlay: !this.data.isPlay
      })
    },
    // 切换题目
    changeSwiper(e) {
      this.setData({
packageBookService/pages/bookServices/examination/questionList/index.wxml
@@ -31,10 +31,26 @@
      >
        <!-- 题号 -->
        <text>{{item.number}}.</text>
        <!-- 听力题 -->
        <view wx:if="{{item.questionType == 'singleChoice' && item.src}}">
          <rich-text nodes="{{item.stem.stemTxt }}" />
          <view
            style="margin-top: {{item.stem.stemTxt ? '10rpx' : ''}};"
            class="audio-play-box"
            bind:tap="audioPlay"
            data-src="{{item.src}}"
          >
            <image
              src="{{isPlay ? '/static/images/resourceDetailsMyAudio/zanting@2x.png' : '/static/images/resourceDetailsMyAudio/play@2x.png'}}"
              mode="aspectFit"
            ></image>
          </view>
        </view>
        <!-- 仅文字 -->
        <view
          class="title-content"
          wx:if="{{item.stemStyle == 'Txt' && item.questionType != 'completion'}}"
          wx:elif="{{item.stemStyle == 'Txt' && item.questionType != 'completion'}}"
          >{{item.stem.stemTxt}}</view
        >
        <!-- 仅图片 -->
@@ -123,10 +139,10 @@
                <view
                  wx:if="{{item.optionStyle == 'TxtAndImage'}}"
                  class="fl-center"
                  style="min-height: 144rpx"
                  class="TxtAndImage-box"
                >
                  <text>{{contentItem.value}}、</text>
                  <text class="radio-textimg">{{contentItem.txt}}</text>
                  <view class="radio-textimg">{{contentItem.txt}}</view>
                  <image src="{{contentItem.img}}" mode="aspectFit" />
                </view>
                <!-- 富文本 -->
packageBookService/pages/bookServices/examination/questionList/index.wxss
@@ -248,8 +248,22 @@
  height: min-content;
}
.audio-play-box {
  margin-left: 10rpx;
  background-color: #e7e7e7;
  display: flex;
  align-items: center;
  width: 70rpx;
  height: 70rpx;
}
.TxtAndImage-box {
  display: flex;
  align-items: center;
  min-height: 144rpx;
}
.radio-textimg {
  display: inline-block;
  height: min-content;
  width: calc(100% - 90rpx);
}
packageBookService/pages/bookServices/list/index.js
@@ -245,7 +245,7 @@
    });
  },
  // 获取一级分类下二级分类
  getSecondList(path) {
  async getSecondList(path) {
    const options = [];
    const query = {
      path,
@@ -260,16 +260,7 @@
        field: "LinkOrder",
      },
    };
    app.MG.store.getStoreChannelList(query).then((res) => {
      if (!res.datas.length) {
        this.setData({
          disabledSecondList: true,
        });
      } else {
        this.setData({
          disabledSecondList: false,
        });
      }
    await app.MG.store.getStoreChannelList(query).then((res) => {
      for (let index = 0; index < res.datas.length; index++) {
        const item = res.datas[index];
        options.push({
@@ -441,11 +432,6 @@
      },
    };
    app.MG.store.getProductList(query).then((res) => {
      if (!res.datas.length && !this.data.pathList.length) {
        this.setData({
          disabledSecondList: true
        })
      }
      this.setData({
        bookList: res.datas,
        isMore: null,
@@ -460,6 +446,18 @@
          noData: true,
        });
      }
      // 二级禁用逻辑
      // 1.一级分类未选中,二级分类禁用
      if (!this.data.stairList.value) {
        this.setData({
          disabledSecondList: true
        })
      } else if (this.data.stairList.value && !this.data.secondList.options.length) {
        // 2. 一级分类选中,无二级分类
        this.setData({
          disabledSecondList: true
        })
      }
      if (this.data.triggered) {
        this.setData({
          triggered: false,
@@ -471,7 +469,7 @@
    });
  },
  // 一级分类切换
  onChangeStair(e) {
  async onChangeStair(e) {
    const path = e.detail.value.length ?
      `${this.data.assortCheck.code}\\${e.detail.value}` :
      this.data.assortCheck.code;
@@ -482,16 +480,16 @@
      secondCode: "",
      path: path,
      "stairList.value": e.detail.value,
      disabledSecondList: false
      // disabledSecondList: false
    });
    if (e.detail.value == "") {
      this.setData({
        disabledSecondList: true,
      });
    } else {
      this.getSecondList(path);
    }
    this.getBookList(path);
    // if (e.detail.value == "") {
    //   this.setData({
    //     disabledSecondList: true,
    //   });
    // } else {
    await this.getSecondList(path);
    // }
    await this.getBookList(path);
  },
  // 二级分类切换
  onChangeSecond(e) {