闫增涛
2024-03-19 33615d230f898d8dc48c3baed0570f51aef26330
组卷购买
6个文件已修改
1个文件已添加
597 ■■■■ 已修改文件
packageBookService/pages/bookServices/detail/components/testResource/testResource.wxml 134 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/components/testResource/testResource.wxss 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/index.js 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/index.wxml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/examination/examination.js 338 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageDomain/pages/sampleBookList/applicationForm/index.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/images/bookService/examination/zhuangtai-icon.png 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/components/testResource/testResource.wxml
@@ -1,146 +1,74 @@
<!--pages/bookServices/detail/components/testResource/testResource.wxml-->
<view class="test-resource">
  <view class="top-btn">
    <t-radio-group
      class="test-radio"
      t-class="horizontal-box"
      value="{{radioItem}}"
      bind:change="onRadioChange"
      style="margin: 0px"
    >
    <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
            >
            <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>
            <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
            >
              组卷</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="{{ 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=" {{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="{{ 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"
      bind:tap="goMycollect"
      data-answerType="errorQuestion"
    >
    <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"
      bind:tap="goMycollect"
      data-answerType="collectQuestion"
    >
    <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"
    wx:if="{{radioItem == 'test'}}"
  >
  <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 wx:if="{{mockData.mockList.length}}">
    <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-time">{{item.createDate}}</view></view
        >
        <view class="mock-score" wx:if="{{item.report.userScore}}"
          >{{item.report.userScore}}分</view
        >
          <view class="mock-score" wx:if="{{item.report.userScore}}">{{item.report.userScore}}分</view>
        </view>
      </view>
    </view>
  </view>
</view>
  <view wx:else class="not-mock">
    <t-image src="/static/images/bookService/examination/zhuangtai-icon.png"></t-image>
    <view class="not-mock-message note-mock-text">组卷是收费功能,请购买后使用!</view>
    <view class="note-mock-price note-mock-text">价格:<text class="mock-price">¥{{mockData.price}}</text> 元/次</view>
  </view>
</view>
packageBookService/pages/bookServices/detail/components/testResource/testResource.wxss
@@ -31,7 +31,8 @@
.top-btn {
  display: flex;
  justify-content: space-evenly;
  padding-left: 15rpx;
  padding: 0 0 20rpx 15rpx;
  border-bottom: 1px solid #EFF0F1;
}
.top-btn image {
@@ -207,4 +208,34 @@
.Incomplete {
  background-color: #e9e9e9;
  color: #666;
}
.not-mock {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.not-mock image {
  width: 328rpx;
  height: 328rpx;
}
.note-mock-text {
  color: #333;
  font-size: 28rpx;
}
.not-mock-message {
  margin: 24rpx 0;
}
.note-mock-price {
  margin-bottom: 50rpx;
}
.mock-price {
  color: #ff6c00;
  font-size: 36rpx;
}
packageBookService/pages/bookServices/detail/index.js
@@ -1,6 +1,7 @@
// pages/bookServices/detail/index.js
import Message from 'tdesign-miniprogram/message/index.js';
import Toast from 'tdesign-miniprogram/toast';
import tool from '../../../../assets/js/toolClass'
const app = getApp();
Page({
  /**
@@ -49,7 +50,8 @@
      useCount: 0, // 组件已使用次数
      residue: 0, // 组卷剩余次数
      mockList: [] // 用户组卷提交信息
    }
    },
    flag: true
  },
@@ -1115,6 +1117,88 @@
          })
        }
      })
  }
  },
  // 购买组卷
  async buyMock() {
    let res
    if (!this.data.mockData.id) return wx.showToast({
      icon: "error",
      title: '暂无组卷',
      mask: true
    })
    // 构建订单查询对象
    try {
      let query = {
        remarks: '组卷',
        requests: [
          {
            saleMethodId: this.data.mockData.id,
            count: 1
          }
        ]
      }
      if (this.data.flag) {
        this.setData({
          flag: false
        })
        res = await app.MG.store.initOrder(query)
      }
      if (res.orderNumber && this.data.mockData.price) {
        wx.navigateTo({
          url: `/pages/cart/paymentPage/index?orderNumber=${res.orderNumber}`,
        })
      } else {
        // 0元直接领取
        // 确认订单
        const confirmOrderRes = await app.MG.store.confirmOrder({ orderNum: res.orderNumber })
        if (confirmOrderRes) {
          wx.showToast({
            icon: "success",
            title: '领取成功',
          })
          this.setData({
            flag: true
          })
          await this.recordBuyMock() // 记录购买时间
        }
      }
    } catch (error) {
      console.log(error)
    }
  },
  // 记录购买组卷时间
  recordBuyMock() {
    const num = this.data.mockData.mockList.length
    const id = tool.uuid(8)
    const createDate = new Date().getTime()
    const mockList = this.data.mockData.mockList
    mockList.push({ id, createDate, name: `第${num + 1}套试卷`, state: '0' })
    this.setData({
      'mockData.mockList': mockList
    })
    // 记录购买时间,并设状态state为1,表示刚购买完成组卷
    app.MG.identity.setUserKey({
      setKeyRequests: [
        {
          domain: 'mockData',
          key: this.data.bookDetail.id + '',
          value: JSON.stringify(this.data.mockData.mockList)
        }
      ]
    })
  },
  // 底部购买按钮
  buyBtn() {
    if (this.data.tabValue == 'brief') {
      this.buyBook()
    }
    else if (this.data.tabValue == 'jsek_cloudLearning') {
      console.log('云学习');
    } else if (this.data.tabValue == 'questionBank') {
      this.buyMock()
    } else {
      console.log(this.data.tabValue);
    }
  }
})
packageBookService/pages/bookServices/detail/index.wxml
@@ -137,7 +137,7 @@
      <view class="btn-text">纸质样书申请</view>
    </view>
    <view class="shopCar" bind:tap="addBookShopcCar">加入购物车</view>
    <view class="buy" bind:tap="buyBook">立即购买</view>
    <view class="buy" bind:tap="buyBtn">立即购买</view>
  </view>
</scroll-view>
<!-- 我要建议弹窗 -->
packageBookService/pages/bookServices/examination/examination.js
@@ -29,6 +29,17 @@
    total: 0,   // 题目总数
    cardList: [],  // 提交项,
    questionDataList: [],  // 显示题目列表
    mockid: 0,
    uuid: 0,
    mockData: {
      // 组卷信息
      state: '0',
      score: 0, // 总分
      sumTime: 0,
      time: 0, // 答题剩余时间
      datas: [], // 所有模考记录数据(题目列表,用户答题,考试报告)
      answer: []
    }
  },
  /**
@@ -46,8 +57,14 @@
      productLinkPath: options.productLinkPath ? options.productLinkPath : '',
      rootCmsItemId: options.rootCmsItemId,
      idPathList: options.idPathList ? JSON.parse(options.idPathList) : [],
      answerType: options.answerType
      answerType: options.answerType,
    });
    if (this.data.answerType == 'mock') {
      this.setData({
        uuid: options.uuid,
        mockid: options.mockid
      })
    }
    this.init()
    console.log('传参', options);
  },
@@ -172,7 +189,6 @@
  },
  // 点击答题卡跳转题目
  goQuestion(e) {
    console.log(e);
    const id = e.detail.id
    this.data.questionDataList.forEach((item, index) => {
      if (item.id == id) {
@@ -296,6 +312,40 @@
      // loadings.value = true
      await this.getErrorIdList()
      await this.getCollectIdList() // 获取收藏id列表
    } else if (this.data.answerType == 'mock') {
      this.getErrorList()
      this.getCollectIdList()
      this.getMockInfo(async (res) => {
        let mocklist
        try {
          mocklist = JSON.parse(res[0].value)
        } catch (error) {
          mocklist = []
        }
        if (mocklist.length && this.data.uuid) {
          const oldMockData = mocklist.find((mockItem) => mockItem.id == this.data.uuid)
          this.setData({
            'mockData.state': oldMockData.state,
            'mockData.score': oldMockData.score,
            'mockData.datas': mocklist,
          })
          if (oldMockData.state == '0') {
            // 组卷购买了,但未进入页面
            await this.getEduQuizConfig()
          } else if (oldMockData.state == '1' || oldMockData.state == '2' || oldMockData.state == '3') {
            // 组卷后进入过页面,但是未答过题
            let oldQuestionList = []
            oldQuestionList = await this.getMockQuestionList()
            const userAnswerList = await this.getMockAnswer()
            await this.getMockDataList(oldQuestionList, userAnswerList)
            this.setData({
              'mockData.sumTime': oldMockData.time,
              cardList: oldQuestionList
            })
          }
        }
      })
    }
  },
  async restart() {
@@ -689,7 +739,6 @@
    this.setData({
      cardList: cardUpdatedList
    })
    // console.log(this.data.questionDataList, this.data.cardList);
  },
  // 题目收藏按钮,收藏和取消同一接口,取消数组减去该项id
  setCollect() {
@@ -841,7 +890,6 @@
            }
          })
        }
        // console.log('收藏', collectList.value)
      })
  },
  // 获取收藏夹
@@ -1118,6 +1166,286 @@
      })
    })
    // loadings.value = false
    // console.log('错题集', topicList.value)
  },
  // 获取组卷结果
  async getEduQuizConfig() {
    await app.MG.edu
      .getEduQuizConfigResult({
        idOrRefCode: this.data.mockid
      })
      .then(async (configRes) => {
        // 获取 分数 时间
        this.setData({
          'mockData.score': configRes.score
        })
        try {
          this.setData({
            'mockData.time': JSON.parse(configRes.config).time * 1000
          })
        } catch (error) {
          this.setData({
            'mockData.time': 3600 * 1000
          })
        }
        this.setData({
          'mockData.sumTime': this.data.mockData.time
        })
        let itemIds = []
        let numberIndex = 1
        // 获取抽题结果
        const cardList = configRes.eduQuizConfigStageResultList.map((item) => {
          let questionIds = []
          // 获取必含题目
          let list = item.cmsItemList.map((idItem) => {
            itemIds.push(idItem.id + '')
            questionIds.push({ id: idItem.id + '', score: idItem.score })
            numberIndex++
            return {
              number: numberIndex,
              itemId: idItem.id,
              score: idItem.score
            }
          })
          // 获取抽题题目
          let extractList = []
          for (let i = 0; i < item.generatorResultList.length; i++) {
            const extractItem = item.generatorResultList[i]
            let extractItemList = extractItem.cmsItemList.map((extractCmsItem) => {
              itemIds.push(extractCmsItem.id + '')
              questionIds.push({ id: extractCmsItem.id + '', score: extractCmsItem.score })
              numberIndex++
              return {
                number: numberIndex,
                itemId: extractCmsItem.id,
                score: extractCmsItem.score
              }
            })
            extractList = extractList.concat(extractItemList)
          }
          return {
            path: item.id,
            catalogName: item.name,
            infoList: list.concat(extractList)
          }
        })
        this.setData({
          cardList: cardList
        })
        // 更新该条组卷的数据状态,包括记录改试卷总分,更改组卷状态state为1,表示已经抽题完成,并要将抽屉数据记录下来
        if (this.data.mockData.datas && this.data.mockData.datas.length) {
          const mockData = this.data.mockData
          mockData.datas.forEach((item, index) => {
            if (item.id == this.data.uuid) {
              item.state = '1'
              item.time = mockData.time
              item.score = configRes.score
              mockData.state = '1'
            }
          })
          this.setData({
            mockData: mockData
          })
        }
        this.setMockInfo(this.data.mockData.datas) // 记录试卷总分 时长,修改state为 1
        // 更新本地mockData
        this.saveMockQuestionList(this.data.cardList) // 记录题目列表
        await this.getMockDataList(this.data.cardList) // 请求题目数据
      })
  },
  // 获取组卷数据
  getMockInfo(callback) {
    app.MG.identity
      .getUserKey({
        domain: 'mockData',
        keys: [this.data.bookId]
      })
      .then((res) => {
        if (callback) callback(res)
      })
  },
  // 记录购买组卷时间
  setMockInfo(data) {
    app.MG.identity.setUserKey({
      setKeyRequests: [
        {
          domain: 'mockData',
          key: this.data.bookId + '',
          value: JSON.stringify(data)
        }
      ]
    })
  },
  // 记录组卷题目列表
  saveMockQuestionList(data) {
    app.MG.identity
      .setUserKey({
        setKeyRequests: [
          {
            domain: 'mockQuestionData',
            key: this.data.uuid,
            value: JSON.stringify(data)
          }
        ]
      })
      .then((res) => {
        console.log('模考题目列表已记录')
      })
  },
  // 获取记录组卷题目列表
  async getMockQuestionList() {
    let list = []
    await app.MG.identity
      .getUserKey({
        domain: 'mockQuestionData',
        keys: [this.data.uuid]
      })
      .then((res) => {
        list = JSON.parse(res[0].value)
      })
    return list
  },
  // 获取模考用户答题数据
  async getMockAnswer() {
    let data
    await app.MG.identity
      .getUserKey({
        domain: 'mockAnswerData',
        keys: [this.data.uuid]
      })
      .then((res) => {
        if (res[0]) {
          this.setData({
            'mockData.time': JSON.parse(res[0].value).timem,
            'mockData.answer': JSON.parse(res[0].value).answerData
          })
          data = JSON.parse(res[0].value).answerData
        }
      })
    return data
  },
  // 组卷获取题目列表
  async getMockDataList(questionList, oldList) {
    const questionDataList = this.data.questionDataList
    questionList.forEach(async (pathitem, pathindex) => {
      let itemIds = []
      pathitem.infoList.forEach(item => {
        itemIds.push(item.itemId + '')
      })
      let query = {
        path: '*',
        cmsPath: this.data.rootCmsItemId,
        cmsType: '*',
        productId: this.data.bookId,
        queryType: '*',
        itemIds,
        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) => {
        res.datas.cmsDatas[0].datas.forEach((item, index) => {
          // 循环questionList,给每题赋值分数
          let oldObj
          if (oldList) oldObj = oldList.find((oldItem) => oldItem.id == item.id)
          let questionObj = {
            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: oldObj
              ? oldObj.answer
              : item.Embedded_QuestionBank_QuestionType == 'completion' ||
                item.Embedded_QuestionBank_QuestionType == 'multipleChoice'
                ? []
                : '',
            isRight: oldObj ? oldObj.isRight : null,
            // isComplete: oldObj ? oldObj.isComplete : false,
            isComplete: oldObj ? oldObj.isComplete : false,
            isCollect: this.data.collectList.indexOf(item.id) > -1 ? true : false,
            isUnfold: '' // 控制解析的折叠面板是否展开
          }
          const cardList = this.data.cardList
          for (let a = 0; a < cardList.length; a++) {
            const cardItem = cardList[a];
            for (let b = 0; b < cardItem.infoList.length; b++) {
              if (cardItem.infoList[b].itemId == item.id) {
                questionObj.number = cardItem.infoList[b].number;
                questionObj.score = cardItem.infoList[b].score;
                cardItem.infoList[b] = obj;
              }
            }
          }
          this.setData({
            cardList: cardList
          })
          // 多选和填空答案肯为数组,要转换JSON格式
          if (
            questionObj.questionType == 'completion' ||
            questionObj.questionType == 'multipleChoice'
          ) {
            try {
              questionObj.answer = JSON.parse(questionObj.answer)
            } catch (error) {
              questionObj.answer = item.Embedded_QuestionBank_Answer
            }
          }
          // 填空题改造
          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'
                }
                if (!oldObj) questionObj.userAnswer[index] = ''
                index++
              }
            }
          }
          if (oldObj && oldObj.isRight) {
            this.setData({
              correctNum: this.data.correctNum + 1
            })
          }
          if (item.questionType != 'shortAnswer') {
            this.setData({
              subjectiveTotal: this.data.subjectiveTotal + 1
            })
          }
          // if (oldObj && isHaveAnswer(oldObj.answer)) countDownRef.value.changeAlready()
          questionDataList.push(questionObj)
        })
      })
    })
    this.setData({
      questionDataList: questionDataList,
      loading: false
    })
  }
})
packageDomain/pages/sampleBookList/applicationForm/index.js
@@ -1,4 +1,4 @@
import { worksDataBytool } from "../../../../../assets/js/toolClass.js";
import { worksDataBytool } from "../../../../assets/js/toolClass.js";
const app = getApp();
Page({
  data: {
static/images/bookService/examination/zhuangtai-icon.png