xz
litian
2024-08-30 485fcbbc57cbf7495286359250135c482ec1360a
xz
28个文件已修改
9个文件已添加
1777 ■■■■■ 已修改文件
app.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app.wxss 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/js/middleGround/api/resource.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/components/brief/index.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/components/brief/index.wxml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/components/teachResource/index.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/components/teachResource/index.wxml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/components/teachResource/index.wxss 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/index.js 248 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/index.json 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/index.wxml 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageBookService/pages/bookServices/detail/index.wxss 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packageDomain/pages/teacherCertification/index.wxss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/digitalCourses/digitalCoursesDetails/index.js 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/digitalCourses/digitalCoursesDetails/index.wxml 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/digitalCourses/digitalCoursesDetails/index.wxss 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/digitalTextbooks/digitalTextbooksDetails/index.js 157 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/digitalTextbooks/digitalTextbooksDetails/index.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/digitalTextbooks/digitalTextbooksDetails/index.wxml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/digitalTextbooks/digitalTextbooksDetails/index.wxss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/digitalTextbooks/index.wxml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/personalCenter/certificate/index.js 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/personalCenter/certificate/index.json 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/personalCenter/certificate/index.wxml 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/personalCenter/certificate/index.wxss 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/personalCenter/index.js 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/personalCenter/pointsRecord/index.js 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/personalCenter/pointsRecord/index.json 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/personalCenter/pointsRecord/index.wxml 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/personalCenter/pointsRecord/index.wxss 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/images/certificate/jczs.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/images/certificate/kczs.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/images/certificate/szjc.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/images/certificate/szkc.jpg 补丁 | 查看 | 原始文档 | blame | 历史
static/images/home/zhuantitaolun2.png 补丁 | 查看 | 原始文档 | blame | 历史
static/images/personal/jifen-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
app.json
@@ -12,6 +12,7 @@
    "pages/personalCenter/index",
    "pages/personalCenter/feedBackSubmit/index",
    "pages/personalCenter/certificate/index",
    "pages/personalCenter/pointsRecord/index",
    "pages/bookServices/assort/index",
    "pages/testLogin/index",
    "pages/bindInfo/index",
app.wxss
@@ -18,3 +18,8 @@
  font-family: "JDLANGZHENGTI";
  src: url('https://jsek.bnuic.com/home/font/JDLANGZHENGTI.TTF')format("truetype");
}
@font-face {
  font-family: 'FZXBSJW';
  src: url('https://jsek.bnuic.com/home/font/FZXBSJW.TTF') format('truetype');
}
assets/js/middleGround/api/resource.js
@@ -62,14 +62,14 @@
      Description: [],
      Name: [],
      Icon: [],
      // RefCode: [],
      RefCode: [],
      Type: [],
      TypeId: [],
      State: [],
      Tag: [],
      LinkInfo: [],
      LinkFile: [],
      // CmsItemType: [],
      CmsItemType: [],
      ChildrenFolderCount: [],
      ChildrenCount: [],
      ...fields,
@@ -92,7 +92,7 @@
        }]
      })
    };
    let token = wx.getStorageSync('tokenKey');
    let token = wx.getStorageSync(tokenKey);
    return request({
      url: token ? "/resource/api/ApiAppUserQuery" : "/resource/api/ApiQuery",
      method: "post",
package.json
@@ -29,7 +29,8 @@
    "mp-html": "^2.4.3",
    "spark-md5": "^3.0.2",
    "tdesign-miniprogram": "^1.0.0",
    "tslib": "^1.11.1"
    "tslib": "^1.11.1",
    "wxml2canvas": "^1.0.1"
  },
  "devDependencies": {
    "@commitlint/cli": "^17.4.2",
packageBookService/pages/bookServices/detail/components/brief/index.js
@@ -4,6 +4,10 @@
      type: String,
      value: '',
    },
    catalogue: {
      type: String,
      value: '',
    },
    authorIntroduction: {
      type: String,
      value: '',
packageBookService/pages/bookServices/detail/components/brief/index.wxml
@@ -8,6 +8,15 @@
    </view>
    <rich-text nodes="{{content}}" style="{{richStyle}}"></rich-text>
  </view>
  <view class="basic" wx:if="{{content}}">
    <view class="basic-title">
      <view>
        <image src="/static/images/bookService/detail/label.png" />
      </view>
      <view class="title-name">图书目录</view>
    </view>
    <rich-text nodes="{{catalogue}}" style="{{richStyle}}"></rich-text>
  </view>
  <view class="basic" wx:if="{{authorIntroduction}}">
    <view class="basic-title">
      <view>
packageBookService/pages/bookServices/detail/components/teachResource/index.js
@@ -56,5 +56,8 @@
        showRejectDialog: false,
      });
    },
    uploadBtn() {
      this.triggerEvent("uploadFile", true);
    },
  },
});
packageBookService/pages/bookServices/detail/components/teachResource/index.wxml
@@ -1,12 +1,12 @@
<view class="teach-btn" wx:if="{{false}}">
  <t-button theme="primary" style="width: 120px; height: 36px" class="btn-upload" wx:if="{{false}}">
<view class="teach-btn">
  <t-button theme="primary" style="width: 120px; height: 36px" class="btn-upload" bind:tap="uploadBtn">
    <t-image src="/static/images/bookService/detail/upload.png" style="margin-top: 20rpx"></t-image>
    <text>上传资源</text>
  </t-button>
  <t-button theme="primary" style="width: 120px; height: 36px">
  <!-- <t-button theme="primary" style="width: 120px; height: 36px">
    <t-image src="/static/images/bookService/detail/download.png"></t-image>
    批量下载
  </t-button>
  </t-button> -->
</view>
<view class="applyResult  {{applyState == 'none' ? 'applyNone' : applyState == 'Normal' ? 'applyPass' : applyState == 'WaitAudit' ? 'applying' :applyState == 'Reject' ? 'applyReject' :'' }}">
  <view wx:if="{{applyState == 'WaitAudit'}}">资源下载申请正在审核中,请耐心等待!</view>
packageBookService/pages/bookServices/detail/components/teachResource/index.wxss
@@ -1,7 +1,8 @@
.teach-btn {
  display: flex;
  justify-content: flex-start;
  justify-content: flex-end;
  align-items: center;
  padding: 0 40rpx;
  height: 134rpx;
  --td-button-primary-bg-color: #fff;
  --td-button-primary-border-color: #FF6C00;
packageBookService/pages/bookServices/detail/index.js
@@ -4,6 +4,7 @@
import {
  loginInfo
} from "../../../../assets/js/login";
import FormData from '../../../../utils/formdata/index.js';
const app = getApp();
Page({
  /**
@@ -157,7 +158,17 @@
    showIndex: '',
    successOrderNumber: '',
    applicationState: '', // 电子样书申请状态
    dialogBox: false,
    resourceInfo: {
      resourceName: '',
      fileType: '',
      description: '',
      agree: false
    },
    fileList: [],
    isShowUp: true,
    protocolShow: false,
    protocolTxt: ''
  },
  resetTree: function (e) {
@@ -376,6 +387,7 @@
        dangdangLink: [],
        weidianLink: [],
        content: [],
        catalogue: [],
        authorIntroduction: [],
        // isApplyPaperBook: [],
        // isApplyEBook: [],
@@ -2527,32 +2539,250 @@
  },
  // 传递ids,将需要展开的id的children 赋值
  increaseTreeData(treeList, list, openid) {
    let num = 0;
    // let useData = treeList.find(item => item.id == openid)
    for (let index = 0; index < treeList.length; index++) {
      const item = treeList[index];
      if (item.id == openid && num >= 3) {
        debugger
        let useArr = item.children ? item.children : []
        changeList(list, openid, useArr)
        this.changeList(list, openid, useArr)
      } else {
        num += 1
        this.increaseTreeData(item.children, list, openid)
      }
    }
  },
    // 递归前两层,找出需要展开的
    const changeList = (isList, id, childrenList) => {
  changeList(isList, id, childrenList) {
      for (let dindex = 0; dindex < isList.length; dindex++) {
        const ditem = isList[cindex];
      const ditem = isList[dindex];
        if (ditem.id == id) {
          diitem.children = childrenList
        ditem.children = childrenList
          return true
        } else {
          changeList(ditem.children, id, childrenList)
        this.changeList(ditem.children, id, childrenList)
        }
      }
    return childrenList
  },
  uploadFile(e) {
    console.log(123)
    this.setData({
      dialogBox: true,
      isShowUp: true
    });
  },
  closeDialog() {
    this.setData({
      dialogBox: false,
    });
  },
  onCloseProtocol() {
    this.setData({
      protocolShow: false,
    });
  },
  onVisibleChange(e) {
    this.setData({
      protocolShow: e.detail.visible,
    });
  },
  //查看协议
  getAgreement() {
    let query = {
      path: 'jsek_protocol',
      fields: {
        content: [],
    }
    return list
    }
    app.MG.resource.getItem(query).then((res) => {
      try {
        const data = res.datas.find((e) => e.refCode == 'jsek_authorizationAndConsentLetter')
        this.setData({
          protocolTxt: data && data.content ? data.content : '暂无协议',
          protocolShow: true
        });
      } catch (error) {
        this.setData({
          protocolTxt: '暂无协议',
          protocolShow: true,
        });
      }
    })
  },
  onNameInput(e) {
    console.log(e.detail.value)
    this.setData({
      'resourceInfo.resourceName': e.detail.value,
    });
  },
  onFileTypeInput(e) {
    this.setData({
      'resourceInfo.fileType': e.detail.value,
    });
  },
  textareaChange(e) {
    this.setData({
      'resourceInfo.description': e.detail.value,
    });
  },
  onChange() {
    if (this.data.resourceInfo.agree) {
      this.setData({
        'resourceInfo.agree': false,
      });
    } else {
      this.setData({
        'resourceInfo.agree': true,
      });
    }
  },
  uploadPicture() {
    var that = this;
    wx.chooseMessageFile({
      count: 1,
      type: 'file',
      success(res) {
        const isLt2M = res.tempFiles[0].size / 1024 / 1024 < 50
        if (!isLt2M) {
          return wx.showToast({
            title: "上传文件大小不能超过 50MB!",
            icon: "none",
            duration: 1000,
          });
        }
        const FileName = res.tempFiles[0].name.split('.')[0]
        const Extension = res.tempFiles[0].name.split('.')[1]
        var medioType = ''
        const audioData = ['mp3', 'mp3']
        const videoData = ['mp4', 'avi']
        const pdfData = ['pdf']
        const Compression = ['rar', 'zip']
        const pictureData = ['jpg', 'png']
        if (audioData.indexOf(Extension) > -1) {
          medioType = '音频'
        } else if (videoData.indexOf(Extension) > -1) {
          medioType = '视频'
        } else if (pdfData.indexOf(Extension) > -1) {
          medioType = 'PDF'
        } else if (Compression.indexOf(Extension) > -1) {
          medioType = '资源包'
        } else if (pictureData.indexOf(Extension) > -1) {
          medioType = '图片'
        } else {
          medioType = '其他'
        }
        wx.getFileSystemManager().getFileInfo({
          filePath: res.tempFiles[0].path, //选择图片返回的相对路径
          // encoding: 'binary', //编码格式
          success: ress => {
            //成功的回调
            let md5 = ress.digest;
            let formData = new FormData();
            formData.append('Md5', md5);
            formData.append('FileName', FileName);
            formData.append('FileType', res.tempFiles[0].type);
            formData.appendFile("file", res.tempFiles[0].path);
            const data = formData.getData();
            let _token = wx.getStorageSync(app.config.tokenKey);
            let header = {};
            if (_token == null) {
              header["Authorization"] = `Basic ${Base64.encode(website.clientId + ":" + website.clientSecret)}`;
            } else {
              header["Authorization"] = `Bearer ` + _token;
            }
            new Promise((resolve, reject) => {
              wx.request({
                url: app.config.requestCtx + '/file/api/ApiUpload',
                method: 'POST',
                header: {
                  'content-type': data.contentType,
                  ...header
                },
                data: data.buffer,
                success(res1) {
                  resolve(res1.data);
                  if (res1.data) {
                    let file = [{
                      name: res.tempFiles[0].name,
                      md5: md5,
                      type: medioType,
                      FileType: Extension
                    }]
                    that.setData({
                      "resourceInfo.resourceName": FileName,
                      "resourceInfo.fileType": medioType,
                      fileList: file,
                      isShowUp: false
                    })
                  }
                }
              })
            })
          }
        })
      }
    })
  },
  handleRemove(e) {
    console.log(e)
    let md5 = e.currentTarget.dataset.md5
    for (let i = 0; i < this.data.fileList.length; i++) {
      if (this.data.fileList.md5 == md5) {
        this.data.fileList.splice(i, 1)
      }
    }
    this.setData({
      isShowUp: true,
    });
  },
  confirmM() {
    if (this.data.resourceInfo.resourceName == '') {
      return wx.showToast({
        icon: "error",
        title: "请填写资源名称",
      });
    }
    if (this.data.resourceInfo.fileType == '') {
      return wx.showToast({
        icon: "error",
        title: "请填写资源类型",
      });
    }
    if (!this.data.fileList.length) {
      return wx.showToast({
        icon: "error",
        title: "请上传资源文件",
      });
    }
    if (!this.data.resourceInfo.agree) {
      return wx.showToast({
        icon: "none",
        title: "请同意《授权同意书》!",
      });
    }
    let query = {
      topicIdOrRefCode: "uploadFiles",
      name: this.data.bookDetail.name,
      content: JSON.stringify(JSON.parse(JSON.stringify(this.data.fileList))),
      type: 'UserSubmit',
      description: this.data.resourceInfo.description,
      cmsTypeRefCode: '',
      newDataListRequest: []
    }
    app.MG.ugc.newTopicMessage(query).then((res) => {
      wx.showToast({
        icon: "success",
        title: "请上传资源文件",
      });
      this.setData({
        dialogBox: false,
      });
    })
  }
})
packageBookService/pages/bookServices/detail/index.json
@@ -21,7 +21,11 @@
    "t-fab": "tdesign-miniprogram/fab/fab",
    "t-skeleton": "tdesign-miniprogram/skeleton/skeleton",
    "suggest-dialog": "/packageBookService/pages/bookServices/detail/components/suggestDialog/index",
    "empty": "/components/empty/index"
    "empty": "/components/empty/index",
    "t-input": "tdesign-miniprogram/input/input",
    "t-textarea": "tdesign-miniprogram/textarea/textarea",
    "t-checkbox": "tdesign-miniprogram/checkbox/checkbox",
    "t-popup": "tdesign-miniprogram/popup/popup"
  },
  "onReachBottomDistance": 200,
  "disableScroll": true
packageBookService/pages/bookServices/detail/index.wxml
@@ -111,8 +111,8 @@
      <view class="book-resource">
        <t-tabs value="{{tabValue}}" bind:change="onTabsChange" t-class="custom-tabs" t-class-content="custom-panel" class="tab-class">
          <t-tab-panel label="图书简介" icon="{{ tabValue == 'brief' ? briefIconClick : briefIcon}}" value="brief" style="{{tabPanelstyle}}">
            <book-brief content="{{bookDetail.content}}" authorIntroduction="{{bookDetail.authorIntroduction}}" wx:if="{{bookDetail.content || bookDetail.authorIntroduction}}"></book-brief>
          <t-tab-panel label="图书信息" icon="{{ tabValue == 'brief' ? briefIconClick : briefIcon}}" value="brief" style="{{tabPanelstyle}}">
            <book-brief content="{{bookDetail.content}}" catalogue="{{bookDetail.catalogue}}" authorIntroduction="{{bookDetail.authorIntroduction}}" wx:if="{{bookDetail.content || bookDetail.authorIntroduction}}"></book-brief>
            <view wx:if="{{!bookDetail.content && !bookDetail.authorIntroduction && !loading}}" class="noData">
              <!-- <t-empty icon="folder-open" description="暂无数据" /> -->
              <empty />
@@ -127,7 +127,7 @@
        </t-tab-panel> -->
          <t-tab-panel label="教学资源" icon="{{tabValue == 'jsek_teachingResources' ? teachResourcesClickIcon : teachResourcesIcon}}" value="jsek_teachingResources" class="{{loading ? 'loading': ''}}">
            <view wx:if="{{!loading && teach.length && !noResources && applyState}}">
              <teach-resource applyState="{{applyState}}" rejectCause="{{rejectCause}}" deadline="{{deadline}}" bind:applyResource="applyResource" applyResourceLoading="{{applyResourceLoading}}"></teach-resource>
              <teach-resource applyState="{{applyState}}" rejectCause="{{rejectCause}}" deadline="{{deadline}}" bind:applyResource="applyResource" applyResourceLoading="{{applyResourceLoading}}" bind:uploadFile="uploadFile"></teach-resource>
              <tree id="teach-tree" openIds="{{openTeachids}}" bookInfo="{{bookDetail}}" treeList="{{teach}}" tab="{{tabValue}}" applyState="{{applyState}}" deadline="{{deadline}}" bind:downloadTeach="downloadTeach" bind:handleTree="handleTree" openTeachids="{{openTeachids}}" wx:if="{{teach.length}}" isShoppingCart="isShoppingCart" bind:updateCloudLearning="updateCloudLearning"></tree>
            </view>
            <!-- <t-loading
@@ -209,7 +209,80 @@
    <view class="buy read" bind:tap="goRead" wx:if="{{bookBuy || applicationState == 'Normal'}}">立即查看</view>
  </view>
</view>
<view wx:if="{{dialogBox}}">
  <view class="popup-box" bindtap="closeDialog"></view>
  <view class="info-center">
    <view>
      <view class="row-info">
        <view class="body">
          <view class="dialog-title">文件上传</view>
          <view style="width: 100%; height: 2rpx; background-color: #F4F4F4;"></view>
          <view class="from-item">
            <view class="label">
              <text class="icon">*</text>资源名称:
            </view>
            <view class="item-content">
              <view class="inputBox1">
                <t-input placeholder="输入资源名称" borderless value="{{resourceInfo.resourceName}}" bindchange="onNameInput" />
              </view>
            </view>
          </view>
          <view class="from-item">
            <view class="label">
              <text class="icon">*</text>资源类型:
            </view>
            <view class="item-content">
              <view class="inputBox1">
                <t-input placeholder="输入资源类型" borderless value="{{resourceInfo.fileType}}" bindchange="onFileTypeInput" />
              </view>
            </view>
          </view>
          <view class="from-item">
            <view class="label">文件描述:</view>
            <view class="item-content">
              <view class="inputBox1">
                <t-textarea placeholder="请输入文件描述" value="{{resourceInfo.description}}" disableDefaultPadding="{{true}}" autosize="{{true}}" maxlength="300" indicator bind:change="textareaChange" />
              </view>
            </view>
          </view>
          <view class="from-item">
            <view class="label">
              <text class="icon">*</text>上传文件:
            </view>
            <view class="item-content">
              <t-button size="small" class="right-btn" bind:tap="uploadPicture" wx:if="{{isShowUp}}">点击上传</t-button>
              <view wx:if="{{!isShowUp && fileList.length > 0}}" class="fileList">
                <text>{{fileList[0].name}}</text>
                <image src="/static/images/bookService/detail/deleteHover.png" class="deleteBtn" data-md5="{{fileList[0].md5}}" bind:tap="handleRemove" />
              </view>
            </view>
            <view class="tip">注:文件大小不得超过50MB</view>
          </view>
          <view class="from-item">
            <view class="protocolBox">
              <t-checkbox label="同意" icon="rectangle" checked="{{resourceInfo.agree}}" bind:change="onChange" />
              <text class="wait" bind:tap="getAgreement">《授权同意书》</text>
            </view>
          </view>
        </view>
        <view class="row-btn">
          <view class="left-btn" bindtap="closeDialog">取消</view>
          <view class="right-btn" bindtap="confirmM">确认</view>
        </view>
      </view>
    </view>
  </view>
</view>
<view class="popupBox">
  <t-popup visible="{{protocolShow}}" bind:visible-change="onVisibleChange" placement="center">
    <view class="block">
      <view class="protocol">
        <rich-text space="emsp" nodes="{{protocolTxt}}" class="content" />
      </view>
      <t-icon t-class="close-btn" name="close-circle" size="32" color="#fff" bind:tap="onCloseProtocol" />
    </view>
  </t-popup>
</view>
<!-- <view class="loading" wx:if="{{pageLoading}}">
  <t-loading loading="{{pageLoading}}" size="40"></t-loading>
</view> -->
packageBookService/pages/bookServices/detail/index.wxss
@@ -463,3 +463,156 @@
/* .t-collapse-panel__content {
  padding: 0rpx !important;
} */
/* 蒙层 */
.popup-box {
  position: absolute;
  z-index: 99;
  top: 0;
  background-color: rgba(0, 0, 0, 0.5);
  width: 100%;
  height: 100vh;
}
.info-center {
  position: fixed;
  top: 15%;
  z-index: 999;
  background-color: white;
  align-items: center;
  justify-content: center;
  border-radius: 10rpx;
  width: 80%;
  margin-left: 10%;
  margin-right: 10%;
}
.row-info .body {
  min-height: 300rpx;
  padding: 0 20rpx;
}
.dialog-title {
  padding: 20rpx 0;
  text-align: center;
  font-weight: bold;
  font-size: 29rpx;
  color: #333333;
}
.row-info .body .from-item .label {
  min-width: 100rpx;
  height: 60rpx;
  line-height: 60rpx;
  font-size: 28rpx;
}
.row-btn {
  width: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  border-top: 1rpx solid #f1f1f1;
}
.row-btn view {
  flex: 1;
  text-align: center;
  margin: 20rpx 10%;
  padding: 12rpx 0;
  font-size: 32rpx;
  border-radius: 10rpx;
}
.left-btn {
  background-color: #f1f1f1;
  color: #5C5C5C;
}
.right-btn {
  background-color: #ff6c00;
  color: white;
}
.t-input {
  padding: 10rpx !important;
}
.t-input__content,
.t-textarea {
  border: 2rpx solid #D9D9D9 !important;
  border-radius: 15rpx;
  padding: 10rpx !important;
}
.from-item .label .icon {
  color: #f56c6c !important;
  margin-right: 5rpx;
}
.tip {
  font-size: 24rpx;
  color: #606266;
}
.t-input__placeholder,
.t-textarea__placeholder {
  font-size: 28rpx !important;
}
.protocolBox {
  padding: 40rpx 20rpx;
  display: flex;
}
.t-checkbox {
  background: none !important
}
.t-checkbox--block {
  padding: 0 !important;
}
.t-checkbox__title {
  font-size: 28rpx;
}
.wait {
  line-height: 48rpx;
  font-size: 28rpx;
  color: #FF6C00;
}
.block {
  position: relative;
  width: 600rpx;
  height: 820rpx;
  padding: 20rpx 0;
  background: #fff;
  border-radius: 16rpx;
}
.protocol {
  padding: 0 20rpx;
  height: 800rpx !important;
  overflow: auto !important;
}
.close-btn {
  position: absolute;
  left: 50%;
  margin-left: -32rpx;
  bottom: calc(-1 * (48rpx + 64rpx));
}
.fileList {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10rpx;
  background: #f1f1f1;
}
.deleteBtn {
  width: 30rpx;
  height: 30rpx;
}
packageDomain/pages/teacherCertification/index.wxss
@@ -158,7 +158,6 @@
.protocolBox {
  padding: 20rpx;
  display: flex;
}
.t-checkbox {
pages/digitalCourses/digitalCoursesDetails/index.js
@@ -1,5 +1,9 @@
// pages/digitalCourses/digitalCoursesDetails/index.js
const app = getApp()
import SparkMD5 from 'spark-md5'
import FormData from '../../../utils/formdata/index.js';
// import Wxml2Canvas from 'wxml2canvas';
// const Wxml2Canvas = require('Wxml2Canvas')
import {
  worksDataBytool
} from "../../../assets/js/toolClass.js";
@@ -50,6 +54,12 @@
    onlineQuestioningClick: {
      name: "/static/images/digitalCourses/tiwen-click@2x.png"
    },
    testResourceClickIocn: {
      name: "/static/images/digitalTextbooks/link-t-click@3x.png",
    },
    testResourceIocn: {
      name: "/static/images/digitalTextbooks/link-t@3x.png",
    },
    dialogBox: false,
    lecturerList: [],
@@ -80,9 +90,15 @@
    isLearn: false,
    isTest: false,
    userInfo: {
      fullName: '' //名称
      fullName: '', //名称
      userPicture: '' //申请证书用户图片
    },
    publishingUnit: ''
    pictureMd5: '',
    publishingUnit: '',
    pubCertificateHide: true,
    cbzsImg: '', //出版证书base64
    rzzsImg: '' //认证证书base64
  },
  formatDate(dateString) {
    if (!dateString) {
@@ -293,6 +309,7 @@
          }
        })
      }
      this.getAboutBook(res.datas.productLinkInfo[res.datas.productLinkInfo.length - 1].LinkPath)
      this.setData({
        lecturerList: lecturer,
@@ -561,6 +578,56 @@
      }
    }
  },
  // 获取相关教材
  getAboutBook(path) {
    let query = {
      path,
      queryType: '*',
      coverSize: {
        width: 260
      },
      paging: {
        start: 0,
        size: 9
      },
      fields: {
        author: [],
        publicationDate: []
      }
    }
    app.MG.store.getProductList(query).then(res => {
      const Arr = res.datas.filter(
        (item) => item.id != this.data.digitalsData.id
      );
      let bookArr = []
      if (Arr.length) {
        if (Arr.length > 9) {
          for (var i = 0; i < 9; i++) {
            var _num = Math.floor(Math.random() * Arr.length)
            var mm = Arr[_num]
            Arr.splice(_num, 1)
            bookArr.push(mm)
          }
        } else {
          bookArr = Arr
        }
        bookArr.forEach(item => {
          if (item.icon == '') {
            item.icon = '/static/images/default-book-img.png'
          }
        })
        this.setData({
          relatedBookData: bookArr
        })
        console.log(this.data.relatedBookData);
      } else {
        this.setData({
          relatedBookData: []
        })
      }
    })
  },
  //学习笔记
  //在线提问
  // 图书添加购物车
@@ -679,7 +746,23 @@
    });
  },
  //申请证书
  async saveAsImage() {
    await nextTick()
    let query = wx.createSelectorQuery();
    let value = query.select("#pubCertificate").boundingClientRect();
    Wxml2Canvas(value).then((canvas) => {
      const img = canvas.toDataURL('image/png')
      this.setData({
        cbzsImg: img,
      })
    })
    // Wxml2Canvas(textCertificate.value).then((canvas1) => {
    //   const img1 = canvas1.toDataURL('image/png')
    //   rzzsImg.value = img1
    // })
    pubCertificateHide.value = false
  },
  //获取字段
  getType() {
    app.MG.resource.getCmsTypeByRefCode({
@@ -713,6 +796,8 @@
      })
    })
  },
  onCertificate() {
    // if (!this.data.isBuy) {
@@ -763,13 +848,95 @@
      "userInfo.fullName": e.detail.value,
    });
  },
  uploadPicture() {
    var that = this;
    wx.chooseMedia({
      count: 1, // 默认9
      sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
      success: function (res) {
        wx.getFileSystemManager().readFile({
          filePath: res.tempFiles[0].tempFilePath, //选择图片返回的相对路径
          // encoding: 'binary', //编码格式
          success: ress => {
            //成功的回调
            console.log(ress.data, 45613489)
            let spark = new SparkMD5.ArrayBuffer();
            spark.append(ress.data);
            let md5 = spark.end(false);
            let formData = new FormData();
            formData.append('Md5', md5);
            formData.append('FileName', md5);
            formData.append('FileType', res.tempFiles[0].fileType);
            formData.appendFile("file", res.tempFiles[0].tempFilePath);
            const data = formData.getData();
            let _token = wx.getStorageSync(app.config.tokenKey);
            let header = {};
            if (_token == null) {
              header["Authorization"] = `Basic ${Base64.encode(website.clientId + ":" + website.clientSecret)}`;
            } else {
              header["Authorization"] = `Bearer ` + _token;
            }
            new Promise((resolve, reject) => {
              wx.request({
                url: app.config.requestCtx + '/file/api/ApiUpload',
                method: 'POST',
                header: {
                  'content-type': data.contentType,
                  ...header
                },
                data: data.buffer,
                success(res) {
                  if (res.statusCode == 200) {
                    resolve(res.data);
                    if (res.data) {
                      console.log(md5, "md5555")
                      that.setData({
                        'userInfo.userPicture': app.config.requestCtx + `/file/GetPreViewImage?md5=` + md5,
                        pictureMd5: md5
                      });
                    }
                  } else {
                    reject('运行时错误,请稍后再试');
                  }
                }
              })
            })
          }
        })
      }
    });
  },
  confirmM() {
    if (this.data.userInfo.fullName) {
      if (this.data.pictureMd5 == '') {
        wx.showToast({
          title: "请上传照片",
          icon: "none",
          duration: 1000,
        });
        return false
      }
      let data = {}
      let bookInfo = {
        bookId: this.data.digitalsData.id,
        icon: this.data.digitalsData.icon,
        courseLeader: this.data.digitalsData.courseLeader,
        name: this.data.digitalsData.name,
        ISBN: this.data.digitalsData.isbn,
        affiliatedUnit: this.data.digitalsData.affiliatedUnit,
        publicationDate: this.data.digitalsData.publicationDate,
        classHours: this.data.digitalsData.classHours,
        lecturerList: this.data.lecturerList.length > 0 ?
          this.data.lecturerList[0].name : this.data.digitalsData.courseLeader,
        userPicture: this.data.pictureMd5,
        certificate: this.data.rzzsImg
      }
      data = {
        topicIdOrRefCode: 'applyCourseCertificate',
        name: this.data.userInfo.fullName,
        content: JSON.stringify(this.data.digitalsData),
        content: JSON.stringify(bookInfo),
        state: 'WaitAudit',
        cmsTypeRefCode: 'jsek_courseCertificate',
        type: 'applyCourse',
@@ -866,14 +1033,14 @@
  //证书查看
  onClick1() {
    this.setData({
      images: ['/static/images/certificate/cbzs.jpg'],
      images: ['/static/images/certificate/szkc.jpg'],
      showIndex: true,
      visible: true,
    })
  },
  onClick2() {
    this.setData({
      images: ['/static/images/certificate/rzzs.jpg'],
      images: ['/static/images/certificate/kczs.jpg'],
      showIndex: true,
      visible: true,
    })
pages/digitalCourses/digitalCoursesDetails/index.wxml
@@ -94,13 +94,26 @@
          <view class="course-content">
            <view class="certificateChart">
              <view class="chart" bind:tap="onClick1">
                <image src="/static/images/certificate/cbzs.jpg" mode="" />
                <image src="/static/images/certificate/szkc.jpg" mode="" />
              </view>
              <view class="chart" bind:tap="onClick2">
                <image src="/static/images/certificate/rzzs.jpg" mode="" />
                <image src="/static/images/certificate/kczs.jpg" mode="" />
              </view>
            </view>
          </view>
          <!-- <view id="pubCertificate" wx:if="pubCertificateHide">
            <image src="/static/images/certificate/szkc.jpg" mode="" class="bgImg" />
            <view class="certificateInfo">
              <view class="bookName">{{digitalsData.name}}</view>
              <view class="author">{{digitalsData.courseLeader || '-' }}</view>
              <view class="affiliatedUnit">{{digitalsData.affiliatedUnit || '-'}}</view>
              <view class="affiliatedUnit"> {{ digitalsData.isbn || '-'}}</view>
              <view class="affiliatedUnit">{{digitalsData.publicationDate}}</view>
              <view class="affiliatedUnit">{{publishingUnit}}</view>
              <view class="website">{{website}}</view>
              <view class="codeBox"></view>
            </view>
          </view> -->
        </t-tab-panel>
        <t-tab-panel icon="{{ tabValue == '2' ? courseLearningClick : courseLearning}}" label="课程学习" value="2">
          <view class="course-content">
@@ -167,6 +180,27 @@
            </view> -->
          </view>
        </t-tab-panel>
        <t-tab-panel icon="{{tabValue == '5' ? testResourceClickIocn : testResourceIocn}}" value="5" label="相关课程" style="{{tabPanelstyle}}">
          <view class="rubricBox">
            <view class="rubricimgBox">
              <image src="/static/images/digitalTextbooks/Link@3x.png" mode="" />
            </view>
            <view class="basic"> 相关课程</view>
          </view>
          <view class="noDataBox" wx:if="{{relatedBookData.length <= 0}}">
            <empty />
          </view>
          <view class="correlation" wx:else>
            <view style="margin-bottom: 30rpx;" wx:for="{{relatedBookData}}" wx:key="index" wx:for-item="item" wx:for-index="index" data-item="{{item}}" bind:tap="onCorrelationBook">
              <view class="correlationImage">
                <image src="{{item.icon}}" mode="" />
                <img wx:if="{{item.icon == ''}}" src="/static/images/default-book-img.png" alt="" />
              </view>
              <view class="correlationName">{{item.name}}</view>
              <view class="correlationAuthor">{{digitalsData.author}}</view>
            </view>
          </view>
        </t-tab-panel>
      </t-tabs>
    </view>
    <view class="box-bottom">
@@ -194,7 +228,7 @@
<!-- 弹窗 -->
<view wx:if="{{dialogBox}}">
  <view class="popup-box" bindtap="closeDialog"></view>
  <view class="info-center" style="top:{{height*0.4}}px;">
  <view class="info-center">
    <view>
      <view class="row-info">
        <view class="body">
@@ -203,6 +237,12 @@
          <view class="input-box">
            <t-input class="input" borderless placeholder="请输入真实姓名" value="{{userInfo.fullName}}" bind:change="onFullNameInput"></t-input>
          </view>
          <view class="contentImg">
            <image src="{{userInfo.userPicture}}" mode="aspectFill" />
          </view>
          <view class="buttonBox">
            <t-button size="small" class="right-btn" bind:tap="uploadPicture">上传照片</t-button>
          </view>
        </view>
        <view class="row-btn">
          <view class="left-btn" bindtap="closeDialog">取消</view>
pages/digitalCourses/digitalCoursesDetails/index.wxss
@@ -412,3 +412,122 @@
.t-textarea__placeholder {
  font-size: 28rpx !important;
}
.contentImg {
  width: 189rpx;
  height: 264rpx;
  border: 2rpx solid #949494;
  margin: 0 auto;
}
.buttonBox {
  margin: 10rpx;
  text-align: center;
}
#pubCertificate {
  width: 595px;
  height: 845px;
  position: relative;
}
.bgImg {
  width: 100%;
  height: 100%;
}
.certificateInfo {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}
.bookName {
  padding-top: 260px;
  text-align: center;
  font-size: 30px;
  color: #000;
  font-family: 'FZXBSJW';
}
.author {
  margin-top: 30px;
  font-size: 24px;
  margin-left: 250px;
  color: #000;
  margin-bottom: 50px;
  font-family: 'FZXBSJW';
}
.affiliatedUnit {
  margin-top: 13px;
  margin-left: 46%;
  color: #000;
  font-family: 'SimHei', sans-serif;
}
.website {
  margin-top: 62px;
  margin-left: 27%;
  color: #000;
  font-family: 'SimHei', sans-serif;
}
.codeBox {
  margin-top: 24px;
  text-align: center;
}
.rubricBox {
  display: flex;
  flex-direction: row;
  margin: 40rpx;
  margin-bottom: 0;
}
.rubricimgBox {
  width: 40rpx;
  height: 45rpx;
}
.basic {
  margin-left: 18rpx;
  font-size: 32rpx;
  color: #333;
  font-weight: bold;
}
.basic-content {
  padding: 30rpx 40rpx;
}
.correlationImage {
  width: 300rpx;
  height: 180rpx;
}
.correlation {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  flex-wrap: wrap;
  margin: 30rpx 50rpx;
  margin-bottom: 160rpx;
}
.correlationName {
  width: 300rpx;
  margin-top: 20rpx;
  word-break: break-all;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-weight: bold;
  font-size: 25rpx;
  color: #333333;
}
pages/digitalTextbooks/digitalTextbooksDetails/index.js
@@ -7,6 +7,8 @@
import {
  worksDataBytool
} from "../../../assets/js/toolClass.js";
import SparkMD5 from 'spark-md5'
import FormData from '../../../utils/formdata/index.js';
const app = getApp()
Page({
@@ -53,7 +55,7 @@
    testResourceClickIocn: {
      name: "/static/images/digitalTextbooks/link-t-click@3x.png",
    },
    showIndex1: '',
    catalogue: {
      name: "/static/images/digitalTextbooks/mulu-t@3x.png",
    },
@@ -61,13 +63,22 @@
      name: "/static/images/digitalTextbooks/mulu-t-click@3x.png",
    },
    userInfo: {
      fullName: '' //名称
      fullName: '', //名称
      userPicture: '' //申请证书用户图片
    },
    pictureMd5: '',
    worksInfo: [],
    isCertificate: {},
    isLearn: false,
    isTest: false,
    publishingUnit: ''
    publishingUnit: '',
    cbzsImg: '', //出版证书base64
    rzzsImg: '', //认证证书base64
    visible: false,
    showIndex: false,
    closeBtn: false,
    deleteBtn: false,
    images: [],
  },
  /**
@@ -665,15 +676,13 @@
  suggestBtn() {
    // 检查登录状态
    const token = wx.getStorageSync(app.config.tokenKey);
    console.log(465);
    const child = this.selectComponent("#suggest-component");
    // if (token)
    //   // child.showDialog();
    //   this.setData({
    //     showIndex: '1'
    //   })
    const child = this.selectComponent("#suggest-component1");
    if (token)
      // child.showDialog();
      this.setData({
        showIndex1: '1'
      })
  },
  //申请证书
@@ -711,30 +720,30 @@
  },
  onCertificate() {
    if (!this.data.isBuy) {
      wx.showToast({
        title: "请先购买,体验完整服务",
        icon: "none",
        duration: 1000,
      });
      return false
    }
    if (!this.data.isLearn) {
      wx.showToast({
        title: "您的学习任务还未完成,暂不能申请证书,加油哦!",
        icon: "none",
        duration: 1000,
      });
      return false
    }
    if (this.data.isCertificate && this.data.isCertificate.state == 'WaitAudit') {
      wx.showToast({
        title: "您申请的证书正在审核中",
        icon: "none",
        duration: 1000,
      });
      return false
    }
    // if (!this.data.isBuy) {
    //   wx.showToast({
    //     title: "请先购买,体验完整服务",
    //     icon: "none",
    //     duration: 1000,
    //   });
    //   return false
    // }
    // if (!this.data.isLearn) {
    //   wx.showToast({
    //     title: "您的学习任务还未完成,暂不能申请证书,加油哦!",
    //     icon: "none",
    //     duration: 1000,
    //   });
    //   return false
    // }
    // if (this.data.isCertificate && this.data.isCertificate.state == 'WaitAudit') {
    //   wx.showToast({
    //     title: "您申请的证书正在审核中",
    //     icon: "none",
    //     duration: 1000,
    //   });
    //   return false
    // }
    var page = getCurrentPages().pop(); // 获取当前页面实例
    page.setData({
@@ -759,13 +768,89 @@
      "userInfo.fullName": e.detail.value,
    });
  },
  uploadPicture() {
    var that = this;
    wx.chooseMedia({
      count: 1, // 默认9
      sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
      success: function (res) {
        wx.getFileSystemManager().readFile({
          filePath: res.tempFiles[0].tempFilePath, //选择图片返回的相对路径
          // encoding: 'binary', //编码格式
          success: ress => {
            //成功的回调
            let spark = new SparkMD5.ArrayBuffer();
            spark.append(ress.data);
            let md5 = spark.end(false);
            let formData = new FormData();
            formData.append('Md5', md5);
            formData.append('FileName', md5);
            formData.append('FileType', res.tempFiles[0].fileType);
            formData.appendFile("file", res.tempFiles[0].tempFilePath);
            const data = formData.getData();
            let _token = wx.getStorageSync(app.config.tokenKey);
            let header = {};
            if (_token == null) {
              header["Authorization"] = `Basic ${Base64.encode(website.clientId + ":" + website.clientSecret)}`;
            } else {
              header["Authorization"] = `Bearer ` + _token;
            }
            new Promise((resolve, reject) => {
              wx.request({
                url: app.config.requestCtx + '/file/api/ApiUpload',
                method: 'POST',
                header: {
                  'content-type': data.contentType,
                  ...header
                },
                data: data.buffer,
                success(res) {
                  if (res.statusCode == 200) {
                    resolve(res.data);
                    if (res.data) {
                      that.setData({
                        'userInfo.userPicture': app.config.requestCtx + `/file/GetPreViewImage?md5=` + md5,
                        pictureMd5: md5
                      });
                    }
                  } else {
                    reject('运行时错误,请稍后再试');
                  }
                }
              })
            })
          }
        })
      }
    });
  },
  confirmM() {
    if (this.data.userInfo.fullName) {
      if (this.data.pictureMd5 == '') {
        wx.showToast({
          title: "请上传照片",
          icon: "none",
          duration: 1000,
        });
        return false
      }
      let data = {}
      let bookInfo = {
        bookId: this.data.digitalsData.id,
        icon: this.data.digitalsData.icon,
        name: this.data.digitalsData.name,
        author: this.data.digitalsData.author,
        ISBN: this.data.digitalsData.isbn,
        publicationDate: this.data.digitalsData.publicationDate,
        userPicture: this.data.pictureMd5,
        certificate: this.data.rzzsImg
      }
      data = {
        topicIdOrRefCode: 'applyTextbookCertificate',
        name: this.data.userInfo.fullName,
        content: JSON.stringify(this.data.digitalsData),
        content: JSON.stringify(bookInfo),
        state: 'WaitAudit',
        cmsTypeRefCode: 'jsek_textbookCertificate',
        type: 'applyTextbook',
pages/digitalTextbooks/digitalTextbooksDetails/index.json
@@ -6,6 +6,7 @@
    "t-image": "tdesign-miniprogram/image/image",
    "t-toast": "tdesign-miniprogram/toast/toast",
    "t-empty": "tdesign-miniprogram/empty/empty",
    "t-button": "tdesign-miniprogram/button/button",
    "suggest": "/packageBookService/pages/bookServices/detail/components/suggest/suggest",
    "t-input": "tdesign-miniprogram/input/input",
    "t-image-viewer": "tdesign-miniprogram/image-viewer/image-viewer",
pages/digitalTextbooks/digitalTextbooksDetails/index.wxml
@@ -97,10 +97,10 @@
            </view>
            <view class="certificateChart">
              <view class="chart" bind:tap="onClick1">
                <image src="/static/images/certificate/cbzs.jpg" mode="" />
                <image src="/static/images/certificate/szjc.jpg" mode="" />
              </view>
              <view class="chart" bind:tap="onClick2">
                <image src="/static/images/certificate/rzzs.jpg" mode="" />
                <image src="/static/images/certificate/jczs.jpg" mode="" />
              </view>
            </view>
            <view class="noDataBox">
@@ -147,7 +147,6 @@
              <view class="basic"> 相关教材</view>
            </view>
            <view class="noDataBox" wx:if="{{relatedBookData.length <= 0}}">
              <!-- <t-empty icon="folder-open" description="暂无数据" font-size="80" /> -->
              <empty />
            </view>
            <view class="correlation" wx:else>
@@ -167,9 +166,6 @@
    </scroll-view>
    <!-- 我要建议弹窗 -->
    <suggest class="suggest-component" id="suggest-component" bookIcon="{{bookDetail.icon}}" bookName="{{bookDetail.name}}"></suggest>
    <view class="box-bottom">
      <view class="collection" bind:tap="setCoolect">
        <view class="collectionImage">
@@ -195,7 +191,7 @@
    </view>
  </view>
</view>
<suggest class="suggest-component" id="suggest-component1" showIndex="{{showIndex1}}" bookIcon="{{digitalsData.icon}}" bookName="{{digitalsData.name}}"></suggest>
<!-- 弹窗 -->
<view wx:if="{{dialogBox}}">
  <view class="popup-box" bindtap="closeDialog"></view>
@@ -208,6 +204,12 @@
          <view class="input-box">
            <t-input class="input" borderless placeholder="请输入真实姓名" value="{{userInfo.fullName}}" bind:change="onFullNameInput"></t-input>
          </view>
          <view class="contentImg">
            <image src="{{userInfo.userPicture}}" mode="aspectFill" />
          </view>
          <view class="buttonBox">
            <t-button size="small" class="right-btn" bind:tap="uploadPicture">上传照片</t-button>
          </view>
        </view>
        <view class="row-btn">
          <view class="left-btn" bindtap="closeDialog">取消</view>
@@ -217,6 +219,6 @@
    </view>
  </view>
</view>
<t-image-viewer usingCustomNavbar deleteBtn="{{deleteBtn}}" closeBtn="{{closeBtn}}" showIndex="{{showIndex}}" visible="{{visible}}" images="{{images}}" bind:change="onChange" bind:close="onClose"></t-image-viewer>
<t-image-viewer usingCustomNavbar deleteBtn="{{deleteBtn}}" closeBtn="{{closeBtn}}" showIndex="{{showIndex}}" visible="{{visible}}" images="{{images}}" bind:close="onClose"></t-image-viewer>
<t-toast id="t-toast" />
pages/digitalTextbooks/digitalTextbooksDetails/index.wxss
@@ -522,3 +522,15 @@
.t-textarea__placeholder {
  font-size: 28rpx !important;
}
.contentImg {
  width: 189rpx;
  height: 264rpx;
  border: 2rpx solid #949494;
  margin: 0 auto;
}
.buttonBox {
  margin: 10rpx;
  text-align: center;
}
pages/digitalTextbooks/index.wxml
@@ -11,9 +11,7 @@
  </view>
  <t-tabs defaultValue="{{0}}" bind:change="selectTab" t-class="custom-tabs" t-class-content="custom-panel">
    <t-tab-panel wx:for="{{tabList}}" wx:key="index" wx:for-item="item" wx:for-index="index" label="{{item.name}}" value="{{index}}" style="{{tabPanelstyle}}">
      <view class="contentBox">
        <view class="titleBox">
          <view class="frameBox"></view>
          <view class="titleTextBox">
@@ -21,13 +19,7 @@
            <view>数字教材列表</view>
          </view>
        </view>
        <scroll-view scroll-y="{{true}}" class="outsideContentBox" bindscrolltolower="onScrollToLower">
          <view class="bookContentBox">
            <view class="external" wx:for="{{digitalTextbooksData}}" wx:key="index" wx:for-item="item" wx:for-index="index" data-item="{{item}}" bind:tap="jumpDetails">
              <view class="amountClick">
@@ -53,24 +45,8 @@
              <empty />
            </view>
          </view>
        </scroll-view>
      </view>
    </t-tab-panel>
  </t-tabs>
</view>
pages/personalCenter/certificate/index.js
@@ -1,10 +1,39 @@
const app = getApp();
Page({
  /**
   * 页面的初始数据
   */
  data: {
    active: 0,
    topicIdOrRefCode: "applyCourseCertificate",
    tabList: [{
        label: '课程证书',
        key: 1,
        topicIdOrRefCode: 'applyCourseCertificate',
      },
      {
        label: '教材证书',
        key: 2,
        topicIdOrRefCode: 'applyTextbookCertificate',
      }
    ],
    list: [],
    //分页
    page: 1,
    limit: 6,
    pageTotalCount: 0,
    bottomLoading: false,
    isMoreData: false,
    // 返回顶部
    isBackTop: false,
    setScrollValue: 0,
    skeletonLoding: true,
    visible: false,
    showIndex: false,
    closeBtn: false,
    deleteBtn: false,
    images: [],
  },
  /**
@@ -12,6 +41,7 @@
   */
  onLoad(options) {
    console.log(options);
    this.getDataList(false);
  },
  /**
@@ -28,6 +58,81 @@
  },
  tabBookClick(item) {
    let that = this;
    let info = this.data.tabList[item.detail.value]
    that.setData({
      skeletonLoding: true,
      active: item.detail.value,
      topicIdOrRefCode: info.topicIdOrRefCode,
      list: [],
      page: 1,
      bottomLoading: false,
      isMoreData: false,
    })
    that.getDataList(false);
  },
  getDataList(isReachBottom) {
    const data = {
      start: this.data.page * this.data.limit - this.data.limit,
      size: this.data.limit,
      topicIdOrRefCode: this.data.topicIdOrRefCode,
      appRefCode: app.config.appRefCode,
      filterList: [],
      sort: {
        type: 'Desc',
        field: 'CreateDate'
      }
    }
    app.MG.ugc.getTopicMessageList(data)
      .then((res) => {
        if (res.datas.length > 0) {
          res.datas.forEach((item) => {
            item.updateDate = item.updateDate.split('T')[0]
            if (item.content) {
              item.productList = JSON.parse(item.content)
            }
          })
          let dataList = res.datas;
          //触底加载新数据并保留老数据
          if (isReachBottom) {
            dataList = [...this.data.list, ...dataList] //将新数据加入老数据中
          }
          this.setData({
            list: dataList,
            pageTotalCount: res.totalSize,
            bottomLoading: false,
            isMoreData: dataList.length > 0 ? false : true,
            skeletonLoding: false,
            loading: false
          })
        } else {
          this.setData({
            list: [],
            skeletonLoding: false,
            loading: false
          })
        }
      })
      .catch(() => {})
  },
  goBookDetails(e) {
    let productList = e.currentTarget.dataset.book.productList
    this.setData({
      images: productList.certificate ? [productList.certificate] : this.data.active === 0 ? ['/static/images/certificate/kczs.jpg'] : ['/static/images/certificate/jczs.jpg'],
      showIndex: true,
      visible: true,
    })
  },
  onClose(e) {
    const {
      trigger
    } = e.detail;
    this.setData({
      visible: false,
    });
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
@@ -46,14 +151,47 @@
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
    if (this._freshing) return
    this.setData({
      // list: [],
      page: 1,
      limit: 6,
      pageTotalCount: 0,
      bottomLoading: false,
      isMoreData: false
    })
    this._freshing = true;
    this.setData({
      triggered: false,
    })
    this.getDataList(false);
    this._freshing = false
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
    this.setData({
      bottomLoading: true,
      isMoreData: false
    })
    let bool = false;
    if (this.data.pageTotalCount > this.data.list.length) {
      bool = true;
      this.setData({
        page: this.data.page + 1,
      })
    } else {
      setTimeout(() => {
        this.setData({
          bottomLoading: false,
          isMoreData: true
        })
      }, 100)
      return false;
    }
    this.getDataList(bool);
  },
  /**
pages/personalCenter/certificate/index.json
@@ -1,4 +1,14 @@
{
  "navigationBarTitleText": "我的证书",
  "usingComponents": {}
  "usingComponents": {
    "t-tabs": "tdesign-miniprogram/tabs/tabs",
    "t-tab-panel": "tdesign-miniprogram/tab-panel/tab-panel",
    "t-back-top": "tdesign-miniprogram/back-top/back-top",
    "t-pull-down-refresh": "tdesign-miniprogram/pull-down-refresh/pull-down-refresh",
    "t-loading": "tdesign-miniprogram/loading/loading",
    "t-image": "tdesign-miniprogram/image/image",
    "t-empty": "tdesign-miniprogram/empty/empty",
    "t-image-viewer": "tdesign-miniprogram/image-viewer/image-viewer",
    "empty": "/components/empty/index"
  }
}
pages/personalCenter/certificate/index.wxml
@@ -1,2 +1,40 @@
<!--pages/personalCenter/certificate/index.wxml-->
<text>pages/personalCenter/certificate/index.wxml</text>
<view class="container">
  <t-tabs t-class="t-tabs" defaultValue="{{active}}" split="{{false}}" bind:change="tabBookClick" wx:if="{{!skeletonLoding}}">
    <t-tab-panel wx:for="{{tabList}}" wx:for-index="index" wx:key="index" label="{{item.label}}" value="{{index}}" />
  </t-tabs>
  <view class="pageInfo" wx:if="{{!skeletonLoding}}">
    <scroll-view class="scroll content" bind:scroll="onPageScroll" model:scroll-top="{{setScrollValue}}" scroll-y refresher-enabled="{{true}}" lower-threshold="{{200}}" refresher-threshold="{{80}}" refresher-default-style="none" refresher-triggered="{{triggered}}" bindrefresherpulling="{{refresh.onPulling}}" bindrefresherrefresh="onPullDownRefresh" bindscrolltolower="onReachBottom">
      <view slot="refresher" class="refresh-container">
        <view class="loading">
          <t-loading theme="circular" size="40rpx" text="正在刷新..." class="wrapper" />
        </view>
      </view>
      <view class="list" wx:if="{{list.length > 0 && !skeletonLoding}}">
        <view class="listBox">
          <view class="content-item" wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="index">
            <view class="icon" data-book="{{item}}" bindtap="goBookDetails">
              <image src="{{item.productList.certificate}}" mode="aspectFit" class="img" wx:if="{{item.productList.certificate}}" />
              <image src="/static/images/certificate/kczs.jpg" mode="aspectFit" class="img" wx:if="{{!item.productList.certificate && active == 0}}" />
              <image src="/static/images/certificate/jczs.jpg" mode="aspectFit" class="img" wx:if="{{!item.productList.certificate && active == 1}}" />
            </view>
            <view class="body-info">
              <view class="name">{{item.productList.name}}</view>
            </view>
          </view>
        </view>
      </view>
      <view wx:if="{{list.length == 0 && !skeletonLoding}}" class="empyt">
        <!-- <t-empty icon="folder-open" description="暂无数据" /> -->
        <empty />
      </view>
      <view class="bottom-loading" wx:if="{{bottomLoading}}">
        <t-loading theme="circular" size="40rpx" text="加载中..." class="wrapper" />
      </view>
      <view class="bottom-loading" style="color: #ccc;font-size: 28rpx;" wx:if="{{isMoreData}}">
        <text>没有更多了</text>
      </view>
    </scroll-view>
  </view>
  <t-back-top theme="round" wx:if="{{isBackTop}}" text="顶部" bind:to-top="onToTop"></t-back-top>
  <t-image-viewer deleteBtn="{{deleteBtn}}" closeBtn="{{closeBtn}}" showIndex="{{showIndex}}" visible="{{visible}}" images="{{images}}" bind:close="onClose"></t-image-viewer>
</view>
pages/personalCenter/certificate/index.wxss
@@ -1 +1,134 @@
/* pages/personalCenter/certificate/index.wxss */
page {
  background-color: #F2F3F8;
}
.container {
  width: 100vw;
  height: 100vh;
}
.pageInfo {
  background: #fff;
}
.content {
  height: calc(100vh - env(safe-area-inset-bottom) - 116rpx);
  box-sizing: border-box;
}
.t-tabs__track {
  display: none;
}
.t-tabs {
  margin-top: 20rpx;
  background: none !important;
}
.t-tabs__wrapper {
  background: none !important;
}
.t-tabs__nav :nth-child(1) {
  border-radius: 30rpx 30rpx 0 0rpx;
}
.t-tabs__nav :nth-child(2) {
  border-radius: 0rpx 30rpx 0 30rpx;
}
.t-tabs__item {
  flex: 1 !important;
  background: #E6E8F1;
  height: 76rpx !important;
  margin-top: 16rpx;
  border-radius: 30rpx 0 30rpx 0rpx !important;
}
.t-tabs__item--active {
  color: #333 !important;
  background: #fff;
  height: 96rpx;
  font-size: 32rpx;
  margin-top: 0;
  height: 96rpx !important;
  border-radius: 30rpx 30rpx 0 0rpx !important;
}
.t-tabs__item--active+.t-tabs__item {
  border-radius: 0 30rpx 0 30rpx !important;
}
.t-tabs__content {
  background: #fff !important;
  margin-top: -30rpx;
  padding-top: 30rpx;
}
.refresh-container {
  margin: 0 auto;
}
.bottom-loading,
.loading {
  padding: 20rpx;
  text-align: center;
}
.listBox {
  display: flex;
  flex-flow: row wrap;
  padding: 30rpx 0;
}
.content-item {
  width: calc(100%/2 - 40rpx);
  margin-bottom: 30rpx;
  margin: 0 20rpx;
  align-self: stretch;
}
.content-item .icon {
  height: 470rpx;
  width: 100%;
  box-shadow: 0px 0px 20rpx 2px rgba(0, 0, 0, 0.16);
}
.content-item .icon .img,
.class--tem .icon .img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.body-info {
  padding: 20rpx 0;
}
.body-info .name {
  font-size: 32rpx;
  height: 88rpx;
  color: #333333;
  font-weight: bold;
  line-height: 44rpx;
  display: -webkit-box;
  margin-bottom: 10rpx;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  text-overflow: ellipsis;
}
.empyt {
  padding: 200rpx 0;
}
.body-loading {
  padding: 200rpx 0;
  text-align: center;
}
pages/personalCenter/index.js
@@ -18,7 +18,7 @@
  {
    title: '我的证书',
    icon: '/static/images/personal/certificate.png',
    url: '',
    url: '/pages/personalCenter/certificate/index',
    type: 'certificate',
  },
  {
@@ -125,8 +125,6 @@
      size: '10rpx',
    },
    scrollTop: 0,
    visibleIntegral: false,
    recordList: []
  },
  /**
   * 生命周期函数--监听页面加载
@@ -349,56 +347,12 @@
      })
  },
  getIntegralList() {
    app.MG.store
      .getWalletHistory({
        Size: 999,
        Start: 0,
        sort: {
          type: 'Desc',
          field: 'CreateDate'
        },
        type: 'integral'
      })
      .then((res) => {
        if (res.datas.length > 0) {
          res.datas.forEach((element) => {
            element.createDate = moment(element.createDate).format('YYYY-MM-DD HH:mm:ss')
            if (element.refType == 'sign') {
              element.type = '每日登录'
            }
            if (element.refType == 'Reward') {
              element.type = '上传资源奖励'
            }
            if (element.refType == 'OrderCoinBonus') {
              element.type = '订单支付奖励'
            }
            if (element.refType == 'Order' && element.value < 0) {
              element.type = '订单支付抵扣'
            }
            if (element.refType == 'Order' && element.value > 0) {
              element.type = '订单取消退回'
            }
            if (element.refType == 'AdminRecharge') {
              element.type = '管理员充值'
            }
          })
          this.setData({
            recordList: res.datas,
            visibleIntegral: true
    wx.navigateTo({
      url: `/pages/personalCenter/pointsRecord/index`,
          });
        }
      })
  },
  onVisibleIntegralChange(e) {
    this.setData({
      visibleIntegral: e.detail.visible,
    });
  },
  onClose() {
    this.setData({
      visibleIntegral: false,
    });
  },
  //点击目录
  toPages(item) {
pages/personalCenter/pointsRecord/index.js
New file
@@ -0,0 +1,159 @@
// pages/personalCenter/pointsRecord/index.js
const app = getApp();
import moment from 'moment'
Page({
  /**
   * 页面的初始数据
   */
  data: {
    integral: 0,
    recordList: [],
    page: 1,
    limit: 20,
    pageTotalCount: 0,
    bottomLoading: false,
    isMoreData: false,
    // 返回顶部
    isBackTop: false,
    setScrollValue: 0,
    skeletonLoding: true,
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.getIntegral()
    this.getIntegralList(false)
  },
  getIntegral() {
    app.MG.store
      .getUserWallet({
        type: 'integral'
      })
      .then((res) => {
        this.setData({
          integral: res.balance,
        });
      })
  },
  getIntegralList(isReachBottom) {
    app.MG.store
      .getWalletHistory({
        Size: this.data.limit,
        Start: this.data.page * this.data.limit - this.data.limit,
        sort: {
          type: 'Desc',
          field: 'CreateDate'
        },
        type: 'integral'
      })
      .then((res) => {
        if (res.datas.length > 0) {
          res.datas.forEach((element) => {
            element.createDate = moment(element.createDate).format('YYYY-MM-DD HH:mm:ss')
            if (element.refType == 'sign') {
              element.type = '每日登录'
            }
            if (element.refType == 'Reward') {
              element.type = '上传资源奖励'
            }
            if (element.refType == 'OrderCoinBonus') {
              element.type = '订单支付奖励'
            }
            if (element.refType == 'Order' && element.value < 0) {
              element.type = '订单支付抵扣'
            }
            if (element.refType == 'Order' && element.value > 0) {
              element.type = '订单取消退回'
            }
            if (element.refType == 'AdminRecharge') {
              element.type = '管理员充值'
            }
          })
          let dataList = res.datas;
          //触底加载新数据并保留老数据
          if (isReachBottom) {
            dataList = [...this.data.list, ...dataList] //将新数据加入老数据中
          }
          this.setData({
            recordList: dataList,
            pageTotalCount: res.totalSize,
            bottomLoading: false,
            isMoreData: dataList.length > 0 ? false : true,
            skeletonLoding: false,
          })
        } else {
          this.setData({
            skeletonLoding: false,
          })
        }
      })
  },
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
    if (this._freshing) return
    this.setData({
      page: 1,
      limit: 10,
      pageTotalCount: 0,
      bottomLoading: false,
      isMoreData: false
    })
    this._freshing = true;
    this.setData({
      triggered: false,
    })
    this.getIntegralList(false);
    this._freshing = false
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
    this.setData({
      bottomLoading: true,
      isMoreData: false
    })
    let bool = false;
    if (this.data.pageTotalCount > this.data.recordList.length) {
      bool = true;
      this.setData({
        page: this.data.page + 1,
      })
    } else {
      setTimeout(() => {
        this.setData({
          bottomLoading: false,
          isMoreData: true
        })
      }, 100)
      return false;
    }
    this.getIntegralList(bool);
  },
  // 监听滚动距离
  onPageScroll(e) {
    if (e && e.scrollTop >= 1000) {
      this.setData({
        isBackTop: true
      })
    } else {
      this.setData({
        isBackTop: false
      })
    }
  },
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {
  }
})
pages/personalCenter/pointsRecord/index.json
New file
@@ -0,0 +1,10 @@
{
  "navigationBarTitleText": "我的下载",
  "usingComponents": {
    "t-back-top": "tdesign-miniprogram/back-top/back-top",
    "t-pull-down-refresh": "tdesign-miniprogram/pull-down-refresh/pull-down-refresh",
    "t-loading": "tdesign-miniprogram/loading/loading",
    "t-empty": "tdesign-miniprogram/empty/empty",
    "empty": "/components/empty/index"
  }
}
pages/personalCenter/pointsRecord/index.wxml
New file
@@ -0,0 +1,40 @@
<view class="container" wx:if="{{!skeletonLoding}}">
  <scroll-view class="scroll content" bind:scroll="onPageScroll" model:scroll-top="{{setScrollValue}}" scroll-y refresher-enabled="{{true}}" lower-threshold="{{200}}" refresher-threshold="{{80}}" refresher-default-style="none" refresher-triggered="{{triggered}}" bindrefresherpulling="{{refresh.onPulling}}" bindrefresherrefresh="onPullDownRefresh" bindscrolltolower="onReachBottom">
    <view slot="refresher" class="refresh-container">
      <view class="loading">
        <t-loading theme="circular" size="40rpx" text="正在刷新..." class="wrapper" />
      </view>
    </view>
    <view class="pageBox">
      <view class="integralBox">
        <image src="/static/images/personal/jifen-bg.png" mode="" class="image" />
        <view class="integra">
          <view class="num">{{integral}}</view>
          <view>总积分</view>
        </view>
      </view>
      <view class="pageInfo" wx:if="{{recordList.length > 0 && !skeletonLoding}}">
        <view class="title">积分记录</view>
        <view class="content-item" wx:for="{{recordList}}" wx:for-item="item" wx:for-index="index" wx:key="index">
          <view class="item-con">
            <view class="lable">{{item.type}}</view>
            <view class="createDate">{{item.createDate ? item.createDate : '-'}}</view>
          </view>
          <view class="value yes" wx:if="item.value > 0">{{'+' + item.value}}</view>
          <view class="value no" wx:else>{{item.value}}</view>
        </view>
      </view>
      <view wx:if="{{recordList.length == 0 && !skeletonLoding}}" class="empyt">
        <!-- <t-empty icon="folder-open" description="暂无数据" /> -->
        <empty />
      </view>
      <view class="bottom-loading" wx:if="{{bottomLoading}}">
        <t-loading theme="circular" size="40rpx" text="加载中..." class="wrapper" />
      </view>
      <view class="bottom-loading" style="color: #ccc;font-size: 28rpx;" wx:if="{{isMoreData}}">
        <text>没有更多了</text>
      </view>
    </view>
  </scroll-view>
  <t-back-top theme="round" wx:if="{{isBackTop}}" text="顶部" bind:to-top="onToTop"></t-back-top>
</view>
pages/personalCenter/pointsRecord/index.wxss
New file
@@ -0,0 +1,94 @@
/* pages/personalCenter/pointsRecord/index.wxss */
.container {
  width: 100vw;
  height: 100vh;
  background: linear-gradient(180deg, #ffd9bd 0%, #F2F3F8 100%);
}
.content {
  height: calc(100vh - env(safe-area-inset-bottom));
  box-sizing: border-box;
}
.pageBox {
  padding: 30rpx;
}
.integralBox {
  height: 192rpx;
  width: 100%;
  position: relative;
}
.image {
  height: 192rpx;
  width: 100%;
}
.integra {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  text-align: center;
  color: #fff;
  padding: 30rpx 0;
}
.num {
  font-size: 56rpx;
}
.pageInfo {
  margin-top: 40rpx;
  padding: 24rpx;
  background: #fff;
  border-radius: 20rpx;
}
.title {
  font-size: 32rpx;
  font-weight: bold;
}
.content-item {
  padding: 30rpx 0;
  display: flex;
  border-bottom: 1px solid #EDEDED;
  justify-content: space-between;
}
.lable {
  font-size: 28rpx;
  font-weight: bold;
}
.createDate {
  color: #7C7C7C;
  margin-top: 20rpx;
  font-size: 24rpx;
}
.yes {
  color: #1fbc1f
}
.no {
  color: #ee1818;
}
.refresh-container {
  margin: 0 auto;
}
.bottom-loading,
.loading {
  padding: 20rpx;
  text-align: center;
}
.body-loading {
  padding: 200rpx 0;
  text-align: center;
}
static/images/certificate/jczs.jpg
static/images/certificate/kczs.jpg
static/images/certificate/szjc.jpg
static/images/certificate/szkc.jpg
static/images/home/zhuantitaolun2.png

static/images/personal/jifen-bg.png