pull/15/head
脆皮鸭 1 year ago
parent 1596959583
commit 97547afc4d
  1. 2
      src/App.vue
  2. 9
      src/jtools/api/pay.js
  3. 42
      src/jtools/pay/index.js
  4. 19
      src/jtools/store/question.js
  5. 261
      src/jtools/wechat/wechat.js
  6. 7
      src/pages.json
  7. 19
      src/pages/index/components/Subject1.vue
  8. 22
      src/pages/index/components/Subject2.vue
  9. 12
      src/pages/index/index.vue
  10. 43
      src/pages/index/paySuccess.vue
  11. 82
      src/pages/index/videoVip.vue
  12. 163
      src/pages/questionBank/components/Question.vue
  13. 34
      src/pages/questionBank/exclusiveExercise.vue
  14. 9
      src/pages/questionBank/practiceResult.vue
  15. 3
      src/pages/questionBank/questionBank.vue
  16. 231
      src/pages/questionBank/videoDetail.vue
  17. BIN
      src/static/image/index/paysucess.jpg
  18. BIN
      src/static/image/practice/vip_bg.jpg
  19. BIN
      src/static/image/practice/vip_bg.png

@ -4,8 +4,8 @@ import useQuestionStore from '@/jtools/store/question' //引入store
export default {
onLaunch: function () {
useUserStore().queryVipList()
if(useUserStore().isLogin) {
useQuestionStore().getOrderQuestion('1')
if(useUserStore().isLogin) {
useUserStore().getUserInfo()
useUserStore().searchUserVip()
}

@ -0,0 +1,9 @@
import request from '../request/index.js';
export function prePay(data) {
return request({
url: 'driver-api/applet/pay/prepay',
method: 'POST',
data,
});
}

@ -1,10 +1,10 @@
import request from '../request/index.js';
// #ifdef H5
import wxsdk from '@/jtools/wechat/sdk'
// import wxsdk from '@/jtools/wechat/sdk'
// #endif
import wechat from '@/jtools/wechat/wechat'
// import wechat from '@/jtools/wechat/wechat'
import $platform from '@/jtools/platform';
import {prePay} from '@/jtools/api/pay'
/**
* 支付
*
@ -60,26 +60,17 @@ export default class JtoolsPay {
const p = $platform.device()
const tradeInfoType = p == 'android' ? 'Android' : p == 'ios' ? 'iOS' : 'Wap'
let params = {
orderId: this.order.orderId,
orderPayType: this.order.orderPayType,
money: this.order.money,
microServiceName: this.order.microServiceName,
prepayParamUrl: this.order.prepayParamUrl,
paymentType: 'weChatPay',
payType: 'JSAPI',
tradeInfoType: tradeInfoType,
tenantId: '-1',
clientType: 'miniWx'
"code":this.order.code,
"description": this.order.description,
"money": this.order.money,
"outTradeNo": this.order.outTradeNo,
"userId": this.order.userId
}
if (uni.getStorageSync('openId')) {
params.openId = uni.getStorageSync('openId');
}
request({
url: 'driver-api/applet/pay/prepay',
method: 'POST',
param,
}).then(res => {
if (res.code == 'SUCCESS') {
prePay(params).then(res => {
if (res.code == '0000') {
resolve(res);
}
})
@ -91,18 +82,19 @@ export default class JtoolsPay {
async wxMiniProgramPay() {
let that = this;
let result = await this.prepay();
const params = result.data.jsApiResult
const params = result.data
uni.requestPayment({
provider: 'wxpay',
...{
appId: params.appId, //公众号名称,由商户传入
timeStamp: params.timestamp, //时间戳,自1970年以来的秒数
timeStamp: params.timeStamp, //时间戳,自1970年以来的秒数
nonceStr: params.nonceStr, //随机串
package: `prepay_id=${params.prepay_id}`,
package: params.packageVal,
signType: params.signType, //微信签名方式:
paySign: params.paySign, //微信签名
},
success: res => {
console.log(res);
that.payResult('success', result.data.orderPayNo)
},
fail: err => {
@ -126,7 +118,6 @@ export default class JtoolsPay {
that.payResult('success')
},
fail: err => {
console.log('支付取消或者失败:', err);
err.errMsg !== "requestPayment:fail cancel" && that.payResult('fail')
}
});
@ -137,6 +128,7 @@ export default class JtoolsPay {
async wechatPay() {
let that = this;
let result = await this.prepay();
console.log('微信支付');
if (result.code === 1) {
uni.requestPayment({
provider: 'wxpay',
@ -156,9 +148,9 @@ export default class JtoolsPay {
// 支付结果跳转,success:成功,fail:失败
payResult(resultType, orderPayNo) {
const that = this;
let path = ''
let path = 'paySuccess'
uni.navigateTo({
url:path
url: path
})
}

@ -21,10 +21,27 @@ const question = defineStore({
getOrderQuestion(val) {
queryQuestion({
carTypeId: this.currentCartype,
subject: val
subject: val,
// questionIdList:[10982,10983,10985,10986]
}).then(res => {
if (res.code == '0000') {
this.orderQuestion = res.data
const falseList =storage.get(`wrongList_subject${val}`) || []
const trueList =storage.get(`rightList_subject${val}`) || []
const falseArr=[]
const rightArr=[]
this.orderQuestion.forEach(item=>{
if(falseList.includes(item.questionId)){
falseArr.push(item.questionId)
}
if(trueList.includes(item.questionId)){
rightArr.push(item.questionId)
}
})
console.log('falseArr',falseArr);
storage.set(`wrongList_subject${val}`,falseArr)
storage.set(`rightList_subject${val}`,rightArr)
console.log(storage.get(`wrongList_subject${val}`));
}
})
},

@ -0,0 +1,261 @@
/**
* Wechat v1.1.0
* @Class Wechat
* @description jtools-wechat 1.1.0 wehcat第三方登录组件
* @Author lidongtony
* @Date 2020-05-20
* @Email lidongtony@qq.com
*/
import api from "@/jtools/request/index";
import $platform from "@/jtools/platform";
import store from "@/jtools/store";
import {
API_URL
} from "@/env";
export default {
eventMap(event) {
let map = "";
switch (event) {
case "login":
map = "登录中...";
break;
case "refresh":
map = "更新中...";
break;
case "bind":
map = "绑定中...";
break;
}
return map;
},
async login() {
let token = "";
// #ifdef MP-WEIXIN
token = await this.wxMiniProgramOauth("login");
return token;
// #endif
// #ifdef H5
this.wxOfficialAccountOauth("login");
// #endif
// #ifdef APP-PLUS
token = await this.wxOpenPlatformOauth("login");
return token;
// #endif
},
async refresh() {
let token = "";
// #ifdef MP-WEIXIN
token = await this.wxMiniProgramOauth("refresh");
return token;
// #endif
// #ifdef H5
this.wxOfficialAccountOauth("refresh");
// #endif
// #ifdef APP-PLUS
token = await this.wxOpenPlatformOauth("refresh");
return token;
// #endif
},
async bind() {
let token = "";
// #ifdef MP-WEIXIN
token = await this.wxMiniProgramOauth("bind");
return token;
// #endif
// #ifdef H5
this.wxOfficialAccountOauth("bind");
// #endif
// #ifdef APP-PLUS
token = await this.wxOpenPlatformOauth("bind");
return token;
// #endif
},
// #ifdef H5
// 微信公众号网页登录&刷新头像昵称&绑定
wxOfficialAccountOauth(event = "login") {
if ($platform.get() !== "wxOfficialAccount") {
uni.showToast({
title: "请在微信浏览器中打开",
icon: "none"
});
throw false;
}
let host = $platform.host();
let payloadObject = {
host: host,
event,
token: (event !== "login" && store.getters.isLogin) ? uni.getStorageSync("token") : ""
};
let payload = encodeURIComponent(JSON.stringify(payloadObject));
let redirect_uri = encodeURIComponent(`${API_URL}user/wxOfficialAccountOauth?payload=${payload}`);
let oauthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + store.getters.initWechat.appid +
`&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=1`;
uni.setStorageSync("lastPage", window.location.href);
window.location = oauthUrl;
},
// 微信公众号网页静默登录:临时登录获取OpenId 不入库不绑定用户
wxOfficialAccountBaseLogin() {
let state = encodeURIComponent(window.location.href);
window.location = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + store.getters.initWechat.appid +
`&redirect_uri=${API_URL}user/wxOfficialAccountBaseLogin&response_type=code&scope=snsapi_base&state=${state}`;
throw "stop";
},
// #endif
// #ifdef APP-PLUS
// 微信开放平台登录
wxOpenPlatformOauth(event = "login") {
let that = this;
return new Promise((resolve, reject) => {
uni.login({
provider: "weixin",
success: function(loginRes) {
if (loginRes.errMsg === "login:ok") {
let authResult = loginRes.authResult;
api("user.wxOpenPlatformOauth", {
authResult,
event
}, that.eventMap(event)).then(res => {
if (res.code === 1) {
resolve(res.data.token);
} else {
resolve(false);
}
});
}
},
fail: function(res) {
uni.showToast({
title: "登录失败,请稍后再试"
});
resolve(false);
api("common.debug", {
info: res
});
},
complete: function(res) {}
});
});
},
// #endif
// #ifdef MP-WEIXIN
// 微信小程序静默登录
async getWxMiniProgramSessionKey(autoLogin = true) {
let sessionStatus = false;
let session_key = "";
return new Promise((resolve, reject) => {
uni.checkSession({
success(res) {
if (res.errMsg === "checkSession:ok") sessionStatus = true;
},
complete() {
if (uni.getStorageSync("session_key") && sessionStatus && !autoLogin) {
resolve(uni.getStorageSync("session_key"));
} else {
uni.login({
success: function(info) {
let code = info.code;
api("user.getWxMiniProgramSessionKey", {
code: code,
autoLogin: autoLogin
}).then(res => {
if (res.code === 1) {
uni.setStorageSync("session_key", res
.data.session_key);
if (autoLogin) {
if (res.data.token) {
resolve(res.data.token);
} else {
resolve(false);
}
}
resolve(res.data.session_key);
} else {
reject(res.msg);
}
});
}
});
}
}
});
});
},
// 微信小程序获取用户信息登录
wxMiniProgramOauth(event = "login") {
let that = this;
let session_key = uni.getStorageSync("session_key");
uni.showLoading({
title: that.eventMap(event)
});
return new Promise((resolve, reject) => {
uni.getUserProfile({ // 必须手动确认触发
desc: "完善会员资料", // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: res => {
if (res.errMsg === "getUserProfile:ok") {
api("user.wxMiniProgramOauth", {
event,
session_key,
encryptedData: res.encryptedData,
iv: res.iv,
signature: res.signature,
}).then(res => {
console.log(res)
if (res.code === 1) {
resolve(res.data.token);
} else {
uni.removeStorageSync("session_key");
that.getWxMiniProgramSessionKey(false);
resolve(false);
}
});
}
},
complete: res => {
uni.hideLoading();
}
});
});
},
// 小程序更新
checkMiniProgramUpdate() {
if (uni.canIUse("getUpdateManager")) {
const updateManager = uni.getUpdateManager();
updateManager.onCheckForUpdate(function(res) {
// 请求完新版本信息的回调
if (res.hasUpdate) {
updateManager.onUpdateReady(function() {
uni.showModal({
title: "更新提示",
content: "新版本已经准备好,是否重启应用?",
success: function(res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
}
}
});
});
updateManager.onUpdateFailed(function() {
// 新的版本下载失败
uni.showModal({
title: "已经有新版本了哟~",
content: "新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~"
});
});
}
});
}
},
// #endif
};

@ -131,6 +131,13 @@
"navigationBarTitleText": "考场实况",
"enablePullDownRefresh": false
}
},
{
"path": "pages/index/paySuccess",
"style": {
"navigationBarTitleText": "支付结果",
"enablePullDownRefresh": false
}
}
],

@ -8,7 +8,7 @@
<view class="btn-item flex ai-c jc-c">
<view class="text-center cor-fff" style="line-height: 40rpx;" @tap="toAnswer('顺序答题',false)">
<view class="fs16">顺序练习</view>
<text class="fs14">{{rightList.length+wrongList.length}}/{{orderQuestion.length}}</text>
<text class="fs14">{{getDoNum}}/{{orderQuestion.length}}</text>
</view>
</view>
</view>
@ -103,20 +103,27 @@
props:{
subject:{
type:[String,Number],
},
rightList:{
type:Array
},
wrongList:{
type:Array
}
},
data() {
return {
rightList:storage.get(`rightList_subject${this.subject}`) || [],
wrongList:storage.get(`wrongList_subject${this.subject}`) || [],
allQuestionNum:0,
}
},
onLoad(){
// this.allQuestionNum=useQuestionStore().orderQuestion.length
mounted(){
},
computed: {
...mapState(useQuestionStore, ["orderQuestion"]) //tagslist
...mapState(useQuestionStore, ["orderQuestion"]) ,//tagslist
getDoNum(){
return this.rightList.length+this.wrongList.length
}
},
methods: {
toTestRoom(){

@ -9,17 +9,17 @@
<view class="p14lr" style="margin-top: -20px;">
<view class="video_box">
<view class="flex ai-c jc-sb mt5">
<text class="fs18 cor-000">科二考试项目讲解</text>
<text class="fs18 cor-000">{{subject=='2'?'':'三'}}考试项目讲解</text>
<view class="flex ai-c" style="height: 34rpx;line-height: 34rpx;" @tap="changeDiverType">
<text style="color:#05C341;font-size: 16px;">{{diverTypeList[diverTypeIndex].configItemName}}</text>
<text style="color:#05C341;font-size: 16px;">{{diverTypeList[diverTypeIndex]?.configItemName}}</text>
<u-icon name="list" color="#05C341" size="18"></u-icon>
</view>
</view>
<view class="flex ai-c jc-sb mt15">
<view class="tab_iem" :class="videoIndex===item.value?'checked_tab':''" v-for="(item,index) of operateList" :key="index" @tap="checkVideo(index)">{{item.description}}</view>
<view class="tab_iem" :class="videoIndex===index?'checked_tab':''" v-for="(item,index) of operateList" :key="index" @tap="checkVideo(index)">{{item.description}}</view>
</view>
<view class="mt15">
<video style="width: 100%;height: 362rpx;border-radius: 16rpx;" id="myVideo" :src="operateList[videoIndex].videoList[0].videoUrl"></video>
<view class="mt15" @tap="toVideo">
<video style="width: 100%;height: 362rpx;border-radius: 16rpx;" id="myVideo" src="http://flv4mp4.people.com.cn/videofile7/pvmsvideo/2021/3/10/ChenQiuNan_3c561132970edeedc50e153fcf3b186b_android_c.mp4"></video>
</view>
</view>
<view class="video_box mt10">
@ -52,6 +52,7 @@ export default {
diverTypeIndex:0,
diverTypeList:[],
videoIndex:0,
projectId:undefined,
operateList:[]
}
},
@ -59,17 +60,20 @@ export default {
await this.getDiverType()
},
methods:{
toVideo(){
uni.navigateTo({
url:"/pages/questionBank/videoDetail?driveType="+this.diverTypeList[this.diverTypeIndex].configItemCode+"&subject="+this.subject+"&projectId="+this.projectId+"&type=1"
})
},
getVideoList(){
console.log('index',this.diverTypeIndex);
console.log(this.diverTypeList[this.diverTypeIndex]);
queryProjectList({
"carTypeId": storage.get('carType') || '1001',
"driveType": this.diverTypeList[this.diverTypeIndex].configItemCode,
"subject": String(this.subject),
"projectId":'1001',
"type": "1"
}).then(resp=>{
this.operateList=resp.data
this.projectId=this.operateList[0]?.projectId
})
},
getDiverType(){
@ -86,6 +90,8 @@ export default {
this.getVideoList()
},
checkVideo(val){
console.log(val);
this.projectId=this.operateList[val]?.projectId
this.videoIndex=val
},
toDetail(){

@ -5,7 +5,7 @@
</u-sticky>
<view style="height: 100vh;background-color: rgb(245, 245, 245);">
<template v-if="tIndex===0 || tIndex===3">
<Subject1 :subject="tIndex+1" />
<Subject1 :subject="tIndex+1" :rightList="rightList" :wrongList="wrongList" />
</template>
<template v-else>
<subject2 :subject="tIndex+1" />
@ -34,10 +34,16 @@
name:'科目3'
},{
name:'科目4'
}]
}],
rightList:storage.get(`rightList_subject${this.tIndex+1}`) || [],
wrongList:storage.get(`wrongList_subject${this.tIndex+1}`) || [],
};
},
onLoad() {
onShow() {
if(this.tIndex==0||this.tIndex==3){
this.rightList=storage.get(`rightList_subject${this.tIndex+1}`) || []
this.wrongList=storage.get(`wrongList_subject${this.tIndex+1}`) || []
}
},
methods:{
...mapActions(useQuestionStore,['getOrderQuestion']),

@ -0,0 +1,43 @@
<template>
<view class="wp100 flex jc-c bc-fff " style="height: 100vh;">
<view class="mt50 text-center flex ai-c" style="flex-direction: column;">
<view style="width: 211rpx;" class="text-center">
<image style="width: 211rpx;height: 222rpx;;" src="../../static/image/index/paysucess.jpg"></image>
</view>
<view style="width: 385rpx;" class="text-center">
<view class="fw600 fs16 cor-000 mb10">支付成功</view>
<tetx class="fs14 cor-666">恭喜您您已成功购买VIP课程赶紧去学习吧</tetx>
</view>
<button class="btn mt10" @click="goBack">去学习</button>
</view>
</view>
</template>
<script>
export default{
data(){
return{
}
},
methods:{
goBack(){
uni.switchTab({
url:"/pages/index/index"
})
}
}
}
</script>
<style scoped>
.btn{
width: 260rpx;
height: 80rpx;
line-height: 80rpx;
text-align: center;
color:#00B74F;
border: 2px solid #00B74F;
border-radius: 40rpx;
}
</style>

@ -2,15 +2,15 @@
<view class="relative" style="height: 100vh;">
<image style="width: 100%;height: 600rpx;" src="../../static/image/index/vip_bg.jpg"></image>
<view class="p14">
<view class="flex jc-sb ai-c">
<view class="option_tem relative" :class="checkedPrice===item.priceId?'checked_item':''" v-for="(item,index) of priceList" :key="index" @click="checkPrice(item.priceId,item.money)">
<text class="fw600 fs16 cor-333">{{item.title}}</text>
<view class="flex jc-fa ai-c wp100">
<view class="option_tem relative mr20" :class="checkedId===item.memberId?'checked_item':''" v-for="(item,index) of priceList" :key="index" @click="checkPrice(item.memberId,item.price)">
<text class="fw600 fs15 cor-333">{{item.memberName}}</text>
<view class="mt5">
<text class="fs14" style="color: #FF6E02;">¥</text>
<text class="fs30 fw600" style="color: #FF6E02;">{{item.money}}</text>
<text class="fs30 fw600" style="color: #FF6E02;">{{item.price}}</text>
</view>
<text class="fs12 cor-999">长期有效</text>
<view class="bottom_box fs12 cor-333" :class="checkedPrice===item.priceId?'checked_bottom':''">赠送vip题库</view>
<view class="bottom_box fs12 cor-333" :class="checkedId===item.memberId?'checked_bottom':''">赠送vip题库</view>
<view class="tag" v-if="item.all">
<text style="transform:scale(0.83);">合买更优惠</text>
</view>
@ -30,7 +30,7 @@
</view>
</view>
</view>
<view class="wp100 p14" style="position: absolute;left: 0;bottom:20px">
<view class="wp100 p14" style="position: absolute;left: 0;bottom:20px" @tap="handlePay()">
<view class="sub_btn flex ai-c jc-sb">
<text class="cor-fff fs14">¥<text class="fs24 cor-fff">{{nowPrice}}</text></text>
<image style="width: 276rpx;height: 88rpx;margin-top: -5px;" src="../../static/image/index/buy.png"></image>
@ -40,34 +40,66 @@
</template>
<script>
import {
mapState,
mapActions
} from 'pinia' //
import { getVipList } from '@/jtools/api/vip'
import storage from '@/jtools/storage';
import Pay from '@/jtools/pay/index.js';
import useUserStore from '@/jtools/store/user'
export default {
data(){
return{
nowPrice:168,
checkedPrice:0,
priceList:[{
priceId:0,
title:'科一精品课',
money:168,
all:false
checkedId:0,
priceList:[],
order:{
money:1,
description:'会员充值'
}
}
},
{
priceId:1,
title:'科四精品课',
money:168,
all:false
onLoad(){
this.getVipList()
this.getWXOpenId()
this.$set(this.order, 'userId', this.userInfo.userId);
},
{
priceId:2,
title:'科一+科四',
money:268,
all:true,
}]
}
computed: {
...mapState(useUserStore, ["userInfo"])
},
methods:{
handlePay(){
console.log(this.order);
new Pay('wechat', this.order);
},
getWXOpenId() {
const that = this
uni.login({
success(res) {
that.$set(that.order, 'code', res.code);
}
})
},
getVipList(){
getVipList({
currentCartype: storage.get('carType') || '1001',
subject:'1'
}).then(resp=>{
this.priceList=resp.data
this.checkedId=this.priceList[0].memberId
this.order.outTradeNo=this.priceList[0].memberId
this.nowPrice=this.priceList[0].price
this.priceList.forEach(item=>{
if(item.subjects.length>1){
item.all=true
}
})
})
},
checkPrice(val,price){
this.checkedPrice=val
this.checkedId=val
this.order.outTradeNo=val
this.nowPrice=price
}
}

@ -13,6 +13,7 @@
<text class="tag_box">{{getQuestType(quesItem.type)}}</text>
<text class="fs18">{{quesItem.question}}</text>
</view>
<template v-if="quesItem.type!='3'">
<view class="flex m14lr ai-c mt20" v-for="(item,index) in quesItem.optionList"
:key="item.op" @tap="answerQues(item.opValue,index)">
<template v-if="item.opDesc">
@ -21,7 +22,7 @@
<u-icon class="mr15" name="checkmark-circle-fill" color="#05C341" size="32"></u-icon>
</template>
<template
v-else-if="quesItem.clickAnswer&&quesItem.clickAnswer.includes(item.opValue)&&!quesItem.trueAnswer.includes(item.opValue)">
v-else-if="quesItem.clickAnswer&&quesItem.clickAnswer?.includes(item.opValue)&&!quesItem.trueAnswer.includes(item.opValue)">
<u-icon class="mr15" name="close-circle-fill" color="red" size="32"></u-icon>
</template>
<template v-else-if="!item.chooseOption">
@ -31,12 +32,47 @@
</template>
</view>
<view class="m14lr mt30"
v-if="quesItem.clickAnswer&&!quesItem.trueAnswer.includes(quesItem.clickAnswer) || tCurrent===1">
v-if="quesItem.clickAnswer&&!quesItem.trueAnswer.includes(quesItem.clickAnswer)">
<view class="answer_box">
<text class="fs18 fw600 cor-000">答案:{{getRightOp(quesItem.trueAnswer)}}</text>
<view class="fs18 cor-000" style="text-indent:2em;"> {{quesItem.bestAnswer}}</view>
</view>
</view>
</template>
<template v-else>
<view class="flex m14lr ai-c mt20" v-for="(item,index) in quesItem.optionList"
:key="item.op" @tap="answerQues(item.opValue,index)">
<template v-if="item.opDesc">
<template
v-if="quesItem.isChoose&&quesItem.trueAnswer.includes(item.opValue)&&quesItem.clickAnswer&&quesItem.clickAnswer.includes(item.opValue)">
<u-icon class="mr15" name="checkmark-circle-fill" color="#05C341" size="32"></u-icon>
</template>
<template
v-else-if="quesItem.isChoose&&quesItem.clickAnswer&&quesItem.clickAnswer.includes(item.opValue)&&!quesItem.trueAnswer.includes(item.opValue)">
<u-icon class="mr15" name="close-circle-fill" color="red" size="32"></u-icon>
</template>
<template v-else-if="!quesItem.isChoose||quesItem.clickAnswer&&!quesItem.clickAnswer.includes(item.opValue)&&quesItem.isChoose">
<template v-if="quesItem.isChoose">
<view class="option_item" :class="quesItem.trueAnswer.includes(item.opValue)&&quesItem.clickAnswer&&!quesItem.clickAnswer.includes(item.opValue)?'right_option':''">{{item.op}}</view>
</template>
<template v-else>
<view class="option_item" :class="quesItem.clickAnswer&&quesItem.clickAnswer.includes(item.opValue)&&!quesItem.isChoose?'checked_option':''">{{item.op}}</view>
</template>
</template>
<text class="fs18">{{item.opDesc}}</text>
</template>
</view>
<view class="p14">
<button :class="quesItem.clickAnswer&&quesItem.clickAnswer.length>1?'dx_checked':'dx_btn'" @click="duoxuan(quesItem.clickAnswer)">确认</button>
</view>
<view class="m14lr mt30"
v-if="isShowAnswer">
<view class="answer_box">
<text class="fs18 fw600 cor-000">答案:{{getRightOp(quesItem.trueAnswer)}}</text>
<view class="fs18 cor-000" style="text-indent:2em;"> {{quesItem.bestAnswer}}</view>
</view>
</view>
</template>
</view>
</scroll-view>
</swiper-item>
@ -174,8 +210,8 @@
<image style="width: 65rpx;height: 65rpx; position: absolute;right: 20px;top: -5px;" src="../../static/image/practice/vip_include.png"></image>
</view>
</view>
<view style="height: 528rpx;width: 100%;background-image: url(../../static/image/practice/vip_bg.png);background-size: 100% 100%;margin-top: -65px;position: relative;">
<text style="position: absolute;top: 138px;left:100px;rotate: 16deg;" class="fs25 cor-fff">VIP题库</text>
<view style="height: 528rpx;width: 100%;background-image: url(../../static/image/practice/vip_bg.jpg);background-size: 100% 100%;margin-top: -65px;position: relative;">
<text style="position: absolute;top: 151px;left:117px;rotate: 16deg;" class="fs25 cor-fff">VIP题库</text>
</view>
<view class="wp100 p14" style="position: absolute;left: 0;bottom:20px">
<view class="sub_btn flex ai-c jc-sb">
@ -247,10 +283,90 @@ export default {
},
computed: {
...mapState(useQuestionStore, ["currentIndex_subject1","currentIndex_subject2"]) //tagslist
...mapState(useQuestionStore, ["currentIndex_subject1","currentIndex_subject2"]) ,//tagslist
isShowAnswer(){
// quesItem.isChoose&&quesItem.clickAnswer&&!quesItem.trueAnswer.includes(quesItem.clickAnswer)
if(this.questionList[this.topicIndex].isChoose){
const arr1=this.questionList[this.topicIndex].clickAnswer.split('')
const arr2=this.questionList[this.topicIndex].trueAnswer.split('')
if(!this.isArrEqual(arr1,arr2)){
return true
}else{
return false
}
}else{
return false
}
}
},
methods: {
...mapActions(useQuestionStore,['getCurrentIndex']),
duoxuan(val){
if(val&&val.length>1){
this.questionList[this.topicIndex].isChoose=true
const falseList =storage.get(`wrongList_subject${this.subject}`) || []
const trueList =storage.get(`rightList_subject${this.subject}`) || []
if(this.tCurrent!==1){
const arr1=this.questionList[this.topicIndex].clickAnswer.split('')
const arr2=this.questionList[this.topicIndex].trueAnswer.split('')
if(this.isArrEqual(arr1,arr2)){
//IDPush()
//
if(!this.rightList.includes(this.questionList[this.topicIndex].questionId)){
this.rightList.push(this.questionList[this.topicIndex].questionId)
}
if(!trueList.includes(this.questionList[this.topicIndex].questionId)){
trueList.push(this.questionList[this.topicIndex].questionId)
storage.set(`rightList_subject${this.subject}`,trueList)
}
if(this.wrongList.includes(this.questionList[this.topicIndex].questionId)){
const wIndex=this.wrongList.indexOf(this.questionList[this.topicIndex].questionId)
this.wrongList.splice(wIndex,1)
}
if(falseList.includes(this.questionList[this.topicIndex].questionId)){
const wIndex=falseList.indexOf(this.questionList[this.topicIndex].questionId)
falseList.splice(wIndex,1)
storage.set(`wrongList_subject${this.subject}`,falseList)
}
//
if(this.topicIndex<this.questionList.length-1){
this.topicIndex ++;
this.qIndex=this.topicIndex
setTimeout(()=>{
console.log(12345);
this.renderSwiper(this.topicIndex);
},1000)
}
if(this.topicIndex<=this.questionList.length-1){
this.qIndex=this.topicIndex
}else{
this.qIndex++
}
if(this.qIndex>=this.questionList.length-1){
setTimeout(()=>{
this.tipShow=true
},1000)
}else{
this.tipShow=false
}
}else{
if(!this.wrongList.includes(this.questionList[this.topicIndex].questionId)){
this.wrongList.push(this.questionList[this.topicIndex].questionId)
}
if(!falseList.includes(this.questionList[this.topicIndex].questionId)){
falseList.push(this.questionList[this.topicIndex].questionId)
storage.set(`wrongList_subject${this.subject}`,falseList)
}
if(trueList.includes(this.questionList[this.topicIndex].questionId)){
const rIndex=trueList.indexOf(this.questionList[this.topicIndex].questionId)
trueList.splice(rIndex,1)
storage.set(`rightList_subject${this.subject}`,trueList)
}
}
}
}
},
timeChange(e){
this.time=e
if(e.hours==0&&e.minutes==0&&e.seconds==0&&e.milliseconds==0){
@ -407,6 +523,7 @@ export default {
//
this.topicIndex--;
}
this.getCurrentIndex(this.topicIndex,this.subject)
// Vue
this.swiperIndex = e.detail.current;
@ -447,8 +564,13 @@ export default {
if (!this.questionList[this.topicIndex].clickAnswer) {
this.questionList[this.topicIndex].optionList[index].chooseOption =`${this.questionList[this.topicIndex].optionList[index].chooseOption?this.questionList[this.topicIndex].optionList[index].chooseOption:''}${op}`
this.questionList[this.topicIndex].clickAnswer = `${this.questionList[this.topicIndex].optionList[index].clickAnswer?this.questionList[this.topicIndex].optionList[index].clickAnswer:''}${op}`
}else{
if(this.questionList[this.topicIndex].type=='3'&&!this.questionList[this.topicIndex].clickAnswer.includes(op)){
this.questionList[this.topicIndex].optionList[index].chooseOption =`${this.questionList[this.topicIndex].optionList[index].chooseOption?this.questionList[this.topicIndex].optionList[index].chooseOption:''}${op}`
this.questionList[this.topicIndex].clickAnswer =`${this.questionList[this.topicIndex].clickAnswer}${op}`
}
if(this.tCurrent!==1){
}
if(this.tCurrent!==1&&this.questionList[this.topicIndex].type!='3'){
const arr1=this.questionList[this.topicIndex].clickAnswer.split('')
const arr2=this.questionList[this.topicIndex].trueAnswer.split('')
if(this.isArrEqual(arr1,arr2)){
@ -521,6 +643,7 @@ export default {
isCollect=true
}
this.questionList.push({
isChoose:false,
isCollect:isCollect,
...item
})
@ -536,6 +659,11 @@ export default {
</script>
<style scoped lang="scss">
.checked_option{
background-color: #000;
border: 1px solid #000;
color:#fff
}
.type_box {
width: 350rpx;
height: 72rpx;
@ -657,4 +785,27 @@ export default {
border-radius: 55rpx;
padding: 14rpx;
}
.dx_btn{
width:100%;
height: 100rpx;
line-height: 100rpx;
text-align: center;
color:#fff;
background: rgb(204,204,204);
border-radius:100rpx;
}
.dx_checked{
width:100%;
height: 100rpx;
line-height: 100rpx;
text-align: center;
color:#fff;
background: #05C341;
border-radius:100rpx;
}
.right_option{
border-color: #05C341;
background-color: #fff;
color: #05C341
}
</style>

@ -31,9 +31,9 @@
<view class="mt14 p14 bc-fff" style="border-radius: 20rpx;">
<text class="fs18 cor-000 fw600">常见考点</text>
<view class="flex ai-c wp100 mt15" style="flex-wrap: wrap;">
<view class="wp50 flex ai-c mb15" v-for="(item,index) of testCenterList" :key="index">
<view class="wp50 flex ai-c mb25" v-for="(item,index) of testCenterList" :key="index" @tap="toQuestionBank(item)">
<view class="dot_item">{{index+1}}</view>
<text class="ml5">{{item.label}}</text>
<text class="ml5">{{item.configItemName}}</text>
</view>
</view>
</view>
@ -44,6 +44,10 @@
import errorIcon from "../../static/image/practice/error_icon.png"
import newRulesIcon from "../../static/image/practice/newRules_icon.png"
import neverWriteIcon from "../../static/image/practice/neverWrite_icon.png"
import {
querySysConfigList,
} from '@/jtools/api/question';
import storage from '@/jtools/storage';
export default {
data() {
return {
@ -75,23 +79,31 @@
subTitle:'392题',
image:neverWriteIcon
}],
testCenterList:[
{label:'驾驶证申请相关'},
{label:'驾驶证申请相关'},
{label:'驾驶证登记处罚'},
{label:'机动车强制报废'},
{label:'其他考点'},
{label:'驾驶证登记处罚'},
{label:'机动车强制报废'},
{label:'其他考点'}]
testCenterList:[]
}
},
onLoad(){
this.getExamPoint()
},
methods: {
getExamPoint(){
const carTypeId=storage.get('carType') || '1001'
querySysConfigList(carTypeId,'ExamKeys').then(resp=>{
if(resp.code==='0000'){
this.testCenterList=resp.data
}
})
},
toAnswer(title) {
uni.navigateTo({
url:"/pages/questionBank/questionBank?navTitle="+title
})
},
toQuestionBank(val){
uni.navigateTo({
url:"/pages/questionBank/questionBank?navTitle="+val.configItemName+"&examKey="+val.configItemCode
})
},
toIconSkill(){
uni.navigateTo({
url:"/pages/index/iconSkill"

@ -5,8 +5,9 @@
<view class="p14 wp100">
<GradesChart :titleName="rightPencentDesc" :actualValue="Number(rightPencent)" />
<view class="top_box flex jc-c" style="flex-direction: column;">
<view class="wp100 text-center" >
<text>太棒了正确率很高了</text>
<view class="wp100 text-center" style="margin-top: -80px;">
<text v-if="Number(rightPencent)>=90">太棒了正确率很高了</text>
<text v-else>继续努力吧正确率有点低~</text>
<view class="flex ai-c jc-c mt10">
<view class="text-center wp50" @tap="toQuestionBank">
<view>{{wrongList.length}}/{{allDoNum}}</view>
@ -25,7 +26,7 @@
<view class="flex ai-c jc-sb">
<view>
<text class="fs18 cor-000 fw600">累计练题</text>
<text class="fs14 cor-666 ml10">33</text>
<text class="fs14 cor-666 ml10">{{allRightList.length+allWrongList.length}}</text>
</view>
<text class="fs14 cor-666">未做题{{getNotDoNum}}</text>
</view>
@ -80,7 +81,7 @@
}
if(op.wrongList){
this.wrongList=JSON.parse(op.wrongList)
this.rightPencent=((this.allDoNum-this.wrongList.length)/this.allDoNum).toFixed(2)
this.rightPencent=this.allDoNum>0?((this.allDoNum-this.wrongList.length)/this.allDoNum).toFixed(2):0
this.rightPencentDesc=(this.rightPencent*100).toFixed(0)+'%'
}
if(op.subject){

@ -75,6 +75,9 @@
if(op.chapter){
param.chapter=op.chapter
}
if(op.examKey){
param.examKey=op.examKey
}
queryQuestion(param).then(res => {
if (res.code == '0000') {
this.questionArr = res.data

@ -1,13 +1,16 @@
<template>
<view>
<sunny-video style="width: 100%" videoHeight="422rpx" ref="sunny-video" title="测试视频" src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20200317.mp4" @timeupdate="timeupdate" />
<view class="p14 bc-fff">
<u-scroll-list :indicator="false" v-if="videoType=='test'">
<view class="flex ai-c jc-sb mt15">
<view class="tab_iem mr15" :class="videoIndex===item.value?'checked_tab':''" v-for="(item,index) of testList" :key="index" @tap="checkTest(item.value)">{{item.label}}</view>
</view>
</u-scroll-list>
<view class="flex ai-c jc-sb mt10 wp100">
<sunny-video style="width: 100%" videoHeight="422rpx" ref="sunny-video" title="测试视频"
src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20200317.mp4"
@timeupdate="timeupdate" />
<view class="p14tb bc-fff">
<view class="skill-sequence-panel-content-wrapper pr14" v-if="videoType=='test'">
<scroll-view class="skill-sequence-panel-content" scroll-x>
<view class="skill-sequence-skill-wrapper tab_iem" :class="videoIndex===item.value?'checked_tab':''" v-for="(item,index) of testList"
:key="index" @tap="checkTest(item.value)">{{item.label}}</view>
</scroll-view>
</view>
<view class="flex ai-c jc-sb mt10 wp100 p14">
<text class="fs18 fw600 cor-000">C1捷达-基础操作视频讲解</text>
<view class="flex" @tap="popupShow=true" v-if="videoType!='test'">
<text class="fs14 cor-666">更多</text>
@ -18,20 +21,23 @@
<view>
</view>
</view>
<view class="pl14 bc-fff">
<u-scroll-list :indicator="false" class="mr15">
<view v-for="(item, index) in videoList" :key="index" class="mr15" @click="checkVideo(item.id)">
<view class="bc-fff pl14">
<view class="skill-sequence-panel-content-wrapper">
<scroll-view class="skill-sequence-panel-content" scroll-x :scroll-left="164*currentIndex">
<view class="skill-sequence-skill-wrapper" v-for="(item, index) in videoList" :key="index"
@click="checkVideo(item.projectId)">
<view>
<view class="mb10 relative">
<image class="contain-box" src="../../static/image/index/index_bg.png"></image>
<view v-if="nowVideo===item.id" class="playLogo">播放中</view>
<view v-if="projectId==item.projectId" class="playLogo">播放中</view>
<image class="play_btn" src="../../static/image/index/play.png" />
<text style="position: absolute;right: 8rpx;bottom: 8rpx;color:#fff">13:14</text>
</view>
<text :style="{color:nowVideo===item.id?'#FF6E02':'#333'}">正确的驾驶姿势</text>
<text :style="{color:projectId==item.projectId?'#FF6E02':'#333'}">{{item.description}}</text>
</view>
</view>
</scroll-view>
</view>
</u-scroll-list>
</view>
<u-popup :show="popupShow" mode="bottom" :closeOnClickOverlay="true" @close="popupShow=false">
<view class="p14 flex ai-c jc-sb">
@ -39,14 +45,15 @@
<text class="fs16 cor-666" @tap="popupShow=false">收起</text>
</view>
<view style="max-height: 800rpx;overflow-y: scroll;" class="p14lr">
<view class="flex bc-fff mt10" style="border-radius: 16rpx;" v-for="(item,index) of videoList" :key="index" @tap="toDetail">
<view class="flex bc-fff mt10" style="border-radius: 16rpx;" v-for="(item,index) of videoList" :key="index"
@tap="toDetail">
<view class="pic relative">
<image class="pic" src="../../static/image/index/index_bg.png"></image>
<image class="play_btn_2" src="../../static/image/index/play.png" />
<text style="position: absolute;right: 8rpx;bottom: 8rpx;color:#fff">13:14</text>
</view>
<view class="ml10">
<text class="fs16 cor-000 fw600">上车下车的方法</text>
<text class="fs16 cor-000 fw600">{{item.description}}</text>
<view class="fs14 mt5 cor-666">上车下车的方法</view>
</view>
</view>
@ -56,73 +63,103 @@
</template>
<script>
export default{
data(){
return{
videoIndex:0,
testList:[{
label:"八一考场",
value:0,
},{
label:"富凯考场",
value:1
},{
label:"新亚考场",
value:2
},{
label:"庐江考场",
value:3
},{
label:"富凯考场",
value:4
},{
label:"新亚考场",
value:5
},{
label:"庐江考场",
value:6
import {
queryProjectList
} from '@/jtools/api/question';
import storage from '@/jtools/storage';
export default {
data() {
return {
currentIndex:0,
videoIndex: 0,
testList: [{
label: "八一考场",
value: 0,
}, {
label: "富凯考场",
value: 1
}, {
label: "新亚考场",
value: 2
}, {
label: "庐江考场",
value: 3
}, {
label: "富凯考场",
value: 4
}, {
label: "新亚考场",
value: 5
}, {
label: "庐江考场",
value: 6
}],
videoType: '',
popupShow: false,
videoList: [{
title: '正确的驾驶姿势',
time: '13:14',
id: 0
}, {
title: '正确的驾驶姿势',
time: '13:14',
id: 1
}, {
title: '正确的驾驶姿势',
time: '13:14',
id: 2
}, {
title: '正确的驾驶姿势',
time: '13:14',
id: 3
}, {
title: '正确的驾驶姿势',
time: '13:14',
id: 4
}, {
title: '正确的驾驶姿势',
time: '13:14',
id: 5
}],
videoType:'',
popupShow:false,
nowVideo:0,
videoList:[{
title:'正确的驾驶姿势',
time:'13:14',
id:0
},{
title:'正确的驾驶姿势',
time:'13:14',
id:1
},{
title:'正确的驾驶姿势',
time:'13:14',
id:2
},{
title:'正确的驾驶姿势',
time:'13:14',
id:3
},{
title:'正确的驾驶姿势',
time:'13:14',
id:4
},{
title:'正确的驾驶姿势',
time:'13:14',
id:5
}]
projectId:undefined,
param:{}
}
},
onLoad(op){
onLoad(op) {
if (op.type) {
this.videoType = op.type
}
if(op.projectId){
this.projectId=op.projectId
}
if(op.driveType){
this.param.driveType=op.driveType
}
if(op.subject){
this.param.subject=op.subject
}
if(op.type){
this.videoType=op.type
this.param.type=op.type
}
this.getVieoList()
},
methods:{
checkTest(val){
this.videoIndex=val
methods: {
getVieoList(){
queryProjectList({
"carTypeId": storage.get('carType') || '1001',
"driveType": this.param.driveType,
"subject": this.param.subject,
"type": this.param.type
}).then(resp=>{
this.videoList=resp.data
this.currentIndex=this.videoList.findIndex(item=>item.projectId==this.projectId)
})
},
checkVideo(val){
this.nowVideo=val
checkTest(val) {
this.videoIndex = val
},
checkVideo(val) {
this.projectId = val
}
}
}
@ -135,7 +172,8 @@
background: #00B74F;
border-radius: 8rpx;
}
.playLogo{
.playLogo {
width: 90rpx;
height: 40rpx;
background: #FF6E02;
@ -146,39 +184,58 @@
font-size: 12px;
position: absolute;
left: 0;
top:0
top: 0
}
.play_btn{
.play_btn {
width: 65rpx;
height: 65rpx;
position: absolute;
left: 97.5rpx;
top:39.5rpx
top: 39.5rpx
}
.play_btn_2{
.play_btn_2 {
width: 65rpx;
height: 65rpx;
position: absolute;
left: 117.5rpx;
top:52rpx
top: 52rpx
}
.pic{
.pic {
width: 300rpx;
height: 169rpx;
background: #00B74F;
border-radius: 8rpx;
}
.tab_iem{
.tab_iem {
width: 145rpx;
height: 56rpx;
line-height: 56rpx;
text-align: center;
background: #F5F5F5;
border-radius: 10rpx;
color:#333
color: #333
}
.checked_tab{
.checked_tab {
background: linear-gradient(90deg, #11DF20 0%, #01B74F 100%);
color:#fff
color: #fff
}
/*scroll-view外层*/
.skill-sequence-panel-content-wrapper{
position: relative;
white-space:nowrap;
}
/*scroll-view本身*/
.skill-sequence-panel-content{
min-width:100%;
}
/*scroll-view内层*/
.skill-sequence-skill-wrapper{
display: inline-block;
margin-right: 15px;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Loading…
Cancel
Save