luyun 4 vuotta sitten
commit
75b2e5045d

+ 22 - 0
.gitignore

@@ -0,0 +1,22 @@
+
+# dependencies
+**/node_modules
+
+.idea
+.DS_Store
+
+# misc
+npm-debug.log*
+yarn-error.log
+yarn.lock
+package-lock.json
+*bak
+
+# visual studio code
+.vscode
+.history
+*.log
+functions/*
+.temp/**
+
+.eslintcache

+ 3 - 0
.kaitian/project-ide.json

@@ -0,0 +1,3 @@
+{
+  "ignoreHttpDomainCheck": true
+}

+ 27 - 0
app.acss

@@ -0,0 +1,27 @@
+.flex {
+  display: flex;
+}
+
+.flex_1 {
+  flex: 1;
+}
+
+.align-center {
+  align-items: center;
+}
+
+.justify-center {
+  justify-content: center;
+}
+
+.justify-space-between {
+  justify-content: space-between;
+}
+.justify-space-around {
+  justify-content: space-around;
+}
+.flex-direct {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}

+ 58 - 0
app.js

@@ -0,0 +1,58 @@
+import apiUrl from './common/api.js'
+import numfn from "./common/common"
+App({
+  globaldata: {
+    corpId: "",
+    serverurl: 'https://rismanage3.pacsonline.cn',
+    authCode: '',
+    apiUrl: apiUrl
+  },
+  // 封装网络请求
+  https(httpstype, url, data, type) {
+    dd.showLoading();
+    let endurl;
+    let headers = {}
+    endurl = encodeURI(this.globaldata.serverurl + url);
+    headers = {
+      "Content-Type": 'application/json;charset=utf-8',
+      Authorization: 'Bearer ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiI1ZDVjOTkwODY1NmZmODAwYTE3ZTExNzUiLCJyYW5kb20iOiJjNjJhNWE2ZDk3OTliMTE1IiwidXNlcm5hbWUiOiLnlJjkuJzkuJwiLCJpYXQiOjE1NjY0NDE4OTR9.LZFdeYmNUCes-xF2HdFIGER4xVddDYn4RvtI3n1kLzs'
+    }
+    return new Promise((resolve, reject) => {
+      dd.httpRequest({
+        headers: headers,
+        url: endurl,
+        method: httpstype,
+        data: data,
+        dataType: 'json',
+        success: (res) => {
+          if (res.data.msg && res.data.msg != 'ok') {
+            dd.showToast({
+              content: res.data.msg,
+              duration: 3000
+            });
+            return
+          }
+          resolve(res)
+        },
+        fail: (res) => {
+          reject(res)
+
+        },
+        complete: (res) => {
+          dd.hideLoading()
+        }
+      })
+    })
+  },
+  onLaunch(options) {
+    // 第一次打开
+    // debugger
+    // options.query == {number:1}
+    this.globaldata.corpId = options.query.corpId;
+    console.info('App onLaunch');
+  },
+  onShow(options) {
+    // 从后台被 scheme 重新打开
+    // options.query == {number:1}
+  },
+});

+ 31 - 0
app.json

@@ -0,0 +1,31 @@
+{
+  "pages": [
+    "pages/ad/ad",
+    "pages/index/index",
+    "pages/answer/answer",
+    "pages/my/my",
+    "pages/result/result"
+  ],
+  "window": {
+    "defaultTitle": "中世康恺科技有限公司"
+  },
+  "tabBar": {
+    "textColor": "#404040",
+    "selectedColor": "#108ee9",
+    "backgroundColor": "#F5F5F9",
+    "items": [
+      {
+        "pagePath": "pages/index/index",
+        "icon": "image/home.png",
+        "activeIcon": "image/home-H.png",
+        "name": "考试"
+      },
+      {
+        "pagePath": "pages/my/my",
+        "icon": "image/my.png",
+        "activeIcon": "image/my-H.png",
+        "name": "我的"
+      }
+    ]
+  }
+}

+ 13 - 0
common/api.js

@@ -0,0 +1,13 @@
+export default {
+  // 后台接口
+  getUserDetail:"/api/train/getUserDetail",
+  getUndoneExam: "/api/train/getUndoneExam",//未完成接口
+  getQualifiedExam: "/api/train/getQualifiedExam",//合格
+  getUnqualifiedExam: "/api/train/getUnqualifiedExam",//不合格
+  getMissedExam: "/api/train/getMissedExam",//缺考
+  startExam: "/api/train/startExam",//开始考试
+  getExamQuestions: "/api/train/getExamQuestions",//获取全部考题
+  subExam: "/api/train/subExam",//提交
+  retakeExam: "/api/train/retakeExam",//重新考试
+  getRemainingTime: "/api/train/getRemainingTime"
+}

+ 52 - 0
common/common.js

@@ -0,0 +1,52 @@
+let filterData = (arr1, arr2) => {
+  let map = {};
+  for (let i = 0; i < arr1.length; i++) {
+    if (arr1[i]) {
+      map[arr1[i].question_id] = arr1[i].answer
+    }
+  }
+  return arr2.map((item) => {
+    for (let i = 0; i < item.answer.length; i++) {
+      const value = item.answer[i];
+      const va = map[item.id]
+      // console.log(va)
+      if (va) {
+        // const maparr = map[item.question_id]
+        for (let j = 0; j < va.length; j++) {
+          if (va[j].key == value.key) {
+            value.checked = 1;
+          }
+        }
+      }
+    }
+    return item
+  })
+}
+let examDjsFn = (examSurplusTime) => {
+  let timer = null;
+  let time = examSurplusTime * 1000
+  timer = setInterval(() => {
+    let m, s
+    if (time >= 0) {
+      m = Math.floor(time / 1000 / 60 % 60);
+      s = Math.floor(time / 1000 % 60);
+      m = m < 10 ? ('0' + m) : m;
+      s = s < 10 ? ('0' + s) : s;
+      let duration = m + ':' + s;
+      console.log(duration)
+      // that.setData({
+      //   duration: duration
+      // })
+      
+      time = time - 1000
+      return duration
+    } else {
+      clearInterval(timer);
+      return '00:00'
+    }
+  }, 1000);
+}
+export default {
+  filterData,
+  examDjsFn
+};

BIN
image/ad.png


BIN
image/default-header.png


BIN
image/fail.png


BIN
image/home-H.png


BIN
image/home.png


BIN
image/my-H.png


BIN
image/my.png


BIN
image/success.png


BIN
image/time.png


+ 22 - 0
pages/ad/ad.acss

@@ -0,0 +1,22 @@
+.ad-page {
+  text-align: center
+}
+
+.ad-page image {
+  width: 444rpx;
+  height: 455rpx;
+  margin-top: 282rpx;
+}
+
+.ad-page .ver {
+  width: 100%;
+  text-align: center;
+  font-size: 28rpx;
+  font-family: PingFang SC;
+  font-weight: 400;
+  line-height: 40rpx;
+  color: #000000;
+  opacity: 1;
+  position: fixed;
+  bottom: 284rpx;
+}

+ 4 - 0
pages/ad/ad.axml

@@ -0,0 +1,4 @@
+<view class="ad-page">
+    <image mode="scaleToFill" src="../../image/ad.png"/>
+    <view class="ver">v1.0</view>
+</view>

+ 68 - 0
pages/ad/ad.js

@@ -0,0 +1,68 @@
+
+let app = getApp()
+let domain = "https://rismanage3.pacsonline.cn";
+let url = domain + '/api/train/getUserDetail';
+Page({
+  data: {
+    authCode: "",
+    corpId: ''
+  },
+  onLoad() {
+    // let that = this;
+    let time = null
+    this.setData({
+      corpId: app.globaldata.corpId
+    })
+   
+    // dd.showLoading();
+    dd.getAuthCode({
+      success: (res) => {
+        this.setData({
+          authCode: res.authCode
+        })
+        //dd.alert({content: "step1"});
+        dd.httpRequest({
+          url: url,
+          method: 'POST',
+          data: {
+            code: res.authCode
+          },
+          dataType: 'json',
+          success: (res) => {
+            // dd.alert({content: "step2"});
+            console.log('success----', res)
+            dd.setStorage({
+              key: 'userInf',
+              data: {
+                phone: res.data.data.mobile,
+                name: res.data.data.name,
+                avatar: res.data.data.avatar
+              }
+            });
+            time = setInterval(function () {
+              dd.reLaunch({
+                url: "/pages/index/index"
+              })
+              clearInterval(time);
+            }, 1000)
+            
+          },
+          fail: (res) => {
+            console.log("httpRequestFail---", res)
+            dd.alert({ content: JSON.stringify(res) });
+          },
+          complete: (res) => {
+            // dd.hideLoading();
+          }
+
+        });
+      },
+      fail: (err) => {
+        // dd.alert({content: "step3"});
+        dd.alert({
+          content: JSON.stringify(err)
+        })
+      }
+    })
+  }
+});

+ 3 - 0
pages/ad/ad.json

@@ -0,0 +1,3 @@
+{
+  "defaultTitle": ""
+}

+ 101 - 0
pages/answer/answer.acss

@@ -0,0 +1,101 @@
+.answer-page {
+  padding: 40rpx 32rpx;
+}
+.answer-page .answer-time{
+  font-size: 30rpx;
+  float: right;
+}
+.answer-page .sheet{
+  height: 90vh!important;
+}
+.answer-page .answer-title {
+  width: 686rpx;
+  border-bottom: 2rpx solid #E8E8E8;
+  opacity: 1;
+  padding-bottom: 32rpx;
+}
+
+.answer-page .answer-title .current-index {
+  font-size: 30rpx;
+  font-family: PingFang SC;
+  font-weight: 400;
+  line-height: 42rpx;
+  color: #333333;
+}
+
+.answer-page .answer-title .total-index {
+  font-size: 30rpx;
+  font-family: PingFang SC;
+  font-weight: 400;
+  line-height: 42rpx;
+  color: #999999;
+}
+
+.answer-page .answer-title .answer-type {
+  width: 96rpx;
+  height: 40rpx;
+  background: rgba(81, 205, 228, .24);
+  border-radius: 40rpx 40rpx 40rpx 0rpx;
+  color: #51CDE4;
+  font-size: 24rpx;
+  margin-left: 18rpx;
+}
+
+.answer-page .answer-title .title {
+  font-size: 30rpx;
+  font-family: PingFang SC;
+  font-weight: bold;
+  line-height: 42rpx;
+  color: #333333;
+  opacity: 1;
+  margin-top: 18rpx;
+}
+.page-section-demo{
+  padding-left: 16rpx;
+}
+.answer-page .radio {
+  width: 100%;
+  margin-top: 46rpx;
+}
+.answer-page .checkbox {
+  width: 100%;
+  margin-top: 46rpx;
+}
+.answer-page .radio .a-radio-checked .a-icon-success{
+  fill: rgba(81, 205, 228, 1)!important;
+}
+.answer-page .checkbox .a-checkbox-checked{
+  background: rgba(81, 205, 228, 1)!important;
+}
+.answer-page .checkbox .a-checkbox-checked .a-icon-success_no_circle{
+  fill: #FFFFFF!important;
+}
+.answer-page .radio .radio-text, .answer-page .checkbox .checkbox-text{
+  margin-left: 18rpx;
+}
+
+.page-section-btns {
+  width: 670rpx;
+  position: fixed;
+  bottom: 42rpx;
+  padding-bottom: 48rpx;
+  border-bottom: 1px solid #E8E8E8;
+  justify-content: space-around;
+
+}
+
+.page-section-btns button {
+  width: 216rpx;
+  height: 88rpx;
+  background: #FFFFFF;
+  border: 2rpx solid #51CDE4;
+  opacity: 1;
+  border-radius: 44rpx;
+  font-size: 34rpx;
+  font-family: PingFang SC;
+  font-weight: 400;
+  line-height: 48rpx;
+  color: #51CDE4;
+  opacity: 1;
+  line-height: 88rpx;
+}

+ 50 - 0
pages/answer/answer.axml

@@ -0,0 +1,50 @@
+<view class="answer-page">
+  <view class="answer-time">
+    {{duration}}
+  </view>
+  <swiper class='sheet' current='{{id}}' onChange="swiperChange">
+    <block a:for="{{data}}" a:for-index="index" a:for-item="item">
+      <swiper-item>
+        <!--<form bindsubmit='submit'><view class='naire'><view class='question'>{{item.question}}</view><radio-group class='radio-group' name='answer' bindchange='radioChange'><label class='radio'><radio value="A" color='#fcbe39' />{{item.option.a}}</label><label class='radio'><radio value="B" color='#fcbe39' />{{item.option.b}}</label><label class='radio'><radio value="C" color='#fcbe39' />{{item.option.c}}</label><label class='radio'><radio value="D" color='#fcbe39' />{{item.option.d}}</label></radio-group></view><view class='button-group'><button class='button' hover-class='none' bindtap='lastq' disabled='{{id==0}}'>上一题</button><button wx:if="{{id<19}}" class='button' hover-class='none' form-type='submit' bindtap='nextq'>下一题</button><button wx:else class='button' hover-class='none' form-type='submit' bindtap='formSubmit'>提交</button></view><view class='id'>{{id+1}}/{{qnaire.length}}</view></form> -->
+        <view class="answer-title">
+          <view class="flex" style="padding-left:14rpx;">
+            <text class="current-index">{{index+1}}</text>
+            <text class="total-index">/{{data.length}}</text>
+            <view class="answer-type flex align-center justify-center" a:if="{{item.type==1||item.type==3}}">
+              单选
+            </view>
+            <view class="answer-type flex align-center justify-center" a:if="{{item.type == 2}}">
+              多选
+            </view>
+          </view>
+          <view class="title">{{item.title}}</view>
+        </view>
+        <view class="radio-item">
+          <form onSubmit="onSubmit" onReset="onReset">
+            <view class="page-section-demo" a:if="{{item.type==1||item.type==3}}">
+              <radio-group class="radio-group" data-id="{{item.id}}" onChange="radioChange" name="lib">
+                <label class="radio" a:for="{{item.answer}}" a:for-item="items" a:for-index="i" data-index="{{i}}">
+                  <radio value="{{items.key}}" checked="{{items.checked}}"/>
+                  <text class="radio-text">{{items.title}}</text>
+                </label>
+              </radio-group>
+            </view>
+            <view class="page-section-demo" a:if="{{item.type==2}}">
+              <checkbox-group name="libs" data-id="{{item.id}}" onChange="checkedChange">
+                <label class="checkbox" a:for="{{item.answer}}" a:for-item="items" a:for-index="i" data-index="{{i}}">
+                  <checkbox value="{{items.key}}" checked="{{items.checked}}" />
+                  <text class="checkbox-text">{{items.title}}</text>
+                </label>
+              </checkbox-group>
+            </view>
+            <view class="page-section-btns flex">
+              <button size="mini" type="ghost" formType="reset" onTap="lastq" disabled='{{id==0}}'>上一题</button>
+              <button size="mini" type="ghost" formType="submit" a:if="{{id+1 != data.length}}" data-id="{{item.id}}" onTap="nextq">下一题</button>
+              <button size="mini" type="primary" a:if="{{id+1 == data.length}}" data-id="{{item.id}}" onTap="formSubmit">提交</button>
+            </view>
+          </form>
+        </view>
+      </swiper-item>
+    </block>
+  </swiper>
+</view>

+ 221 - 0
pages/answer/answer.js

@@ -0,0 +1,221 @@
+import commonConfig from "../../common/common"
+let app = getApp()
+Page({
+  data: {
+    data: [],//all题列表
+    record: [],//提交给后台数据组
+    id: 0,//当前swiper-item的索引值
+    result_id: '',//考试结果id
+    duration: ''//倒计时
+  },
+  onLoad(options) {
+    let that = this
+    if (options.result_status == 1) {
+      dd.getStorage({
+        key: 'record',
+        success: function (res) {
+          let record = res.data
+          if (record && record.length != 0) {
+            dd.getStorage({
+              key: 'data',
+              success: function (r) {
+                console.log(r.data)
+                if (r.data) {
+                  that.setData({
+                    data: r.data
+                  })
+                  that.setData({
+                    record:record
+                  })
+                }
+              },
+              fail: function (res) {
+                dd.alert({ content: res.errorMessage });
+              }
+            })
+            that.setData({
+              id: record.indexOf(null)
+            })
+          } else {
+            that.getExamQuestions(options.exam_id)
+            that.setData({
+              id: 0
+            })
+          }
+
+        },
+        fail: function (res) {
+          dd.alert({ content: res.errorMessage });
+        }
+      });
+
+    } else {
+      that.getExamQuestions(options.exam_id)
+    }
+    dd.setStorage({
+      key: 'answerid',
+      data: {
+        exam_id: options.exam_id,
+        result_id: options.result_id
+      }
+    });
+    that.setData({
+      result_id: options.result_id
+    })
+    that.getdjs()
+  },
+  onUnload() {
+    // 页面被关闭
+    let record = this.data.record
+    console.log('页面被关闭')
+    dd.setStorage({
+      key: 'record',
+      data: record
+    });
+    // dd.showToast({
+    //   type: 'none',
+    //   content: '暂时离开',
+    //   duration: 3000
+    // });
+  },
+  getdjs() {
+    let params = {
+      result_id: this.data.result_id
+    }
+    app.https('POST', app.globaldata.apiUrl.getRemainingTime, JSON.stringify(params), {
+      type: false
+    }).then(res => {
+      this.setData({
+        djs: res.data.data.time
+      })
+      let examSurplusTime = res.data.data.time;//获取考试剩余时间
+      // let examSurplusTime = 60;
+      this.examDjsFn(examSurplusTime)
+    })
+  },
+  examDjsFn(examSurplusTime) {
+    let timer = null;
+    let that = this
+    let time = examSurplusTime * 1000
+    timer = setInterval(() => {
+      let h, m, s
+      if (time >= 0) {
+        m = Math.floor(time / 1000 / 60 % 60);
+        s = Math.floor(time / 1000 % 60);
+        m = m < 10 ? ('0' + m) : m;
+        s = s < 10 ? ('0' + s) : s;
+        let duration = m + ':' + s;
+        that.setData({
+          duration: duration
+        })
+        time = time - 1000
+      } else {
+        clearInterval(timer);
+        let duration = '00:00'
+        that.setData({
+          duration: duration
+        })
+        dd.showToast({
+          type: 'fail',
+          content: '答题超时,将为你自动提交!',
+          duration: 3000,
+          success: () => {
+            that.formSubmit()
+          },
+        });
+
+      }
+    }, 1000);
+  },
+  onSubmit(e) {},
+  radioChange(e) {
+    console.log(e)
+    let record = this.data.record
+    let id = this.data.id;
+    record[id] = { question_id: e.currentTarget.dataset.id, answer: [{ key: e.detail.value, checked: 1 }] };
+    this.setData({
+      record: record,
+    })
+    let data = commonConfig.filterData(this.data.record, this.data.data)
+    dd.setStorage({
+      key: 'data',
+      data: data
+    })
+    console.log(this.data.record)
+  },
+  checkedChange(e) {
+    let record = this.data.record
+    let value = e.detail.value
+    let id = this.data.id;
+    let answers = []
+    answers = value.map((item) => {
+      return {
+        key: item,
+        checked: 1
+      }
+    })
+    record[id] = { question_id: e.currentTarget.dataset.id, answer: answers };
+    console.log(record)
+    this.setData({
+      record: record,
+    })
+    let data = commonConfig.filterData(this.data.record, this.data.data)
+    dd.setStorage({
+      key: 'data',
+      data: data
+    })
+    console.log(this.data.record)
+  },
+  swiperChange(e) {
+    this.setData({
+      id: e.detail.current
+    })
+  },
+  getExamQuestions(exam_id) {
+    let that = this;
+    let params = {
+      exam_id: exam_id
+    }
+    app.https('POST', app.globaldata.apiUrl.getExamQuestions, JSON.stringify(params), {
+      type: false
+    }).then(res => {
+      that.setData({
+        record: new Array(res.data.data.questions.length),
+        data: res.data.data.questions
+      })
+      dd.setStorage({
+        key: 'data',
+        data: res.data.data.questions
+      })
+    })
+  },
+  lastq() {
+    if (this.data.id != 0) {
+      this.setData({
+        id: this.data.id - 1,
+      })
+    }
+  },
+  nextq() {
+    if (this.data.id < this.data.data.length) {
+      this.setData({
+        id: this.data.id + 1,
+      })
+    }
+  },
+  formSubmit() {//提交
+    let params = {
+      result_id: this.data.result_id,
+      record: this.data.record
+    }
+    app.https('POST', app.globaldata.apiUrl.subExam, JSON.stringify(params), {
+      type: false
+    }).then(res => {
+      console.log(res)
+      dd.reLaunch({
+        url: "../result/result?scores=" + res.data.data.scores + "&qualified=" + res.data.data.qualified
+      })
+
+    })
+  }
+});

+ 5 - 0
pages/answer/answer.json

@@ -0,0 +1,5 @@
+{
+  "defaultTitle": "",
+  "backgroundColor": "#ffffff",
+  "titleBarColor": "#51CDE4"
+}

+ 128 - 0
pages/index/index.acss

@@ -0,0 +1,128 @@
+.swiper-tab {
+  width: 100%;
+  text-align: center;
+  line-height: 100rpx;
+  padding: 0 32rpx;
+  box-sizing: border-box;
+  background-color: rgb(255, 255, 255);
+  display: flex;
+  justify-content: space-between;
+  /* position: fixed;
+  left: 0;
+  top: 0; */
+  z-index: 9999;
+}
+
+.swiper-tab-list {
+  font-size: 32rpx;
+  color: #333333;
+}
+
+.on::after {
+  content: '';
+  clear: both;
+  width: 60rpx;
+  height: 6rpx;
+  border-radius: 200rpx;
+  background: #51CDE4;
+  display: inline-block;
+  margin-top: -20rpx;
+}
+
+/* 未完成列表 */
+
+.unfinished-list {
+  height: calc(100vh - 100rpx);
+  margin: 32rpx;
+  /* margin-top: 90rpx; */
+}
+.unfinished-list .demo-swiper{
+  height: 100vh!important;
+}
+.unfinished-list .swiper-item-list-box {
+  width: 686rpx;
+  height: 260rpx;
+  background: #FFFFFF;
+  box-shadow: 0px 4rpx 8rpx rgba(0, 0, 0, 0.1);
+  opacity: 1;
+  border-radius: 16rpx;
+  padding: 28rpx 32rpx;
+  box-sizing: border-box;
+  margin-top: 40rpx;
+}
+
+.swiper-item-list-box .top-header {
+  justify-content: space-between
+}
+
+.swiper-item-list-box .top-header .answer-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333333;
+}
+
+.swiper-item-list-box .top-header .get-score {
+  font-size: 28rpx;
+  color: #666666;
+  margin: 0 20rpx;
+  font-weight: bold;
+}
+
+.swiper-item-list-box .top-header .answer-status {
+  width: 68rpx;
+  height: 34rpx;
+  background: #FFFFFF;
+  border: 2rpx solid #FFA488;
+  opacity: 1;
+  border-radius: 16rpx;
+  font-size: 22rpx;
+  font-family: PingFang SC;
+  font-weight: 400;
+  line-height: 32px;
+  color: #FFA488;
+  opacity: 1;
+}
+
+.swiper-item-list-box .top-header .is-qualified {
+  font-size: 28rpx;
+  font-family: PingFang SC;
+  font-weight: 400;
+  line-height: 40rpx;
+  color: #333333;
+  opacity: 1;
+}
+.swiper-item-list-box .top-header .no-answer{
+  color: #FF0000;
+}
+.swiper-item-list-box .top-header .no-start{
+  color: #0DC280;
+}
+.swiper-item-list-box .top-header .page-section-demo{
+  width: 200rpx;
+}
+.swiper-item-list-box .middle-answer {
+  padding: 32rpx 0;
+  border-bottom: 2rpx solid #E8E8E8;
+  font-size: 26rpx;
+  font-family: PingFang SC;
+  font-weight: 400;
+  line-height: 36rpx;
+  color: #666666;
+  opacity: 1;
+}
+
+.swiper-item-list-box .middle-answer image {
+  width: 24rpx;
+  height: 24rpx;
+  margin-right: 12rpx;
+}
+
+.swiper-item-list-box .bot-submit-time {
+  font-size: 24rpx;
+  font-family: PingFang SC;
+  font-weight: 400;
+  line-height: 48rpx;
+  color: #999999;
+  opacity: 1;
+  margin-top: 26rpx;
+}

+ 79 - 0
pages/index/index.axml

@@ -0,0 +1,79 @@
+<view class="swiper-tab">
+  <block a:for="{{tabs}}" a:for-index="index" a:for-item="item">
+    <view class="swiper-tab-list flex-direct {{currentTab==index ? 'on' : ''}}" data-current="{{index}}" onTap="swichNav">{{item.name}}</view>
+    <!--<view class="swiper-tab-list flex-direct {{currentTab==1 ? 'on' : ''}}" data-current="1" onTap="swichNav">合格</view><view class="swiper-tab-list flex-direct {{currentTab==2 ? 'on' : ''}}" data-current="2" onTap="swichNav">不合格</view><view class="swiper-tab-list flex-direct {{currentTab==3 ? 'on' : ''}}" data-current="3" onTap="swichNav">缺考</view> -->
+  </block>
+</view>
+<view class="unfinished-list">
+  <swiper class="demo-swiper" indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" vertical="{{vertical}}" interval="{{interval}}" circular="{{circular}}" current="{{currentTab}}" onChange="swiperChange">
+    <block a:for="{{tabs}}" a:for-index="index" a:for-item="item">
+      <swiper-item class="swiper-item" key="swiper-item-{{index}}">
+        <block a:for="{{answerList}}">
+        <view class="swiper-item-list-box" a:if="{{currentTab == 0}}" data-resultid="{{item.result_id}}" data-examid="{{item.exam_id}}" data-duration="{{item.duration}}" data-resultstatus="{{item.result_status}}" onTap="goAnswer">
+          <view class="top-header flex align-center">
+            <view class="answer-title">{{item.title}}</view>
+            <view class="is-qualified no-start" a:if="{{item.result_status == 0}}">未开始</view>
+            <view class="page-section-demo" a:if="{{item.result_status == 1}}">
+              <progress percent="{{item.percent}}" show-info stroke-width="4" activeColor="#51CDE4" active="true"/>
+            </view>
+          </view>
+          <view class="middle-answer flex align-center">
+            <image mode="scaleToFill" src="../../image/time.png"/>
+            <text a:if="{{item.result_status == 1}}">开始时间:{{item.result_start_time}}</text>
+            <text a:else>考试时长:{{item.duration}}分钟</text>
+          </view>
+          <view class="bot-submit-time">起止日期:{{item.start_time}}  -  {{(item.end_time).substring(5,19)}}</view>
+        </view>
+        </block>
+        <block a:for="{{qualifiedList}}">
+        <view class="swiper-item-list-box" a:if="{{currentTab == 1}}">
+          <view class="top-header flex align-center">
+            <view class="flex">
+              <view class="answer-title">{{itme.title}}</view>
+              <view class="get-score">得分:{{item.scores}}分</view>
+              <view class="answer-status flex align-center justify-center" a:if="{{item.newest==1}}">最新</view>
+            </view>
+            <view class="is-qualified">合格</view>
+          </view>
+          <view class="middle-answer flex align-center">
+            <image mode="scaleToFill" src="../../image/time.png"/>
+            <text>答题时长:{{itme.duration}} 总分:{{item.total}}分</text>
+          </view>
+          <view class="bot-submit-time">提交时间:{{item.submit_time}}</view>
+        </view>
+        </block>
+        <block a:for="{{unqualifiedList}}">
+        <view class="swiper-item-list-box" a:if="{{currentTab == 2}}" data-scores="{{item.scores}}" data-resultid="{{item.result_id}}" data-examid="{{item.exam_id}}" onTap="goretakeExam">
+          <view class="top-header flex align-center">
+            <view class="flex">
+              <view class="answer-title">{{itme.title}}</view>
+              <view class="get-score">得分:{{item.scores}}分</view>
+              <view class="answer-status flex align-center justify-center" a:if="{{item.newest==0}}">历史</view>
+            </view>
+            <view class="is-qualified">不合格</view>
+          </view>
+          <view class="middle-answer flex align-center">
+            <image mode="scaleToFill" src="../../image/time.png"/>
+            <text>答题时长:{{itme.duration}} 总分:{{item.total}}分</text>
+          </view>
+          <view class="bot-submit-time">提交时间:{{item.submit_time}}</view>
+        </view>
+        </block>
+        <block a:for="{{missedList}}">
+        <view class="swiper-item-list-box" a:if="{{currentTab == 3}}">
+          <view class="top-header flex align-center">
+            <view class="answer-title">{{item.title}}</view>
+            <view class="is-qualified no-answer">缺考</view>
+          </view>
+          <view class="middle-answer flex align-center">
+            <image mode="scaleToFill" src="../../image/time.png"/>
+            <text>剩余时间:00:10:35</text>
+          </view>
+          <view class="bot-submit-time">起止日期:2020-12-01 09:00:00  -  12-03 09:00:00
+          </view>
+        </view>
+        </block>
+      </swiper-item>
+    </block>
+  </swiper>
+</view>

+ 224 - 0
pages/index/index.js

@@ -0,0 +1,224 @@
+let app = getApp()
+Page({
+  data: {
+    tabs: [{
+      name: '未完成'
+    }, {
+      name: '合格'
+    }, {
+      name: '不合格'
+    }, {
+      name: '缺考'
+    }],
+    currentTab: 0,
+    phone: '',
+    answerList: [],
+    qualifiedList: [],
+    unqualifiedList: [],
+    missedList: [],
+    record: [],//答题结果
+    recordindex: 0
+  },
+  onShareAppMessage(){},
+  onLoad() {
+    let that = this;
+    dd.getStorage({
+      key: 'userInf',
+      success: function (res) {
+        that.setData({
+          phone: res.data.phone
+        })
+        let params = {
+          phone: res.data.phone
+          //  phone: '17611172370'
+        }
+        that.getUndoneExam(params)
+      },
+      fail: function (res) {
+        dd.alert({ content: res.errorMessage });
+      }
+    });
+
+
+  },
+  onShow() {
+    let that = this
+    dd.getStorage({
+      key: 'record',
+      success: function (res) {
+        that.setData({
+          record: res
+        })
+
+      },
+      fail: function (res) {
+        dd.alert({ content: res.errorMessage });
+      }
+    });
+  },
+  // tab切换逻辑
+  swichNav(e) {
+    if (this.data.currentTab === e.target.dataset.current) {
+      return false;
+    } else {
+      this.setData({
+        currentTab: e.target.dataset.current
+      })
+      this.getCurrentTab()
+    }
+  },
+  goAnswer(e) {
+    let exam_id = e.target.dataset.examid
+    let result_id = e.target.dataset.resultid
+    let duration = e.target.dataset.duration
+    let result_status = e.target.dataset.resultstatus
+    if (e.target.dataset.resultstatus == 1) {
+      dd.confirm({
+        title: '温馨提示',
+        content: '是否继续考试',
+        confirmButtonText: '是',
+        cancelButtonText: '否',
+        success: (result) => {
+          if (result.confirm) {
+            dd.navigateTo({
+              url: '../answer/answer?exam_id=' + exam_id + '&result_id=' + result_id + '&duration=' + duration + '&result_status=' + result_status
+            })
+          }
+        },
+      });
+
+      return
+    } else {
+      dd.confirm({
+        title: '温馨提示',
+        content: '是否开始考试',
+        confirmButtonText: '是',
+        cancelButtonText: '否',
+        success: (result) => {
+          if (result.confirm) {
+            this.goStartExam(exam_id, result_id, duration, result_status)
+          }
+        },
+      });
+    }
+  },
+  goStartExam(exam_id, result_id, duration, result_status) {
+    let params = {
+      result_id: result_id
+    }
+    app.https('POST', app.globaldata.apiUrl.startExam, JSON.stringify(params), {
+      type: false
+    }).then(res => {
+
+      dd.reLaunch({
+        url: '../answer/answer?exam_id=' + exam_id + '&result_id=' + result_id + '&duration=' + duration + '&result_status=' + result_status
+      })
+    })
+  },
+  goretakeExam(e) {
+    console.log(e)
+    dd.setStorage({
+      key: 'answerid',
+      data: {
+        exam_id:e.target.dataset.examid,
+        result_id: e.target.dataset.resultid
+      }
+    });
+    dd.reLaunch({
+      url: "../result/result?scores=" + e.target.dataset.scores + "&qualified=" + 0
+    })
+  },
+  swiperChange(e) {
+    this.setData({ currentTab: e.detail.current });
+    this.getCurrentTab()
+  },
+  getCurrentTab() {
+    let currentTab = this.data.currentTab
+    console.log(currentTab)
+    let params = {
+      phone: this.data.phone
+    }
+    if (currentTab == 0) {
+      this.getUndoneExam(params);
+    } else if (currentTab == 1) {
+      this.getQualifiedExam(params);
+    } else if (currentTab == 2) {
+      this.getUnqualifiedExam(params);
+    } else {
+      this.getMissedExam(params);
+    }
+
+  },
+  // 未完成
+  getUndoneExam(params) {
+    let that = this
+    app.https('POST', app.globaldata.apiUrl.getUndoneExam, JSON.stringify(params), {
+      type: false
+    }).then(res => {
+      that.setData({
+        answerList: res.data.data
+      })
+      let record = this.data.record.data
+      if (record && record != []) {
+        that.getnum(record)
+      }
+    })
+  },
+  getnum(record) {
+    let that = this
+    let counter = 0;
+    for (let i = 0; i < record.length; i++) {
+      if (record[i]) counter++;
+    }
+    let percent = (counter / (record.length)) * 100
+    dd.getStorage({
+      key: 'answerid',
+      success: function (res) {
+        let answerLists = that.data.answerList.map((item) => {
+          if (item.exam_id == res.data.exam_id) {
+            return {
+              ...item,
+              percent: percent ? percent : 0
+            }
+          } else {
+            return {
+              ...item
+            }
+          }
+        })
+        that.setData({
+          answerList: answerLists
+        })
+        console.log(that.data.answerList)
+      }
+    });
+
+  },
+  getQualifiedExam(params) {
+    app.https('POST', app.globaldata.apiUrl.getQualifiedExam, JSON.stringify(params), {
+      type: false
+    }).then(res => {
+      this.setData({
+        qualifiedList: res.data.data
+      })
+    })
+  },
+  getUnqualifiedExam(params) {
+    app.https('POST', app.globaldata.apiUrl.getUnqualifiedExam, JSON.stringify(params), {
+      type: false
+    }).then(res => {
+      this.setData({
+        unqualifiedList: res.data.data
+      })
+    })
+  },
+  getMissedExam(params) {
+    app.https('POST', app.globaldata.apiUrl.getMissedExam, JSON.stringify(params), {
+      type: false
+    }).then(res => {
+      this.setData({
+        missedList: res.data.data
+      })
+    })
+  }
+});

+ 5 - 0
pages/index/index.json

@@ -0,0 +1,5 @@
+{
+  "defaultTitle": "中世康恺科技有限公司",
+  "backgroundColor": "#F6F6F6",
+  "titleBarColor": "#51CDE4"
+}

+ 61 - 0
pages/my/my.acss

@@ -0,0 +1,61 @@
+.my-page{
+  position: relative
+}
+.my-page .top-bg {
+  width: 750rpx;
+  height: 226rpx;
+  background: #51CDE4;
+  opacity: 1;
+  border-radius: 0px 0px 40rpx 40rpx;
+}
+
+.header-img {
+  width: 240rpx;
+  height: 240rpx;
+  background: #FFFFFF;
+  border-radius: 50%;
+  opacity: 1;
+  margin: 0 auto;
+}
+.defaultImg{
+  width: 106rpx;
+  height: 120rpx;
+}
+.headerImg{
+  width: 240rpx;
+  height: 240rpx;
+  border-radius:50%; 
+}
+.user-inf{
+  width: 100%;
+  text-align: center;
+  position: absolute;
+  top: 106rpx;
+
+}
+.user-inf .name {
+  font-size: 30rpx;
+  font-family: PingFang SC;
+  font-weight: bold;
+  line-height: 42rpx;
+  color: #333333;
+  opacity: 1;
+  margin: 30rpx 0 14rpx 0;
+}
+
+.user-inf .com-name {
+  font-size: 26rpx;
+  font-family: PingFang SC;
+  font-weight: 400;
+  line-height: 36rpx;
+  color: #999999;
+  opacity: 1;
+}
+.my-page .version{
+  width: 100%;
+  text-align: center;
+  position: fixed;
+  bottom: 238rpx;
+  font-size: 26rpx;
+  color: #666666;
+}

+ 12 - 0
pages/my/my.axml

@@ -0,0 +1,12 @@
+<view class="my-page">
+  <view class="top-bg"></view>
+  <view class="user-inf">
+    <view class="header-img flex justify-center align-center">
+      <image class="defaultImg" a:if="{{avatar==''}}" mode="scaleToFill" src="../../image/default-header.png"/>
+      <image class="headerImg" a:if="{{avatar!=''}}" mode="scaleToFill" src="{{avatar}}"/>
+    </view>
+    <view class="name">{{name}}</view>
+    <view class="com-name">--中世康恺科技有限公司--</view>
+  </view>
+  <view class="version">版本号v1.0</view>
+</view>

+ 21 - 0
pages/my/my.js

@@ -0,0 +1,21 @@
+Page({
+  data: {
+    name:'',
+    avatar:''
+  },
+  onLoad() {
+    let that = this;
+    dd.getStorage({
+      key: 'userInf',
+      success: function (res) {
+        that.setData({
+          name: res.data.name,
+          avatar: res.data.avatar
+        })
+      },
+      fail: function (res) {
+        dd.alert({ content: res.errorMessage });
+      }
+    });
+  },
+});

+ 5 - 0
pages/my/my.json

@@ -0,0 +1,5 @@
+{
+  "defaultTitle": "",
+  "backgroundColor": "#F6F6F6",
+  "titleBarColor": "#51CDE4"
+}

+ 61 - 0
pages/result/result.acss

@@ -0,0 +1,61 @@
+.result-page {
+  margin-top: 146rpx;
+}
+
+.result-page .content image {
+  width: 218rpx;
+  height: 218rpx;
+}
+
+.result-page .content .fail-tip, .result-page .content .success-tip {
+  font-size: 30rpx;
+  font-family: PingFang SC;
+  font-weight: 400;
+  line-height: 42rpx;
+  color: #666666;
+  opacity: 1;
+  margin: 44rpx 0 80rpx;
+}
+
+.grade-box {
+  font-size: 44rpx;
+  font-family: PingFang SC;
+  font-weight: 400;
+  line-height: 60px;
+  color: #51CDE4;
+  opacity: 1;
+}
+
+.grade {
+  font-size: 98rpx;
+  font-weight: bold;
+}
+.tag-pass{
+  color: #51CDE4;
+}
+.tag-nopass{
+  color: #FF0000;
+}
+.bot-btn{
+  width: 100%;
+  text-align: center;
+  position: fixed;
+  bottom: 48rpx;
+  padding-bottom: 48rpx;
+  border-bottom: 1px solid #E8E8E8;
+}
+.bot-btn button {
+  width: 654rpx;
+  height: 88rpx;
+  background: #51CDE4;
+  opacity: 1;
+  border-radius: 44rpx;
+  font-size: 34rpx;
+  font-family: PingFang SC;
+  font-weight: 400;
+  line-height: 88rpx;
+  color: #FFFFFF;
+  opacity: 1;
+  border: none;
+  margin: 0 auto;
+}

+ 20 - 0
pages/result/result.axml

@@ -0,0 +1,20 @@
+<view class="result-page">
+  <view class="content flex-direct">
+    <block a:if="{{qualified == 0}}">
+      <image mode="scaleToFill" src="../../image/fail.png"/>
+      <view class="fail-tip">很遗憾!成绩不合格,你没能通过考试~</view>
+    </block>
+    <block a:else>
+      <image mode="scaleToFill" src="../../image/success.png"/>
+      <view class="success-tip">恭喜你!成绩合格,通过考试~</view>
+    </block>
+    <view class="grade-box {{qualified==1 ? 'tag-pass':'tag-nopass'}}">
+      <text class="grade">{{scores}}</text>
+      <text>分</text>
+    </view>
+  </view>
+  <view class="bot-btn flex-direct">
+    <button size="mini" type="ghost" style="margin-bottom:46rpx;" onTap="resetAnswer">重考</button>
+    <button size="mini" type="ghost" onTap="back">返回</button>
+  </view>
+</view>

+ 60 - 0
pages/result/result.js

@@ -0,0 +1,60 @@
+let app = getApp()
+Page({
+  data: {
+    scores: '',
+    qualified: ''
+  },
+  onLoad(options) {
+    this.setData({
+      scores: options.scores,
+      qualified: options.qualified
+    })
+  },
+  resetAnswer() {
+    let that = this
+    let content
+    if (that.data.qualified == '0') {
+      content = "很遗憾!成绩不合格,是否重新本次考试?"
+    } else {
+      content = "您已合格,重考将覆盖原始记录,是否继续?"
+    }
+    dd.confirm({
+      title: '温馨提示',
+      content: content,
+      confirmButtonText: '是',
+      cancelButtonText: '否',
+      success: (result) => {
+        if (result.confirm) {
+          dd.getStorage({
+            key: 'answerid',
+            success: function (res) {
+              that.retakeExam(res.data.exam_id, res.data.result_id)
+            },
+            fail: function (res) {
+              dd.alert({ content: res.errorMessage });
+            }
+          });
+        }
+      },
+    });
+  },
+  retakeExam(exam_id, result_id) {
+    let params = {
+      result_id: result_id
+    }
+    app.https('POST', app.globaldata.apiUrl.retakeExam, JSON.stringify(params), {
+      type: false
+    }).then(res => {
+      console.log(res)
+      dd.reLaunch({
+        url: "../answer/answer?result_id=" + res.data.data.result_id + '&exam_id=' + exam_id
+      })
+
+    })
+  },
+  back() {
+    dd.reLaunch({
+      url: '../index/index'
+    })
+  }
+});

+ 3 - 0
pages/result/result.json

@@ -0,0 +1,3 @@
+{
+  "defaultTitle": ""
+}

BIN
snapshot.png