litian
2024-03-15 3f1ea0a8e4bb02bf7544df8660b15cfa69d6b84a
Merge refs/remotes/origin/master into refs/heads/master
1个文件已删除
66个文件已修改
13个文件已添加
5820 ■■■■ 已修改文件
app.json 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/aboutUs/index.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/aboutUs/index.json 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/aboutUs/index.wxml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/aboutUs/index.wxss 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bibliographyList/index.js 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bibliographyList/index.json 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bibliographyList/index.wxml 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bibliographyList/index.wxss 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookExhibitionDetails/index.wxml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookExhibitionDetails/index.wxss 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookExhibitionList/index.js 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookExhibitionList/index.wxml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookExhibitionList/index.wxss 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/detail/components/note/note.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/detail/components/testResource/testResource.js 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/detail/components/testResource/testResource.json 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/detail/components/testResource/testResource.wxml 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/detail/components/testResource/testResource.wxss 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/detail/components/tree/components/util.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/detail/components/tree/index.js 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/detail/components/tree/index.wxml 161 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/detail/index.js 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/detail/index.json 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/detail/index.wxml 189 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/examination.js 896 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/examination.json 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/examination.wxml 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/examination.wxss 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/questionList/index.js 73 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/questionList/index.json 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/questionList/index.wxml 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/questionList/index.wxss 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/questionOptions/index.js 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/questionOptions/index.json 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/questionOptions/index.wxml 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/questionOptions/index.wxss 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/questionSchedule/index.js 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/examination/questionSchedule/index.wxml 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/webpage/index.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/webpage/index.json 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/webpage/index.wxml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/bookServices/webpage/index.wxss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/cart/index.js 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/cart/index.json 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/cart/index.wxml 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/cart/index.wxss 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/cart/paymentPage/index.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/cart/paymentPage/index.wxml 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/cart/paymentPage/index.wxss 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/home/home.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/home/home.wxml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/personalCenter/index.js 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/personalCenter/index.wxml 补丁 | 查看 | 原始文档 | blame | 历史
pages/resourceDetails/document/index.js 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/resourceDetails/document/index.json 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/resourceDetails/document/index.wxml 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/resourceDetails/document/index.wxss 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/resourceDetails/myAudio/index.js 669 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/resourceDetails/myAudio/index.json 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/resourceDetails/myAudio/index.wxml 141 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/resourceDetails/myAudio/index.wxss 327 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/resourceDetails/myVideo/index.js 321 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/resourceDetails/myVideo/index.json 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/resourceDetails/myVideo/index.wxml 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/resourceDetails/myVideo/index.wxss 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/retrievalPage/index.js 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/retrievalPage/index.wxml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/retrievalPage/index.wxss 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/testLogin/index.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/images/bibliographyList/square.png 补丁 | 查看 | 原始文档 | blame | 历史
static/images/bibliographyList/square@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
static/images/bookExhibitionList/zhuantitaolun.png 补丁 | 查看 | 原始文档 | blame | 历史
static/images/bookService/detail/checkpaper.png 补丁 | 查看 | 原始文档 | blame | 历史
static/images/bookService/detail/notest.png 补丁 | 查看 | 原始文档 | blame | 历史
static/images/document/zip.png 补丁 | 查看 | 原始文档 | blame | 历史
static/images/document/zip200px.png 补丁 | 查看 | 原始文档 | blame | 历史
static/images/document/zip200px@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
static/video/sea.mp4 补丁 | 查看 | 原始文档 | blame | 历史
style/theme.wxss 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app.json
@@ -57,7 +57,8 @@
    "pages/personalCenter/downloads/index",
    "pages/personalCenter/activateProduct/index",
    "pages/testLogin/index",
    "pages/bookServices/examination/examination"
    "pages/bookServices/examination/examination",
    "pages/bookServices/webpage/index"
  ],
  "tabBar": {
    "custom": true,
pages/aboutUs/index.js
@@ -15,6 +15,9 @@
    interval: 5000,//轮播图参数
    navigation: { type: 'dots' },//轮播图参数
    bannerList: [], //轮播图列表
    navBarHeight: '',
    barHeight: '',
    types: '',
  },
  /**
@@ -22,36 +25,22 @@
   */
  onLoad(options) {
    this.getBanner()
    const systInfo = wx.getSystemInfoSync();
    const menu = wx.getMenuButtonBoundingClientRect(); // 胶囊信息
    const navBarHeight = (menu.top - systInfo.statusBarHeight) * 2 + menu.height; // 导航栏高度
    this.setData({
      navBarHeight: navBarHeight,
      barHeight: systInfo.statusBarHeight,
      types: options.types
    })
    console.log(this.data.types);
    // this.getBanner()
    this.getAboutText()
    // drawQrcode({
    //   width: 200, // 必须,二维码宽度,与canvas的width保持一致
    //   height: 200, // 必须,二维码高度,与canvas的height保持一致
    //   canvasId: 'myQrcode',
    //   background: '#ffffff', //    非必须,二维码背景颜色,默认值白色
    //   foreground: '#000', // 非必须,二维码前景色,默认值黑色     '#000000'
    //   // ctx: wx.createCanvasContext('myQrcode'), // 非必须,绘图上下文,可通过 wx.createCanvasContext('canvasId') 获取,v1.0.0+版本支持
    //   text: '13216549865',  // 必须,二维码内容
    //   // v1.0.0+版本支持在二维码上绘制图片
    //   image: {
    //     // imageResource: '../../images/icon.png', // 指定二维码小图标
    //     dx: 70,
    //     dy: 70,
    //     dWidth: 60,
    //     dHeight: 60
    //   }
    // })
  },
  /**
@@ -102,17 +91,15 @@
  onShareAppMessage() {
  },
  //轮播图
  getBanner() {
    app.MG.resource.getItem({
      path: 'jsek_banner\\jsek_aboutUsBanner',
      paging: { start: 0, size: 9 },
      fields: {
        jsek_link: []
      }
    }).then(res => {
      this.setData({
        bannerList: res.datas[0].icon,
        swiperList: res.datas[0].icon
@@ -120,9 +107,12 @@
      console.log(this.data.bannerList, 789);
    })
  },
  //文字  jsek_aboutUs 关于我们
  //jsek_contactUs  联系我们
  getAboutText() {
    app.MG.resource.getItem({
      path: 'jsek_aboutUs',
      path: this.data.types,
      fields: {
        content: []
      },
@@ -138,5 +128,8 @@
    })
  },
  goBack() {
    wx.navigateBack()
  }
})
pages/aboutUs/index.json
@@ -2,6 +2,8 @@
  "component": true,
  "usingComponents": {
    "t-swiper": "tdesign-miniprogram/swiper/swiper",
    "t-swiper-nav": "tdesign-miniprogram/swiper-nav/swiper-nav"
  }
    "t-swiper-nav": "tdesign-miniprogram/swiper-nav/swiper-nav",
    "t-icon": "tdesign-miniprogram/icon/icon"
  },
  "navigationStyle": "custom"
}
pages/aboutUs/index.wxml
@@ -1,30 +1,19 @@
<!--pages/aboutUs/index.wxml-->
<!-- <text>关于我们</text> -->
<view style="width: 100%; height: {{barHeight}}px; "></view>
<view class="nacigationBar" style="width: 70%; height: {{navBarHeight}}px;">
  <view>
    <t-icon name="chevron-left" size="30" data-name="{{item}}" bind:click="goBack" />
  </view>
  <view wx:if="{{types == 'jsek_aboutUs'}}" class="navbar-title">关于我们</view>
  <view wx:else class="navbar-title">联系我们</view>
</view>
<!-- 二维码展示 -->
<!-- <view class="">
    <canvas style="width: 200px; height: 200px;margin:0 auto" canvas-id="myQrcode"></canvas>
</view> -->
<!-- <view class="swiper-wrap">
  <t-swiper list="{{bannerList}}" current="{{current}}" autoplay="{{autoplay}}" duration="{{duration}}" interval="{{interval}}" navigation="{{navigation}}" />
</view> -->
<view class="aboutUs">
  <!-- <view class="imageBox">
    <image src="{{swiperList}}" alt="" />
  </view> -->
  <view class="aboutText">
    <rich-text nodes="{{aboutText}}"></rich-text>
  </view>
pages/aboutUs/index.wxss
@@ -1,4 +1,25 @@
/* pages/aboutUs/index.wxss */
.nacigationBar {
  background-color: #fff;
  display: flex;
  align-items: center;
}
.navbar-title {
  white-space: nowrap;
  /* overflow: hidden; */
  text-overflow: ellipsis;
  color: #0F1214;
  margin-bottom: 5rpx;
  font-weight: bold;
  font-size: 36rpx;
  color: #0F1214;
}
image {
  width: 100%;
  height: 100%;
@@ -12,7 +33,6 @@
.aboutUs {
  margin: 30rpx;
}
.aboutText {
pages/bibliographyList/index.js
@@ -15,7 +15,8 @@
      teacherTotal: 0,
      value: '',
      BarHeight: '',
      navBarHeight: ''
      navBarHeight: '',
    },
    /**
@@ -26,13 +27,12 @@
      this.vocationalGet()
      this.teacherGet()
      //获取系统信息,状态栏高度为sysInfo['statusBarHeight'];
      let sysInfo = wx.getSystemInfoSync();
      let menu = wx.getMenuButtonBoundingClientRect(); //胶囊信息
      let navBarHeight = (menu.top - sysInfo.statusBarHeight) * 2 + menu.height; // 导航栏高度
      const systInfo = wx.getSystemInfoSync();
      const menu = wx.getMenuButtonBoundingClientRect(); // 胶囊信息
      const navBarHeight = (menu.top - systInfo.statusBarHeight) * 2 + menu.height; // 导航栏高度
      this.setData({
        BarHeight: sysInfo.statusBarHeight, navBarHeight: navBarHeight
        navBarHeight: navBarHeight,
        barHeight: systInfo.statusBarHeight,
      })
@@ -227,9 +227,9 @@
      console.log(111);
      const item = event.currentTarget.dataset.item;
      // console.log(item.datas.freeFile.Value);
      const URL = 'http://182.92.203.7:3001/file/api/ApiDownload?md5=' + item.datas.freeFile.Value
      const URL = app.config.requestCtx + '/file/api/ApiDownload?md5=' + item.datas.freeFile.Value
      item.determine = false
      console.log(URL, 'URL');
      setTimeout(() => {
        if (URL) {
          item.determine = true
@@ -264,6 +264,8 @@
    },
    goBack() {
      wx.navigateBack();
    },
  })
pages/bibliographyList/index.json
@@ -3,7 +3,8 @@
  "usingComponents": {
    "t-tabs": "tdesign-miniprogram/tabs/tabs",
    "t-tab-panel": "tdesign-miniprogram/tab-panel/tab-panel",
    "t-search": "tdesign-miniprogram/search/search"
    "t-search": "tdesign-miniprogram/search/search",
    "t-icon": "tdesign-miniprogram/icon/icon"
  },
  "navigationStyle": "custom"
}
pages/bibliographyList/index.wxml
@@ -1,10 +1,17 @@
<!--pages/bibliographyList/index.wxml-->
<view style="width: 100%; height: {{barHeight}}px; "></view>
<view class="nacigationBar" style="width: 70%; height: {{navBarHeight}}px;">
  <view>
    <t-icon name="chevron-left" size="30" data-name="{{item}}" bind:click="goBack" />
  </view>
<view class="example-search">
  <t-search model:value="{{value}}" placeholder="请输入书目名称" bind:submit="onSearchSubmit" />
</view>
</view>
<!--状态栏高度 -->
pages/bibliographyList/index.wxss
@@ -6,6 +6,22 @@
.custom-panel {
  height: 120px;
} */
.nacigationBar {
  background-color: #fff;
  display: flex;
  align-items: center;
}
.navbar-title {
  white-space: nowrap;
  /* overflow: hidden; */
  text-overflow: ellipsis;
  color: #0F1214;
  font-size: 40rpx;
  font-weight: bold;
  margin-bottom: 5rpx;
}
.higherBox {
  width: 220rpx;
@@ -65,7 +81,7 @@
.example-search {
  background-color: #fff;
  padding: 16rpx 32rpx;
  /* padding: 16rpx 32rpx; */
}
@@ -95,3 +111,12 @@
  line-height: 75rpx;
  height: 75rpx;
}
.t-tabs__item--active {
  color: #FF6C00 !important;
}
.t-tabs__track {
  background-color: #FF6C00 !important;
}
pages/bookExhibitionDetails/index.wxml
@@ -18,7 +18,7 @@
<image class="partingBox" src="/static/images/bookExhibitionDetails/Parting.png" mode="" />
<image class="partingBox" src="/static/images/bookExhibitionDetails/Parting.png" mode="aspectFill" />
<image class="bannerBox" src="{{bookImage}}" mode="" />
pages/bookExhibitionDetails/index.wxss
@@ -16,15 +16,33 @@
  font-size: 40rpx;
  font-weight: bold;
  margin-bottom: 5rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
}
.titleBox {
  height: 60rpx;
  font-weight: 800;
  font-size: 45rpx;
  display: flex;
  justify-content: center;
  padding: 0 30rpx;
  /* text-indent: 6%; */
  /* overflow: hidden;
  text-overflow: ellipsis;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1; */
  margin: 0 130rpx;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
  text-overflow: ellipsis;
}
.informationBox {
pages/bookExhibitionList/index.js
@@ -29,7 +29,6 @@
      options: [
        {
          value: '*',
          label: '总分类',
        },
        {
@@ -50,7 +49,9 @@
          price: 'jsek_teacherEducation',
          label: '教师教育',
        },
      ],
    },
    multipleSelect: {
      value: [],
@@ -169,6 +170,8 @@
      });
      this.bookExhibitionGet(); // 调用方法加载更多数据
      console.log(1111);
    }
  },
@@ -199,6 +202,7 @@
      queryType: '*',
      fields: {
        jsek_link: [],
        subtitle: [],
        'bookClassification*': this.data.keynoteValue || [],
        ...searchObj
      },
@@ -208,7 +212,10 @@
      //   width: 100
      // },
    }).then(res => {
      res.datas.forEach((item) => {
        item.subtitleName = item.subtitle + item.name
      })
      console.log(res, 'item');
      this.data.total = res.total
      //  list.push(res.datas)
pages/bookExhibitionList/index.wxml
@@ -34,14 +34,15 @@
<view class="assembleContent">
  <view class="titleBox">
    <view class="frameBox"></view> <text class="titleTextBox"> 线上书展</text>
    <view class="frameBox"></view>
    <image class="titleTextBox" src="/static/images/bookExhibitionList/zhuantitaolun.png" mode="aspectFit" />
  </view>
  <view class="outside">
    <view class="contentBox" wx:for="{{bookExhibitionList}}" wx:key="index" wx:for-item="item" wx:for-index="index" bindtap="onBookExhibitionDetails" data-item="{{item}}">
      <image wx:if="{{item.icon}}" src="{{item.icon}}" mode="aspectFit" />
      <image wx:else="" src="/static/images/bookExhibitionList/banner.png" mode="" />
      <view class="textBox" title="{{item.name}}"> <text>{{item.name}}</text></view>
      <view class="textBox" title="{{item.subtitleName}}"> <text>{{item.subtitleName}}</text></view>
    </view>
  </view>
pages/bookExhibitionList/index.wxss
@@ -93,13 +93,14 @@
.titleBox {
  display: flex;
  align-items: center;
  margin: 10px;
  margin-left: 0;
  padding-top: 30rpx;
}
.frameBox {
  width: 13rpx;
  width: 7rpx;
  height: 54rpx;
  background: #FF6C00;
  border-radius: 0rpx 9rpx 9rpx 0rpx;
@@ -107,10 +108,13 @@
}
.titleTextBox {
  font-size: 20px;
  font-weight: bolder;
  margin-left: 10px;
  font-family: JDLangZhengTi, JDLangZhengTi;
  margin-left: 5px;
  width: 150rpx;
  height: 37rpx;
}
.classification {
pages/bookServices/detail/components/note/note.js
@@ -62,6 +62,7 @@
      })
    },
    openDialog() {
      console.log(this.properties.bookInfo.name);
      this.setData({
        submitTitle: this.properties.bookInfo.name,
        showNoteDialog: true
@@ -138,6 +139,7 @@
      // this.setData({
      //   loading: true
      // })
      console.log(this.properties.bookInfo.id, 'this.properties.bookInfo.id');
      let topicId
      await app.MG.ugc
        .getProductUserSubmitTopic({
pages/bookServices/detail/components/testResource/testResource.js
@@ -12,6 +12,10 @@
    bookInfo: {
      type: Object,
      value: "",
    },
    mockData: {
      type: Object,
      value: {}
    }
  },
@@ -19,7 +23,8 @@
   * 组件的初始数据
   */
  data: {
    selectBtn: 'test',  // test  mock
    radioItem: 'test',
  },
  /**
@@ -56,7 +61,6 @@
        })
      } else {
        const res = await app.MG.store.getProductDetail(query)
        debugger
        res.datas.cmsDatas[0].datas.forEach((item) => {
          idPathList.push({
            id: item.id,
@@ -79,6 +83,51 @@
      wx.navigateTo({
        url: `/pages/bookServices/examination/examination?bookId=${this.properties.bookInfo.id}&productLinkPath=${value.productLinkPath}&rootCmsItemId=${this.properties.bookInfo.rootCmsItemId}&idPathList=${JSON.stringify(idPathList)}&answerTitle=${value.name}&answerType=${'option'}`,
      })
    },
    goMycollect(e) {
      const answertype = e.currentTarget.dataset.answertype
      const token = wx.getStorageSync('jsek-token')
      if (!token) {
        return wx.getUserProfile({
          desc: '用户登录',
          success: (res) => {
            console.log(res);
          }
        })
      }
      wx.navigateTo({
        url: `/pages/bookServices/examination/examination?bookId=${this.properties.bookInfo.id}&rootCmsItemId=${this.properties.bookInfo.rootCmsItemId}&answerTitle=${'我的收藏'}&answerType=${answertype}`,
      })
    },
    // 练习 组件切换
    onRadioChange(e) {
      this.setData({
        radioItem: e.detail.value
      })
    },
    async getMockId() {
      let id
      let query = {
        start: 0,
        size: 99,
        productId: this.properties.bookInfo.id
      }
      await app.MG.edu.getQuizConfigListByProduct(query).then((res) => {
        id = res.datas[0].id
      })
      return id
    },
    // 组卷跳转答题界面
    async goMackPaper(e) {
      // const token = localStorage.getItem('jsek-token')
      // if (!token) {
      //   return logIn()
      // }
      const mockid = await this.getMockId()
      const item = e.currentTarget.dataset.item
      wx.navigateTo({
        url: `/pages/bookServices/examination/examination?bookId=${this.properties.bookInfo.id}&rootCmsItemId=${this.properties.bookInfo.rootCmsItemId}&answerTitle=${item.name}&answerType=${'mock'}&uuid=${item.id}&mockid=${mockid}`,
      })
    }
  }
})
pages/bookServices/detail/components/testResource/testResource.json
@@ -2,6 +2,8 @@
  "component": true,
  "usingComponents": {
    "t-button": "tdesign-miniprogram/button/button",
    "t-image": "tdesign-miniprogram/image/image"
    "t-image": "tdesign-miniprogram/image/image",
    "t-radio": "tdesign-miniprogram/radio/radio",
    "t-radio-group": "tdesign-miniprogram/radio-group/radio-group"
  }
}
pages/bookServices/detail/components/testResource/testResource.wxml
@@ -1,39 +1,146 @@
<!--pages/bookServices/detail/components/testResource/testResource.wxml-->
<view class="test-resource">
  <view class="top-btn">
    <t-button class="practice-btn" theme="primary" size="medium" style="width: 85px;">
    <t-radio-group
      class="test-radio"
      t-class="horizontal-box"
      value="{{radioItem}}"
      bind:change="onRadioChange"
      style="margin: 0px"
    >
      <view class="card {{radioItem == 'test' ? 'card--active' : ''}}">
        <t-radio value="test" icon="none" borderless style="height: 80rpx">
          <view class="radio-content" slot="content">
            <t-image
              src="{{ radioItem == 'test' ? '/static/images/bookService/detail/practice-icon.png' : '/static/images/bookService/detail/notest.png'}}"
            ></t-image>
            <text style="color: {{radioItem == 'test' ? '#fff':''}};"
              >练习</text
            >
          </view>
        </t-radio>
      </view>
      <view class="card {{radioItem == 'mock' ? 'card--active' : ''}}">
        <t-radio value="mock" icon="none" borderless>
          <view class="radio-content" slot="content">
            <t-image
              src="{{ radioItem == 'mock' ? '/static/images/bookService/detail/checkpaper.png' : '/static/images/bookService/detail/zujuan.png'}}"
            ></t-image>
            <text style="color: {{radioItem == 'mock' ? '#fff':''}};">
              组卷</text
            >
          </view>
        </t-radio>
      </view>
    </t-radio-group>
    <!-- <t-button
      class="  {{selectBtn == 'test' ? 'practice-btn' : 'paper-btn'}}"
      theme="default"
      size="medium"
      style="width: 85px"
      bind:tap="changeBtn"
      data-type="test"
    >
      <view slot="content">
        <t-image src="/static/images/bookService/detail/practice-icon.png"></t-image>
        练习
        <t-image
          src="{{ selectBtn == 'test' ? '/static/images/bookService/detail/practice-icon.png' : '/static/images/bookService/detail/notest.png'}}"
        ></t-image>
        <text>练习</text>
      </view>
    </t-button>
    <t-button class="paper-btn" theme="default" size="medium" style="width: 85px;">
    <t-button
      class=" {{selectBtn == 'mock' ? 'practice-btn' : 'paper-btn'}}"
      theme="default"
      size="medium"
      style="width: 85px"
      bind:tap="changeBtn"
      data-type="mock"
    >
      <view slot="content">
        <t-image src="/static/images/bookService/detail/zujuan.png"></t-image>
        <t-image
          src="{{ selectBtn == 'mock' ? '/static/images/bookService/detail/checkpaper.png' : '/static/images/bookService/detail/zujuan.png'}}"
        ></t-image>
        组卷
      </view>
    </t-button>
    <t-button class="error-btn" theme="default" size="medium" style="padding: 0 12rpx;">
    </t-button> -->
    <t-button
      class="error-btn"
      theme="default"
      size="medium"
      style="padding: 0 12rpx"
      bind:tap="goMycollect"
      data-answerType="errorQuestion"
    >
      <view slot="content">
        <t-image src="/static/images/bookService/detail/cuoti.png"></t-image>
        我的错题
      </view>
    </t-button>
    <t-button class="collect-btn" theme="default" size="medium" style="padding: 0 12rpx;">
    <t-button
      class="collect-btn"
      theme="default"
      size="medium"
      style="padding: 0 12rpx"
      bind:tap="goMycollect"
      data-answerType="collectQuestion"
    >
      <view slot="content">
        <t-image src="/static/images/bookService/detail/wodeshoucang.png"></t-image>
        <t-image
          src="/static/images/bookService/detail/wodeshoucang.png"
        ></t-image>
        我的收藏
      </view>
    </t-button>
  </view>
  <view class="resource-list" wx:for="{{list}}" wx:key="item.id">
  <!-- 练习列表 -->
  <view
    class="resource-list"
    wx:for="{{list}}"
    wx:key="item.id"
    wx:if="{{radioItem == 'test'}}"
  >
    <view class="list-title">
      <t-image src="/static/images/bookService/detail/test-icon.png"></t-image>
      <text>{{item.name}}</text>
    </view>
    <view class="practice" bind:tap="goTest" data-value="{{item}}">
      <t-image src="/static/images/bookService/detail/lianxi-icon.png"></t-image>
      <t-image
        src="/static/images/bookService/detail/lianxi-icon.png"
      ></t-image>
    </view>
  </view>
</view>
<!-- 组卷列表 -->
<view class="mock-data" wx:if="{{radioItem == 'mock'}}">
  <view class="mack-num">已组卷{{mockData.mockList.length}}次</view>
  <view class="mock-list">
    <view
      class="mock-list-box"
      wx:for="{{mockData.mockList}}"
      data-item="{{item}}"
      bind:tap="goMackPaper"
    >
      <view class="mock-title">{{item.name}}</view>
      <view class="mock-message">
        <view class="message-box">
          <view class="mack-state">
            <text wx:if="{{item.state == '3'}}" class="complete state-pad"
              >已完成</text
            >
            <text
              wx:elif="{{item.state == '2' || item.state == '1'}}"
              class="Incomplete state-pad"
              >未完成</text
            >
            <text wx:else class="Incomplete state-pad">未开始</text>
          </view>
          <view class="mock-time">{{item.createDate}}</view></view
        >
        <view class="mock-score" wx:if="{{item.report.userScore}}"
          >{{item.report.userScore}}分</view
        >
      </view>
    </view>
  </view>
</view>
pages/bookServices/detail/components/testResource/testResource.wxss
@@ -31,6 +31,7 @@
.top-btn {
  display: flex;
  justify-content: space-evenly;
  padding-left: 15rpx;
}
.top-btn image {
@@ -40,17 +41,170 @@
}
.practice-btn {
  --td-button-primary-bg-color: #ff6c00;
  --td-button-primary-border-color: #ff6c00;
  --td-button-primary-active-bg-color: #ff984d;
  --td-button-primary-active-border-color: #ff984d;
  --td-button-default-bg-color: #ff6c00;
  --td-button-default-border-color: #ff6c00;
  --td-button-default-active-bg-color: #ff984d;
  --td-button-default-active-border-color: #ff984d;
}
.practice-btn image {
  margin-top: 25rpx;
  margin-right: 10rpx;
  width: 26rpx;
  height: 30rpx;
}
.practice-btn text {
  font-size: 28rpx;
}
.paper-btn,
.error-btn,
.collect-btn {
  --td-button-default-bg-color: #fff;
  --td-button-default-color: #ff6c00;
  --td-button-default-color: #0F1214;
  --td-button-default-active-bg-color: #fff0e6;
  --td-button-medium-font-size: 28rpx
}
.card {
  position: relative;
  margin: 32rpx;
  border-radius: 12rpx;
  overflow: hidden;
  box-sizing: border-box;
  border: 3rpx solid #ff6c00;
  --td-radio-content-color: #0F1214;
}
.card--active {
  border-color: #ff6c00;
  --td-radio-bg-color: #ff6c00;
  --td-radio-content-color: #fff;
}
/* .card--active::after {
  content: '';
  display: block;
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  border: 14px solid #0052d9;
  border-bottom-color: transparent;
  border-right-color: transparent;
} */
.card__icon {
  color: #fff;
  position: absolute;
  left: 1.5px;
  top: 1.5px;
  z-index: 1;
}
/* 横向布局 */
.horizontal-box {
  width: 350rpx;
  display: flex;
  align-items: center;
  margin: 32rpx;
}
.horizontal-box .card {
  flex: 1;
  margin: 0;
}
.horizontal-box .card+.card {
  margin-left: 24rpx;
}
.test-radio {
  --td-radio-content-font-size: 28rpx;
  --td-radio-vertical-padding: 0
}
.radio-content {
  padding: 0 8rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 68rpx;
}
.radio-content image {
  margin: 0 10rpx 10rpx 0;
}
.mock-data {
  padding: 0 32rpx;
}
.mack-num {
  width: 100%;
  height: 100rpx;
  display: flex;
  align-items: center;
  color: #333;
  font-size: 28rpx;
}
.mock-list-box {
  padding: 32rpx;
  background-color: #F9F9F9;
  margin-bottom: 30rpx;
}
.mock-title {
  color: #333;
  font-size: 32rpx;
  font-weight: 600;
}
.mock-message {
  margin-top: 10rpx;
  display: flex;
  justify-content: space-between;
}
.message-box {
  height: 60rpx;
  display: flex;
  align-items: center;
}
.mack-state {
  width: 94rpx;
  height: 42rpx;
}
.mock-score {
  font-size: 28rpx;
  color: #ff6c00;
}
.mock-time {
  color: #333;
  margin-left: 20rpx;
}
.state-pad {
  width: 80rpx;
  border-radius: 10rpx;
  display: inline-block;
  padding: 10rpx;
}
.complete {
  background-color: #d8f0d8;
  color: #1FBC1F;
}
.Incomplete {
  background-color: #e9e9e9;
  color: #666;
}
pages/bookServices/detail/components/tree/components/util.js
New file
@@ -0,0 +1,27 @@
/* 加载动画相关 */
const showLoading = (tips = '加载中...') => {
  wx.showNavigationBarLoading()
  wx.showLoading({
    title: tips,
  })
}
const hideLoading = () => {
  wx.hideLoading()
  wx.hideNavigationBarLoading()
}
const hideLoadingWithErrorTips = (err = '加载失败...') => {
  hideLoading()
  wx.showToast({
    title: err,
    icon: 'error',
    duration: 2000
  })
}
module.exports = {
  showLoading: showLoading,
  hideLoading: hideLoading,
  hideLoadingWithErrorTips: hideLoadingWithErrorTips,
}
pages/bookServices/detail/components/tree/index.js
@@ -1,5 +1,6 @@
import Message from 'tdesign-miniprogram/message/message';
const util = require('./components/util') // 引入封装过的加载提示
const app = getApp()
Component({
  properties: {
@@ -33,11 +34,14 @@
    }
  },
  data: {
    activeValues: [0]
    activeValues: [0],
    webpageSrc: ''
  },
  onShow() {
  },
  methods: {
    // 节点展开
    handleChange(e) {
@@ -83,17 +87,69 @@
      //   "pages/resourceDetails/myAudio/index",
      // "pages/resourceDetails/myVideo/index",
      // "pages/resourceDetails/document/index",
      let url
      if (item.selectType == 'video') {
        url = '/pages/resourceDetails/myVideo/index'
      } else if (item.selectType == 'audio') {
        url = '/pages/resourceDetails/myAudio/index'
      } else {
      } else if (item.selectType == 'picture' || item.selectType == 'zip') {
        url = '/pages/resourceDetails/document/index'
      }
      // else {
      //
      // }
      wx.navigateTo({
        url: `${url}?productLinkPath=${item.productLinkPath}&parentProductLinkPath=${parent.productLinkPath}&parentName=${parent.name}&activeId=${item.id}&bookId=${this.properties.bookInfo.id}&bookName=${this.properties.bookInfo.name}&cmsId=${this.properties.bookInfo.rootCmsItemId}`,
      })
      if (item.selectType == 'document' || item.selectType == 'pdf') {
        const fileLink = app.config.requestCtx + '/file/api/ApiDownload?md5=' + item.file
        console.log(fileLink, 'fileLink');
        //提示加载中
        util.showLoading()
        // 单次下载允许的最大文件为 200MB
        wx.downloadFile({
          url: fileLink, // 地址已打码,自己换个其他的地址("https://www.xxxxx.com/file/测试通知.pdf")
          success: function (res) {
            console.log(res, "wx.downloadFile success res")
            if (res.statusCode != 200) {
              util.hideLoadingWithErrorTips()
              return false
            }
            var Path = res.tempFilePath //返回的文件临时地址,用于后面打开本地预览所用
            wx.openDocument({
              filePath: Path,
              showMenu: true,
              success: function (res) {
                console.log('打开成功');
                util.hideLoading()
              }
            })
          },
          fail: function (err) {
            console.log(err, "wx.downloadFile fail err");
            util.hideLoadingWithErrorTips()
          }
        })
      }
      if (item.selectType == 'webpage') {
        console.log(11);
        this.setData({
          webpageSrc: item.jsek_link
        })
        console.log(this.data.webpageSrc, 'webpageSrc');
      }
    },
    // 拿到所有项
    getAllChildren(id) {
@@ -116,6 +172,7 @@
          result.push(...item.children);
        }
      }
      console.log(this.properties.treeList);
      this.properties.treeList.forEach(item => {
        findChildren(item);
      });
@@ -180,6 +237,7 @@
    // 章节勾选
    checkResourceTitle(e) {
      const item = e.currentTarget.dataset.item
      console.log(item, 'item');
      let list = this.flattenTree([item])
      let ids = []
      list.forEach(item => {
@@ -188,5 +246,11 @@
      const tab = this.findAndUpdateItemsByIds([item], ids)
      console.log(ids, tab);
    }
  },
  onCloudShoppingCart() {
    console.log(this.properties.treeList);
  },
  oncheckbox() {
    console.log(111);
  }
})
pages/bookServices/detail/components/tree/index.wxml
@@ -1,168 +1,59 @@
<view class="tree">
  <t-collapse default-value="{{activeValues}}" bind:change="handleChange">
    <t-collapse-panel
      wx:for="{{treeList}}"
      wx:for-item="item"
      wx:for-index="index"
      wx:key="id"
      value="{{index}}"
      expandIcon
    >
    <t-collapse-panel wx:for="{{treeList}}" wx:for-item="item" wx:for-index="index" wx:key="id" value="{{index}}" expandIcon>
      <view slot="header" class="header-title">
        <view wx:if="{{tab == 'jsek_cloudLearning'}}">
          <t-checkbox
            icon="rectangle"
            checked="{{item.checked}}"
            data-item="{{item}}"
            bind:change="checkResourceTitle"
          />
          <t-checkbox icon="rectangle" checked="{{item.checked}}" data-item="{{item}}" bind:change="checkResourceTitle" />
        </view>
        <text>{{item.name}}</text>
      </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.type == 'productItem'}}"
        >
          <view
            class="itemsInfo"
            wx:if="{{citem.name}}"
            data-item="{{citem}}"
            data-index="{{cindex}}"
          >
            <view
              class="contentBox"
              bind:tap="goPlayer"
              data-item="{{citem}}"
              data-parent="{{item}}"
            >
        <view class="listItems" wx:if="{{citem.childrenFolderCount <= 0 && citem.type == 'productItem'}}">
          <view class="itemsInfo" wx:if="{{citem.name}}" data-item="{{citem}}" data-index="{{cindex}}">
            <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="box-image" style="{{ tab == 'jsek_teachingResources' ? 'width: 350rpx;' : 'width: 450rpx;'}}">
                <view class="checkBox" wx:if="{{tab == 'jsek_cloudLearning'}}">
                  <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}}"
                  />
                  <!-- 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}}" />
                </view>
                <!-- 教学资源图标 -->
                <view class="teach-icon">
                  <t-image
                    wx:if="{{citem.selectType == 'audio'}}"
                    src="/static/images/bookService/detail/audioIcon.png"
                    mode="aspectFill"
                  />
                  <t-image
                    wx:if="{{citem.selectType == 'video'}}"
                    src="/static/images/bookService/detail/video.png"
                    mode="aspectFill"
                  />
                  <t-image
                    wx:if="{{citem.selectType == 'pdf'}}"
                    src="/static/images/bookService/detail/pdf.png"
                    mode="aspectFill"
                  />
                  <t-image
                    wx:if="{{citem.selectType == 'webpage'}}"
                    src="/static/images/bookService/detail/net.png"
                    mode="aspectFill"
                  />
                  <t-image
                    wx:if="{{citem.selectType == 'picture'}}"
                    src="/static/images/bookService/detail/picture.png"
                    mode="aspectFill"
                  />
                  <t-image
                    wx:if="{{citem.selectType == 'zip'}}"
                    src="/static/images/bookService/detail/zip.png"
                    mode="aspectFill"
                  />
                  <t-image
                    wx:if="{{ citem.fileMap[citem.file].extension == 'doc' ||  citem.fileMap[citem.file].extension == 'docx'}}"
                    src="/static/images/bookService/detail/word.png"
                    mode="aspectFill"
                  />
                  <t-image
                    wx:if="{{ citem.fileMap[citem.file].extension == 'xlsx' ||  citem.fileMap[citem.file].extension == 'xlsx'}}"
                    src="/static/images/bookService/detail/excel.png"
                    mode="aspectFill"
                  />
                  <t-image
                    wx:if="{{ citem.fileMap[citem.file].extension == 'ppt' ||  citem.fileMap[citem.file].extension == 'pptx'}}"
                    src="/static/images/bookService/detail/PPT.png"
                    mode="aspectFill"
                  />
                  <t-image wx:if="{{citem.selectType == 'audio'}}" src="/static/images/bookService/detail/audioIcon.png" mode="aspectFill" />
                  <t-image wx:if="{{citem.selectType == 'video'}}" src="/static/images/bookService/detail/video.png" mode="aspectFill" />
                  <t-image wx:if="{{citem.selectType == 'pdf'}}" src="/static/images/bookService/detail/pdf.png" mode="aspectFill" />
                  <t-image wx:if="{{citem.selectType == 'webpage'}}" src="/static/images/bookService/detail/net.png" mode="aspectFill" />
                  <t-image wx:if="{{citem.selectType == 'picture'}}" src="/static/images/bookService/detail/picture.png" mode="aspectFill" />
                  <t-image wx:if="{{citem.selectType == 'zip'}}" src="/static/images/bookService/detail/zip.png" mode="aspectFill" />
                  <t-image wx:if="{{ citem.fileMap[citem.file].extension == 'doc' ||  citem.fileMap[citem.file].extension == 'docx'}}" src="/static/images/bookService/detail/word.png" mode="aspectFill" />
                  <t-image wx:if="{{ citem.fileMap[citem.file].extension == 'xlsx' ||  citem.fileMap[citem.file].extension == 'xlsx'}}" src="/static/images/bookService/detail/excel.png" mode="aspectFill" />
                  <t-image wx:if="{{ citem.fileMap[citem.file].extension == 'ppt' ||  citem.fileMap[citem.file].extension == 'pptx'}}" src="/static/images/bookService/detail/PPT.png" mode="aspectFill" />
                </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'}}">
                <!--  下载按钮 -->
                <t-image
                  src="/static/images/bookService/detail/download-icon.png"
                  width="16"
                  height="16"
                  class="download"
                  data-value="{{citem}}"
                  catchtap="downloadTeach"
                ></t-image>
                <t-image src="/static/images/bookService/detail/download-icon.png" width="16" height="16" class="download" data-value="{{citem}}" catchtap="downloadTeach"></t-image>
              </view>
              <view wx:if="{{tab == 'jsek_cloudLearning'}}">
                <!-- 云学习试看图标 -->
                <t-image
                  src="/static/images/bookService/detail/shikan.png"
                  class="testSee"
                  wx:if="{{!citem.isbuy ? false : citem.freeFile ? true : false}}"
                ></t-image>
                <t-image src="/static/images/bookService/detail/shikan.png" class="testSee" wx:if="{{!citem.isbuy ? false : citem.freeFile ? true : false}}"></t-image>
                <!-- 云学习加入购物车图标 -->
                <t-image
                  src="/static/images/bookService/detail/cart.png"
                  wx:if="{{citem.isShopCar}}"
                  class="shopCar"
                ></t-image>
                <t-image src="/static/images/bookService/detail/cart.png" wx:if="{{citem.isShopCar}}" class="shopCar" bind:tap="onCloudShoppingCart"></t-image>
                <!-- 云学习购买图标 -->
                <t-image
                  src="/static/images/bookService/detail/need-buy.png"
                  class="need-buy"
                  wx:if="{{citem.isbuy }}"
                ></t-image>
                <t-image bind:tap="onCloudShoppingCart" src="/static/images/bookService/detail/need-buy.png" class="need-buy" wx:if="{{citem.isbuy }}"></t-image>
              </view>
            </view>
          </view>
        </view>
        <!-- // 判断 不是商品 有子项 递归组件 -->
        <tree
          wx:else
          bookInfo="{{bookInfo}}"
          treeList="{{[citem]}}"
          itemId="{{itemId}}"
          tab="{{tab}}"
          openTeachids="{{openTeachids}}"
          openLearnids="{{openLearnids}}"
        ></tree>
        <tree wx:else bookInfo="{{bookInfo}}" treeList="{{[citem]}}" itemId="{{itemId}}" tab="{{tab}}" openTeachids="{{openTeachids}}" openLearnids="{{openLearnids}}"></tree>
      </view>
      <view class="listItems" wx:if="{{children.length <= 0 && !loading}}">
        暂无数据
@@ -173,3 +64,5 @@
    </t-collapse-panel>
  </t-collapse>
</view>
<web-view wx:if="{{webpageSrc}}" src="{{webpageSrc}}"></web-view>
pages/bookServices/detail/index.js
@@ -1,5 +1,6 @@
// pages/bookServices/detail/index.js
import Message from 'tdesign-miniprogram/message/index.js';
import Toast from 'tdesign-miniprogram/toast/index';
const app = getApp();
Page({
  /**
@@ -41,7 +42,16 @@
    loading: false,
    isShowTeachDownload: false,  // 提示PC下载弹窗状态
    confirmBtn: { content: '我知道了', variant: 'base' },
    mockData: {
      id: 0, // 销售id
      price: 0, // 售价
      count: 0, // 组卷已购买次数
      useCount: 0, // 组件已使用次数
      residue: 0, // 组卷剩余次数
      mockList: [] // 用户组卷提交信息
    }
  },
  resetTree: function (e) {
    this.setData({
@@ -69,10 +79,11 @@
    });
    this.getBookInfo(options.id);
    this.getResourceClass() // 获取资源所属分类
    this.getApplyInfo(options.id)
    const token = wx.getStorageSync('jsek-token')
    if (token) {
      this.getShoppingCartProductGet()
      this.getApplyInfo(options.id)
      this.getMockData()
    }
  },
@@ -177,6 +188,11 @@
  },
  // 获取图书详情
  getBookInfo(id) {
    this.setData({
      "mockData'.id": 0,
      "mockData.price": 0,
      "mockData.count": 0
    })
    const query = {
      path: '*',
      queryType: '*',
@@ -212,7 +228,7 @@
      },
    };
    app.MG.store.getProductDetail(query).then(async (res) => {
      console.log(res.datas);
      this.setData({
        bookDetail: res.datas,
        cmsDatas: res.datas.cmsDatas[0].datas,
@@ -222,6 +238,29 @@
      const iconType = JSON.parse(res.datas.bookClassification)[0][0];
      const classType = JSON.parse(res.datas.bookClassification)[0][1];
      const className = await this.getBookClass(iconType, classType)
      // 获取组卷销售id
      if (res.datas.saleMethod && res.datas.saleMethod.length) {
        res.datas.saleMethod.forEach((item) => {
          if (item.SaleType == 'combinationTestPaper') {
            this.setData({
              'mockData.id': item.Id,
              'mockData.price': item.Price
            })
          }
        })
      }
      // 获取组卷已购买次数
      if (res.datas.purchasedSaleMethodIdList && res.datas.purchasedSaleMethodIdList.length) {
        if (this.data.mockData.id) {
          let count = res.datas.purchasedSaleMethodIdList.filter(
            (item) => item == this.data.mockData.id
          ).length
          this.setData({
            'mockData.count': count
          })
        }
      }
      console.log('组卷信息', this.data.mockData);
      this.setData({
        'bookDetail.publicationDate': this.formatDate(this.data.bookDetail.publicationDate),
        'bookDetail.class': className,
@@ -230,6 +269,7 @@
        'bookDetail.paperPrice': this.numFormat(this.data.bookDetail.paperPrice),
      });
    });
  },
  // 获取图书分类
  async getBookClass(iconType, classType) {
@@ -296,8 +336,8 @@
  goShop(e) {
    const { link } = e.currentTarget.dataset;
    wx.navigateTo({
      url: link,
    });
      url: `/pages/bookServices/webpage/index?url=${link}`,
    })
  },
  onTabsChange(e) {
    this.setData({
@@ -380,6 +420,8 @@
                item.checked = false
              })
              const list = await this.getAllResource(res.datas.cmsDatas[0].datas)
              console.log(list, 'list');
              this.setData({
                teach: list,
                loading: false
@@ -507,7 +549,25 @@
  },
  // 图书添加购物车
  addBookShopcCar() {
  async addBookShopcCar() {
    const shoppingCartGetId = []
    let query = {
      start: 0,
      size: 999,
      filterList: [],
      searchList: []
    }
    const res = await app.MG.store.getShoppingCartProductList(query)
    res.datas.forEach((item) => {
      shoppingCartGetId.push(item.saleMethod.id)
    })
    console.log(shoppingCartGetId, 'shoppingCartGetId');
    console.log(this.data.bookDetail.defaultSaleMethodId, 'this.data.bookDetail.defaultSaleMethodId');
    const determine = shoppingCartGetId.some((item) => item == this.data.bookDetail.defaultSaleMethodId)
    console.log(determine);
    if (!determine) {
    let query = {
      requests: [
        {
@@ -518,7 +578,60 @@
      ]
    }
    const addRes = app.MG.store.addShoppingCart(query)
      this.showSuccessToast()
    } else {
      Toast({
        context: this,
        selector: '#t-toast',
        message: '已添加',
        theme: 'success',
        direction: 'column',
      });
    }
  },
  showSuccessToast() {
    Toast({
      context: this,
      selector: '#t-toast',
      message: '添加成功',
      theme: 'success',
      direction: 'column',
    });
  },
  async buyBook() {
    let bookOrdersId = ''
    let query = {
      remarks: '电子书',
      requests: [
        {
          saleMethodId: this.data.bookDetail.defaultSaleMethodId,
          count: 1
        }
      ]
    }
    // 发起订单初始化请求并等待结果
    const res = await app.MG.store.initOrder(query)
    // 获取订单号并赋值给 orderNumber.value
    bookOrdersId = res.orderNumber
    console.log(bookOrdersId);
    // 检查订单号是否存在
    if (bookOrdersId) {
      const url = '/pages/cart/paymentPage/index?orderNumber=' + bookOrdersId
      wx.navigateTo({
        url
      })
    } else {
      console.log(222);
    }
  },
  // 获取教学资源下载是否申请通过
  getApplyInfo(id) {
    // 获取当前时间
@@ -908,7 +1021,7 @@
    if (initOrderRes.orderNumber) {
      // bookService: orderNumber.value,  少传这个 ,暂时不知道有什么用
      wx.navigateTo({
        url: `/pages/cart/paymentPage/index?&bookId=${this.data.bookDetail.id}&bookName=${this.data.bookDetail.name}&orderNum=${initOrderRes.orderNumber}`,
        url: `/pages/cart/paymentPage/index?&bookId=${this.data.bookDetail.id}&bookName=${this.data.bookDetail.name}&orderNumber=${initOrderRes.orderNumber}`,
      })
    } else {
      // 订单号不存在,显示警告消息
@@ -939,5 +1052,69 @@
  handleTrue() {
    // findAndUpdateItemsByIds(this.date.)
  },
  // 组卷格式化日期显示
  DateFormat(date, fmt) {
    if (date && fmt) {
      let _date = new Date(date)
      var o = {
        'M+': _date.getMonth() + 1, //月份
        'd+': _date.getDate(), //日
        'h+': _date.getHours(), //小时
        'm+': _date.getMinutes(), //分
        's+': _date.getSeconds(), //秒
        'q+': Math.floor((_date.getMonth() + 3) / 3), //季度
        S: _date.getMilliseconds() //毫秒
      }
      if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (_date.getFullYear() + '').substr(4 - RegExp.$1.length))
      }
      for (var k in o) {
        if (new RegExp('(' + k + ')').test(fmt)) {
          fmt = fmt.replace(
            RegExp.$1,
            RegExp.$1.length == 1
              ? (o)[k]
              : ('00' + (o)[k]).substr(('' + (o)[k]).length)
          )
        }
      }
      return fmt
    } else {
      return ''
    }
  },
  // 获取组卷答题数据
  getMockData() {
    this.setData({
      'mockData.useCount': 0,
      'mockData.mockList': []
    })
    app.MG.identity
      .getUserKey({
        domain: 'mockData',
        keys: [this.data.bookId]
      })
      .then((res) => {
        console.log(JSON.parse(res[0].value));
        if (res && res.length) {
          const mock = JSON.parse(res[0].value)
          mock.forEach(item => {
            item.createDate = this.DateFormat(item.createDate, 'yyyy-MM-dd')
          })
          this.setData({
            'mockData.mockList': mock
          })
          // 组卷已使用次数
          res.forEach((item) => {
            // 已经有答题分数等数据,证明组卷已经使用完毕
            if (item.resultData) {
              this.setData({
                'mockData.useCount': this.data.mockData.useCount + 1
              })
            }
          })
        }
      })
  }
})
pages/bookServices/detail/index.json
@@ -1,4 +1,5 @@
{
  "component": true,
  "usingComponents": {
    "t-icon": "tdesign-miniprogram/icon/icon",
    "t-image": "tdesign-miniprogram/image/image",
@@ -14,7 +15,8 @@
    "tree": "/pages/bookServices/detail/components/tree/index",
    "suggest": "/pages/bookServices/detail/components/suggest/suggest",
    "t-loading": "tdesign-miniprogram/loading/loading",
    "t-dialog": "tdesign-miniprogram/dialog/dialog"
    "t-dialog": "tdesign-miniprogram/dialog/dialog",
    "t-toast": "tdesign-miniprogram/toast/toast"
  },
  "navigationStyle": "custom",
  "onReachBottomDistance": 200
pages/bookServices/detail/index.wxml
@@ -3,48 +3,30 @@
<view style="width: 100%; height: {{barHeight}}px; "></view>
<view class="nacigationBar" style="width: 70%; height: {{navBarHeight}}px;">
  <view>
    <t-icon
      name="chevron-left"
      size="30"
      data-name="{{item}}"
      bind:click="goBack"
    />
    <t-icon name="chevron-left" size="30" data-name="{{item}}" bind:click="goBack" />
  </view>
  <view class="navbar-title">{{options.name}}</view>
</view>
<t-toast id="t-toast" />
<scroll-view scroll-y="{{true}}" class="book" bindscrolltolower="onReachBottom">
  <!-- 图书详情 -->
  <view class="book-box">
    <view class="book-detail">
      <view class="detail-left">
        <view class="book-img">
          <t-image
            src="{{bookDetail.icon}}"
            mode="aspectFill"
            width="120"
            height="170"
            aria-label="{{bookDetail.name}}"
          />
          <t-image src="{{bookDetail.icon}}" mode="aspectFill" width="120" height="170" aria-label="{{bookDetail.name}}" />
        </view>
        <view class="book-use">
          <view class="collect" bind:tap="setCollect">
            <view>
              <t-image
                src="/static/images/bookService/detail/collect.png"
                wx:if="{{!bookDetail.isFavourite}}"
              ></t-image>
              <t-image
                src="/static/images/bookService/detail/collecting.png"
                wx:if="{{bookDetail.isFavourite}}"
              ></t-image>
              <t-image src="/static/images/bookService/detail/collect.png" wx:if="{{!bookDetail.isFavourite}}"></t-image>
              <t-image src="/static/images/bookService/detail/collecting.png" wx:if="{{bookDetail.isFavourite}}"></t-image>
            </view>
            <view class="use-title">收藏</view>
          </view>
          <view class="suggest" bind:tap="suggestBtn">
            <view>
              <t-image
                src="/static/images/bookService/detail/suggest.png"
              ></t-image>
              <t-image src="/static/images/bookService/detail/suggest.png"></t-image>
            </view>
            <view class="use-title">我要建议</view>
          </view>
@@ -69,11 +51,7 @@
            <view class="li-title">出版时间:</view>
            <view class="li-content">{{bookDetail.publicationDate}}</view>
          </view>
          <view
            class="message-li"
            wx:if="{{bookDetail.class}}"
            style="height: 80rpx"
          >
          <view class="message-li" wx:if="{{bookDetail.class}}" style="height: 80rpx">
            <view class="li-title">图书分类:</view>
            <view class="class-name showTow">{{bookDetail.class}}</view>
          </view>
@@ -86,16 +64,11 @@
        <!-- 电子书售价 -->
        <view class="electron-price">
          <view>
            <t-image
              src="/static/images/bookService/detail/electon-price.png"
            ></t-image>
            <t-image src="/static/images/bookService/detail/electon-price.png"></t-image>
          </view>
          <view class="price">
            <view class="price-text"
              >¥{{bookDetail.price == '0.00' ? '免费' :bookDetail.price}}</view
            >
            <view class="price-old" wx:if="{{bookDetail.oldPrice != '0.00'}}"
              >¥{{bookDetail.oldPrice}} <view class="line"></view>
            <view class="price-text">¥{{bookDetail.price == '0.00' ? '免费' :bookDetail.price}}</view>
            <view class="price-old" wx:if="{{bookDetail.oldPrice != '0.00'}}">¥{{bookDetail.oldPrice}} <view class="line"></view>
            </view>
          </view>
          <view> </view>
@@ -103,131 +76,49 @@
        <!-- 纸质书售价 -->
        <view class="paper-price">
          <view>
            <t-image
              src="/static/images/bookService/detail/paper-price.png"
            ></t-image>
            <t-image src="/static/images/bookService/detail/paper-price.png"></t-image>
          </view>
          <view class="price"
            >¥{{bookDetail.paperPrice == '0.00' ? '免费' :
            bookDetail.paperPrice}}</view
          >
          <view class="price">¥{{bookDetail.paperPrice == '0.00' ? '免费' :
            bookDetail.paperPrice}}</view>
        </view>
      </view>
      <!-- 网店 -->
      <view class="book-web">
        <t-image
          src="/static/images/bookService/detail/jd.png"
          wx:if="{{bookDetail.JDLink}}"
          bind:tap="goShop"
          data-link="{{bookDetail.tmallLink}}"
          data-type="jd"
        ></t-image>
        <t-image
          src="/static/images/bookService/detail/tmall.png"
          width="32"
          height="22"
          bind:tap="goShop"
          data-link="{{bookDetail.tmallLink}}"
          wx:if="{{bookDetail.tmallLink}}"
        ></t-image>
        <t-image
          src="/static/images/bookService/detail/dangdang.png"
          bind:tap="goShop"
          data-link="{{bookDetail.dangdangLink}}"
          wx:if="{{bookDetail.dangdangLink}}"
        ></t-image>
        <t-image
          src="/static/images/bookService/detail/jd.png"
          bind:tap="goShop"
          data-link="{{bookDetail.weidianLink}}"
          wx:if="{{bookDetail.weidianLink}}"
        ></t-image>
        <t-image src="/static/images/bookService/detail/jd.png" wx:if="{{bookDetail.JDLink}}" bind:tap="goShop" data-link="{{bookDetail.JDLink}}" data-type="jd"></t-image>
        <t-image src="/static/images/bookService/detail/tmall.png" width="32" height="22" bind:tap="goShop" data-link="{{bookDetail.tmallLink}}" wx:if="{{bookDetail.tmallLink}}"></t-image>
        <t-image src="/static/images/bookService/detail/dangdang.png" bind:tap="goShop" data-link="{{bookDetail.dangdangLink}}" wx:if="{{bookDetail.dangdangLink}}"></t-image>
        <t-image src="/static/images/bookService/detail/jd.png" bind:tap="goShop" data-link="{{bookDetail.weidianLink}}" wx:if="{{bookDetail.weidianLink}}"></t-image>
      </view>
    </view>
  </view>
  <view class="book-resource">
    <t-tabs
      defaultValue="{{tabValue}}"
      bind:change="onTabsChange"
      t-class="custom-tabs"
      t-class-content="custom-panel"
      class="tab-class"
    >
    <t-tabs defaultValue="{{tabValue}}" bind:change="onTabsChange" t-class="custom-tabs" t-class-content="custom-panel" class="tab-class">
      <t-tab-panel label="图书简介" value="brief" style="{{tabPanelstyle}}">
        <book-brief
          content="{{bookDetail.content}}"
          authorIntroduction="{{bookDetail.authorIntroduction}}"
        ></book-brief>
        <book-brief content="{{bookDetail.content}}" authorIntroduction="{{bookDetail.authorIntroduction}}"></book-brief>
      </t-tab-panel>
      <t-tab-panel label="电子书" value="1" style="{{tabPanelstyle}}">
        电子书
      </t-tab-panel>
      <t-tab-panel
        label="教学资源"
        value="jsek_teachingResources"
        class="{{loading ? 'loading': ''}}"
      >
      <t-tab-panel label="教学资源" value="jsek_teachingResources" class="{{loading ? 'loading': ''}}">
        <view wx:if="{{!loading && teach.length}}">
          <teach-resource
            applyState="{{applyState}}"
            rejectCause="{{rejectCause}}"
            bind:applyResource="applyResource"
          ></teach-resource>
          <tree
            bookInfo="{{bookDetail}}"
            treeList="{{teach}}"
            tab="{{tabValue}}"
            applyState="{{applyState}}"
            bind:downloadTeach="downloadTeach"
            openTeachids="{{openTeachids}}"
          ></tree>
          <teach-resource applyState="{{applyState}}" rejectCause="{{rejectCause}}" bind:applyResource="applyResource"></teach-resource>
          <tree bookInfo="{{bookDetail}}" treeList="{{teach}}" tab="{{tabValue}}" applyState="{{applyState}}" bind:downloadTeach="downloadTeach" openTeachids="{{openTeachids}}"></tree>
        </view>
        <t-loading
          theme="circular"
          size="60rpx"
          class="loading"
          loading="{{loading}}"
        />
        <t-loading theme="circular" size="60rpx" class="loading" loading="{{loading}}" />
      </t-tab-panel>
      <t-tab-panel
        label="云学习"
        value="jsek_cloudLearning"
        style="{{tabPanelstyle}}"
      >
      <t-tab-panel label="云学习" value="jsek_cloudLearning" style="{{tabPanelstyle}}">
        <view wx:if="{{!loading && learn.length}}">
          <learn-resource
            bind:getFreeResource="getFreeResource"
            bind:allAddShoppiingCar="allAddShoppiingCar"
            id="learn-resource"
          ></learn-resource>
          <tree
            bookInfo="{{bookDetail}}"
            tab="{{tabValue}}"
            treeList="{{learn}}"
            buyIds="{{buyIdList}}"
            openLearnids="{{openLearnids}}"
          ></tree>
          <learn-resource bind:getFreeResource="getFreeResource" bind:allAddShoppiingCar="allAddShoppiingCar" id="learn-resource"></learn-resource>
          <tree bookInfo="{{bookDetail}}" tab="{{tabValue}}" treeList="{{learn}}" buyIds="{{buyIdList}}" openLearnids="{{openLearnids}}"></tree>
        </view>
      </t-tab-panel>
      <t-tab-panel
        label="云测试"
        value="questionBank"
        style="{{tabPanelstyle}}"
      >
      <t-tab-panel label="云测试" value="questionBank" style="{{tabPanelstyle}}">
        <view wx:if="{{!loading && test.length}}">
          <test-resource
            list="{{test}}"
            bookInfo="{{bookDetail}}"
          ></test-resource>
          <test-resource list="{{test}}" bookInfo="{{bookDetail}}" mockData="{{mockData}}"></test-resource>
        </view>
      </t-tab-panel>
      <t-tab-panel label="云笔记" value="jesk_note" style="{{tabPanelstyle}}">
        <note
          bookInfo="{{bookDetail}}"
          id="note"
          class="note-list"
          bind:changeLoaidng="changeLoaidng"
        ></note>
        <note bookInfo="{{bookDetail}}" id="note" class="note-list" bind:changeLoaidng="changeLoaidng"></note>
      </t-tab-panel>
    </t-tabs>
  </view>
@@ -241,29 +132,15 @@
    </view>
    <view class="bottom-btn">
      <view>
        <t-image
          src="/static/images/bookService/detail/paper-book.png"
        ></t-image>
        <t-image src="/static/images/bookService/detail/paper-book.png"></t-image>
      </view>
      <view class="btn-text">纸质样书申请</view>
    </view>
    <view class="shopCar" bind:tap="addBookShopcCar">加入购物车</view>
    <view class="buy">立即购买</view>
    <view class="buy" bind:tap="buyBook">立即购买</view>
  </view>
</scroll-view>
<!-- 我要建议弹窗 -->
<suggest
  class="suggest-component"
  id="suggest-component"
  bookIcon="{{bookDetail.icon}}"
  bookName="{{bookDetail.name}}"
></suggest>
<suggest class="suggest-component" id="suggest-component" bookIcon="{{bookDetail.icon}}" bookName="{{bookDetail.name}}"></suggest>
<!-- 教学资源下载提示弹窗 -->
<t-dialog
class="teachDownloadDialog"
  visible="{{isShowTeachDownload}}"
  title="提示"
  content="请前往PC端下载"
  confirm-btn="{{ confirmBtn }}"
  bind:confirm="closeTeachDownload"
/>
<t-dialog class="teachDownloadDialog" visible="{{isShowTeachDownload}}" title="提示" content="请前往PC端下载" confirm-btn="{{ confirmBtn }}" bind:confirm="closeTeachDownload" />
pages/bookServices/examination/examination.js
@@ -1,3 +1,4 @@
import { getPublicImage } from '../../../assets/js/middleGround/tool'
const app = getApp()
Page({
@@ -9,20 +10,25 @@
    navBarHeight: "",
    loading: false,
    answerTitle: "",  // 导航栏标题
    countdownInterval: null,   // 计时器
    isCountdownRunning: true, // 是否倒计时
    countdownTime: 0,  // 倒计时时间
    bookId: "",
    productLinkPath: "",
    rootCmsItemId: "",
    idPathList: [],  // 题目列表
    answerType: "",  // 答题类型
    answerType: "",  // 答题模式
    submitStatus: false,  // 提交状态
    currentIndex: 0, // 当前答题数
    currentIndex: 0, // 当前显示的题号
    collectList: [],   //  收藏题目列表 
    subjectiveNum: 0, // 主观题得分
    subjectiveGrade: 0, // 主观题总分
    total: 0,   // 题目总数
    errorList: [],  // 错题列表
    subjectiveTotal: 0,  // 客观题总数
    subjectiveNum: 0, // 客观题得分
    subjectiveGrade: 0, // 客观题总分
    correctNum: 0,  // 正确题目数量
    total: 0,   // 题目总数
    cardList: [],  // 提交项,
    questionDataList: []
    questionDataList: [],  // 显示题目列表
  },
  /**
@@ -37,12 +43,13 @@
      navBarHeight: navBarHeight,
      answerTitle: options.answerTitle,
      bookId: options.bookId,
      productLinkPath: options.productLinkPath,
      productLinkPath: options.productLinkPath ? options.productLinkPath : '',
      rootCmsItemId: options.rootCmsItemId,
      idPathList: JSON.parse(options.idPathList),
      idPathList: options.idPathList ? JSON.parse(options.idPathList) : [],
      answerType: options.answerType
    });
    this.init()
    console.log('传参', options);
  },
  /**
@@ -70,7 +77,9 @@
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
    if (this.data.countdownInterval !== null) {
      clearInterval(this.data.countdownInterval)
    }
  },
  /**
@@ -96,12 +105,243 @@
  goBack() {
    wx.navigateBack();
  },
  // 获取保存的倒计时时间
  getSavedTime() {
    const savedTime = wx.getStorageSync('countdownTime')
    return savedTime ? parseInt(savedTime) : null
  },
  // 保存倒计时时间到本地存储
  saveTime() {
    wx.setStorageSync('countdownTime', this.data.countdownTime.toString())
  },
  clearTime() {
    this.setData({
      countdownTime: 2 * 60 * 60 * 1000
    })
  },
  // 暂停或继续倒计时
  toggleCountdown() {
    if (this.data.countdownInterval) {
      clearInterval(this.data.countdownInterval)
      this.setData({
        countdownInterval: null,
        isCountdownRunning: false
      })
    } else {
      this.startCountdown()
      this.setData({
        isCountdownRunning: true
      })
    }
  },
  // 开始倒计时
  startCountdown() {
    // 如果计时器已经存在,先清除之前的计时器
    if (this.data.countdownInterval) {
      clearInterval(this.data.countdownInterval)
      this.setData({
        countdownInterval: null
      })
    }
    this.setData({
      countdownInterval: setInterval(() => {
        this.setData({
          countdownTime: this.data.countdownTime - 1000
        })
        if (this.data.countdownTime <= 0) {
          clearInterval(this.data.countdownInterval)
          this.setData({
            countdownTime: 0,
            isCountdownRunning: false
          })
        }
        this.saveTime()
      }, 1000)
    })
  },
  // 切换题目
  changeSwiper(e) {
    this.setData({
      currentIndex: e.detail.index
    })
    let index = e.detail.index - 1 >= 0 ? e.detail.index - 1 : 0
    let flag = this.isHaveAnswer(this.data.questionDataList[index].userAnswer)
    if (flag) this.handleQuestion(e.detail.index)
  },
  // 点击答题卡跳转题目
  goQuestion(e) {
    console.log(e);
    const id = e.detail.id
    this.data.questionDataList.forEach((item, index) => {
      if (item.id == id) {
        this.setData({
          currentIndex: index
        })
      }
    })
  },
  // 单选 多选 触发
  onChangeRadio(e) {
    const radioData = e.detail.value.currentTarget.dataset.value
    const id = e.detail.value.currentTarget.dataset.id
    const radioChecked = e.detail.value.detail.value
    const questionList = this.data.questionDataList
    questionList.forEach(item => {
      if (item.id == id) {
        item.userAnswer = radioChecked
      }
    })
    this.setData({
      questionDataList: questionList
    })
    console.log(this.data.questionDataList);
  },
  // 输入框触发
  onChangeInput(e) {
    const inputData = e.detail.value.detail.value
    const id = e.detail.value.currentTarget.dataset.id
    const index = e.detail.value.currentTarget.dataset.index
    const questionList = this.data.questionDataList
    questionList.forEach(item => {
      if (item.id == id) {
        item.userAnswer[index] = inputData
      }
    })
    this.setData({
      questionDataList: questionList
    })
    console.log(this.data.questionDataList);
  },
  // 数组转为字符串方法
  arrayToString(data) {
    // 检查是否为数组
    if (Array.isArray(data)) {
      // 使用 join 方法将数组转换为字符串,默认使用逗号分隔
      return data.join(',').replace(/<[^>]*>/g, '')
    } else {
      // 如果不是数组,直接返回原始值
      return data.replace(/<[^>]*>/g, '')
    }
  },
  // 判断是否有用户答案
  isHaveAnswer(data) {
    if (typeof data == 'string') {
      data = data
        .replace(/<[^>]*>/g, '')
        .replace(/&nbsp;/g, '')
        .trim()
      if (data.length) {
        return true
      } else {
        return false
      }
    } else {
      const answer = data.find((item) => item.length > 0)
      if (answer) {
        return true
      } else {
        return false
      }
    }
  },
  // 提交逻辑
  submitPaper() {
    this.setData({
      submitStatus: true
    })
    if (this.data.answerType == 'option') {
      this.toggleCountdown()
      const child = this.selectComponent('#question-options')
      if (this.data.answerType == 'option' || this.data.answerType == 'errorQuestion') {
        // 先遍历所有题目,将未批改的题目批改
        const qustionList = this.data.questionDataList
        for (let index = 0; index < qustionList.length; index++) {
          const item = qustionList[index];
          if (!item.isComplete) this.handleQuestion(index + 1)
        }
      }
      if (this.data.answerType == 'option') {
        this.recordAnswerData()
        child.openTestReportDialog()
      }
    } else if (this.data.answerType == 'collectQuestion' || this.data.answerType == 'errorQuestion') {
      this.goBack()
    }
  },
  // 初始化函数
  async init() {
    this.setData({
      loading: true,
      subjectiveTotal: 0,
      subjectiveNum: 0,
      subjectiveGrade: 0
    })
    if (this.data.answerType == 'option') {
      if (this.data)
        this.startCountdown()
      this.setData({
        countdownTime: 2 * 60 * 60 * 1000
      })
      // 测试答题
      await this.getCollectIdList() // 获取收藏id列表
      // await getErrorList() // 获取错题id列表
      await this.getErrorList()   // 获取错题id列表
    } else if (this.data.answerType == 'collectQuestion') {
      // 我的收藏
      await this.getcollectId() // 获取收藏题目
    } else if (this.data.answerType == 'errorQuestion') {
      // 我的错题
      // loadings.value = true
      await this.getErrorIdList()
      await this.getCollectIdList() // 获取收藏id列表
    }
  },
  async restart() {
    const countDownRef = this.selectComponent('#countDownRef')
    this.setData({
      loading: true,
      total: 0,
      subjectiveGrade: 0,
      subjectiveTotal: 0,
      subjectiveNum: 0,
      currentIndex: 0,
      submitStatus: false
    })
    if (this.data.answerType == 'option') {
      this.setData({
        countdownTime: 2 * 60 * 60 * 1000
      })
      this.delAnswerInfo(() => {
        this.getQuestionList()
        this.clearTime()
      })
      if (!this.data.submitStatus) {
        this.startCountdown()
      }
    } else if (this.data.answerType == 'mock') {
      // 组卷模式
      // 清空答题记录
      await app.MG.identity.setUserKey({
        setKeyRequests: [
          {
            domain: 'mockAnswerData',
            key: route.query.uuid,
            value: JSON.stringify({
              time: countDownRef.value.countdownTime,
              answerData: []
            })
          }
        ]
      })
      this.init()
    } else {
      this.init()
      this.clearTime()
      if (submitStatus.value) {
        this.startCountdown()
      }
    }
  },
  // 获取收藏题目列表id
@@ -111,7 +351,7 @@
        domain: 'collectData',
        keys: [this.data.rootCmsItemId]
      })
      .then(async (res) => {
      .then((res) => {
        try {
          this.setData({
            collectList: JSON.parse(res[0].value)
@@ -120,16 +360,18 @@
        }
        if (this.data.answerType == 'option') {
          // 先获取用户答题记录
          await this.getAnswerInfo((res) => {
          this.getAnswerInfo(async (res) => {
            if (res.length) {
              // 有记录,不能答题,状态设为已提交
              this.setData({
                submitStatus: true
              })
              let value = JSON.parse(res[0].value)
              // console.log('答题记录', JSON.parse(res[0].value))
              // 有答题记录,得分赋值
              if (value) {
                this.setData({
                  submitStatus: true
                })
                value.dataList.forEach((item) => {
                  if (item.name == '客观题得分' && item.path == this.data.productLinkPath)
                    this.setData({
@@ -141,11 +383,28 @@
                currentIndex: value.currentIndex
              })
              // 携带答题记录 获取题目
              this.getQuestionList(value.dataList)
              await this.getQuestionList(value.dataList)
            } else {
              this.getQuestionList() // 获取题库题目
              await this.getQuestionList() // 获取题库题目
            }
          })
        }
      })
  },
  // 获取错题id列表
  getErrorList() {
    app.MG.identity
      .getUserKey({
        domain: 'errorData',
        keys: [this.data.rootCmsItemId]
      })
      .then((res) => {
        try {
          this.setData({
            errorList: JSON.parse(res[0].value)
          })
        } catch (error) {
        }
      })
  },
@@ -153,22 +412,21 @@
  getQuestionList(oldData) {
    // 清空正确题数记录
    this.setData({
      correctNum: 0
      cardList: [],
      correctNum: 0,
    })
    let flag = 0
    this.data.idPathList.forEach((pathitem) => {
      const pathList = this.data.cardList
      pathList.push({
        name: pathitem.name,
        path: pathitem.productLinkPath,
        catalogName: pathitem.type,
        catalogName: pathitem.name,
        infoList: []
      })
      this.setData({
        cardList: pathList
      })
      // 获取题目
      let questionArr = []
      let query = {
        path: '*',
        queryType: '*',
@@ -210,6 +468,7 @@
          let questionObj = {
            // num: index, // 题号
            id: item.id,
            type: pathitem.name,
            stem:
              item.Embedded_QuestionBank_QuestionType == 'completion'
                ? JSON.parse(item.Embedded_QuestionBank_Stem)
@@ -249,6 +508,8 @@
              questionObj.answer = item.Embedded_QuestionBank_Answer
            }
          }
          // questionObj.userAnswer = this.arrayToString(questionObj.userAnswer)
          // questionObj.isHaveAnswer = this.isHaveAnswer(questionObj.userAnswer)
          // 填空题改造
          if (questionObj.questionType == 'completion') {
            let index = 0
@@ -264,7 +525,20 @@
              }
            }
          }
          questionArr.push(questionObj)
          // 获取图片
          if (questionObj.stemStyle == 'Image' || questionObj.stemStyle == 'TxtAndImage') {
            questionObj.stem.stemImage = getPublicImage(questionObj.stem.stemImage, 150)
          }
          if (questionObj.optionStyle == 'Image' || questionObj.optionStyle == 'TxtAndImage') {
            questionObj.option.forEach(optionItem => {
              if (optionItem.img) optionItem.img = getPublicImage(optionItem.img, 150)
            })
          }
          // if (questionObj.optionStyle == 'RichText') {
          //   questionObj.option.forEach(optionItem => {
          //     optionItem.txt.replace(/<img>/g, "<img class='imgClass'>")
          //   })
          // }
          // 旧数据里 题目已经作答,修改已答题目数量
          // if (oldObj && oldObj.userAnswer.length > 0) countDownRef.value.changeAlready()
          // 旧数据里 题目正确 记录正确数量
@@ -273,57 +547,240 @@
              correctNum: this.data.correctNum + 1
            })
          }
          // if (pathitem.name == '判断题') {
          //   topicList.value.judge.data = questionArr
          //   topicList.value.judge.path = pathitem.productLinkPath
          //   if (oldData) subjectiveTotal.value += 1 // 有旧数据,计算主观题数
          // } else if (pathitem.name == '填空题') {
          //   topicList.value.gap.data = questionArr
          //   topicList.value.gap.path = pathitem.productLinkPath
          //   if (oldData) subjectiveTotal.value += 1
          // } else if (pathitem.name == '多选题') {
          //   topicList.value.check.data = questionArr
          //   topicList.value.check.path = pathitem.productLinkPath
          //   if (oldData) subjectiveTotal.value += 1
          // } else if (pathitem.name == '单选题') {
          //   topicList.value.radio.data = questionArr
          //   topicList.value.radio.path = pathitem.productLinkPath
          //   if (oldData) subjectiveTotal.value += 1
          // } else if (pathitem.name == '简答题') {
          //   topicList.value.short.data = questionArr
          //   topicList.value.short.path = pathitem.productLinkPath
          // } else if (pathitem.name == '翻译题') {
          //   topicList.value.translate.data = questionArr
          //   topicList.value.translate.path = pathitem.productLinkPath
          // } else if (pathitem.name == '听力题') {
          //   topicList.value.listen.data = questionArr
          //   topicList.value.listen.path = pathitem.productLinkPath
          //   if (oldData) subjectiveTotal.value += 1
          // }
          let infoList =
            this.data.cardList[this.data.cardList.findIndex((item) => item.path == pathitem.productLinkPath)]
              .infoList
          if (pathitem.name == '判断题' || pathitem.name == '填空题' || pathitem.name == '多选题' || pathitem.name == '单选题' || pathitem.name == '听力题') {
            if (oldObj) {
              this.setData({
                subjectiveTotal: this.data.subjectiveTotal + 1
              })
            }
          }
          // cardList赋值
          let cardIndex = this.data.cardList.findIndex((item) => item.path == pathitem.productLinkPath)
          let infoList = this.data.cardList[cardIndex].infoList
          infoList.push(questionObj)
          this.setData({
            [`cardList[${cardIndex}].infoList`]: infoList
          })
          //   this.data.cardList[this.data.cardList.findIndex((item) => item.path == pathitem.productLinkPath)]
          //     .infoList
          // infoList.push(questionObj)
          flag++;
          let questionList = []
          const cardUpdatedList = this.data.cardList
          // if (flag == this.data.idPathList.length) {
          this.data.cardList.forEach(aitem => {
            aitem.infoList.forEach(bitem => {
          cardUpdatedList.forEach(aitem => {
            aitem.infoList.forEach((bitem, bindex) => {
              questionList.push(bitem)
              bitem.number = questionList.length
              bitem.number = bindex + 1
              bitem.grade = 2
            })
          })
          this.setData({
            questionDataList: questionList
            questionDataList: questionList,
            cardList: cardUpdatedList
          })
          // }
        })
      })
    })
    this.setData({
      loading: false,
    })
    console.log('题目列表', this.data.questionDataList, this.data.cardList);
  },
  // 批改题目 (练习,我的错题,我的收藏)
  handleQuestion(num) {
    const questionList = this.data.questionDataList
    const index = num - 1 >= 0 ? num - 1 : 0
    if (questionList[index].isComplete) {
      // 题目已完成,跳过
      return true
    }
    questionList[index].isComplete = true
    const item = questionList[index]
    // 批改题目
    if (item.questionType == 'multipleChoice') {
      // 多选题
      // subjectiveGrade.value += item.score
      if (item.answer.length == item.userAnswer.length) {
        const sortedArr1 = item.answer.slice().sort()
        const sortedArr2 = item.userAnswer.slice().sort()
        questionList[index].isRight = sortedArr1.every(
          (value, valueIndex) => value === sortedArr2[valueIndex]
        )
      } else {
        questionList[index].isRight = false
      }
    } else if (item.questionType == 'singleChoice' || item.questionType == 'judge') {
      // 单选 判断
      // subjectiveGrade.value += item.score
      questionList[index].isRight = item.answer == item.userAnswer
    } else if (item.questionType == 'shortAnswer') {
      // 简答 翻译
      questionList[index].isRight = null
    } else if (item.questionType == 'completion') {
      // 填空
      // subjectiveGrade.value += item.score
      if (typeof item.answer == 'string') {
        questionList[index].isRight = item.answer == item.userAnswer[0]
      } else {
        if (item.answer.length != item.userAnswer.length) {
          questionList[index].isRight = false
        } else {
          questionList[index].isRight = item.answer.every(
            (value, valueIndex) => value === item.userAnswer[valueIndex]
          )
        }
      }
    }
    if (item.questionType != 'shortAnswer') {
      this.setData({
        subjectiveTotal: this.data.subjectiveTotal + 1,
        subjectiveGrade: this.data.subjectiveGrade + item.grade
      })
    }
    if (questionList[index].isRight && item.questionType != 'shortAnswer') {
      // 客观题回答正确
      this.setData({
        subjectiveNum: this.data.subjectiveNum + item.grade,
        correctNum: this.data.correctNum + 1
      })
    }
    if (!questionList[index].isRight && item.questionType != 'shortAnswer') {
      // 客观题回答错误 记录错题
      if (this.data.errorList.findIndex((errorItem) => errorItem == item.id) == -1) {
        this.data.errorList.push(item.id)
      }
    } else {
      if (this.data.answerType == 'errorQuestion' || this.data.answerType == 'option') {
        // 从错题集中移除
        let errorIndex = this.data.errorList.findIndex((erroritem) => erroritem == item.id)
        if (errorIndex > -1) {
          this.data.errorList.splice(errorIndex, 1)
        }
      }
    }
    if (this.data.answerType != 'collectQuestion') {
      // 记录错题
      app.MG.identity
        .setUserKey({
          setKeyRequests: [
            {
              domain: 'errorData',
              key: this.data.rootCmsItemId,
              value: JSON.stringify(this.data.errorList)
            }
          ]
        })
        .then((res) => {
          console.log(res)
        })
    }
    this.setData({
      questionDataList: questionList
    })
    const cardUpdatedList = this.data.cardList
    cardUpdatedList.forEach((item) => {
      item.infoList.forEach((citem) => {
        if (citem.id == questionList[index].id) {
          citem = questionList[index];
        }
      });
    });
    this.setData({
      cardList: cardUpdatedList
    })
    // console.log(this.data.questionDataList, this.data.cardList);
  },
  // 题目收藏按钮,收藏和取消同一接口,取消数组减去该项id
  setCollect() {
    const citem = this.data.questionDataList[this.data.currentIndex]
    const questionList = this.data.questionDataList
    for (let index = 0; index < questionList.length; index++) {
      const item = questionList[index];
      if (item.id == citem.id) {
        item.isCollect = !item.isCollect
      }
    }
    this.setData({
      questionDataList: questionList
    })
    if (this.data.collectList.length == 0) {
      this.setData({
        collectList: [citem.id]
      })
    } else {
      const collectItme = this.data.collectList.filter((item) => item == citem.id)
      if (collectItme.length) {
        const arr = this.data.collectList.filter((item) => item != citem.id)
        this.setData({
          collectList: arr
        })
      } else {
        const collectArr = this.data.collectList
        collectArr.push(citem.id)
        this.setData({
          collectList: collectArr
        })
      }
    }
    app.MG.identity
      .setUserKey({
        setKeyRequests: [
          {
            domain: 'collectData',
            key: this.data.rootCmsItemId,
            value: JSON.stringify(this.data.collectList)
          }
        ]
      })
      .then((res) => { })
  },
  // 处理答题数据
  recordAnswerData() {
    this.data.cardList.push(
      {
        name: '客观题得分',
        score: this.data.subjectiveNum,
        path: this.data.productLinkPath,
        // infoList: [],
        // catalogName: ''
      }
    )
    let setInfoData = {
      currentIndex: this.data.currentIndex,
      dataList: JSON.parse(JSON.stringify(this.data.cardList))
    }
    for (let i = 0; i < setInfoData.dataList.length; i++) {
      const item = setInfoData.dataList[i]
      if (!item.name && !item.name == '客观题得分') {
        for (let j = 0; j < item.infoList.length; j++) {
          let obj = {
            id: item.infoList[j].id,
            userAnswer: item.infoList[j].userAnswer,
            isComplete: item.infoList[j].isComplete,
            isRight: item.infoList[j].isRight,
            isCollect: item.infoList[j].isCollect
          }
          item.infoList[j] = obj
        }
      }
    }
    this.setAnswerInfo(setInfoData)
  },
  // 提交答题数据
  setAnswerInfo(data) {
    app.MG.identity
      .setUserKey({
        setKeyRequests: [
          {
            domain: 'answerData',
            key: this.data.productLinkPath,
            value: JSON.stringify(data)
          }
        ]
      })
      .then((res) => { })
  },
  // 获取答题数据
  getAnswerInfo(callback) {
@@ -335,5 +792,332 @@
      .then((res) => {
        if (callback) callback(res)
      })
  },
  // 删除答题数据
  delAnswerInfo(callback) {
    app.MG.identity
      .delUserKey({
        domain: 'answerData',
        keys: [this.data.productLinkPath]
      })
      .then((res) => {
        if (callback) callback()
      })
  },
  // 我的收藏模式下获取收藏题目id
  async getcollectId() {
    app.MG.identity
      .getUserKey({
        domain: 'collectData',
        keys: [this.data.rootCmsItemId]
      })
      .then(async (res) => {
        try {
          this.setData({
            collectList: JSON.parse(res[0].value)
          })
          // total.value = collectList.value.length
        } catch (error) {
        }
        if (this.data.collectList && this.data.collectList.length) {
          await this.getCollectDataList()
        } else {
          this.setData({
            loading: false
          })
          wx.showModal({
            title: '提示',
            content: '收藏夹暂无数据',//editable如果为true,这就是输入框的内容
            editable: false,//是否显示输入框
            showCancel: false,
            success: (res) => {
              if (res.confirm) {
                this.setData({
                  submitStatus: true
                })
                this.goBack()
              }
            }
          })
        }
        // console.log('收藏', collectList.value)
      })
  },
  // 获取收藏夹
  async getCollectDataList() {
    let questionArr = []
    this.setData({
      cardList: [
        {
          catalogName: '收藏夹',
          infoList: []
        }
      ]
    })
    let query = {
      path: '*',
      cmsPath: this.data.rootCmsItemId,
      cmsType: '*',
      productId: this.data.bookId,
      queryType: '*',
      itemIds: this.data.collectList.map((item) => item + ''),
      itemFields: {
        Embedded_QuestionBank_Stem: [],
        Embedded_QuestionBank_AnalysisCon: [],
        Embedded_QuestionBank_Answer: [],
        Embedded_QuestionBank_Option: [],
        Embedded_QuestionBank_QuestionType: [],
        Embedded_QuestionBank_StemStyle: [],
        Embedded_QuestionBank_OptionStyle: [],
        Embedded_QuestionBank_KnowledgePoint: [],
        Embedded_QuestionBank_Difficulty: []
      }
    }
    app.MG.store.getProductDetail(query).then((res) => {
      let questionArr = []
      res.datas.cmsDatas[0].datas.forEach((item, index) => {
        const questionObj = {
          number: index + 1, // 题号
          id: item.id,
          stem:
            item.Embedded_QuestionBank_QuestionType == 'completion'
              ? JSON.parse(item.Embedded_QuestionBank_Stem)
                .stemTxt.replaceAll('<vacancy>', ',input,')
                .split(',')
              : JSON.parse(item.Embedded_QuestionBank_Stem), // 题干
          answer: item.Embedded_QuestionBank_Answer, // 答案
          option: item.Embedded_QuestionBank_Option
            ? JSON.parse(item.Embedded_QuestionBank_Option)
            : '', // 选择题选项
          analysisCon: item.Embedded_QuestionBank_AnalysisCon, // 解析
          questionType: item.Embedded_QuestionBank_QuestionType, // 题型
          optionStyle: item.Embedded_QuestionBank_OptionStyle, // 选项显示类型
          stemStyle: item.Embedded_QuestionBank_StemStyle, // 题干显示类型
          difficulty: item.Embedded_QuestionBank_Difficulty
            ? 4 - item.Embedded_QuestionBank_Difficulty
            : 0, // 难度等级
          userAnswer:
            item.Embedded_QuestionBank_QuestionType == 'completion' ||
              item.Embedded_QuestionBank_QuestionType == 'multipleChoice'
              ? []
              : '',
          isSubmit: false, // 查看解析
          isRight: null, // 是否正确
          isComplete: false,
          isCollect: true
        }
        // 多选和填空答案肯为数组,要转换JSON格式
        if (
          questionObj.questionType == 'completion' ||
          questionObj.questionType == 'multipleChoice'
        ) {
          try {
            questionObj.answer = JSON.parse(questionObj.answer)
          } catch (error) {
            //
          }
        }
        // 填空题改造
        if (questionObj.questionType == 'completion') {
          let index = 0
          for (let i = 0; i < questionObj.stem.length; i++) {
            const item = questionObj.stem[i]
            if (item == 'input') {
              questionObj.stem[i] = {
                num: index,
                data: 'input'
              }
              questionObj.userAnswer[index] = ''
              index++
            }
          }
        }
        // 获取图片
        if (questionObj.stemStyle == 'Image' || questionObj.stemStyle == 'TxtAndImage') {
          questionObj.stem.stemImage = getPublicImage(questionObj.stem.stemImage, 150)
        }
        if (questionObj.optionStyle == 'Image' || questionObj.optionStyle == 'TxtAndImage') {
          questionObj.option.forEach(optionItem => {
            if (optionItem.img) optionItem.img = getPublicImage(optionItem.img, 150)
          })
        }
        // if (item.Embedded_QuestionBank_QuestionType == 'judge') {
        //   topicList.value.judge.data.push(questionObj)
        // } else if (item.Embedded_QuestionBank_QuestionType == 'singleChoice') {
        //   topicList.value.radio.data.push(questionObj)
        // } else if (item.Embedded_QuestionBank_QuestionType == 'multipleChoice') {
        //   topicList.value.check.data.push(questionObj)
        // } else if (item.Embedded_QuestionBank_QuestionType == 'completion') {
        //   topicList.value.gap.data.push(questionObj)
        // } else if (item.Embedded_QuestionBank_QuestionType == 'shortAnswer') {
        //   topicList.value.short.data.push(questionObj)
        // }
        questionArr.push(questionObj)
        // cardList.value[0].infoList.push(questionObj)
      })
      // loadings.value = false
      this.setData({
        questionDataList: questionArr,
        ['cardList[0].infoList']: questionArr,
        loading: false,
      })
    })
  },
  // 我的错题模式下获取错题id列表
  async getErrorIdList() {
    await app.MG.identity
      .getUserKey({
        domain: 'errorData',
        keys: [this.data.rootCmsItemId]
      })
      .then((res) => {
        try {
          this.setData({
            errorList: JSON.parse(res[0].value)
          })
        } catch (error) {
        }
        if (this.data.errorList && this.data.errorList.length) {
          this.getErrorDataList()
        } else {
          this.setData({
            loading: true
          })
          wx.showModal({
            title: '提示',
            content: '错题集暂无数据',//editable如果为true,这就是输入框的内容
            editable: false,//是否显示输入框
            showCancel: false,
            success: (res) => {
              if (res.confirm) {
                this.setData({
                  submitStatus: true
                })
                this.goBack()
              }
            }
          })
        }
      })
  },
  // 获取错题集
  async getErrorDataList() {
    this.setData({
      cardList: [
        {
          catalogName: '错题集',
          infoList: []
        }
      ]
    })
    let query = {
      path: '*',
      cmsPath: this.data.rootCmsItemId,
      cmsType: '*',
      productId: this.data.bookId,
      queryType: '*',
      itemIds: this.data.errorList.map((item) => item + ''),
      itemFields: {
        Embedded_QuestionBank_Stem: [],
        Embedded_QuestionBank_AnalysisCon: [],
        Embedded_QuestionBank_Answer: [],
        Embedded_QuestionBank_Option: [],
        Embedded_QuestionBank_QuestionType: [],
        Embedded_QuestionBank_StemStyle: [],
        Embedded_QuestionBank_OptionStyle: [],
        Embedded_QuestionBank_KnowledgePoint: [],
        Embedded_QuestionBank_Difficulty: []
      }
    }
    await app.MG.store.getProductDetail(query).then((res) => {
      let questionArr = []
      res.datas.cmsDatas[0].datas.forEach((item, index) => {
        const questionObj = {
          number: index + 1, // 题号
          id: item.id,
          stem:
            item.Embedded_QuestionBank_QuestionType == 'completion'
              ? JSON.parse(item.Embedded_QuestionBank_Stem)
                .stemTxt.replaceAll('<vacancy>', ',input,')
                .split(',')
              : JSON.parse(item.Embedded_QuestionBank_Stem), // 题干
          answer: item.Embedded_QuestionBank_Answer, // 答案
          option: item.Embedded_QuestionBank_Option
            ? JSON.parse(item.Embedded_QuestionBank_Option)
            : '', // 选择题选项
          analysisCon: item.Embedded_QuestionBank_AnalysisCon, // 解析
          questionType: item.Embedded_QuestionBank_QuestionType, // 题型
          optionStyle: item.Embedded_QuestionBank_OptionStyle, // 选项显示类型
          stemStyle: item.Embedded_QuestionBank_StemStyle, // 题干显示类型
          difficulty: item.Embedded_QuestionBank_Difficulty
            ? 4 - item.Embedded_QuestionBank_Difficulty
            : 0, // 难度等级
          userAnswer:
            item.Embedded_QuestionBank_QuestionType == 'completion' ||
              item.Embedded_QuestionBank_QuestionType == 'multipleChoice'
              ? []
              : '',
          isSubmit: false, // 查看解析
          isRight: null, // 是否正确
          isComplete: false,
          isCollect: this.data.collectList.some((collectItem) => collectItem == item.id)
        }
        // 多选和填空答案肯为数组,要转换JSON格式
        if (
          questionObj.questionType == 'completion' ||
          questionObj.questionType == 'multipleChoice'
        ) {
          try {
            questionObj.answer = JSON.parse(questionObj.answer)
          } catch (error) {
            //
          }
        }
        // 填空题改造
        if (questionObj.questionType == 'completion') {
          let index = 0
          for (let i = 0; i < questionObj.stem.length; i++) {
            const item = questionObj.stem[i]
            if (item == 'input') {
              questionObj.stem[i] = {
                num: index,
                data: 'input'
              }
              questionObj.userAnswer[index] = ''
              index++
            }
          }
        }
        // 获取图片
        if (questionObj.stemStyle == 'Image' || questionObj.stemStyle == 'TxtAndImage') {
          questionObj.stem.stemImage = getPublicImage(questionObj.stem.stemImage, 150)
        }
        if (questionObj.optionStyle == 'Image' || questionObj.optionStyle == 'TxtAndImage') {
          questionObj.option.forEach(optionItem => {
            if (optionItem.img) optionItem.img = getPublicImage(optionItem.img, 150)
          })
        }
        // if (item.Embedded_QuestionBank_QuestionType == 'judge') {
        //   topicList.value.judge.data.push(questionObj)
        // } else if (item.Embedded_QuestionBank_QuestionType == 'singleChoice') {
        //   topicList.value.radio.data.push(questionObj)
        // } else if (item.Embedded_QuestionBank_QuestionType == 'multipleChoice') {
        //   topicList.value.check.data.push(questionObj)
        // } else if (item.Embedded_QuestionBank_QuestionType == 'completion') {
        //   topicList.value.gap.data.push(questionObj)
        // } else if (item.Embedded_QuestionBank_QuestionType == 'shortAnswer') {
        //   topicList.value.short.data.push(questionObj)
        // }
        questionArr.push(questionObj)
      })
      this.setData({
        questionDataList: questionArr,
        ['cardList[0].infoList']: questionArr,
        loading: false
      })
    })
    // loadings.value = false
    // console.log('错题集', topicList.value)
  }
})
pages/bookServices/examination/examination.json
@@ -5,7 +5,8 @@
    "question-list": "/pages/bookServices/examination/questionList/index",
    "t-icon": "tdesign-miniprogram/icon/icon",
    "t-image": "tdesign-miniprogram/image/image",
    "t-button": "tdesign-miniprogram/button/button"
    "t-button": "tdesign-miniprogram/button/button",
    "t-loading": "tdesign-miniprogram/loading/loading"
  },
  "navigationStyle": "custom"
}
pages/bookServices/examination/examination.wxml
@@ -12,13 +12,62 @@
  </view>
  <view class="navbar-title">{{answerTitle}}</view>
</view>
<!--
<view class="lodaing-box" wx:if="{{loaidng}}">
  <t-loading
    theme="circular"
    size="80rpx"
    class="wrapper"
    loading="{{loading}}"
  />
</view> -->
<view class="page-content">
  <question-schedule></question-schedule>
  <question-list questionList="{{questionDataList}}"></question-list>
  <question-schedule
    wx:if="{{!loading}}"
    id="countDownRef"
    answerType="{{answerType}}"
    countdownTime="{{countdownTime}}"
    currentIndex="{{currentIndex}}"
    questionList="{{questionDataList}}"
    submitStatus="{{submitStatus}}"
  ></question-schedule>
  <question-list
    wx:if="{{!loading}}"
    currentIndex="{{currentIndex}}"
    questionList="{{questionDataList}}"
    submitStatus="{{submitStatus}}"
    bind:onChangeRadio="onChangeRadio"
    bind:onChangeInput="onChangeInput"
    bind:changeSwiper="changeSwiper"
  ></question-list>
  <view class="lodaing-box">
    <t-loading
      theme="circular"
      size="80rpx"
      class="wrapper"
      loading="{{loading}}"
  /></view>
</view>
<!-- 底部区域-->
<view class="page-bottom">
  <question-options></question-options>
  <question-options
    id="question-options"
    submitStatus="{{submitStatus}}"
    answerType="{{answerType}}"
    countdownTime="{{countdownTime}}"
    currentIndex="{{currentIndex}}"
    questionDataList="{{questionDataList}}"
    cardList="{{cardList}}"
    subjectiveTotal="{{subjectiveTotal}}"
    subjectiveNum="{{subjectiveNum}}"
    subjectiveGrade="{{subjectiveGrade}}"
    correctNum="{{correctNum}}"
    bind:setCollect="setCollect"
    bind:submitPaper="submitPaper"
    bind:restart="restart"
    bind:goQuestion="goQuestion"
  ></question-options>
</view>
pages/bookServices/examination/examination.wxss
@@ -14,6 +14,14 @@
  font-weight: 600;
}
.lodaing-box {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  --td-loading-color: #ff6c00;
}
.page-content {
  box-sizing: border-box;
  width: 100%;
pages/bookServices/examination/questionList/index.js
@@ -1,14 +1,4 @@
// pages/bookServices/examination/questionList/index.js
const imageCdn = 'https://tdesign.gtimg.com/mobile/demos';
const swiperList = [
  `${imageCdn}/swiper1.png`,
  `${imageCdn}/swiper2.png`,
  `${imageCdn}/swiper1.png`,
  `${imageCdn}/swiper2.png`,
  `${imageCdn}/swiper1.png`,
];
Component({
  /**
   * 组件的属性列表
@@ -17,28 +7,85 @@
    questionList: {
      type: Array,
      value: []
    },
    submitStatus: {
      type: Boolean,
      value: false
    },
    currentIndex: {
      type: Number,
      value: 1
    }
  },
  created() {
    console.log('组件传参', this.properties);
    // console.log('组件传参', this.properties);
  },
  /**
   * 组件的初始数据
   */
  data: {
    inputstyle: 'border: 2rpx solid rgba(220,220,220,1);border-radius: 12rpx;',
    placeholderstyle: "font-size:28rpx",
    current: 2,
    autoplay: true,
    duration: 500,
    interval: 5000,
    paginationPosition: 'bottom-right',
    swiperList,
    navigation: { type: 'fraction' },
    showIndex: 0,
  },
  /**
   * 组件的方法列表
   */
  methods: {
    // 切换题目
    changeSwiper(e) {
      console.log(e);
      this.setData({
        showIndex: e.detail.current
      })
      var myEventDetail = {
        index: e.detail.current
      } // detail对象,提供给事件监听函数
      var myEventOption = {
        bubbles: true,
        composed: true,
      } // 触发事件的选项
      this.triggerEvent('changeSwiper', myEventDetail, myEventOption)
    },
    // 单选  富文本框输入  触发
    onChangeRadio(e) {
      var myEventDetail = {
        value: e
      } // detail对象,提供给事件监听函数
      var myEventOption = {
        bubbles: true,
        composed: true,
      } // 触发事件的选项
      this.triggerEvent('onChangeRadio', myEventDetail, myEventOption)
    },
    // 多选触发
    onChangeCheck(e) {
      var myEventDetail = {
        value: e
      } // detail对象,提供给事件监听函数
      var myEventOption = {
        bubbles: true,
        composed: true,
      } // 触发事件的选项
      this.triggerEvent('onChangeRadio', myEventDetail, myEventOption)
    },
    // 输入框触发
    onChangeInput(e) {
      var myEventDetail = {
        value: e
      } // detail对象,提供给事件监听函数
      var myEventOption = {
        bubbles: true,
        composed: true,
      } // 触发事件的选项
      this.triggerEvent('onChangeInput', myEventDetail, myEventOption)
    },
  }
})
pages/bookServices/examination/questionList/index.json
@@ -2,6 +2,13 @@
  "component": true,
  "usingComponents": {
    "t-swiper": "tdesign-miniprogram/swiper/swiper",
  "t-swiper-nav": "tdesign-miniprogram/swiper-nav/swiper-nav"
    "t-swiper-nav": "tdesign-miniprogram/swiper-nav/swiper-nav",
    "t-image": "tdesign-miniprogram/image/image",
    "t-input": "tdesign-miniprogram/input/input",
    "t-radio": "tdesign-miniprogram/radio/radio",
    "t-radio-group": "tdesign-miniprogram/radio-group/radio-group",
    "t-checkbox": "tdesign-miniprogram/checkbox/checkbox",
    "t-checkbox-group": "tdesign-miniprogram/checkbox-group/checkbox-group",
    "t-textarea": "tdesign-miniprogram/textarea/textarea"
  }
}
pages/bookServices/examination/questionList/index.wxml
@@ -1,13 +1,217 @@
<!--pages/bookServices/examination/questionList/index.wxml-->
<view class="question-list">
  <!-- 题型title -->
  <view class="question-title">
    <text class="title-name">单选题</text><text class="title-score">(每题2分)</text>
  <view class="question-title" wx:if="{{questionList[showIndex].type}}">
    <text class="title-name">{{questionList[showIndex].type}}</text
    ><text class="title-score">(每题{{questionList[showIndex].grade}}分)</text>
  </view>
  <!-- 题目列表 -->
  <swiper>
    <swiper-item wx:for="{{questionList}}">
  <swiper class="swiper" bind:change="changeSwiper" current="{{currentIndex}}">
    <swiper-item wx:for="{{questionList}}" wx:key="{{item.id}}">
      <!-- 题干 -->
      <view class="question-stem title-score">
        <!-- 题号 -->
        <text>{{item.number}}.</text>
        <!-- 仅文字 -->
        <view
          wx:if="{{item.stemStyle == 'Txt' && item.questionType != 'completion'}}"
          >{{item.stem.stemTxt}}</view
        >
        <!-- 仅图片 -->
        <view wx:elif="{{item.stemStyle == 'Image'}}">
          <t-image src="{{item.stem.stemImage}}" />
        </view>
        <!-- 图片加文字 -->
        <view
          wx:elif="{{item.stemStyle == 'TxtAndImage'}}"
          class="title-TxtAndImage"
        >
      <text>{{item.stem.stemTxt}}</text>
          <t-image src="{{item.stem.stemImage}}"></t-image>
        </view>
        <!-- 富文本 -->
        <view
          wx:elif="{{item.stemStyle == 'RichText'}} "
          class="title-RichText"
        >
          <rich-text nodes="{{item.stem.stemTxt}}"></rich-text>
        </view>
        <!-- 填空题 -->
        <view wx:if="{{item.questionType == 'completion'}}">
          <view
            class="completion-box"
            wx:for="{{item.stem}}"
            wx:for-item="inputItem"
            wx:for-index="inputIndex"
            wx:key="inputIndex"
          >
            <t-input
              disabled="{{item.isComplete}}"
              bind:change="onChangeInput"
              data-value="{{item.option}}"
              data-id="{{item.id}}"
              data-index="{{inputItem.num}}"
              class="title-input"
              style="{{inputstyle}}"
              placeholder-style="{{placeholderstyle}}"
              wx:if="{{inputItem.data == 'input'}}"
              placeholder="请输入文字"
              value="{{item.userAnswer[inputItem.num]}}"
            ></t-input>
            <text wx:else>{{inputItem}}</text>
          </view>
        </view>
      </view>
      <!-- 答题区域 -->
      <view class="question-answer">
        <!-- 单选题 -->
        <t-radio-group
          wx:if="{{item.questionType == 'singleChoice' || item.questionType == 'judge'}}"
          defaultValue="{{item.userAnswer}}"
          disabled="{{item.isComplete}}"
          bind:change="onChangeRadio"
          class="radio-group"
          data-value="{{item.option}}"
          data-id="{{item.id}}"
        >
          <view
            wx:for="{{item.option}}"
            wx:for-item="contentItem"
            wx:for-index="contentIndex"
            wx:key="contentIndex"
          >
            <t-radio
              value="{{contentItem.value}}"
              icon="none"
              placement="right"
              borderless
            >
              <view
                class="radio-item {{item.answer == contentItem.value && item.answer == item.userAnswer  ? 'radio-correct' : item.userAnswer == contentItem.value && item.userAnswer != item.answer ?'radio-error' :''}}"
              >
                <!-- 仅文字 -->
                <text wx:if="{{item.optionStyle == 'Txt'}}"
                  >{{contentItem.value}}、{{contentItem.txt}}</text
                >
                <!-- 仅图片 -->
                <view wx:if="{{item.optionStyle == 'Image'}}" class="fl-center">
                  <text>{{contentItem.value}}、</text>
                  <t-image src="{{contentItem.img}}"></t-image>
                </view>
                <!-- 文字加图片 -->
                <view
                  wx:if="{{item.optionStyle == 'TxtAndImage'}}"
                  class="fl-center"
                >
                  <text>{{contentItem.value}}、</text>
                  <text>{{contentItem.txt}}</text>
                  <t-image src="{{contentItem.img}}"></t-image>
                </view>
                <!-- 富文本 -->
                <view wx:if="{{item.optionStyle == 'RichText'}}">
                  <text>{{contentItem.value}}、</text>
                  <rich-text nodes="{{contentItem.txt}}"></rich-text>
                </view>
                <text
                  wx:if="{{item.answer == contentItem.value && item.answer == item.userAnswer}}"
                  >对</text
                >
                <text
                  wx:if="{{item.userAnswer == contentItem.value && item.userAnswer != item.answer}}"
                  >错</text
                >
              </view>
            </t-radio>
          </view>
        </t-radio-group>
        <!-- 多选题 -->
        <t-checkbox-group
          disabled="{{item.isComplete}}"
          class="checkbox-group"
          wx:elif="{{item.questionType == 'multipleChoice'}}"
          t-class="box"
          borderless
          bind:change="onChangeRadio"
          data-value="{{item.option}}"
          data-id="{{item.id}}"
          defaultValue="{{item.userAnswer}}"
        >
          <view
            wx:for="{{item.option}}"
            wx:for-item="contentItem"
            wx:for-index="contentIndex"
            wx:key="contentIndex"
          >
            <t-checkbox block="{{false}}" value="{{contentItem.value}}">
              <!-- 仅文字 -->
              <text wx:if="{{item.optionStyle == 'Txt'}}"
                >{{contentItem.value}}、{{contentItem.txt}}</text
              >
              <!-- 仅图片 -->
              <view wx:if="{{item.optionStyle == 'Image'}}" class="fl-center">
                <text>{{contentItem.value}}、</text>
                <t-image src="{{contentItem.img}}"></t-image>
              </view>
              <!-- 文字加图片 -->
              <view
                wx:if="{{item.optionStyle == 'TxtAndImage'}}"
                class="fl-center"
              >
                <text>{{contentItem.value}}、</text>
                <text>{{contentItem.txt}}</text>
                <t-image src="{{contentItem.img}}"></t-image>
              </view>
              <!-- 富文本 -->
              <view wx:if="{{item.optionStyle == 'RichText'}}">
                <text>{{contentItem.value}}、</text>
                <rich-text nodes="{{contentItem.txt}}"></rich-text>
              </view>
            </t-checkbox>
          </view>
        </t-checkbox-group>
        <!-- 简答 翻译 -->
        <t-textarea
          disabled="{{item.isComplete}}"
          value="{{item.userAnswer}}"
          bind:change="onChangeRadio"
          data-value="{{item.option}}"
          data-id="{{item.id}}"
          class="option-textarea"
          wx:elif="{{item.questionType == 'shortAnswer'}}"
          t-class="external-class"
          placeholder="请输入文字"
          bordered
          maxlength="500"
          disableDefaultPadding="{{true}}"
          indicator
          style="{{style}}"
        />
      </view>
      <!-- 解析 -->
      <view class="analysis" wx:if="{{item.isComplete}}">
        <view class="analysis-answer">
          <view class="answer-correct">
            <text class="analysis-title-box">正确答案:</text>
            <rich-text
              nodes="{{item.answer}}"
              style="font-size: 40rpx"
            ></rich-text>
          </view>
          <view class="answer-error">
            <text class="analysis-title-box">您的答案:</text
            ><text class="answer-text">{{item.userAnswer}}</text>
          </view>
        </view>
        <view class="analysis-text" wx:if="{{item.analysisCon}}">
          答案解析:<rich-text
            nodes="{{item.analysisCon}}"
            class="analysis-content"
          ></rich-text>
        </view>
      </view>
    </swiper-item>
    <swiper-item>
      <text>没有更多了。。。</text>
    </swiper-item>
  </swiper>
</view>
pages/bookServices/examination/questionList/index.wxss
@@ -23,3 +23,128 @@
.title-score {
  color: #000;
}
.question-stem {
  font-size: 32rpx;
  font-weight: bold;
  display: flex;
  margin-bottom: 20rpx;
}
.swiper {
  min-height: 900rpx;
}
/* 单选题 */
.radio-group {
  margin-top: 20rpx;
  --td-radio-vertical-padding: 12rpx
}
.radio-item {
  padding: 0 32rpx;
  min-height: 98rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: #F9F9F9;
}
.radio-correct {
  background-color: #EAF7EE;
}
.radio-error {
  background-color: #FFEBEB;
}
.question-stem image {
  margin-left: 20rpx;
  width: 300rpx;
  object-fit: contain;
  height: 200rpx;
}
.title-RichText img {
  width: 300rpx;
  height: 200rpx;
}
.question-answer image {
  margin: 10rpx 0 10rpx 10rpx;
  width: 180rpx;
  height: 120rpx;
}
.fl-center {
  display: flex;
  align-items: center;
}
.checkbox-group {
  --td-checkbox-icon-checked-color: #ff6c00;
}
.t-checkbox {
  display: flex;
  align-items: center;
}
.completion-box {
  display: inline-block;
}
.title-input {
  /* display: inline-block; */
  height: 40rpx;
  --td-input-vertical-padding: 16rpx
}
.option-textarea {
  width: 97%;
}
/* 解析 */
.analysis {
  margin-top: 40rpx;
}
.analysis-answer {
  display: flex;
  justify-content: space-between;
}
.answer-correct {
  color: #1FBC1F;
}
.answer-error {
  color: #EE1818;
}
.answer-text {
  font-size: 40rpx;
}
.answer-correct {
  display: flex;
}
.analysis-title-box {
  display: inline-block;
  width: 160rpx;
  height: 52rpx;
  white-space: nowrap;
}
.analysis-content {
  display: inline-block
}
.analysis-text {
  color: #333333;
  font-size: 28rpx;
  margin-top: 20rpx;
}
pages/bookServices/examination/questionOptions/index.js
@@ -1,10 +1,50 @@
// pages/bookServices/examination/questionOptions/index.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    currentIndex: {
      type: Number,
      value: 0,
    },
    questionDataList: {
      type: Array,
      value: []
    },
    cardList: {
      type: Array,
      value: []
    },
    subjectiveTotal: {
      type: Number,
      value: 0
    },
    countdownTime: {
      type: Number,
      value: 0,
    },
    answerType: {
      type: String,
      value: ''
    },
    subjectiveNum: {
      type: Number,
      value: 0
    },
    subjectiveGrade: {
      type: Number,
      value: 0
    },
    correctNum: {
      type: Number,
      value: 0
    },
    submitStatus: {
      type: Boolean,
      value: false
    }
  },
  /**
@@ -12,12 +52,212 @@
   */
  data: {
    btnStyle: "width:320rpx;border-radius:60rpx",
    noReady: 0,
    questionCardState: false,
    setUpPopup: false,
    testReportState: false,
    sliderValue: 0,
    useTime: ''
  },
  observers: {
    "countdownTime": function (newValue, oldValue) {
      if (this.properties.answerType == 'option') {
        this.setData({
          useTime: this.formatTime(2 * 60 * 60 * 1000 - this.properties.countdownTime)
        })
      }
      if (newValue == 0 && (this.properties.answerType == 'option' || this.properties.answerType == 'mock')) {
        this.timeout()
      }
    },
  },
  created() {
  },
  /**
   * 组件的方法列表
   */
  methods: {
    // // 格式化时间
    formatTime(ms) {
      const hours = Math.floor((ms / (1000 * 60 * 60)) % 24)
        .toString()
        .padStart(2, '0')
      const minutes = Math.floor((ms / (1000 * 60)) % 60)
        .toString()
        .padStart(2, '0')
      const seconds = Math.floor((ms / 1000) % 60)
        .toString()
        .padStart(2, '0')
      return `${hours}:${minutes}:${seconds}`
    },
    // 判断是否输入答案
    isHaveAnswer(data) {
      if (typeof data == 'string') {
        data = data
          .replace(/<[^>]*>/g, '')
          .replace(/&nbsp;/g, '')
          .trim()
        if (data.length) {
          return true
        } else {
          return false
        }
      } else {
        const answer = data.find((item) => item.length > 0)
        if (answer) {
          return true
        } else {
          return false
        }
      }
    },
    setCollect() {
      var myEventDetail = {
      }
      var myEventOption = {
        bubbles: true,
        composed: true,
      }
      this.triggerEvent('setCollect', myEventDetail, myEventOption)
    },
    // 答题卡按钮
    handlePopup() {
      this.setData({
        questionCardState: true
      })
    },
    // 答题卡跳转题目
    goQuestion(e) {
      var myEventDetail = {
        id: e.currentTarget.dataset.id
      }
      var myEventOption = {
        bubbles: true,
        composed: true,
      }
      this.triggerEvent('goQuestion', myEventDetail, myEventOption)
    },
    // 答题卡遮罩层点击
    onVisibleChange(e) {
      this.setData({
        questionCardState: e.detail.visible,
      });
    },
    // 设置按钮
    setUpBtn() {
      this.setData({
        setUpPopup: true
      })
    },
    // 滑块变化
    onChangeSlider(e) {
      console.log(e);
      this.setData({
        sliderValue: e.detail.value
      })
    },
    // 设置遮罩层点击
    onSetUpChange(e) {
      this.setData({
        setUpPopup: e.detail.visible
      })
    },
    // 重做按钮
    resterBtn() {
      wx.showModal({
        title: '提示',
        content: '是否重新开始答题?',//editable如果为true,这就是输入框的内容
        editable: false,//是否显示输入框
        success: (res) => {
          if (res.confirm) {
            this.restart()
          }
        }
      })
    },
    // 重做事件
    restart() {
      var myEventDetail = {
      }
      var myEventOption = {
        bubbles: true,
        composed: true,
      }
      this.triggerEvent('restart', myEventDetail, myEventOption)
    },
    // 还有N道题未做弹窗
    confrimPromptDialog() {
      wx.showModal({
        title: '提示',
        content: `您还有 ${this.data.noReady}道题未答,是否提交?`,//editable如果为true,这就是输入框的内容
        editable: false,//是否显示输入框
        success: (res) => {
          if (res.confirm) {
            this.submitPaper()
          }
        }
      })
    },
    // 底部提交按钮
    submitBtn() {
      // 我的错题和收藏  直接走提交逻辑
      if (this.properties.answerType !== 'option' || this.properties.answerType !== 'option') {
        return this.submitPaper()
      }
      this.properties.questionDataList.forEach(item => {
        if (!this.isHaveAnswer(item.userAnswer)) {
          this.setData({
            noReady: this.data.noReady + 1
          })
        }
      })
      // 未做完,打开提示弹窗
      if (this.data.noReady > 0) {
        this.confrimPromptDialog()
      } else {
        // 做完了直接执行提交事件
        this.submitPaper()
      }
    },
    // 提交事件
    submitPaper() {
      var myEventDetail = {
      }
      var myEventOption = {
        bubbles: true,
        composed: true,
      }
      this.triggerEvent('submitPaper', myEventDetail, myEventOption)
    },
    // 打开测试报告弹窗
    openTestReportDialog() {
      this.setData({
        testReportState: true
      })
    },
    // 关闭测试报告弹窗
    closeTestReportDialog(e) {
      this.setData({
        testReportState: false
      })
    },
    // 测试报告弹窗查看答案解析按钮
    viewAnswer() {
      this.closeTestReportDialog()
    },
    // 答题时间到
    timeout() {
      wx.showModal({
        title: '提示',
        content: '答题时间已到',//editable如果为true,这就是输入框的内容
        editable: false,//是否显示输入框
        showCancel: false,
        success: (res) => {
        }
      })
      this.submitPaper()
    }
  }
})
pages/bookServices/examination/questionOptions/index.json
@@ -3,6 +3,9 @@
  "usingComponents": {
    "t-icon": "tdesign-miniprogram/icon/icon",
    "t-image": "tdesign-miniprogram/image/image",
    "t-button": "tdesign-miniprogram/button/button"
    "t-button": "tdesign-miniprogram/button/button",
    "t-dialog": "tdesign-miniprogram/dialog/dialog",
    "t-popup": "tdesign-miniprogram/popup/popup",
    "t-slider": "tdesign-miniprogram/slider/slider"
  }
}
pages/bookServices/examination/questionOptions/index.wxml
@@ -1,24 +1,155 @@
<!--pages/bookServices/examination/questionOptions/index.wxml-->
<view class="page-bottom">
  <view class="li-option">
    <t-image src="/static/images/bookService/examination/collect.png"></t-image>
  <view class="li-option" bind:tap="setCollect">
    <t-image
      src="{{ questionDataList[currentIndex].isCollect ? '/static/images/bookService/detail/collecting.png' : '/static/images/bookService/examination/collect.png'}}"
    >
    </t-image>
    收藏
  </view>
  <view class="li-option">
  <view class="li-option" bind:tap="handlePopup">
    <t-image
      src="/static/images/bookService/examination/questionCard.png"
    ></t-image>
    答题卡
  </view>
  <view class="li-option">
  <view class="li-option" bind:tap="setUpBtn">
    <t-image src="/static/images/bookService/examination/setting.png"></t-image>
    设置
  </view>
  <view class="li-option">
  <view
    class="li-option"
    bind:tap="resterBtn"
    wx:if="{{answerType == 'option' || answerType == 'mock'}}"
  >
    <t-image src="/static/images/bookService/examination/reset.png"></t-image>
    重做
  </view>
  <view class="bottom-submit">
    <t-button theme="primary" size="large" style="{{btnStyle}}">提交</t-button>
    <t-button
      theme="primary"
      size="large"
      style="{{btnStyle}}"
      bind:tap="submitBtn"
      >{{(answerType == 'option' || answerType == 'mock') ? '提交' :
      '退出'}}</t-button
    >
  </view>
</view>
<!-- 答题卡 -->
<t-popup
  visible="{{questionCardState}}"
  bind:visible-change="onVisibleChange"
  placement="bottom"
>
  <view class="popup-block">
    <view class="popup-header">
      <view class="popup-title">答题卡</view>
    </view>
    <view class="question-explain">
      <view class="explain-answered">
        <text class="answered explain-color-box"></text>
        <text>已答</text>
      </view>
      <view class="explain-un-answered">
        <text class="un-answered explain-color-box"></text>
        <text>未答</text>
      </view>
    </view>
    <view class="question-card-list">
      <view wx:for="{{cardList}}" class="card-box">
        <!-- 题型 -->
        <view class="question-title">
          <text class="color-box"></text>
          <text class="title-text">{{item.catalogName}}</text>
        </view>
        <view class="question-list">
          <view
            bind:tap="goQuestion"
            data-id="{{citem.id}}"
            wx:for="{{item.infoList}}"
            wx:for-item="citem"
            wx:for-index="cindex"
            class="question-box {{citem.isComplete ? 'answered' : 'un-answered'}}"
          >
            {{citem.number}}
          </view>
        </view>
      </view>
    </view>
  </view>
</t-popup>
<!-- 设置 -->
<t-popup
  visible="{{setUpPopup}}"
  bind:visible-change="onSetUpChange"
  placement="bottom"
>
  <view class="popup-block set-up-popup">
    <view class="popup-header">
      <view class="popup-title">设置</view>
    </view>
    <!-- 亮度 -->
    <view>
      <t-slider defaultValue="{{30}}" theme="capsule" />
    </view>
    <!-- 模式 -->
  </view>
</t-popup>
<!-- 测试报告 -->
<t-dialog
  class="test-report"
  visible="{{testReportState}}"
  cancel-btn="{{null}}"
  confirm-btn="{{null}}"
  close-btn="{{true}}"
  title="测试报告"
  bind:close="closeTestReportDialog"
>
  <view slot="content" class="test-report">
    <view class="report-content-top">
      <view class="report-li">
        <view class="report-li-left">题目总数:</view>
        <view class="report-li-right">{{questionDataList.length}}道</view>
      </view>
      <view class="report-li">
        <view class="report-li-left">用时:</view>
        <view class="report-li-right">{{useTime}}</view>
      </view>
      <view class="report-li">
        <view class="report-li-left">其中客观题:</view>
        <view class="report-li-right"
          >{{subjectiveTotal}}道,分值{{subjectiveGrade}}分</view
        >
      </view>
      <view class="report-li">
        <view class="report-li-left">答对:</view>
        <view class="report-li-right"
          ><text class="correct-color">{{correctNum}}</text> 道</view
        >
      </view>
      <view class="report-li">
        <view class="report-li-left">答错:</view>
        <view class="report-li-right"
          ><text class="error-color">{{subjectiveTotal - correctNum}}</text>
          道</view
        >
      </view>
      <view class="report-li">
        <view class="report-li-left">客观题得分:</view>
        <view class="report-li-right"
          ><text class="score-color">{{subjectiveNum}}</text> 分</view
        >
      </view>
    </view>
    <view class="report-content-bottom">
      <t-button theme="primary" bind:tap="viewAnswer" style="width: 560rpx"
        >查看答案与解析</t-button
      >
    </view>
  </view>
</t-dialog>
pages/bookServices/examination/questionOptions/index.wxss
@@ -29,3 +29,159 @@
  --td-button-primary-active-bg-color: #ff984d;
  --td-button-primary-active-border-color: #ff984d;
}
/* 答题卡 */
.popup-block {
  width: 100vw;
  height: 700rpx;
  background: #fff;
  border-top-left-radius: 16rpx;
  border-top-right-radius: 16rpx;
}
.popup-header {
  display: flex;
  align-items: center;
  height: 116rpx;
}
.popup-title {
  color: #333;
  flex: 1;
  text-align: center;
  font-weight: 600;
  font-size: 36rpx;
}
.question-card-list {
  padding: 0 20rpx;
  height: 100%;
  overflow-y: auto;
}
.question-title {
  margin-top: 40rpx;
  display: flex;
  align-items: center;
}
.question-explain {
  padding-right: 40rpx;
  display: flex;
  justify-content: flex-end;
}
.explain-un-answered {
  margin-left: 80rpx;
}
.explain-answered,
.explain-un-answered {
  display: flex;
  align-items: center;
}
.explain-color-box {
  width: 30rpx;
  height: 30rpx;
  border-radius: 5rpx;
  display: inline-block;
  margin-right: 10rpx;
}
.color-box {
  display: inline-block;
  width: 8rpx;
  height: 60rpx;
  background-color: #ff6c00;
  border-radius: 0 10rpx 10rpx 0;
}
.title-text {
  color: #333;
  margin-left: 10rpx;
}
.card-box:last-child {
  margin-bottom: 200rpx;
}
.question-list {
  margin: 46rpx 0 64rpx 0;
  display: flex;
  flex-wrap: wrap;
}
.question-box {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 38rpx 20rpx 0 0;
  width: 126rpx;
  height: 62rpx;
  font-size: 34rpx;
}
.question-box:nth-child(5n) {
  margin-right: 0;
}
.answered {
  background-color: #FF6C00;
  color: #fff;
}
.un-answered {
  background-color: #F1F3F8;
  color: #B4B6BD;
}
/* 设置 */
.set-up-popup {
  height: 400rpx;
}
/* 测试报告 */
.test-report {
  --td-dialog-width: 660rpx
}
.report-content-top {
  padding-top: 40rpx;
}
.report-li {
  display: flex;
  color: #333;
  margin-bottom: 44rpx;
}
.report-li-left {
  width: 192rpx;
}
.report-li-right {
  margin-left: 120rpx;
}
.report-content-bottom {
  --td-button-border-radius: 60rpx;
  --td-button-primary-bg-color: #fff;
  --td-button-primary-color: #ff6c00;
  --td-button-primary-border-color: #ff6c00;
  --td-button-primary-active-bg-color: #fff0e6;
  --td-button-primary-active-border-color: #ff6c00;
}
.correct-color {
  color: #1FBC1F;
}
.error-color {
  color: #EE1818;
}
.score-color {
  color: #ff6c00;
}
pages/bookServices/examination/questionSchedule/index.js
@@ -5,45 +5,87 @@
   * 组件的属性列表
   */
  properties: {
    questionList: {
      type: Array,
      value: []
    },
    submitStatus: {
      type: Boolean,
      value: false
    },
    currentIndex: {
      type: Number,
      value: 1
    },
    countdownTime: {
      type: Number,
      value: 0
    },
    answerType: {
      type: String,
      value: ''
    }
  },
  created() {
    // if (props.answerType == 'option') {
    // this.startCountdown()
    this.setData({
      countdownTime: 2 * 60 * 60 * 1000
    })
    // }
  },
  detached() {
    if (this.data.countdownInterval !== null) {
      clearInterval(this.data.countdownInterval)
    }
  },
  /**
   * 组件的初始数据
   */
  data: {
    countdownInterval: null,   // 计时器
    isCountdownRunning: true, // 是否倒计时
    countdownTime: "",  // 时间
    showTime: '',
    showTime: '', //
    percentage: 0,
    ready: 0
  },
  observers: {
    'countdownTime': function (newValue, oldValue) {
      const showTime = this.formatTime(this.data.countdownTime)
    'countdownTime': function (newValue) {
      const showTime = this.formatTime(this.properties.countdownTime)
      this.setData({
        showTime: showTime
      })
      console.log(this.data.showTime);
    },
    'questionList': function (newValue) {
      this.setData({
        ready: 0
      })
      for (let index = 0; index < newValue.length; index++) {
        const item = newValue[index];
        if (this, this.isHaveAnswer(item.userAnswer)) {
          this.setData({
            ready: this.data.ready + 1
          })
        }
      }
    }
  },
  /**
   * 组件的方法列表
   */
  methods: {
    // 格式化时间
    // 判断是否有用户答案
    isHaveAnswer(data) {
      if (typeof data == 'string') {
        data = data
          .replace(/<[^>]*>/g, '')
          .replace(/&nbsp;/g, '')
          .trim()
        if (data.length) {
          return true
        } else {
          return false
        }
      } else {
        const answer = data.find((item) => item.length > 0)
        if (answer) {
          return true
        } else {
          return false
        }
      }
    },
    // // 格式化时间
    formatTime(ms) {
      const hours = Math.floor((ms / (1000 * 60 * 60)) % 24)
        .toString()
@@ -56,60 +98,60 @@
        .padStart(2, '0')
      return `${hours}:${minutes}:${seconds}`
    },
    // 获取保存的倒计时时间
    getSavedTime() {
      const savedTime = wx.getStorageSync('countdownTime')
      return savedTime ? parseInt(savedTime) : null
    },
    // 保存倒计时时间到本地存储
    saveTime() {
      wx.setStorageSync('countdownTime', this.data.countdownTime.toString())
    },
    clearTime() {
      this.setData({
        countdownTime: 2 * 60 * 60 * 1000
      })
    },
    // 暂停或继续倒计时
    toggleCountdown() {
      if (countdownInterval) {
        clearInterval(this.data.countdownInterval)
        this.setData({
          countdownInterval: null,
          isCountdownRunning: false
        })
      } else {
        this.startCountdown()
        this.setData({
          isCountdownRunning: true
        })
      }
    },
    // 开始倒计时
    startCountdown() {
      // 如果计时器已经存在,先清除之前的计时器
      if (this.data.countdownInterval) {
        clearInterval(this.data.countdownInterval)
        this.setData({
          countdownInterval: null
        })
      }
      this.setData({
        countdownInterval: setInterval(() => {
          this.setData({
            countdownTime: this.data.countdownTime - 1000
          })
          if (this.data.countdownTime <= 0) {
            clearInterval(this.data.countdownInterval)
            this.setData({
              countdownTime: 0,
              isCountdownRunning: false
            })
          }
          this.saveTime()
        }, 1000)
      })
    // // 获取保存的倒计时时间
    // getSavedTime() {
    //   const savedTime = wx.getStorageSync('countdownTime')
    //   return savedTime ? parseInt(savedTime) : null
    // },
    // // 保存倒计时时间到本地存储
    // saveTime() {
    //   wx.setStorageSync('countdownTime', this.data.countdownTime.toString())
    // },
    // clearTime() {
    //   this.setData({
    //     countdownTime: 2 * 60 * 60 * 1000
    //   })
    // },
    // // 暂停或继续倒计时
    // toggleCountdown() {
    //   if (countdownInterval) {
    //     clearInterval(this.data.countdownInterval)
    //     this.setData({
    //       countdownInterval: null,
    //       isCountdownRunning: false
    //     })
    //   } else {
    //     this.startCountdown()
    //     this.setData({
    //       isCountdownRunning: true
    //     })
    //   }
    // },
    // // 开始倒计时
    // startCountdown() {
    //   // 如果计时器已经存在,先清除之前的计时器
    //   if (this.data.countdownInterval) {
    //     clearInterval(this.data.countdownInterval)
    //     this.setData({
    //       countdownInterval: null
    //     })
    //   }
    //   this.setData({
    //     countdownInterval: setInterval(() => {
    //       this.setData({
    //         countdownTime: this.data.countdownTime - 1000
    //       })
    //       if (this.data.countdownTime <= 0) {
    //         clearInterval(this.data.countdownInterval)
    //         this.setData({
    //           countdownTime: 0,
    //           isCountdownRunning: false
    //         })
    //       }
    //       this.saveTime()
    //     }, 1000)
    //   })
    }
    // }
  }
})
pages/bookServices/examination/questionSchedule/index.wxml
@@ -1,11 +1,17 @@
<!--pages/bookServices/examination/questionSchedule/questionSchedule.wxml-->
<view class="schedule">
  <view class="schedule-top">
    <view class="question-schedule">答题进度<text class="parimary-color question-num">1</text> <text>/18</text></view>
    <view class="remainder">剩余时间 <text class="parimary-color">{{showTime}}</text></view>
    <view class="question-schedule"
      >答题进度<text class="parimary-color question-num">{{ready}}</text>
      <text>/{{questionList.length}}</text></view
    >
    <view
      class="remainder"
      wx:if="{{!submitStatus && (answerType == 'option' || answerType == 'mock')}}"
      >剩余时间 <text class="parimary-color">{{showTime}}</text></view
    >
  </view>
  <view class="schedule-progress">
    <t-progress percentage="80" color="#ff6c00" label="" />
    <t-progress percentage="{{percentage}}" color="#ff6c00" label="" />
  </view>
</view>
pages/bookServices/webpage/index.js
New file
@@ -0,0 +1,69 @@
// pages/bookServices/webpage/index.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
    url: ''
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    console.log(options);
    this.setData({
      url: options.url
    })
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {
  },
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
  },
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
  },
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {
  }
})
pages/bookServices/webpage/index.json
New file
@@ -0,0 +1,3 @@
{
  "usingComponents": {}
}
pages/bookServices/webpage/index.wxml
New file
@@ -0,0 +1,2 @@
<!--pages/bookServices/webpage/index.wxml-->
<web-view src="{{url}}"></web-view>
pages/bookServices/webpage/index.wxss
New file
@@ -0,0 +1 @@
/* pages/bookServices/webpage/index.wxss */
pages/cart/index.js
@@ -1,6 +1,7 @@
const app = getApp();
// import { getPublicImage } from '@/assets/js/middleGround/tool.js'
import { getPublicImage } from '../../assets/js/middleGround/tool';
import Toast from 'tdesign-miniprogram/toast/index';
Page({
  data: {
@@ -9,7 +10,8 @@
    checkAll: false,
    checkedList: [],
    selectedCount: 0,
    totalPrice: 0.00
    totalPrice: 0.00,
    type: ''
  },
  onLoad(options) {
@@ -39,6 +41,12 @@
    app.MG.store.getShoppingCartProductList(query).then(res => {
      res.datas.forEach(item => {
        item.imgUrl = getPublicImage(item.productMonWithLinkDto.product.icon, '', '160');
        console.log(item);
        console.log(item.saleMethod.type, 'item.saleMethod.type')
        this.setData({
          type: item.saleMethod.type == 'createProductItemSaleMethod' ? 'item' : 'product'
        })
      });
      this.setData({
@@ -98,22 +106,29 @@
    });
  },
  goPaymentPage() {
    const selectedItems = this.data.shoppingCartData.filter(item => item.checked);
    console.log(selectedItems, 789);
    // console.log(selectedItems, 789);
    const selectedIds = selectedItems.map(item => item.id);
    console.log('选中的商品 id:', selectedIds);
    if (selectedIds.length) {
    app.MG.store.shoppingCartCreateOrder({ linkIds: selectedIds }).then(res => {
      console.log(res.orderNumber, 456);
        console.log(res, 456);
      const url = '/pages/cart/paymentPage/index?orderNumber=' + res.orderNumber
      wx.navigateTo({
        url
      });
    })
    } else {
      Toast({
        context: this,
        selector: '#t-toast',
        message: '请选择商品',
        theme: 'warning',
        direction: 'column',
      });
    }
  }
pages/cart/index.json
@@ -4,6 +4,8 @@
    "t-checkbox": "tdesign-miniprogram/checkbox/checkbox",
    "t-swipe-cell": "tdesign-miniprogram/swipe-cell/swipe-cell",
    "t-cell": "tdesign-miniprogram/cell/cell",
    "t-button": "tdesign-miniprogram/button/button"
    "t-button": "tdesign-miniprogram/button/button",
    "t-toast": "tdesign-miniprogram/toast/toast",
    "t-empty": "tdesign-miniprogram/empty/empty"
  }
}
pages/cart/index.wxml
@@ -1,18 +1,51 @@
<view class="outsideContentBox">
  <!-- <checkbox-group bindchange="HandelItemChange"> -->
  <view wx:if="{{!shoppingCartData}}" class="noDataBox">
    <t-empty icon="folder-open" description="暂无数据" font-size="80" />
  </view>
  <t-swipe-cell wx:for="{{shoppingCartData}}" wx:key="index" wx:for-item="item" wx:for-index="index">
    <!-- <view class="contentBox"> -->
    <!-- <view class="contentCheckbox">
          <checkbox value="{{item.id}}" checked="{{item.checked}}"></checkbox>
        </view> -->
    <view class="itemWarp">
      <t-cell bordered="{{false}}" title="{{item.productMonWithLinkDto.product.name}}" description="¥{{item.saleMethod.price}}">
      <t-cell bordered="{{false}}">
        <view slot="title" class="titleBox">
          <view class="labelBox">
            <view class="eBook" wx:if="{{type == 'product'}}">电子书</view>
            <view wx:if="{{type == 'item'}}" class="cloudLearning">云学习</view>
          </view>
          <view class="boosName">
            {{item.productMonWithLinkDto.product.name}}
          </view>
        </view>
        <view slot="description" class="descriptionBox">
          <view>
            <view class="textBox" wx:if="{{type == 'product'}}">图书服务-电子书</view>
            <view class="textBox" wx:if="{{type == 'item'}}">图书服务-云学习</view>
          </view>
          <view wx:if="{{item.saleMethod.price != 0}}">
            ¥{{item.saleMethod.price}}
          </view>
          <view wx:else class="descriptionBox"> 立即领取</view>
        </view>
        <view slot="left-icon" class="left-icon">
          <view class="contentCheckbox">
            <t-checkbox icon="rectangle" value=" {{item.id}}" data-item="{{item}}" checked="{{item.checked}}" bindchange="HandelItemChange" />
          </view>
          <view class="left-image">
            <image src="{{item.imgUrl}}" class="imageStyle" mode="" />
            <image src="{{item.imgUrl}}" class="imageStyle" mode="aspectFit" />
          </view>
        </view>
      </t-cell>
@@ -36,3 +69,5 @@
    </view>
  </view>
</view>
<t-toast id="t-toast" />
pages/cart/index.wxss
@@ -56,25 +56,24 @@
.settlementBox {
  /* width: 100%; */
  width: 80%;
  display: flex;
  align-items: center;
  /* justify-content: space-between; */
}
.totalPrice {
  flex: 1;
  /* margin: 0 50rpx; */
}
.buttonBox {
  /* margin: 0 30rpx; */
  margin-left: 140rpx;
  margin-right: 80rpx;
}
.tButtonBox {
  background-color: #FF6C00;
  /* background-color: #FF6C00; */
  width: 200rpx;
  height: 80rpx;
}
@@ -167,3 +166,84 @@
  width: 100%;
  height: 100%;
}
.t-checkbox {
  --td-checkbox-icon-checked-color: #FF6C00;
}
.t-checkbox--block {
  padding: 0 !important;
}
.t-button--default {
  background-color: #FF6C00 !important;
}
.noDataBox {
  width: 100%;
  margin-top: 200rpx;
  display: flex;
  justify-content: center;
  align-items: center;
}
page {
  background: #F2F3F8;
}
.titleBox {
  display: flex;
  flex-direction: row;
  margin: 15rpx;
}
.descriptionBox {
  margin: 15rpx;
}
.labelBox {
  width: 125rpx;
  height: 38rpx;
  font-size: 22rpx;
  color: #FFFFFF;
  font-family: PingFang SC, PingFang SC;
  /* margin-right: 30rpx; */
  border-radius: 0px 0px 0px 5px;
}
.eBook {
  width: 90%;
  height: 100%;
  background: #FF6C00;
  text-align: center;
  line-height: 38rpx;
  border-radius: 9rpx;
}
.cloudLearning {
  width: 100%;
  height: 100%;
  background: #5F92FD;
  text-align: center;
  line-height: 38rpx;
}
.boosName {
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}
.textBox {
  font-family: PingFang SC, PingFang SC;
  font-weight: 400;
  font-size: 25rpx;
  color: #333333;
  /* margin: 10rpx 0; */
  margin-bottom: 20rpx;
}
pages/cart/paymentPage/index.js
@@ -143,6 +143,7 @@
      }
    }
    app.MG.store.getOrderByOrderNum(query).then(res => {
      console.log(res, 'res');
      this.setData({
        orderGoods: res.orderNumber
      })
@@ -155,10 +156,11 @@
      res.saleMethodLinks.forEach(item => {
        item.paymentIcon = getPublicImage(item.orderSaleMethod.product.icon)
        console.log(item.orderSaleMethod.type);
        this.setData({
          productList: res.saleMethodLinks
          productList: res.saleMethodLinks,
          type: item.orderSaleMethod.type == 'createProductItemSaleMethod' ? 'item' : 'product'
        })
      })
pages/cart/paymentPage/index.wxml
@@ -1,4 +1,5 @@
<!--pages/cart/paymentPage/index.wxml-->
<!-- 头部 -->
<view class="titleBox">
<view style="width: 100%; height: {{barHeight}}px; "></view>
<view class="nacigationBar" style="width: 70%; height: {{navBarHeight}}px;">
  <view>
@@ -6,21 +7,10 @@
  </view>
  <view class="navbar-title">提交订单</view>
</view>
</view>
<view class="paymentPageBox">
<view class="content">
  <!--
  <t-button t-class="wrapper" theme="primary" size="large" variant="outline" data-key="showCloseBtn" bind:tap="showDialog" block>
    带关闭按钮
  </t-button> -->
  <t-dialog visible="{{showCloseBtn}}" close-btn bind:confirm="closeDialog" bind:cancel="closeDialog">
    <view slot="content" class="slotContent">
      <view class="myQrcodeBox">
@@ -30,25 +20,32 @@
    </view>
  </t-dialog>
  <view class="shoppingCartList">
    <view class="cartList" wx:for="{{productList}}" wx:key="index" wx:for-item="item" wx:for-index="index">
      <image src="{{item.paymentIcon }}" mode="" />
        <view class="imageBox">
          <image src="{{item.paymentIcon }}" mode="aspectFill" />
        </view>
      <view class="cartListContent">
        <view class="cartListDetails">{{item.orderSaleMethod.product.name}}</view>
        <view class="textBox">图书服务-电子书</view>
          <view class="cartListDetails">
            <view class="labelBox">
              <view class="eBook" wx:if="{{type == 'product'}}">电子书</view>
              <view wx:if="{{type == 'item'}}" class="cloudLearning">云学习</view>
            </view>
            <view class="boosName">
              {{item.orderSaleMethod.product.name}}
            </view>
          </view>
          <view class="textBox" wx:if="{{type == 'product'}}">图书服务-电子书</view>
          <view class="textBox" wx:if="{{type == 'item'}}">图书服务-云学习</view>
        <view class="priceBox">¥{{item.payPrice}}</view>
      </view>
    </view>
  </view>
  <view class="priceBreakdown">
    <view class="priceBreakdownContent">价格明细</view>
    <view class="amountMoney">
@@ -60,15 +57,12 @@
    </view>
  </view>
  <view class="interval"></view>
  </view>
  <!-- <view class="interval"></view> -->
  <view class="paymentBox">
    <view class="residue">待支付:<text class="residueTextBox">¥{{payPrice}}</text></view>
    <view>
      <t-button class="buttonBox" shape="round" bind:tap="confirmOrderGet">微信支付</t-button>
    </view>
  </view>
</view>
pages/cart/paymentPage/index.wxss
@@ -18,23 +18,30 @@
.content {
  width: 100%;
  height: 1250rpx;
  background-color: #F2F3F8;
  padding: 40rpx 0;
  padding-top: 1rpx;
  margin-top: 110rpx;
}
.shoppingCartList {
  height: 1000rpx;
  min-height: 150rpx;
  background: #FFFFFF;
  border-radius: 20px;
  margin: 30rpx 0;
}
image {
.imageBox {
  width: 150rpx;
  height: 210rpx;
  margin: 30rpx;
}
image {
  width: 150rpx;
  height: 210rpx;
}
.cartListContent {
@@ -55,6 +62,10 @@
  font-weight: bold;
  font-size: 29rpx;
  color: #333333;
  display: flex;
  flex-direction: row;
  padding: 0 10rpx;
}
.textBox {
@@ -70,14 +81,18 @@
  font-weight: 500;
  font-size: 31rpx;
  color: #0F1214;
  font-family: DIN, DIN;
}
.priceBreakdown {
  height: 280rpx;
  height: 250rpx;
  background: #fff;
  padding: 30rpx;
  margin-bottom: 120rpx;
}
.priceBreakdownContent {
@@ -117,6 +132,10 @@
  justify-content: space-between;
  padding: 30rpx;
  align-items: center;
  background-color: #fff;
  width: 100%;
  position: fixed;
  bottom: 0;
}
.residue {
@@ -132,6 +151,7 @@
.buttonBox {
  background-color: #FF6C00;
  border: #fff;
  margin-right: 80rpx;
}
.myQrcodeBox {
@@ -142,3 +162,55 @@
  text-align: center;
  margin: 30rpx 0;
}
.paymentPageBox {}
page {
  background-color: #F2F3F8;
  position: relative;
}
.titleBox {
  background-color: #fff;
  position: fixed;
  top: 0;
  width: 100%;
}
.eBook {
  width: 90%;
  height: 100%;
  background: #FF6C00;
  text-align: center;
  line-height: 38rpx;
  border-radius: 9rpx;
}
.cloudLearning {
  width: 100%;
  height: 100%;
  background: #5F92FD;
  text-align: center;
  line-height: 38rpx;
  border-radius: 9rpx;
}
.labelBox {
  width: 105rpx;
  height: 38rpx;
  font-size: 22rpx;
  color: #FFFFFF;
  font-family: PingFang SC, PingFang SC;
}
.boosName {
  width: 300rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}
pages/home/home.js
@@ -4,6 +4,7 @@
const app = getApp()
Page({
  data: {
    searchVal: '',
    isWhite: false,
    backUrl: null,
    userInfo: {},
@@ -513,6 +514,16 @@
      isWhite: e.scrollTop > 50 ? true : false
    })
  },
  onRetrievalPage() {
    console.log(this.data.searchVal);
    wx.navigateTo({
      url: '/pages/retrievalPage/index?searchVal=' + this.data.searchVal
    })
  }
});
pages/home/home.wxml
@@ -9,7 +9,7 @@
    <image src="/static/images/home/home-bg@2x.png" mode="heightFix" class="image" />
  </view>
  <view class="search">
    <t-search t-class-input="t-search__input" t-class-input-container="t-search__input-container" placeholder="请输入关键词/书名/ISBN/作者" leftIcon="">
    <t-search t-class-input="t-search__input" t-class-input-container="t-search__input-container" placeholder="请输入关键词/书名/ISBN/作者" leftIcon=""  bind:submit="onRetrievalPage" model:value="{{searchVal}}">
      <t-icon slot="left-icon" prefix="wr" name="search" size="40rpx" color="#bbb" bind:tap="navToSearchPage" />
    </t-search>
  </view>
pages/personalCenter/index.js
@@ -67,13 +67,13 @@
  {
    title: '关于我们',
    icon: '/static/images/personal/about.png',
    url: '/pages/aboutUs/index',
    url: '/pages/aboutUs/index?types=jsek_aboutUs',
    type: 'aboutUs',
  },
  {
    title: '联系我们',
    icon: '/static/images/personal/contact.png',
    url: '',
    url: '/pages/aboutUs/index?types=jsek_contactUs',
    type: 'contact',
  }
];
@@ -211,5 +211,9 @@
      isWhite: e.scrollTop > 50 ? true : false
    })
  },
  //跳转关于我们和联系我们
  onAboutUS() {
    console.log(111);
  }
})
pages/personalCenter/index.wxml
pages/resourceDetails/document/index.js
@@ -1,18 +1,50 @@
// pages/resourceDetails/document/index.js
const app = getApp()
Page({
  /**
   * 页面的初始数据
   */
  data: {
    webpageSrc: '',
    navBarHeight: '',
    barHeight: '',
    activeId: '',
    bookId: '',
    bookName: '',
    cmsId: '',
    parentName: '',
    parentProductLinkPath: '',
    productLinkPath: '',
    showData: '',
    titleName: '',
    selectType: '',
    zipData: '',
    naturalResources: [],
    titleName: '',
    pdfDatA: [],
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    console.log(options);
    const systInfo = wx.getSystemInfoSync();
    const menu = wx.getMenuButtonBoundingClientRect(); // 胶囊信息
    const navBarHeight = (menu.top - systInfo.statusBarHeight) * 2 + menu.height; // 导航栏高度
    this.setData({
      navBarHeight: navBarHeight,
      barHeight: systInfo.statusBarHeight,
      activeId: options.activeId,
      bookId: options.bookId,
      bookName: options.bookName,
      cmsId: options.cmsId,
      parentName: options.parentName,
      parentProductLinkPath: options.parentProductLinkPath,
      productLinkPath: options.productLinkPath
    })
    this.resourceDetailsData()
  },
  /**
@@ -62,5 +94,174 @@
   */
  onShareAppMessage() {
  },
  goBack() {
    wx.navigateBack()
  },
  resourceDetailsData() {
    let query = {
      path: '*',
      queryType: '*',
      productId: this.data.bookId,
      cmsPath: this.data.parentProductLinkPath,
      itemFields: {
        SysType: 'CmsFolder',
        // 资源类型,试读文件,是否允许下载等参数
        selectType: [],
        freeFile: [],
        file: [],
        protectedFile: [],
        resourcesClassification: [],
        isDownload: [],
        jsek_resourceBrief: [],
        jsek_link: [],
        jsek_questionBank: [],
        learnSelectType: []
      },
      pading: {
        start: 0,
        size: 999
  }
    }
    app.MG.store.getProductDetail(query).then((res) => {
      console.log(res);
      res.datas.cmsDatas[0].datas.forEach((item) => {
        //刚刚进来的时候
        if (this.data.productLinkPath == item.productLinkPath) {
          this.handleTeachData(item)
          this.setData({
            titleName: item.name,
            selectType: item.selectType
          })
        }
      })
    })
  },
  //zpi文件下载
  onDownloadButton() {
    const item = this.data.zipData;
    if (!item || !item.file) {
      wx.showToast({
        title: '文件信息缺失',
        icon: 'none'
      });
      return;
    }
    const downloadUrl = app.config.requestCtx + '/file/api/ApiDownload?md5=' + item.file;
    wx.showLoading({
      title: '正在下载...',
    });
    wx.downloadFile({
      url: downloadUrl,
      success(res) {
        if (res.statusCode === 200) {
          // 下载成功,可以在这里进行一些操作,例如预览、保存等
          // 这里以保存文件到系统为例
          wx.saveFile({
            tempFilePath: res.tempFilePath,
            success(saveRes) {
              wx.hideLoading();
              wx.showToast({
                title: '保存成功',
              });
              // 获取保存后的文件路径
              const savedFilePath = saveRes.savedFilePath;
              // 可以在这里进行后续操作,例如打开文件
              wx.openDocument({
                filePath: savedFilePath,
                success: function () {
                  console.log('打开文档成功')
                },
                fail: function (error) {
                  console.error('打开文档失败', error);
                }
              });
            },
            fail() {
              wx.hideLoading();
              wx.showToast({
                title: '保存失败',
                icon: 'none'
              });
            }
          });
        } else {
          wx.hideLoading();
          wx.showToast({
            title: '下载失败',
            icon: 'none'
          });
        }
      },
      fail() {
        wx.hideLoading();
        wx.showToast({
          title: '下载失败',
          icon: 'none'
        });
      }
    });
  },
  //刚进来的时候调用
  handleTeachData(item) {
    //图片
    if (item.selectType == 'picture') {
      this.setData({
        showData: app.config.requestCtx + '/file/api/ApiDownload?md5=' + item.file,
      })
    }
    // 下载文件zip
    if (item.selectType == 'zip') {
      this.setData({
        zipData: item
      })
    }
    //网页
    if (item.selectType == 'webpage') {
      this.setData({
        webpageSrc: item.jsek_link
      })
    }
    //文档等
    if (item.selectType == 'pdf' || item.selectType == 'document') {
      app.MG.file.getPdfInfo({ md5: item.file }).then((res) => {
        if (res && res.totalPages) {
          for (let i = 0; i < res.totalPages; i++) {
            const src = app.config.requestCtx + '/file/GetPdfPageImage?md5=' + item.file + '&index=' + (i + 1) + '&dpi=300'
            this.data.naturalResources.push(src)
            // console.log(this.data.naturalResources, ' this.data.naturalResources');
          }
        }
      })
    }
  },
  handleTap: function () {
    const naturalResources = this.data.naturalResources;
    naturalResources.forEach(function (item) {
      // console.log(item);
    });
  }
})
pages/resourceDetails/document/index.json
@@ -1,3 +1,9 @@
{
  "usingComponents": {}
  "component": true,
  "usingComponents": {
    "t-icon": "tdesign-miniprogram/icon/icon",
    "t-button": "tdesign-miniprogram/button/button",
    "t-image": "tdesign-miniprogram/image/image"
  },
  "navigationStyle": "custom"
}
pages/resourceDetails/document/index.wxml
@@ -1,6 +1,48 @@
<!--pages/resourceDetails/document/index.wxml-->
<text>pages/resourceDetails/document/index.wxml</text>
<view style="width: 100%; height: {{barHeight}}px; "></view>
<view class="nacigationBar" style="width: 70%; height: {{navBarHeight}}px;">
<view>
    <t-icon name="chevron-left" size="30" data-name="{{item}}" bind:click="goBack" />
  </view>
  <view class="navbar-title">资源详情</view>
</view>
<view class="titleNameBox" wx:if="{{selectType != 'webpage'}}">
  {{titleName}}
</view>
<view class="pictureBox" wx:if="{{selectType == 'picture'}}">
  <image src="{{showData}}" mode="aspectFit" />
</view>
<view wx:if="{{selectType == 'zip'}}">
  <view class="zipImageBox">
    <image src="/static/images/document/zip200px.png" mode="aspectFill " />
  </view>
  <view class="button-example">
    <t-button size="large" bind:tap="onDownloadButton">
      <view class="text">
        下载
      </view>
    </t-button>
  </view>
</view>
<view wx:if="{{selectType == 'pdf' ||  selectType == 'document'}}">
  <view wx:for="{{naturalResources}}" wx:key="index" wx:for-item="item" wx:for-index="index">
    <image src="{{item}}" alt="" style="min-height: 550px;"></image>
    <view class="divider">第 {{index + 1}} 页</view>
  </view>
</view>
<web-view wx:if="{{selectType == 'webpage'}}" src="{{webpageSrc}}"></web-view>
<!-- <button bind:tap="handleTap">点位</button> -->
pages/resourceDetails/document/index.wxss
@@ -1 +1,67 @@
/* pages/resourceDetails/document/index.wxss */
.nacigationBar {
  background-color: #fff;
  display: flex;
  align-items: center;
}
.navbar-title {
  white-space: nowrap;
  /* overflow: hidden; */
  text-overflow: ellipsis;
  color: #0F1214;
  font-size: 40rpx;
  font-weight: bold;
  margin-bottom: 5rpx;
}
.button-example {
  margin: 0 70rpx;
  background-color: #ff6c00;
  display: flex;
  justify-content: center;
}
.button-example .text {
  background-color: #ff6c00;
}
.t-button--default {
  background-color: #ff6c00 !important;
}
.t-button {
  --td-button-default-border-color: #ff6c00 !important;
}
.zipImageBox {
  display: flex;
  justify-content: center;
}
.divider {
  text-align: center;
  margin: 20px 0;
}
.titleNameBox {
  height: 77rpx;
  background: #FFFFFF;
  box-shadow: 0rpx 9rpx 9rpx 2rpx rgba(0, 0, 0, 0.06);
  padding: 20rpx 50rpx;
  margin-bottom: 100rpx;
  font-family: PingFang SC, PingFang SC;
  font-weight: 400;
  font-size: 29rpx;
  color: #333333;
}
.pictureBox {
  display: flex;
  justify-content: center;
}
.pictureBox image {
  /* width: 520rpx;
  height: 800rpx; */
}
pages/resourceDetails/myAudio/index.js
@@ -1,52 +1,671 @@
// audio.js
// pages/resourceDetails/index.js
const app = getApp()
const myAudio = wx.createInnerAudioContext();
Page({
  /**
   * 页面的初始数据
   */
  data: {
    poster: 'http://y.gtimg.cn/music/photo_new/T002R300x300M000003rsKF44GyaSk.jpg?max_age=2592000',
    name: '此时此刻',
    author: '许巍',
    src: 'http://182.92.203.7:3001/file/api/ApiDownload?md5=aa72e586dd93b7c2633bee6320bc6c76',
    noteList: [],
    navBarHeight: '',
    barHeight: '',
    flag: true, // 输入框是否显示
    tabPanelstyle: 'display:flex;justify-content:center;align-items:center;',
    activeValues: [0],
    dialogKey: false,
    style: 'border: 2rpx solid rgba(220,220,220,1);border-radius: 12rpx;',
    activeId: '',
    bookId: '',
    bookName: '',
    cmsId: '',
    parentName: '',
    parentProductLinkPath: '',
    productLinkPath: '',
    threeLeveData: [],
    showData: '',
    src: '',
    selectedId: null,
    topicId: '',
    titleName: '',
    submitTitle: "",
    inputStyle: 'border: 2rpx solid rgba(220,220,220,1);border-radius: 12rpx; padding:16rpx',
    textvalue: '',
    style: 'height: 248rpx',
    submitType: "new", //  新建 or 编辑
    noteId: '',
    myAudioDuration: '',  // 视频时间
    myAudioCurrent: '',   // 当前播放进度
    isplay: false, //是否默认播放,
    selectId: '',
    speed: 1.0,
  },
  audio: null,
  // 格式化笔记时间
  convertTimestamp(timestamp) {
    const isoDate = new Date(timestamp)
    const year = isoDate.getFullYear()
    const month = String(isoDate.getMonth() + 1).padStart(2, '0')
    const day = String(isoDate.getDate()).padStart(2, '0')
    const hours = String(isoDate.getHours()).padStart(2, '0')
    const minutes = String(isoDate.getMinutes()).padStart(2, '0')
    const seconds = String(isoDate.getSeconds()).padStart(2, '0')
    const formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
    return formattedDate
  },
  // 时间格式化
  format(t) {
    let time = Math.floor(t / 60) >= 10 ? Math.floor(t / 60) : '0' + Math.floor(t / 60);
    t = time + ':' + ((t % 60) / 100).toFixed(2).slice(-2);
    return t;
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    const systInfo = wx.getSystemInfoSync();
    const menu = wx.getMenuButtonBoundingClientRect(); // 胶囊信息
    const navBarHeight = (menu.top - systInfo.statusBarHeight) * 2 + menu.height; // 导航栏高度
    // console.log(options, 'options');
    this.setData({
      navBarHeight: navBarHeight,
      barHeight: systInfo.statusBarHeight,
      activeId: options.activeId,
      bookId: options.bookId,
      bookName: options.bookName,
      cmsId: options.cmsId,
      parentName: options.parentName,
      parentProductLinkPath: options.parentProductLinkPath,
      productLinkPath: options.productLinkPath
    })
  },
  onReady: function (e) {
    // 使用 wx.createAudioContext 获取 audio 上下文 context
    this.audioCtx = wx.createAudioContext('myAudio')
    this.resourceDetailsData()
    this.getNoteList()
  },
  audioPlay: function () {
    this.audioCtx.play()
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {
  },
  audioPause: function () {
    this.audioCtx.pause()
  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
  },
  audio14: function () {
    this.audioCtx.seek(14)
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {
  },
  audioStart: function () {
    this.audioCtx.seek(0)
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
  },
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
  },
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {
  },
  onTabsChange(event) {
  },
  onTabsClick(event) {
  }, handleChange(e) {
    this.setData({
      activeValues: e.detail.value,
    });
  },
  onTakeNotes() {
  },
  showDialog(e) {
    this.setData({
      submitTitle: this.data.bookName,
      dialogKey: true,
      // textvalue: ''
    });
  },
  closeDialog() {
    this.setData({
      dialogKey: false
    });
  },
  goBack() {
    wx.navigateBack()
    wx.navigateBack();
  },
  resourceDetailsData() {
  MusicStart: function (e) {
    var progress = parseInt((e.detail.currentTime / e.detail.duration) * 100)
    var that = this
    that.setData({
      progress: progress
    let query = {
      path: '*',
      queryType: '*',
      productId: this.data.bookId,
      cmsPath: this.data.parentProductLinkPath,
      itemFields: {
        SysType: 'CmsFolder',
        // 资源类型,试读文件,是否允许下载等参数
        selectType: [],
        freeFile: [],
        file: [],
        protectedFile: [],
        resourcesClassification: [],
        isDownload: [],
        jsek_resourceBrief: [],
        jsek_link: [],
        jsek_questionBank: [],
        learnSelectType: []
      },
      pading: {
        start: 0,
        size: 999
      }
    }
    app.MG.store.getProductDetail(query).then(res => {
      res.datas.cmsDatas[0].datas.forEach((item, index) => {
        if (item.selectType === "audio") {
          this.data.threeLeveData.push(item)
          this.setData({
            threeLeveData: this.data.threeLeveData
    })
    console.log('音乐播放进度为' + progress + '%')
          if (this.data.productLinkPath == item.productLinkPath) {
            console.log(item.id, 'index');
            this.setData({
              showData: app.config.requestCtx + '/file/api/ApiDownload?md5=' + item.file,
              titleName: item.name
            })
            this.pubulicPlayFun()
            // this.setData({
            //   selectedId: index
            // })
          }
        }
      })
      this.data.threeLeveData.forEach((item) => {
        // console.log(item.name);
      })
    })
  },
  onVideo(e) {
    const item = e.currentTarget.dataset.item
    if (this.data.showData != '') {
      this.setData({
        showData: ''
      })
    }
    this.setData({
      selectedId: e.currentTarget.dataset.index,
    })
    this.setData({
      titleName: item.name,
      selectId: item.id
    })
    if (item.selectType == "audio") {
      this.setData({
        showData: app.config.requestCtx + '/file/api/ApiDownload?md5=' + item.file
      })
      this.pubulicPlayFun()
    }
  },
  getProductUserSubmitTopicGet() {
    app.MG.ugc.getProductUserSubmitTopic({
      productId: this.data.bookId,
      appRefCode: app.config.appRefCode
    }).then((res) => {
      // console.log(res);
      this.setData({
        topicId: res.id
      })
    })
  },
  newTopicMessageGet() {
    let query = {
      topicIdOrRefCode: topicId + '',
      name: titleText.value,
      content: form.value.noteContent,
      type: 'note',
      cmsTypeRefCode: '',
      newDataListRequest: []
    }
    app.MG.ugc.newTopicMessage(query).then(res => {
      // console.log(res);
    })
  },
  // 标题改变
  changeTitle(e) {
    // console.log(e.currentTarget.dataset.value);
    this.setData({
      flag: e.currentTarget.dataset.value
    })
  },
  // 标题输入框值
  inputChange(e) {
    this.setData({
      titleName: e.detail.value
    })
  },
  confirmSuggest() {
    if (!this.data.textvalue) {
      return wx.showToast({
        icon: 'error',
        title: '请填写笔记内容',
      })
    } else if (!this.data.titleName) {
      return wx.showToast({
        icon: 'error',
        title: '请填写笔记标题',
      })
    }
    if (this.data.submitType == 'new') {
      this.makeNote()
    } else if (this.data.submitType == 'edit') {
      this.updateNote()
    }
    // console.log(this.data.textvalue);
    // console.log(this.data.titleName);
    this.setData({
      dialogKey: false
    });
  },
  onTextarea() {
    // console.log(this.data.textvalue);
  },
  textareaChange(e) {
    this.setData({
      textvalue: e.detail.value
    })
  },
  // 获取笔记列表
  async getNoteList() {
    // this.setData({
    //   loading: true
    // })
    let topicId
    await app.MG.ugc
      .getProductUserSubmitTopic({
        productId: this.data.bookId,
        appRefCode: app.config.appRefCode
      })
      .then((res) => {
        if (res) {
          topicId = res.id
        } else {
          return wx.showToast({
            icon: "error",
            title: '查询失败',
          })
        }
      })
    // loadings.value.bookResource = true
    let query = {
      start: 0,
      size: 999,
      messageType: 'note',
      sort: {
        type: 'Desc',
        field: 'CreateDate'
      },
      appRefCode: app.config.appRefCode,
      topicIdOrRefCode: topicId + ''
    }
    await app.MG.ugc.getTopicMessageList(query).then((res) => {
      // notePage.value.total = res.totalSize
      res.datas.forEach((item) => {
        // item.compliceHover = false
        // item.deleteHover = false
        item.createDate = this.convertTimestamp(item.createDate)
      })
      this.setData({
        "pageCount.total": res.totalSize,
        noteList: res.datas,
        loading: false
      })
      // console.log('笔记列表', res.datas);
    })
  },
  // 编辑按钮
  editNote(e) {
    const note = e.currentTarget.dataset.note
    this.setData({
      submitType: "edit",
      textvalue: note.content,
      submitTitle: note.name,
      noteId: note.id
    })
    this.showDialog()
  },
  // 删除笔记
  deleteNote(e) {
    const id = e.currentTarget.dataset.id
    const messageIds = []
    messageIds.push(id)
    wx.showModal({
      title: '提示',
      content: '确认删除该笔记吗?',//editable如果为true,这就是输入框的内容
      editable: false,//是否显示输入框
      placeholderText: '请输入内容吧',//输入框的默认内容
      success: (res) => {
        if (res.confirm) {
          app.MG.ugc
            .delTopicMessage({ messageIds })
            .then((res) => {
              wx.showToast({
                title: '删除成功',
              })
              // if ((notePage.value.total % 3) - 1 == 0) {
              //   notePage.value.page -= 1
              // }
              this.getNoteList()
            })
        } else if (res.cancel) {
          // console.log('用户点击取消')
        }
      }
    })
  },
  // 新建笔记接口
  async makeNote() {
    const token = wx.getStorageSync('jsek-token')
    if (!token) {
      return wx.getUserProfile({
        desc: '用户登录',
        success: (res) => {
          // console.log(res);
        }
      })
    }
    let topicId
    await app.MG.ugc
      .getProductUserSubmitTopic({
        productId: this.data.bookId,
        appRefCode: app.config.appRefCode
      })
      .then((res) => {
        if (res) {
          topicId = res.id
        } else {
          return wx.showToast({
            icon: 'error',
            title: '新建失败',
          })
        }
      })
    let query = {
      topicIdOrRefCode: topicId + '',
      name: this.data.submitTitle,
      content: this.data.textvalue,
      type: 'note',
      cmsTypeRefCode: '',
      newDataListRequest: []
    }
    await app.MG.ugc.newTopicMessage(query).then((res) => {
      wx.showToast({
        title: '新建成功',
      })
      this.closeDialog()
      this.getNoteList()
    })
  },
  // 编辑笔记接口
  updateNote() {
    const token = wx.getStorageSync('jsek-token')
    if (!token) {
      return wx.getUserProfile({
        desc: '用户登录',
        success: (res) => {
          // console.log(res);
        }
      })
    }
    if (!this.data.submitTitle) {
      return wx.showToast({
        icon: 'error',
        title: '请填写笔记标题',
      })
    } else if (!this.data.textvalue) {
      return wx.showToast({
        icon: 'error',
        title: '请填写笔记内容',
      })
    }
    let query = {
      id: this.data.noteId,
      name: this.data.submitTitle,
      description: 'string',
      icon: 'string',
      type: 'note',
      content: this.data.textvalue,
      newDataRequests: [],
      updateDataRequests: []
    }
    app.MG.ugc.updateTopicMessage(query).then((res) => {
      wx.showToast({
        title: '编辑成功',
      })
      this.closeDialog()
      this.getNoteList()
    })
    this.setData({
      submitType: "new"
    })
  },
  // 播放公共代码
  pubulicPlayFun() {
    myAudio.src = this.data.showData
    console.log(myAudio.src);
    // 在onCanplay里获取并设置音频时长和播放进度
    myAudio.onCanplay(() => {
      myAudio.duration; //必须写,不然获取不到。。。
      setTimeout(() => {
        console.log(myAudio.duration);
        this.setData({
          myAudioDuration: this.format(myAudio.duration),
          myAudioCurrent: this.format(myAudio.currentTime)
        });
      }, 1000);
    });
    // 播放完成处理,按钮变一下
    myAudio.onEnded((res) => {
      this.setData({
        isplay: false
      })
    });
    //进度条变化
    myAudio.onTimeUpdate(() => {
      this.setData({
        myAudioPos: myAudio.currentTime / myAudio.duration * 100,
        myAudioCurrent: this.format(myAudio.currentTime)
      });
    })
  },
  //播放
  play() {
    console.log(22222);
    myAudio.startTime = this.data.myAudioCurrent; //考虑到进度条被拖动,不一定从00:00:00开始
    myAudio.play();
    this.setData({
      isplay: true
    });
  },
  // 停止
  stop() {
    console.log(11111);
    myAudio.pause();
    this.setData({
      isplay: false
    });
  },
  adsfhaewlf() {
    myAudio.pause();
    this.setData({
      isplay: false
    });
  },
  //右切换
  onLeftSwitch() {
    this.setData({
      speed: 1.0,
      myAudioCurrent: '00:00'
    })
    const index = this.data.threeLeveData.findIndex((item) => item.id == this.data.selectId)
    if (this.data.threeLeveData[index - 1]) {
      this.changeItem(this.data.threeLeveData[index - 1])
      this.setData({
        selectedId: index - 1,
      })
    } else {
      console.log('已经是第一首了');
    }
  },
  //右切换
  onRightSwitch() {
    this.setData({
      speed: 1.0,
      myAudioCurrent: '00:00'
    })
    console.log('右切换');
    const index = this.data.threeLeveData.findIndex((item) => item.id == this.data.selectId)
    if (this.data.threeLeveData[index + 1]) {
      this.changeItem(this.data.threeLeveData[index + 1])
      this.setData({
        selectedId: index + 1,
      })
    } else {
      console.log('已经是最后一首了');
    }
  },
  changeItem(item) {
    console.log(item);
    if (this.data.showData != '') {
      this.setData({
        showData: ''
      })
    }
    this.setData({
      titleName: item.name,
      selectId: item.id
    })
    if (item.selectType == "audio") {
      this.setData({
        showData: app.config.requestCtx + '/file/api/ApiDownload?md5=' + item.file
      })
      this.pubulicPlayFun()
    }
  },
  // 播放倍速
  onSpeed() {
    let c = this.data.speed;
    c += 0.5;
    if (c <= 2) {
      this.setData({
        speed: c,
      })
    } else {
      c = 0.5;
      this.setData({
        speed: c,
      })
    }
    setTimeout(() => {
      myAudio.startTime = this.data.myAudioDuration  //开始时间
      myAudio.playbackRate = this.data.speed; //  播放速率
    }, 200);
  },
  // 拖动进度条,到指定位置
  hanle_slider_change(e) {
    const position = e.detail.value;
    var currentTime = position / 100 * myAudio.duration;
    myAudio.seek(currentTime);
    this.setData({
      myAudioPos: position,
      myAudioCurrent: this.format(currentTime)
    })
  }
})
pages/resourceDetails/myAudio/index.json
@@ -1,6 +1,19 @@
{
  "component": true,
  "usingComponents": {
    "t-icon": "tdesign-miniprogram/icon/icon"
    "t-icon": "tdesign-miniprogram/icon/icon",
    "t-tabs": "tdesign-miniprogram/tabs/tabs",
    "t-tab-panel": "tdesign-miniprogram/tab-panel/tab-panel",
    "t-collapse": "tdesign-miniprogram/collapse/collapse",
    "t-collapse-panel": "tdesign-miniprogram/collapse-panel/collapse-panel",
    "t-button": "tdesign-miniprogram/button/button",
    "t-dialog": "tdesign-miniprogram/dialog/dialog",
    "t-input": "tdesign-miniprogram/input/input",
    "t-image": "tdesign-miniprogram/image/image",
    "t-textarea": "tdesign-miniprogram/textarea/textarea",
    "t-loading": "tdesign-miniprogram/loading/loading",
    "t-popup": "tdesign-miniprogram/popup/popup",
    "t-slider": "tdesign-miniprogram/slider/slider"
  },
  "navigationStyle": "custom"
}
pages/resourceDetails/myAudio/index.wxml
@@ -9,31 +9,136 @@
<view class="audioBox">
  <view class="">
    <image class="imageFront" src="/static/images/resourceDetailsMyAudio/cd.png" mode="aspectFit" />
    <image class=" imageAfter" src="/static/images/resourceDetailsMyAudio/video-bg.png" mode="aspectFit" />
<view class="audioPlayerBox">
  <view class="audioBackground" style="background-image: url('/static/images/resourceDetailsMyAudio/video-bg.png');">
    <image src="/static/images/resourceDetailsMyAudio/cd.png" alt="" />
  </view>
  <view class="controlBox">
  <!-- 视频播放的按钮 -->
  <view class="bigFunctionBox">
    <slider activeColor='#FF6C00' class="mp-slider-bar" block-size="16" value="{{myAudioPos}}" bindchange="hanle_slider_change"></slider>
    <image src="/static/images/resourceDetailsMyAudio/shangyizhang.png" mode="" />
    <image bindtap="audioPlay" src="/static/images/resourceDetailsMyAudio/zanting.png" mode="" />
    <image bindtap="audioPause" src="/static/images/resourceDetailsMyAudio/xiayizhang.png" mode="" />
    <view class="functionBox">
    <image src="/static/images/resourceDetailsMyAudio/Full screen.png" mode="" />
    <!-- <view class="free-MusicProgress">
      <view style="width:{{progress}}%;"></view>
    </view> -->
      <!-- 左切换 -->
      <view class="leftSwitchBox  color" bind:tap="onLeftSwitch">
        <t-icon name="previous" size="24" />
      </view>
      <!-- 暂停播放 -->
      <view class="audioIconBox color">
        <view wx:if="{{!isplay}}" bind:tap='play'>
          <t-icon name="play-circle-stroke" size="24" />
        </view>
        <view wx:else bind:tap="stop">
          <t-icon name="pause-circle-stroke" size="24" />
        </view>
      </view>
      <!-- 右切换 -->
      <view class="rightSwitchBox color" bind:tap="onRightSwitch">
        <t-icon name="next" size="24" />
      </view>
      <!-- 时间 -->
      <view class="current-time color">{{myAudioCurrent}} </view>
      <view class="color" style="margin: 0 10rpx;">/</view>
      <view class="duration-time color"> {{myAudioDuration}} </view>
      <view class="publicBtn color" style="margin-left:100rpx ;" bind:tap="onSpeed">
        <text class="publicText">{{"x "+speed}}</text>
      </view>
    </view>
  </view>
</view>
<audio wx:if="{{false}}" bindtimeupdate="MusicStart" poster="{{poster}}" name="{{name}}" author="{{author}}" src="{{src}}" id="myAudio" controls loop>
<!-- 标题 -->
<view class="titleBox">{{titleName}}</view>
<view class="contentBox">
  <t-tabs defaultValue="{{0}}" bind:change="onTabsChange" bind:click="onTabsClick" t-class="custom-tabs" t-class-content="custom-panel">
    <!-- 资源列表 -->
    <t-tab-panel label="资源列表" value="0" style="{{tabPanelstyle}}" style="width: 750rpx;">
      <view class="wrapper">
        <t-collapse value="{{activeValues}}" bind:change="handleChange">
          <t-collapse-panel header="{{parentName}}" value="{{0}}" expandIcon>
            <view class="detailsName" wx:for="{{threeLeveData}}" wx:key="index" wx:for-item="item" wx:for-index="index" bind:tap="onVideo" data-item="{{item}}" data-index="{{index}}">
              <view style="color: {{selectedId == index ? '#ff6c00' : '#000'}}">{{item.name}}</view>
            </view>
          </t-collapse-panel>
        </t-collapse>
      </view>
    </t-tab-panel>
    <!-- 笔记展示 -->
    <t-tab-panel label="笔记" value="1" style="{{tabPanelstyle}}">
      <view class="wrapper">
        <t-collapse value="{{activeValues}}" bind:change="handleChange">
          <t-collapse-panel value="{{item.id}}" expandIcon wx:for="{{noteList}}">
            <view slot="header" class="collapse-header">
              <t-image class="note-icon" src="/static/images/bookService/detail/note-icon.png"></t-image>
              <view class="header-name">{{item.name}}</view>
            </view>
            <view>
              <view class="note-content">{{item.content}}</view>
              <view class="note-bottom">
                <view class="note-time">{{item.createDate}}</view>
                <view class="bottom-btn">
                  <t-image src="/static/images/bookService/detail/compliceHover.png" class="complice" bind:tap="editNote" data-note="{{item}}"></t-image>
                  <view></view>
                  <t-image src="/static/images/bookService/detail/deleteHover.png" class="delete" bind:tap="deleteNote" data-id="{{item.id}}"></t-image>
                </view>
              </view>
            </view>
          </t-collapse-panel>
        </t-collapse>
      </view>
    </t-tab-panel>
  </t-tabs>
  <!-- 记笔记 -->
  <view class="takeNotes" data-key="showCloseBtn" bind:tap="showDialog">
    <view class="takeNotesLining">
      <image src="/static/images/resourceDetails/jibijii.png" mode="" /> 记笔记
    </view>
  </view>
</view>
</audio>
<!-- <button type="primary" >播放</button>
<button type="primary">暂停</button>
<button type="primary" bindtap="audio14">设置当前播放时间为14秒</button>
<button type="primary" bindtap="audioStart">回到开头</button> -->
<!-- 记笔记弹窗 -->
<t-popup visible="{{dialogKey}}" bind:visible-change="onVisibleChange" placement="center">
  <view class="popup">
    <view slot="title">
      <view class="title-text" wx:if="{{!flag}}">
        <text class="note-title">{{titleName}}</text>
        <t-image src="/static/images/bookService/detail/edit.png" class="edit-icon" bind:tap="changeTitle" data-value="{{true}}"></t-image>
      </view>
      <view wx:else>
        <t-input value="{{titleName}}" style="{{inputStyle}}" data-value="{{false}}" bind:enter="changeTitle" bind:blur="changeTitle" maxlength="{{50}}" bind:change="inputChange"></t-input>
      </view>
    </view>
    <view slot='content'>
      <view class="textarea-example">
        <text class="textarea-example__label">内容:</text>
        <t-textarea value="{{textvalue}}" t-class="external-class" placeholder="请输入文字" bordered maxlength="500" disableDefaultPadding="{{true}}" indicator style="{{inputStyle}}" bind:change="textareaChange" />
      </view>
      <view class="submit-btn">
        <t-button theme="primary" size="large" block bind:tap="confirmSuggest">提交</t-button>
      </view>
    </view>
  </view>
  <t-icon t-class="close-btn" name="close-circle" size="32" color="#fff" bind:tap="closeDialog" />
</t-popup>
pages/resourceDetails/myAudio/index.wxss
@@ -1,14 +1,12 @@
/* pages/resourceDetails/myAudio/index.wxss */
/* pages/resourceDetails/index.wxss */
.nacigationBar {
  background-color: #fff;
  display: flex;
  align-items: center;
}
.navbar-title {
  white-space: nowrap;
  /* overflow: hidden; */
  text-overflow: ellipsis;
  color: #0F1214;
  font-size: 40rpx;
@@ -16,51 +14,306 @@
  margin-bottom: 5rpx;
}
.audioBox {
  width: 100%;
  height: 350rpx;
.titleBox {
  margin: 30rpx;
  border-bottom: 1px #f4f4f4 solid;
  padding-bottom: 20rpx;
  font-weight: bold;
}
.imageFront {
  width: 300rpx;
  height: 300rpx;
  position: absolute;
  top: 150rpx;
  left: 250rpx;
.contentBox {
  position: relative;
}
.imageAfter {
  width: 100%;
.contentBox .custom-tabs {
  width: 400rpx;
}
.controlBox {
.t-tabs__content {
  width: 750rpx !important;
  overflow: auto !important;
}
.custom-panel {
  width: 750rpx;
  height: 96rpx;
  background: #000000;
  border-radius: 0rpx 0rpx 0rpx 0rpx;
  opacity: 0.6;
  position: relative;
}
.controlBox image {
  width: 45rpx;
  height: 45rpx;
  margin: 20rpx 35rpx;
}
.contentBox .takeNotes {
audio {
  position: relative;
}
.free-MusicProgress {
  position: absolute;
  width: 78%;
  left: 21.7%;
  bottom: 1px;
  background: #C3C3C3;
  top: 5rpx;
  right: 0;
  width: 350rpx;
  border-bottom: 1px solid #f4f4f4;
}
.free-MusicProgress>view {
  background: #48c23d;
  height: 5px;
.takeNotes image {
  width: 30rpx;
  height: 30rpx;
  margin-top: 10rpx;
  margin-right: 10rpx;
}
.takeNotesLining {
  margin: 25rpx;
  display: flex;
  justify-content: flex-end;
}
.operateBox {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
}
.iconBox {
  display: flex;
}
.iconBox image {
  width: 26rpx;
  height: 26rpx;
  margin: 0 10rpx;
}
.t-dialog__content {
  padding: 0 !important;
}
.titleImageBox {
  width: 40rpx;
  height: 40rpx;
  margin-left: 20rpx;
}
.dialogTitleBox {
  margin: 30rpx;
  border-bottom: 1px #f4f4f4 solid;
  padding-bottom: 20rpx;
  font-weight: bold;
  display: flex;
  align-items: center;
}
.input-example {
  --td-input-vertical-padding: 24rpx;
  background-color: #fff;
  padding: 32rpx 32rpx 16rpx;
}
.input-example__label {
  color: rgba(0, 0, 0, 0.9);
  font-size: 24rpx;
  line-height: 40rpx;
  margin: 0 8rpx 16rpx;
}
.buttonBox {
  display: flex;
  justify-content: center;
}
.detailsName {
  margin: 30rpx;
  width: 90%;
  height: 60rpx;
  display: flex;
  align-items: center;
  padding-left: 20rpx;
  background-color: #FFF6F0
}
.detailsName:hover {
  background-color: #fff0e6;
  width: 90%;
  height: 60rpx;
  color: #ff6c00;
}
.audioBox {
  width: 750rpx;
  height: 200rpx;
}
.title-text {
  display: flex;
  align-items: center;
}
.note-title {
  width: 80%;
  height: 84rpx;
  line-height: 84rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 10rpx;
  margin-left: 20rpx;
}
.edit-icon {
  margin-left: 10rpx;
  width: 30rpx;
  height: 30rpx;
}
.submit-btn {
  padding: 40rpx;
  --td-button-border-radius: 60rpx;
  --td-button-primary-bg-color: #ff6c00;
  --td-button-primary-border-color: #ff6c00;
  --td-button-primary-active-bg-color: #ff984d;
  --td-button-primary-active-border-color: #ff984d;
}
.edit-icon {
  margin-left: 10rpx;
  width: 30rpx;
  height: 30rpx;
}
.textarea-example {
  padding: 32rpx 32rpx 48rpx;
  background-color: #fff;
}
.external-class {
  padding-top: 24rpx !important;
  padding-bottom: 24rpx !important;
}
.textarea-example__label {
  display: block;
  color: rgba(0, 0, 0, 0.9);
  font-size: 24rpx;
  line-height: 40rpx;
  padding-bottom: 16rpx;
}
.popup {
  padding: 40rpx;
  width: 600rpx;
}
.close-btn {
  position: absolute;
  left: 50%;
  margin-left: -32rpx;
  bottom: calc(-1 * (48rpx + 64rpx));
}
.collapse-header {
  display: flex;
}
.collapse-header .header-name {
  font-size: 32rpx;
  width: 500rpx;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.note-icon {
  width: 44rpx;
  height: 48rpx;
  margin-right: 20rpx;
}
.note-content {
  height: min-content;
  font-size: 28rpx;
  color: #949494;
  margin-bottom: 20rpx;
  max-height: 600rpx;
  text-align: justify;
}
.note-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.note-time {
  color: #D9D9D9;
}
.bottom-btn {
  height: 40rpx;
  display: flex;
  align-items: center;
}
.complice,
.delete {
  width: 30rpx;
  height: 30rpx;
  margin: 0 15rpx;
}
.audioPlayerBox {
  width: 100%;
  height: 460rpx;
  display: flex;
  flex-direction: column;
}
.audioBackground {
  flex: 1;
  background-size: 100% 110%;
  background-color: #f9f9f9;
  display: flex;
  justify-content: center;
  align-items: center;
}
.audioBackground image {
  width: 270rpx;
  height: 280rpx;
}
.functionBox {
  height: 96rpx;
  display: flex;
  align-items: center;
}
.functionBox .color {
  color: #fff;
}
.rightSwitchBox {
  margin: 0 30rpx;
}
.leftSwitchBox {
  margin: 0 30rpx;
}
.bigFunctionBox {
  background: #000000;
  opacity: 0.6;
}
.mp-slider-bar {
  margin: 0 18rpx;
  margin-top: 10rpx;
}
.t-tabs__item--active {
  color: #FF6C00 !important;
}
.t-tabs__track {
  background-color: #FF6C00 !important;
}
pages/resourceDetails/myVideo/index.js
@@ -7,12 +7,13 @@
   * 页面的初始数据
   */
  data: {
    noteList: [],
    navBarHeight: '',
    barHeight: '',
    flag: true, // 输入框是否显示
    tabPanelstyle: 'display:flex;justify-content:center;align-items:center;',
    activeValues: [0],
    dialogKey: true,
    dialogKey: false,
    style: 'border: 2rpx solid rgba(220,220,220,1);border-radius: 12rpx;',
    activeId: '',
    bookId: '',
@@ -25,18 +26,36 @@
    showData: '',
    src: '',
    selectedId: null,
    topicId: ''
    topicId: '',
    titleName: '',
    submitTitle: "",
    inputStyle: 'border: 2rpx solid rgba(220,220,220,1);border-radius: 12rpx; padding:16rpx',
    textvalue: '',
    style: 'height: 248rpx',
    submitType: "new", //  新建 or 编辑
    noteId: '',
  },
  // 格式化笔记时间
  convertTimestamp(timestamp) {
    const isoDate = new Date(timestamp)
    const year = isoDate.getFullYear()
    const month = String(isoDate.getMonth() + 1).padStart(2, '0')
    const day = String(isoDate.getDate()).padStart(2, '0')
    const hours = String(isoDate.getHours()).padStart(2, '0')
    const minutes = String(isoDate.getMinutes()).padStart(2, '0')
    const seconds = String(isoDate.getSeconds()).padStart(2, '0')
    const formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
    return formattedDate
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    console.log(this.data.dialogKey, 'dialogKey');
    const systInfo = wx.getSystemInfoSync();
    const menu = wx.getMenuButtonBoundingClientRect(); // 胶囊信息
    const navBarHeight = (menu.top - systInfo.statusBarHeight) * 2 + menu.height; // 导航栏高度
    console.log(options, 'options');
    this.setData({
      navBarHeight: navBarHeight,
      barHeight: systInfo.statusBarHeight,
@@ -46,10 +65,12 @@
      cmsId: options.cmsId,
      parentName: options.parentName,
      parentProductLinkPath: options.parentProductLinkPath,
      productLinkPath: options.productLinkPath
      productLinkPath: options.productLinkPath,
      flag: false
    })
    console.log(this.data.parentProductLinkPath, 'parentProductLinkPath');
    this.resourceDetailsData()
    this.getNoteList()
  },
  /**
@@ -106,7 +127,8 @@
  onTabsClick(event) {
  }, handleChange(e) {
  },
  handleChange(e) {
    this.setData({
      activeValues: e.detail.value,
    });
@@ -115,22 +137,28 @@
  },
  showDialog(e) {
    const { key } = e.currentTarget.dataset;
    this.setData({ [key]: true, dialogKey: key });
    this.setData({
      submitTitle: this.data.bookName,
      dialogKey: true,
      // textvalue: ''
    });
  },
  closeDialog() {
    this.setData({
      dialogKey: false
      dialogKey: false,
      textvalue: '',
      flag: false
    });
  },
  goBack() {
    wx.navigateBack();
  },
  resourceDetailsData() {
    let query = {
      path: '*',
      queryType: '*',
@@ -157,47 +185,46 @@
    }
    app.MG.store.getProductDetail(query).then(res => {
      console.log(res, 'res');
      const list = []
      res.datas.cmsDatas[0].datas.forEach((item) => {
        if (item.selectType === "video") {
        this.data.threeLeveData.push(item)
        list.push(item)
        this.setData({
          threeLeveData: list
            threeLeveData: this.data.threeLeveData
        })
        if (this.data.productLinkPath == item.productLinkPath) {
          console.log(item, 'item');
          this.setData({
            showData: app.config.requestCtx + '/file/api/ApiDownload?md5=' + item.file
              showData: app.config.requestCtx + '/file/api/ApiDownload?md5=' + item.file,
              titleName: item.name
          })
        }
        // console.log(this.data.threeLeveData, 'threeLeveData');
      })
        }
      })
      this.data.threeLeveData.forEach((item) => {
        console.log(item.name);
      })
    })
  },
  onVideo(e) {
    if (this.data.showData != '') {
      this.setData({
        showData: ''
      })
    }
    this.setData({
      selectedId: e.currentTarget.dataset.index,
    })
    // console.log(e);
    const item = e.currentTarget.dataset.item
    // console.log(item);
    this.setData({
      titleName: item.name
    })
    if (item.selectType == "video") {
      console.log(item.file);
      this.setData({
        showData: app.config.requestCtx + '/file/api/ApiDownload?md5=' + item.file
      })
      console.log(this.data.showData);
    } else {
      console.log(app.config.requestCtx + '/file/api/ApiDownload?md5=' + item.file);
    }
  },
@@ -229,15 +256,229 @@
      console.log(res);
    })
  },
  // currentTarget
  onConfirm() {
    console.log(1111);
  // 标题改变
  changeTitle(e) {
    console.log(e.currentTarget.dataset.value);
    this.setData({
      flag: e.currentTarget.dataset.value
    })
  },
  onCancellation() {
    console.log(222);
  // 标题输入框值
  inputChange(e) {
    this.setData({
      titleName: e.detail.value
    })
  },
    this.data.dialogKey = false
  confirmSuggest() {
    if (!this.data.textvalue) {
      return wx.showToast({
        icon: 'error',
        title: '请填写笔记内容',
      })
    } else if (!this.data.titleName) {
      return wx.showToast({
        icon: 'error',
        title: '请填写笔记标题',
      })
  }
    if (this.data.submitType == 'new') {
      this.makeNote()
    } else if (this.data.submitType == 'edit') {
      this.updateNote()
    }
    console.log(this.data.textvalue);
    console.log(this.data.titleName);
    this.setData({
      dialogKey: false
    });
  },
  onTextarea() {
    console.log(this.data.textvalue);
  },
  textareaChange(e) {
    this.setData({
      textvalue: e.detail.value
    })
  },
  // 获取笔记列表
  async getNoteList() {
    // this.setData({
    //   loading: true
    // })
    let topicId
    await app.MG.ugc
      .getProductUserSubmitTopic({
        productId: this.data.bookId,
        appRefCode: app.config.appRefCode
      })
      .then((res) => {
        if (res) {
          topicId = res.id
        } else {
          return wx.showToast({
            icon: "error",
            title: '查询失败',
          })
        }
      })
    // loadings.value.bookResource = true
    let query = {
      start: 0,
      size: 999,
      messageType: 'note',
      sort: {
        type: 'Desc',
        field: 'CreateDate'
      },
      appRefCode: app.config.appRefCode,
      topicIdOrRefCode: topicId + ''
    }
    await app.MG.ugc.getTopicMessageList(query).then((res) => {
      // notePage.value.total = res.totalSize
      res.datas.forEach((item) => {
        // item.compliceHover = false
        // item.deleteHover = false
        item.createDate = this.convertTimestamp(item.createDate)
      })
      this.setData({
        "pageCount.total": res.totalSize,
        noteList: res.datas,
        loading: false
      })
      console.log('笔记列表', res.datas);
    })
  },
  // 编辑按钮
  editNote(e) {
    const note = e.currentTarget.dataset.note
    this.setData({
      submitType: "edit",
      textvalue: note.content,
      submitTitle: note.name,
      noteId: note.id
    })
    this.showDialog()
  },
  // 删除笔记
  deleteNote(e) {
    const id = e.currentTarget.dataset.id
    const messageIds = []
    messageIds.push(id)
    wx.showModal({
      title: '提示',
      content: '确认删除该笔记吗?',//editable如果为true,这就是输入框的内容
      editable: false,//是否显示输入框
      placeholderText: '请输入内容吧',//输入框的默认内容
      success: (res) => {
        if (res.confirm) {
          app.MG.ugc
            .delTopicMessage({ messageIds })
            .then((res) => {
              wx.showToast({
                title: '删除成功',
              })
              // if ((notePage.value.total % 3) - 1 == 0) {
              //   notePage.value.page -= 1
              // }
              this.getNoteList()
            })
        } else if (res.cancel) {
          console.log('用户点击取消')
        }
      }
    })
  },
  // 新建笔记接口
  async makeNote() {
    const token = wx.getStorageSync('jsek-token')
    if (!token) {
      return wx.getUserProfile({
        desc: '用户登录',
        success: (res) => {
          console.log(res);
        }
      })
    }
    let topicId
    await app.MG.ugc
      .getProductUserSubmitTopic({
        productId: this.data.bookId,
        appRefCode: app.config.appRefCode
      })
      .then((res) => {
        if (res) {
          topicId = res.id
        } else {
          return wx.showToast({
            icon: 'error',
            title: '新建失败',
          })
        }
      })
    let query = {
      topicIdOrRefCode: topicId + '',
      name: this.data.submitTitle,
      content: this.data.textvalue,
      type: 'note',
      cmsTypeRefCode: '',
      newDataListRequest: []
    }
    await app.MG.ugc.newTopicMessage(query).then((res) => {
      wx.showToast({
        title: '新建成功',
      })
      this.closeDialog()
      this.getNoteList()
    })
  },
  // 编辑笔记接口
  updateNote() {
    const token = wx.getStorageSync('jsek-token')
    if (!token) {
      return wx.getUserProfile({
        desc: '用户登录',
        success: (res) => {
          console.log(res);
        }
      })
    }
    if (!this.data.submitTitle) {
      return wx.showToast({
        icon: 'error',
        title: '请填写笔记标题',
      })
    } else if (!this.data.textvalue) {
      return wx.showToast({
        icon: 'error',
        title: '请填写笔记内容',
      })
    }
    let query = {
      id: this.data.noteId,
      name: this.data.submitTitle,
      description: 'string',
      icon: 'string',
      type: 'note',
      content: this.data.textvalue,
      newDataRequests: [],
      updateDataRequests: []
    }
    app.MG.ugc.updateTopicMessage(query).then((res) => {
      wx.showToast({
        title: '编辑成功',
      })
      this.closeDialog()
      this.getNoteList()
    })
    this.setData({
      submitType: "new"
    })
  },
})
pages/resourceDetails/myVideo/index.json
@@ -8,7 +8,11 @@
    "t-collapse-panel": "tdesign-miniprogram/collapse-panel/collapse-panel",
    "t-button": "tdesign-miniprogram/button/button",
    "t-dialog": "tdesign-miniprogram/dialog/dialog",
    "t-input": "tdesign-miniprogram/input/input"
    "t-input": "tdesign-miniprogram/input/input",
    "t-image": "tdesign-miniprogram/image/image",
    "t-textarea": "tdesign-miniprogram/textarea/textarea",
    "t-loading": "tdesign-miniprogram/loading/loading",
    "t-popup": "tdesign-miniprogram/popup/popup"
  },
  "navigationStyle": "custom"
}
pages/resourceDetails/myVideo/index.wxml
@@ -5,15 +5,14 @@
  </view>
  <view class="navbar-title">资源详情-视频</view>
</view>
<!-- 视频 等 -->
<!-- 视频  -->
<view class="videoBox">
  <!-- autoplay='false' 是否自动播放 -->
  <video src="{{showData}}" play-btn-position='center' object-fit='fill' controls enable-play-gesture enable-auto-rotation></video>
</view>
<!-- 标题 -->
<view class="titleBox">基础教育研究背景总体设计</view>
<view class="titleBox">{{titleName}}</view>
<view class="contentBox">
  <t-tabs defaultValue="{{0}}" bind:change="onTabsChange" bind:click="onTabsClick" t-class="custom-tabs" t-class-content="custom-panel">
    <!-- 资源列表 -->
@@ -21,27 +20,32 @@
      <view class="wrapper">
        <t-collapse value="{{activeValues}}" bind:change="handleChange">
          <t-collapse-panel header="{{parentName}}" value="{{0}}" expandIcon>
            <view class="detailsName" wx:for="{{threeLeveData}}" wx:key="index" wx:for-item="item" wx:for-index="index" bind:tap="onVideo" data-item="{{item}}" data-index="{{index}}">
              <view style="color: {{selectedId == index ? '#ff6c00' : '#000'}}">{{item.name}}</view>
            </view>
          </t-collapse-panel>
        </t-collapse>
      </view>
    </t-tab-panel>
    <!-- 笔记展示 -->
    <t-tab-panel label="笔记" value="1" style="{{tabPanelstyle}}">
      <view class="wrapper">
        <t-collapse value="{{activeValues}}" bind:change="handleChange">
          <t-collapse-panel header="第1第1课时 课程视频" value="{{0}}" expandIcon>
            <view> 此处可自定义内容此处可自定义内容此处可自定义内容此处可自定义内容此处可自定义内容此处可自定义内容此处可自定义内容此处可自定义内容</view>
            <view class="operateBox">
              <view>2023-08-29</view>
              <view class="iconBox">
                <image src="/static/images/resourceDetails/jibijiicon2.png" mode="" />
                <image src="/static/images/resourceDetails/jibijiicon3.png" mode="" />
          <t-collapse-panel value="{{item.id}}" expandIcon wx:for="{{noteList}}">
            <view slot="header" class="collapse-header">
              <t-image class="note-icon" src="/static/images/bookService/detail/note-icon.png"></t-image>
              <view class="header-name">{{item.name}}</view>
            </view>
            <view>
              <view class="note-content">{{item.content}}</view>
              <view class="note-bottom">
                <view class="note-time">{{item.createDate}}</view>
                <view class="bottom-btn">
                  <t-image src="/static/images/bookService/detail/compliceHover.png" class="complice" bind:tap="editNote" data-note="{{item}}"></t-image>
                  <view></view>
                  <t-image src="/static/images/bookService/detail/deleteHover.png" class="delete" bind:tap="deleteNote" data-id="{{item.id}}"></t-image>
                </view>
              </view>
            </view>
          </t-collapse-panel>
@@ -60,20 +64,35 @@
<!-- 记笔记弹窗 -->
<t-dialog visible="{{showCloseBtn}}" close-btn bind:confirm="closeDialog" bind:cancel="closeDialog">
  <view slot='title' class="dialogTitleBox">一、道德与品德的关系-有试看
    <image class="titleImageBox" src="/static/images/resourceDetails/edit.png" alt="" />
<t-popup visible="{{dialogKey}}" bind:visible-change="onVisibleChange" placement="center">
  <view class="popup">
    <view slot="title">
      <view class="title-text" wx:if="{{!flag}}">
        <text class="note-title">{{titleName}}</text>
        <t-image src="/static/images/bookService/detail/edit.png" class="edit-icon" bind:tap="changeTitle" data-value="{{true}}"></t-image>
  </view>
      <view wx:else>
        <t-input value="{{titleName}}" style="{{inputStyle}}" data-value="{{false}}" bind:enter="changeTitle" bind:blur="changeTitle" maxlength="{{50}}" bind:change="inputChange"></t-input>
      </view>
    </view>
  <view slot='content'>
    <view class="input-example">
      <view class="input-example__label"> 内容 </view>
      <t-input class="inputBox" placeholder="请输入文字" borderless="{{true}}" style="{{style}}" />
      <view class="textarea-example">
        <text class="textarea-example__label">内容:</text>
        <t-textarea value="{{textvalue}}" t-class="external-class" placeholder="请输入文字" bordered maxlength="500" disableDefaultPadding="{{true}}" indicator style="{{inputStyle}}" bind:change="textareaChange" />
    </view>
    <view class="buttonBox">
      <view>
        <t-button bind:tap="onCancellation" style="margin: 20rpx 30rpx;" variant="outline" size="extra-small">取消</t-button>
        <t-button bind:tap="onConfirm" style="margin: 20rpx 30rpx;" theme="primary" size="extra-small">确认</t-button>
      <view class="submit-btn">
        <t-button theme="primary" size="large" block bind:tap="confirmSuggest">提交</t-button>
      </view>
    </view>
  </view>
</t-dialog>
  <t-icon t-class="close-btn" name="close-circle" size="32" color="#fff" bind:tap="closeDialog" />
</t-popup>
pages/resourceDetails/myVideo/index.wxss
@@ -130,7 +130,8 @@
.buttonBox {
  display: flex;
  justify-content: flex-end;
  /* justify-content: flex-end; */
  justify-content: center;
}
@@ -145,8 +146,9 @@
  height: 60rpx;
  display: flex;
  align-items: center;
  background: #F4F4F4;
  padding-left: 20rpx;
  background-color: #FFF6F0
}
.detailsName:hover {
@@ -160,3 +162,138 @@
  width: 750rpx;
  height: 200rpx;
}
.title-text {
  display: flex;
  align-items: center;
}
.note-title {
  width: 80%;
  height: 84rpx;
  line-height: 84rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 10rpx;
  margin-left: 20rpx;
}
.edit-icon {
  margin-left: 10rpx;
  width: 30rpx;
  height: 30rpx;
}
.submit-btn {
  padding: 40rpx;
  --td-button-border-radius: 60rpx;
  --td-button-primary-bg-color: #ff6c00;
  --td-button-primary-border-color: #ff6c00;
  --td-button-primary-active-bg-color: #ff984d;
  --td-button-primary-active-border-color: #ff984d;
}
.edit-icon {
  margin-left: 10rpx;
  width: 30rpx;
  height: 30rpx;
}
.textarea-example {
  padding: 32rpx 32rpx 48rpx;
  background-color: #fff;
}
.external-class {
  padding-top: 24rpx !important;
  padding-bottom: 24rpx !important;
}
.textarea-example__label {
  display: block;
  color: rgba(0, 0, 0, 0.9);
  font-size: 24rpx;
  line-height: 40rpx;
  padding-bottom: 16rpx;
}
.dialogIconBox {
  /* width: 500rpx;
  height: 300rpx;
  color: #000;
  background-color: ccc; */
}
.popup {
  padding: 40rpx;
  width: 600rpx;
}
.close-btn {
  position: absolute;
  left: 50%;
  margin-left: -32rpx;
  bottom: calc(-1 * (48rpx + 64rpx));
}
.collapse-header {
  display: flex;
}
.collapse-header .header-name {
  font-size: 32rpx;
  width: 500rpx;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.note-icon {
  width: 44rpx;
  height: 48rpx;
  margin-right: 20rpx;
}
.note-content {
  height: min-content;
  font-size: 28rpx;
  color: #949494;
  margin-bottom: 20rpx;
  max-height: 600rpx;
  text-align: justify;
  /* padding-bottom: 200rpx; */
}
.note-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.note-time {
  color: #D9D9D9;
}
.bottom-btn {
  height: 40rpx;
  display: flex;
  align-items: center;
}
.complice,
.delete {
  width: 30rpx;
  height: 30rpx;
  margin: 0 15rpx;
}
.t-tabs__item--active {
  color: #FF6C00 !important;
}
.t-tabs__track {
  background-color: #FF6C00 !important;
}
pages/retrievalPage/index.js
@@ -38,7 +38,7 @@
      navBarHeight: navBarHeight,
      barHeight: systInfo.statusBarHeight,
      searchVal: options.searchVal
    })
@@ -431,6 +431,11 @@
        fields
      })
      datas5.forEach((items) => {
        items.subtitleName = items.subtitle + items.name
      })
      console.log(datas5, 'sadasd');
      this.setData({
        biblioClassificationData: datas5,
        biblioClassificationTotal: data5.totalCount
@@ -517,6 +522,15 @@
    console.log(this.data.searchVal);
    this.retrievalPageGet()
    this.bibliographyGet()
  },
  onBook(e) {
    console.log(e.currentTarget.dataset.item);
    const item = e.currentTarget.dataset.item
    wx.navigateTo({
      url: '/pages/bookServices/detail/index?id=' + item.id + '&name' + item.name
    })
  }
})
pages/retrievalPage/index.wxml
@@ -22,7 +22,7 @@
    <view class="bookDataBox">
      <view class="bookDataForBox" wx:for="{{bookData}}" wx:key="index" wx:for-item="item" wx:for-index="index">
      <view class="bookDataForBox" wx:for="{{bookData}}" wx:key="index" wx:for-item="item" wx:for-index="index" data-item="{{item}}" bind:tap="onBook">
        <view class="imageBox">
          <image src="{{item.icon}}" mode="aspectFill" />
        </view>
@@ -153,7 +153,7 @@
      <view class="contentBox" wx:for="{{biblioClassificationData}}" wx:key="index" wx:for-item="item" wx:for-index="index" bindtap="onBookExhibitionDetails" data-item="{{item}}">
        <image class="bookFairImage" wx:if="{{item.icon}}" src="{{item.icon}}" mode="" />
        <image class="bookFairImage" wx:else="" src="/static/images/bookExhibitionList/banner.png" mode="" />
        <view class="textBox" title="{{item.name}}"> <text>{{item.name}}</text></view>
        <view class="textBox" title="{{item.name}}"> <text>{{item.subtitleName}}</text></view>
      </view>
    </view>
pages/retrievalPage/index.wxss
@@ -131,17 +131,14 @@
}
.body-info .name {
  font-size: 32rpx;
  height: 88rpx;
  color: #333333;
  font-weight: bold;
  line-height: 44rpx;
  display: -webkit-box;
  margin-bottom: 10rpx;
  font-size: 25rpx;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  margin-bottom: 10rpx;
}
.body-info .time {
@@ -176,7 +173,8 @@
.listBox1 .listItemBox {
  height: 220rpx;
  margin-bottom: 30rpx;
  margin-bottom: 20rpx;
  padding: 30rpx;
}
.listBox1 .specialSubject-img {
@@ -287,3 +285,12 @@
  padding: 15rpx;
  margin-bottom: 10rpx;
}
.t-tabs__item--active {
  color: #FF6C00 !important;
}
.t-tabs__track {
  background-color: #FF6C00 !important;
}
pages/testLogin/index.js
@@ -7,7 +7,7 @@
   * 页面的初始数据
   */
  data: {
    textName: "18892081234",
    textName: "15111111116",
    textPassword: "xA123456",
    loading: false,
    userInfo: {
static/images/bibliographyList/square.png
static/images/bibliographyList/square@2x.png
static/images/bookExhibitionList/zhuantitaolun.png
static/images/bookService/detail/checkpaper.png
static/images/bookService/detail/notest.png
static/images/document/zip.png
static/images/document/zip200px.png
static/images/document/zip200px@2x.png
static/video/sea.mp4
Binary files differ
style/theme.wxss
@@ -22,13 +22,13 @@
  --td-button-font-weight: 500;
  --td-button-medium-font-size: 32rpx;
  --td-button-default-color: #fff;
  --td-button-default-bg-color: #fa4126;
  --td-button-default-border-color: #fa4126;
  --td-button-default-bg-color: #FF6C00;
  --td-button-default-border-color: #FF6C00;
  --td-button-default-disabled-color: #fff;
  --td-button-default-disabled-bg: #cccccc;
  --td-button-default-disabled-border-color: #cccccc;
  --td-button-default-active-bg-color: #fa4126;
  --td-button-default-active-border-color: #fa4126;
  --td-button-default-active-bg-color: #FF6C00;
  --td-button-default-active-border-color: #FF6C00;
}
.t-textarea {