Compare commits
59 Commits
3c137e8025
...
jwl-dy
| Author | SHA1 | Date | |
|---|---|---|---|
| 6141270437 | |||
|
|
074b53f307 | ||
|
|
ab05529015 | ||
|
|
056ca965b3 | ||
| 4fd6a21f35 | |||
| 7b1db47383 | |||
| 79236493e6 | |||
| 59c49bfdf2 | |||
| 110e9d4adc | |||
|
|
b533581a5d | ||
| ac8acdccda | |||
| f4b6f96649 | |||
| 9ba3f6ed48 | |||
| 253ab2a80d | |||
| bfdbd3f7f3 | |||
| e3544ee06e | |||
| 7e15974ea6 | |||
| 46972d5bff | |||
| 851319e24c | |||
| 19616d56c5 | |||
| 89c4b2148e | |||
| e68a422cc8 | |||
| 2e93ad93e9 | |||
| c783ff969d | |||
| 4526430a38 | |||
| 3a0545852f | |||
| 0410e5dda9 | |||
| 0c230fa5f1 | |||
| ded28b62fb | |||
| 6834b3f9fe | |||
| 3379a9b18e | |||
| 9e871e4079 | |||
| 728fefac03 | |||
| bf05f771f7 | |||
| 287f123ac7 | |||
| 89c72e336b | |||
| 135bcc71ee | |||
| a09ef61e2f | |||
| d88f92a893 | |||
| dc340c7f4d | |||
| 0c6182e6f5 | |||
| f762ca430d | |||
| 37c5de0899 | |||
|
|
04a4a4781d | ||
| 741b5a1d29 | |||
|
|
f36cffdd37 | ||
|
|
7db9e68e77 | ||
| d82a84798c | |||
| 4bfce94c24 | |||
| c3e6002ca3 | |||
| fa6665d9f6 | |||
| 77de5d5d6e | |||
| 9e4b78882e | |||
| 5640ef7f36 | |||
| d36b01a69f | |||
| 8a1d49b47f | |||
| 0b39b49a5d | |||
| 9afe858077 | |||
| 5f6646ae4e |
@@ -5,7 +5,8 @@ VITE_APP_TITLE = 金武联驾校
|
||||
VITE_APP_ENV = 'development'
|
||||
|
||||
# 金武联驾校/开发环境
|
||||
VITE_APP_BASE_API = 'https://jwl.ahduima.com/'
|
||||
|
||||
VITE_APP_BASE_API = 'https://jwl.ahduima.com/'
|
||||
#
|
||||
VITE_WEB_BASE_URL = 'https://jwl.ahduima.com'
|
||||
VITE_WEB_BASE_URL = 'https://jwl.ahduima.com'
|
||||
# 资源地址
|
||||
VITE_RESOURSE_URL = 'http://huodong.ahduima.com'
|
||||
@@ -5,7 +5,10 @@ VITE_APP_TITLE = 金武联驾校
|
||||
VITE_APP_ENV = 'production'
|
||||
|
||||
# 金武联驾校/开发环境
|
||||
VITE_APP_BASE_API = 'https://jwl.ahduima.com/'
|
||||
VITE_APP_BASE_API = 'https://jwl.ahduima.com/'
|
||||
|
||||
#
|
||||
VITE_WEB_BASE_URL = 'https://jwl.ahduima.com'
|
||||
VITE_WEB_BASE_URL = 'https://jwl.ahduima.com'
|
||||
|
||||
# 资源地址
|
||||
VITE_RESOURSE_URL = 'http://huodong.ahduima.com'
|
||||
@@ -4,8 +4,10 @@
|
||||
"scripts": {
|
||||
"dev:h5": "uni",
|
||||
"dev": "uni -p mp-weixin",
|
||||
"dev:dy": "uni -p mp-toutiao",
|
||||
"build:h5": "uni build",
|
||||
"build": "uni build -p mp-weixin",
|
||||
"build:dy": "uni build -p mp-toutiao",
|
||||
"build-test:mp-weixin": "uni --mode test -p mp-weixin"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -14,6 +16,7 @@
|
||||
"@dcloudio/uni-components": "3.0.0-alpha-3060420220922001",
|
||||
"@dcloudio/uni-h5": "3.0.0-alpha-3060420220922001",
|
||||
"@dcloudio/uni-mp-weixin": "3.0.0-alpha-3060420220922001",
|
||||
"@dcloudio/uni-mp-toutiao": "3.0.0-alpha-3060420220922001",
|
||||
"jsencrypt-plus": "^0.1.0",
|
||||
"pinia": "2.0.36",
|
||||
"pinia-plugin-persist-uni": "^1.2.0",
|
||||
|
||||
15
src/App.vue
@@ -1,16 +1,21 @@
|
||||
<script>
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import useQuestionStore from '@/jtools/store/question' //引入store
|
||||
import storage from './jtools/storage'
|
||||
export default {
|
||||
onLaunch: function () {
|
||||
onLaunch: function (options) {
|
||||
// 如果是二维码扫描过来的,需要保存公司id
|
||||
if (options.query?.scene) {
|
||||
storage.set('companyId', options.query?.scene)
|
||||
}
|
||||
useUserStore().queryVipList()
|
||||
useQuestionStore().getOrderQuestion('1')
|
||||
if(useUserStore().isLogin) {
|
||||
if (useUserStore().isLogin) {
|
||||
useUserStore().getUserInfo()
|
||||
useUserStore().searchUserVip()
|
||||
}
|
||||
},
|
||||
onShow: function () {
|
||||
useQuestionStore().getAllQuestion()
|
||||
console.log('App Show')
|
||||
},
|
||||
onHide: function () {
|
||||
@@ -23,4 +28,8 @@ export default {
|
||||
/*每个页面公共css */
|
||||
@import "uni_modules/uview-plus/index.scss";
|
||||
@import "static/style/index.scss";
|
||||
|
||||
button::after {
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -140,8 +140,8 @@ export default {
|
||||
.cu-bar {
|
||||
width: 100%;
|
||||
.content {
|
||||
// width: 350rpx;
|
||||
display: flex;
|
||||
width: 350rpx;
|
||||
// display: flex;
|
||||
flex-direction: row;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
|
||||
1404
src/components/yan-qr/qrcode.js
Normal file
95
src/components/yan-qr/yan-qr.md
Normal file
@@ -0,0 +1,95 @@
|
||||
## 使用方式
|
||||
``` javascript
|
||||
<yan-qr />
|
||||
```
|
||||
|
||||
## 属性说明
|
||||
|属性名 |类型 | 默认值 |说明 |
|
||||
|-- |-- |-----------|-- |
|
||||
|canvasId |String | 'qrcode' |canvas-id |
|
||||
|text |String | 'hello' |二维码内容 |
|
||||
|size |Number | 340 |单位是px |
|
||||
|margin |Number | 0 |边距 |
|
||||
|level |String | 'L' |二维码解析度L/M/Q/H |
|
||||
|fColor |String | '#000000' |二维码颜色 |
|
||||
|bColor |String | '#ffffff' |二维码背景颜色 |
|
||||
|fileType |String | 'png' |二维码图片类型 |
|
||||
|
||||
## 示例代码
|
||||
``` javascript
|
||||
<template>
|
||||
<view>
|
||||
<view>
|
||||
<view>
|
||||
<view>需要转换的文本:</view>
|
||||
<textarea v-model="content" @blur="inputText" placeholder="请在这里输入" />
|
||||
</view>
|
||||
</view>
|
||||
二维码
|
||||
<view>
|
||||
<yan-qr :filePath.sync="filePath" :text="text" :margin="20" />
|
||||
</view>
|
||||
二维码图片地址
|
||||
<view>
|
||||
<textarea v-model="filePath" disabled />
|
||||
</view>
|
||||
<button @click='btn'>生成二维码</button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
data() {
|
||||
return {
|
||||
qrShow: false,
|
||||
content: '',
|
||||
filePath: '',
|
||||
text: ''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
filePath() {
|
||||
console.log(this.filePath);
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
//*获取文本框内容*//
|
||||
inputText: function(e) {
|
||||
this.content = e.detail.value
|
||||
},
|
||||
|
||||
//*按钮*//
|
||||
btn: function() {
|
||||
if (this.content == '') {
|
||||
uni.showToast({ //显示对话框
|
||||
title: "请输入文本",
|
||||
icon: 'none',
|
||||
duration: 1000,
|
||||
})
|
||||
} else {
|
||||
this.text = this.content
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
textarea {
|
||||
border: 1px solid #000000;
|
||||
width: 98%;
|
||||
}
|
||||
button {
|
||||
width: 80%;
|
||||
margin-top: 180rpx;
|
||||
border-radius: 25px;
|
||||
color: aliceblue;
|
||||
background-color: #55aaff;
|
||||
}
|
||||
|
||||
</style>
|
||||
```
|
||||
115
src/components/yan-qr/yan-qr.vue
Normal file
@@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<view>
|
||||
<canvas :canvas-id="canvasId" v-show="qrShow" :style="qrShowStyle" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uQRCode from './qrcode.js'
|
||||
export default {
|
||||
props: {
|
||||
canvasId: {
|
||||
type: String,
|
||||
default: 'qrcode' //canvas-id
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
default: 'hello' //二维码内容
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 150 //二维码大小
|
||||
},
|
||||
margin: {
|
||||
type: Number,
|
||||
default: 0 //二维码边距
|
||||
},
|
||||
level: {
|
||||
type: String,
|
||||
default: 'L' //二维码质量L/M/Q/H
|
||||
},
|
||||
bColor: {
|
||||
type: String,
|
||||
default: '#ffffff' //二维码背景颜色
|
||||
},
|
||||
fColor: {
|
||||
type: String,
|
||||
default: '#000000' //二维码颜色
|
||||
},
|
||||
fileType: {
|
||||
type: String,
|
||||
default: 'png' //二维码图片类型
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
qrShow: false,
|
||||
qrShowStyle: {
|
||||
"width": "150px",
|
||||
"height": "150px",
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
text(newVal, oldVal) {
|
||||
this.onQrFun()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.onQrFun()
|
||||
},
|
||||
methods: {
|
||||
onQrFun() {
|
||||
this.qrShow = this.text != ''
|
||||
if(this.qrShow){
|
||||
this.qrShowStyle.width = this.size+"px"
|
||||
this.qrShowStyle.height = this.size+"px"
|
||||
let level;
|
||||
switch (this.level) {
|
||||
case "M":
|
||||
case "m":
|
||||
level = uQRCode.errorCorrectLevel.M
|
||||
break;
|
||||
case "Q":
|
||||
case "q":
|
||||
level = uQRCode.errorCorrectLevel.Q
|
||||
break;
|
||||
case "H":
|
||||
case "h":
|
||||
level = uQRCode.errorCorrectLevel.H
|
||||
break;
|
||||
default:
|
||||
level = uQRCode.errorCorrectLevel.L
|
||||
break;
|
||||
}
|
||||
uQRCode.make({
|
||||
canvasId: this.canvasId,
|
||||
componentInstance: this,
|
||||
text: this.text,
|
||||
size: this.size,
|
||||
margin: this.margin,
|
||||
backgroundColor: this.bColor,
|
||||
foregroundColor: this.fColor,
|
||||
fileType: this.fileType,
|
||||
errorCorrectLevel: level,
|
||||
success: res => {}
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
uni.canvasToTempFilePath({
|
||||
canvasId: this.canvasId,
|
||||
success: (res) => {
|
||||
// 在H5平台下,tempFilePath 为 base64
|
||||
this.$emit("update:filePath", res.tempFilePath);
|
||||
}
|
||||
}, this);
|
||||
}, 600)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
75
src/jtools/api/activity.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import request from '../request/index.js';
|
||||
|
||||
//查询活动列表
|
||||
export function queryActivityList(data) {
|
||||
return request({
|
||||
url: 'activity/applet/activity/list',
|
||||
method: 'get',
|
||||
data,
|
||||
noToken: true
|
||||
});
|
||||
}
|
||||
//查询活动详情
|
||||
export function queryActivityDetail(data) {
|
||||
return request({
|
||||
url: 'activity/applet/activity/detail',
|
||||
method: 'get',
|
||||
data,
|
||||
noToken: true
|
||||
});
|
||||
}
|
||||
//查询抽奖次数
|
||||
export function queryLuckyNum(data) {
|
||||
return request({
|
||||
url: 'activity/applet/activity/lucky/num',
|
||||
method: 'get',
|
||||
data,
|
||||
noToken: true
|
||||
});
|
||||
}
|
||||
//查询中奖结果
|
||||
export function queryLuckyResult(data) {
|
||||
return request({
|
||||
url: 'activity/applet/activity/lucky/result',
|
||||
method: 'get',
|
||||
data,
|
||||
noToken: true
|
||||
});
|
||||
}
|
||||
//录入中奖结果
|
||||
export function saveWinner(data) {
|
||||
return request({
|
||||
url: 'activity/applet/activity/winner/save',
|
||||
method: 'POST',
|
||||
data,
|
||||
noToken: true
|
||||
});
|
||||
}
|
||||
//核销
|
||||
export function receiveWinner(data) {
|
||||
return request({
|
||||
url: 'activity/applet/activity/winner/receive',
|
||||
method: 'POST',
|
||||
data,
|
||||
noToken: true
|
||||
});
|
||||
}
|
||||
//查询中奖记录
|
||||
export function getLuckyRecord(data) {
|
||||
return request({
|
||||
url: 'activity/applet/activity/lucky/record',
|
||||
method: 'get',
|
||||
data,
|
||||
noToken: true
|
||||
});
|
||||
}
|
||||
|
||||
//查询中奖记录
|
||||
export function canRecieveGift(data) {
|
||||
return request({
|
||||
url: 'activity/applet/activity/receive/user',
|
||||
method: 'get',
|
||||
data,
|
||||
noToken: true
|
||||
});
|
||||
}
|
||||
@@ -7,4 +7,21 @@ export function getAliCompanyInfo(data) {
|
||||
data,
|
||||
noToken: true
|
||||
});
|
||||
}
|
||||
|
||||
export function getCarTypeList(data) {
|
||||
return request({
|
||||
url: 'driver-api/tdCar/list',
|
||||
method: 'GET',
|
||||
data,
|
||||
noToken: true
|
||||
});
|
||||
}
|
||||
|
||||
export function addInfo(data) {
|
||||
return request({
|
||||
url: 'chaoyuan-api/driver/addInfo',
|
||||
method: 'POST',
|
||||
data
|
||||
});
|
||||
}
|
||||
@@ -13,7 +13,8 @@ export function questionCategory(data) {
|
||||
return request({
|
||||
url: 'driver-api/tdQuestion/questionCategory',
|
||||
method: 'POST',
|
||||
data
|
||||
data,
|
||||
noToken: true
|
||||
});
|
||||
}
|
||||
|
||||
@@ -45,15 +46,65 @@ export function testTotal(data) {
|
||||
export function querySysConfigList(carTypeId, configKey) {
|
||||
return request({
|
||||
url: 'driver-api/tdSysConfigList/querySysConfigList?configKey=' + configKey + '&carTypeId=' + carTypeId,
|
||||
method: 'GET'
|
||||
method: 'GET',
|
||||
noToken: true
|
||||
});
|
||||
}
|
||||
//获取配置
|
||||
export function querySysConfig(carTypeId, configKey) {
|
||||
return request({
|
||||
url: 'driver-api/tdSysConfig/queryConfigByKey?configKey=' + configKey + '&carTypeId=' + carTypeId,
|
||||
method: 'GET',
|
||||
noToken: true
|
||||
});
|
||||
}
|
||||
|
||||
//获取项目列表 (考试项目和基础操作)
|
||||
export function queryProjectList(data) {
|
||||
return request({
|
||||
url: 'driver-api/tdTestProject/queryProjectList',
|
||||
method: 'POST',
|
||||
data
|
||||
data,
|
||||
noToken:true
|
||||
});
|
||||
}
|
||||
//
|
||||
|
||||
//获取专项题目数量
|
||||
export function querySpecialNum(data) {
|
||||
return request({
|
||||
url: 'driver-api/tdQuestion/querySpecialNum',
|
||||
method: 'POST',
|
||||
data,
|
||||
noToken:true
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//获取题库版本
|
||||
export function getVersion(carTypeId) {
|
||||
return request({
|
||||
url: '/driver-api/tdQuestionVersion/currentVersion?carTypeId='+carTypeId,
|
||||
method: 'GET',
|
||||
noToken:true
|
||||
});
|
||||
}
|
||||
|
||||
//获取题目ID
|
||||
export function queryQuestionId(data) {
|
||||
return request({
|
||||
url: '/driver-api/tdQuestion/queryQuestionId',
|
||||
method: 'POST',
|
||||
data,
|
||||
noToken:true
|
||||
});
|
||||
}
|
||||
|
||||
//获取模拟考试ID
|
||||
export function getTestQuestionId(data) {
|
||||
return request({
|
||||
url: '/driver-api/tdQuestion/getTestQuestionId',
|
||||
method: 'POST',
|
||||
data,
|
||||
noToken:true
|
||||
});
|
||||
}
|
||||
|
||||
@@ -64,12 +64,14 @@ export default class JtoolsPay {
|
||||
"description": this.order.description,
|
||||
"money": this.order.money,
|
||||
"outTradeNo": this.order.outTradeNo,
|
||||
"userId": this.order.userId
|
||||
"userId": this.order.userId,
|
||||
"tradeType":'1'
|
||||
}
|
||||
if (uni.getStorageSync('openId')) {
|
||||
params.openId = uni.getStorageSync('openId');
|
||||
}
|
||||
prePay(params).then(res => {
|
||||
console.log('预支付',res);
|
||||
if (res.code == '0000') {
|
||||
resolve(res);
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@ function service(options = {}) {
|
||||
title: res?.data?.message || '请重新登录',
|
||||
icon: 'none'
|
||||
});
|
||||
useUserStore().logout()
|
||||
useUserStore().logoutWithoutToken()
|
||||
//请求成功
|
||||
resolved(res.data);
|
||||
} else if(res.data.code != '0000') {
|
||||
} else if(res.data.code != '0000'&&res.data.code !='4001'&&res.data.code != 200) {
|
||||
uni.showToast({
|
||||
title: res?.data?.message || '访问出错',
|
||||
icon: 'none'
|
||||
|
||||
@@ -3,7 +3,9 @@ import {
|
||||
} from 'pinia';
|
||||
import http from '@/jtools/request/index';
|
||||
import {
|
||||
queryQuestion
|
||||
queryQuestion,
|
||||
getVersion,
|
||||
querySysConfig
|
||||
} from '@/jtools/api/question';
|
||||
import storage from '@/jtools/storage';
|
||||
|
||||
@@ -11,43 +13,224 @@ const question = defineStore({
|
||||
id: 'question',
|
||||
state: () => ({
|
||||
currentCartype: storage.get('carType') || '1001',
|
||||
orderQuestion: [], //顺序做题
|
||||
currentIndex_subject1:0,//科目一索引 顺序做题
|
||||
currentIndex_subject4:0,//科目四索引 顺序做题
|
||||
currentCarName: storage.get('carName') || '小车C1/C2/C3',
|
||||
orderQuestion_subject1: storage.get('question_subject1') || [], //科目一顺序做题
|
||||
orderQuestion_subject4: storage.get('question_subject4') || [], //科目四顺序做题
|
||||
currentIndex_subject1: 0, //科目一索引 顺序做题
|
||||
currentIndex_subject4: 0, //科目四索引 顺序做题
|
||||
curSubject: storage.get('curSubject') || '1',
|
||||
loading_subject1: false,
|
||||
loading_subject4: false,
|
||||
version: storage.get('version') || ''
|
||||
}),
|
||||
|
||||
actions: {
|
||||
// 获取顺序做题
|
||||
getOrderQuestion(val) {
|
||||
queryQuestion({
|
||||
carTypeId: this.currentCartype,
|
||||
// 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)
|
||||
resetStorage(){
|
||||
this.currentIndex_subject1=0
|
||||
this.currentIndex_subject4=0
|
||||
this.curSubject=0
|
||||
storage.remove('curSubject')
|
||||
storage.remove('wrongList_subject1')
|
||||
storage.remove('wrongList_subject4')
|
||||
storage.remove('rightList_subject1')
|
||||
storage.remove('rightList_subject4')
|
||||
this.getAllQuestion()
|
||||
},
|
||||
getAllQuestion() {
|
||||
this.currentCartype = storage.get('carType') || '1001'
|
||||
getVersion(this.currentCartype).then(resp => {
|
||||
if (resp.code === '0000') {
|
||||
querySysConfig(this.currentCartype, 'QuestionBank').then(res => {
|
||||
const urlList = JSON.parse(res.data.configJson)
|
||||
const urlOne = urlList.find(item => item.subject == '1').url
|
||||
const urlFour = urlList.find(item => item.subject == '4').url
|
||||
if (this.version != resp.data) {
|
||||
this.version = resp.data
|
||||
storage.set('version', resp.data)
|
||||
this.getOrderQuestion_sub1(true, urlOne)
|
||||
this.getOrderQuestion_sub4(true, urlFour)
|
||||
} else {
|
||||
this.getOrderQuestion_sub1(false, urlOne)
|
||||
this.getOrderQuestion_sub4(false, urlOne)
|
||||
}
|
||||
})
|
||||
console.log('falseArr',falseArr);
|
||||
storage.set(`wrongList_subject${val}`,falseArr)
|
||||
storage.set(`rightList_subject${val}`,rightArr)
|
||||
console.log(storage.get(`wrongList_subject${val}`));
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
divideArray(array, numChunks) {
|
||||
var chunkSize = Math.ceil(array.length / numChunks);
|
||||
var dividedArray = [];
|
||||
for (var i = 0; i < array.length; i += chunkSize) {
|
||||
dividedArray.push(array.slice(i, i + chunkSize));
|
||||
}
|
||||
return dividedArray;
|
||||
},
|
||||
|
||||
//改变当前科目
|
||||
changeSubject(val) {
|
||||
this.curSubject = val
|
||||
storage.set('curSubject', val)
|
||||
},
|
||||
// 获取顺序做题科目1
|
||||
getOrderQuestion_sub1(isUpdate, url) {
|
||||
if (isUpdate) {
|
||||
this.loading_subject1 = true
|
||||
const that = this
|
||||
uni.request({
|
||||
url: url,
|
||||
success(resp) {
|
||||
if (resp.data) {
|
||||
that.orderQuestion_subject1 = resp.data.data
|
||||
const diveList = that.divideArray(that.orderQuestion_subject1, 5)
|
||||
that.loading_subject1 = false
|
||||
uni.setStorageSync('questionOneSub1', diveList[0])
|
||||
uni.setStorageSync('questionOneSub2', diveList[1])
|
||||
uni.setStorageSync('questionOneSub3', diveList[2])
|
||||
uni.setStorageSync('questionOneSub4', diveList[3])
|
||||
uni.setStorageSync('questionOneSub5', diveList[4])
|
||||
const falseList = storage.get('wrongList_subject1') || []
|
||||
const trueList = storage.get('rightList_subject1') || []
|
||||
const falseArr = []
|
||||
const rightArr = []
|
||||
that.orderQuestion_subject1.forEach(item => {
|
||||
if (falseList.includes(item.questionId)) {
|
||||
falseArr.push(item.questionId)
|
||||
}
|
||||
if (trueList.includes(item.questionId)) {
|
||||
rightArr.push(item.questionId)
|
||||
}
|
||||
})
|
||||
storage.set('wrongList_subject1', falseArr)
|
||||
storage.set('rightList_subject1', rightArr)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const list1 = uni.getStorageSync('questionOneSub1') || []
|
||||
const list2 = uni.getStorageSync('questionOneSub2') || []
|
||||
const list3 = uni.getStorageSync('questionOneSub3') || []
|
||||
const list4 = uni.getStorageSync('questionOneSub4') || []
|
||||
const list5 = uni.getStorageSync('questionOneSub5') || []
|
||||
this.orderQuestion_subject1 = [...list1, ...list2, ...list3, ...list4, ...list5]
|
||||
if (this.orderQuestion_subject1 && this.orderQuestion_subject1.length) {
|
||||
|
||||
} else {
|
||||
this.loading_subject1 = true
|
||||
const that = this
|
||||
uni.request({
|
||||
url: url,
|
||||
success(resp) {
|
||||
if (resp.data) {
|
||||
that.orderQuestion_subject1 = resp.data.data
|
||||
const diveList = that.divideArray(that.orderQuestion_subject1, 5)
|
||||
that.loading_subject1 = false
|
||||
uni.setStorageSync('questionOneSub1', diveList[0])
|
||||
uni.setStorageSync('questionOneSub2', diveList[1])
|
||||
uni.setStorageSync('questionOneSub3', diveList[2])
|
||||
uni.setStorageSync('questionOneSub4', diveList[3])
|
||||
uni.setStorageSync('questionOneSub5', diveList[4])
|
||||
const falseList = storage.get('wrongList_subject1') || []
|
||||
const trueList = storage.get('rightList_subject1') || []
|
||||
const falseArr = []
|
||||
const rightArr = []
|
||||
that.orderQuestion_subject1.forEach(item => {
|
||||
if (falseList.includes(item.questionId)) {
|
||||
falseArr.push(item.questionId)
|
||||
}
|
||||
if (trueList.includes(item.questionId)) {
|
||||
rightArr.push(item.questionId)
|
||||
}
|
||||
})
|
||||
storage.set('wrongList_subject1', falseArr)
|
||||
storage.set('rightList_subject1', rightArr)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
// 获取顺序做题科目4
|
||||
getOrderQuestion_sub4(isUpdate, url) {
|
||||
if (isUpdate) {
|
||||
this.loading_subject4 = true
|
||||
const that = this
|
||||
uni.request({
|
||||
url: url,
|
||||
success(resp) {
|
||||
if (resp.data) {
|
||||
that.orderQuestion_subject4 = resp.data.data
|
||||
const diveList = that.divideArray(that.orderQuestion_subject4, 5)
|
||||
that.loading_subject4 = false
|
||||
uni.setStorageSync('questionFourSub1', diveList[0])
|
||||
uni.setStorageSync('questionFourSub2', diveList[1])
|
||||
uni.setStorageSync('questionFourSub3', diveList[2])
|
||||
uni.setStorageSync('questionFourSub4', diveList[3])
|
||||
uni.setStorageSync('questionFourSub5', diveList[4])
|
||||
const falseList = storage.get('wrongList_subject4') || []
|
||||
const trueList = storage.get('rightList_subject4') || []
|
||||
const falseArr = []
|
||||
const rightArr = []
|
||||
that.orderQuestion_subject4.forEach(item => {
|
||||
if (falseList.includes(item.questionId)) {
|
||||
falseArr.push(item.questionId)
|
||||
}
|
||||
if (trueList.includes(item.questionId)) {
|
||||
rightArr.push(item.questionId)
|
||||
}
|
||||
})
|
||||
storage.set('wrongList_subject4', falseArr)
|
||||
storage.set('rightList_subject4', rightArr)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const list1 = uni.getStorageSync('questionFourSub1') || []
|
||||
const list2 = uni.getStorageSync('questionFourSub2') || []
|
||||
const list3 = uni.getStorageSync('questionFourSub3') || []
|
||||
const list4 = uni.getStorageSync('questionFourSub4') || []
|
||||
const list5 = uni.getStorageSync('questionFourSub5') || []
|
||||
this.orderQuestion_subject4 = [...list1, ...list2, ...list3, ...list4, ...list5]
|
||||
if (this.orderQuestion_subject4 && this.orderQuestion_subject4.length) {
|
||||
|
||||
} else {
|
||||
this.loading_subject4 = true
|
||||
const that = this
|
||||
uni.request({
|
||||
url: url,
|
||||
success(resp) {
|
||||
if (resp.data) {
|
||||
that.orderQuestion_subject4 = resp.data.data
|
||||
const diveList = that.divideArray(that.orderQuestion_subject4, 5)
|
||||
that.loading_subject4 = false
|
||||
uni.setStorageSync('questionFourSub1', diveList[0])
|
||||
uni.setStorageSync('questionFourSub2', diveList[1])
|
||||
uni.setStorageSync('questionFourSub3', diveList[2])
|
||||
uni.setStorageSync('questionFourSub4', diveList[3])
|
||||
uni.setStorageSync('questionFourSub5', diveList[4])
|
||||
const falseList = storage.get('wrongList_subject4') || []
|
||||
const trueList = storage.get('rightList_subject4') || []
|
||||
const falseArr = []
|
||||
const rightArr = []
|
||||
that.orderQuestion_subject4.forEach(item => {
|
||||
if (falseList.includes(item.questionId)) {
|
||||
falseArr.push(item.questionId)
|
||||
}
|
||||
if (trueList.includes(item.questionId)) {
|
||||
rightArr.push(item.questionId)
|
||||
}
|
||||
})
|
||||
storage.set('wrongList_subject4', falseArr)
|
||||
storage.set('rightList_subject4', rightArr)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
//获取索引
|
||||
getCurrentIndex(index,val){
|
||||
this[`currentIndex_subject${val}`]=index
|
||||
getCurrentIndex(index, val) {
|
||||
this[`currentIndex_subject${val}`] = index
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { login,logout,getInfo } from '@/jtools/api/login';
|
||||
import { queryVip,getVipList } from '@/jtools/api/vip'
|
||||
import { login, logout, getInfo } from '@/jtools/api/login';
|
||||
import { queryVip, getVipList } from '@/jtools/api/vip';
|
||||
import constants from '@/jtools/constants';
|
||||
import storage from '@/jtools/storage';
|
||||
|
||||
@@ -16,67 +16,77 @@ const useUserStore = defineStore({
|
||||
}),
|
||||
|
||||
actions: {
|
||||
login(params) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const resp = await login(params);
|
||||
if (resp.code === '0000') {
|
||||
// 保存登录信息,用于重新登录
|
||||
this.isLogin = true;
|
||||
this.token = resp.data.token;
|
||||
this.userInfo = resp.data
|
||||
storage.set('isLogin', true)
|
||||
storage.set('token', resp.data.token)
|
||||
storage.set('userInfo', resp.data)
|
||||
resolve(resp.data);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
},
|
||||
login(params) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const resp = await login(params);
|
||||
if (resp.code === '0000') {
|
||||
// 保存登录信息,用于重新登录
|
||||
this.isLogin = true;
|
||||
this.token = resp.data.token;
|
||||
this.userInfo = resp.data;
|
||||
storage.set('isLogin', true);
|
||||
storage.set('token', resp.data.token);
|
||||
storage.set('userInfo', resp.data);
|
||||
storage.remove('companyId');
|
||||
resolve(resp.data);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
},
|
||||
// 登出
|
||||
logout(force = false) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.resetUserData();
|
||||
uni.redirectTo({
|
||||
url: '/pages/login/login'
|
||||
})
|
||||
});
|
||||
resolve();
|
||||
})
|
||||
});
|
||||
},
|
||||
//过期登出
|
||||
logoutWithoutToken(force = false) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.resetUserData();
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
// 获取用户信息
|
||||
getUserInfo() {
|
||||
getInfo().then(resp => {
|
||||
if(resp.code == '0000') {
|
||||
this.userInfo = resp.data
|
||||
storage.set('userInfo', resp.data)
|
||||
if (resp.code == '0000') {
|
||||
this.userInfo = resp.data;
|
||||
storage.set('userInfo', resp.data);
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
resetUserData() {
|
||||
this.isLogin = false;
|
||||
this.token = '';
|
||||
this.userInfo = {}
|
||||
this.vipOnList = []
|
||||
storage.remove('isLogin')
|
||||
storage.remove('token')
|
||||
storage.remove('userInfo')
|
||||
this.userInfo = {};
|
||||
this.vipOnList = [];
|
||||
storage.remove('isLogin');
|
||||
storage.remove('token');
|
||||
storage.remove('userInfo');
|
||||
},
|
||||
// 查询当前用户的vip开通情况
|
||||
async searchUserVip() {
|
||||
const resp=await queryVip({ carTypeId: this.currentCartype,memberId: null, subject:'' })
|
||||
if(resp.code == '0000') {
|
||||
this.vipOnList = resp.data
|
||||
}
|
||||
this.currentCartype = storage.get('carType') || '1001';
|
||||
const resp = await queryVip({ carTypeId: this.currentCartype, memberId: null, subject: '' });
|
||||
if (resp.code == '0000') {
|
||||
this.vipOnList = resp.data;
|
||||
}
|
||||
},
|
||||
// 查询所有的vip
|
||||
queryVipList() {
|
||||
getVipList({ carTypeId: this.currentCartype,memberId: null, subject:'' }).then(resp => {
|
||||
if(resp.code == '0000') {
|
||||
this.vipAllList = resp.data
|
||||
this.currentCartype = storage.get('carType') || '1001';
|
||||
getVipList({ carTypeId: this.currentCartype, memberId: null, subject: '' }).then(resp => {
|
||||
if (resp.code == '0000') {
|
||||
this.vipAllList = resp.data;
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
export default useUserStore;
|
||||
|
||||
@@ -66,7 +66,13 @@
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true
|
||||
"usingComponents" : true,
|
||||
"appid" : "ttbbd1cd6c24e1c00801",
|
||||
"setting" : {
|
||||
"es6" : true,
|
||||
"postcss" : true,
|
||||
"minified" : true
|
||||
}
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : false
|
||||
|
||||
18
src/package.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"id": "yan-qr",
|
||||
"name": "动态生成二维码",
|
||||
"displayName": "动态生成二维码",
|
||||
"version": "1.0.0",
|
||||
"description": "动态生成二维码",
|
||||
"keywords": [
|
||||
"二维码",
|
||||
"生成二维码",
|
||||
"动态二维码"
|
||||
],
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"前端组件",
|
||||
"通用组件"
|
||||
]
|
||||
}
|
||||
}
|
||||
118
src/pages.json
@@ -8,7 +8,8 @@
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "金武联驾考"
|
||||
"navigationBarTitleText": "金武联驾考",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -86,7 +87,7 @@
|
||||
{
|
||||
"path": "pages/me/tijian",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的体检",
|
||||
"navigationBarTitleText": "上传证件照",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
@@ -100,44 +101,102 @@
|
||||
{
|
||||
"path": "pages/index/videoVip",
|
||||
"style": {
|
||||
"navigationBarTitleText": "视频精品课",
|
||||
"navigationBarTitleText": "开通会员",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/testTip",
|
||||
"style": {
|
||||
"navigationBarTitleText": "模拟考试",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/login",
|
||||
"style": {
|
||||
"navigationBarTitleText": "登录",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/iconSkill",
|
||||
"style": {
|
||||
"navigationBarTitleText": "图标技巧",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/questionBank/chapterExercise",
|
||||
"style": {
|
||||
"navigationBarTitleText": "章节练习",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/testRoom",
|
||||
"style": {
|
||||
"navigationBarTitleText": "考场实况",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/paySuccess",
|
||||
"style": {
|
||||
"navigationBarTitleText": "支付结果",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
}, {
|
||||
"path": "pages/index/trueTest",
|
||||
"style": {
|
||||
"navigationBarTitleText": "真实考场模拟",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/iconSkill",
|
||||
"style": {
|
||||
"navigationBarTitleText": "图标技巧",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/questionBank/chapterExercise",
|
||||
"style": {
|
||||
"navigationBarTitleText": "章节练习",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/testRoom",
|
||||
"style": {
|
||||
"navigationBarTitleText": "考场实况",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/paySuccess",
|
||||
"path": "pages/me/uploadPic",
|
||||
"style": {
|
||||
"navigationBarTitleText": "支付结果",
|
||||
"navigationBarTitleText": "上传证件照",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/secretPapers",
|
||||
"style": {
|
||||
"navigationBarTitleText": "考前密卷",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/me/changeCarType",
|
||||
"style": {
|
||||
"navigationBarTitleText": "切换车型",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/index/activity",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : "活动",
|
||||
"enablePullDownRefresh" : false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/me/myGift",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : "我的奖品",
|
||||
"enablePullDownRefresh" : false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/me/qrCode",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : "核销二维码",
|
||||
"enablePullDownRefresh" : false
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -149,11 +208,10 @@
|
||||
},
|
||||
"tabBar": {
|
||||
"borderStyle": "white",
|
||||
"selectedColor": "#333333",
|
||||
"selectedColor": "#05C341",
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"color": "#999999",
|
||||
"list": [
|
||||
{
|
||||
"list": [{
|
||||
"pagePath": "pages/index/index",
|
||||
"iconPath": "static/image/tabbar/tab-home.png",
|
||||
"selectedIconPath": "static/image/tabbar/tab-home-selected.png",
|
||||
@@ -168,4 +226,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/pages/index/activity.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<view>
|
||||
<GGL></GGL>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GGL from './components/ggl/index'
|
||||
export default {
|
||||
components: {
|
||||
GGL
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -1,192 +1,382 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="box-nav">
|
||||
<image style="width: 100%;" src="../../static/image/index/index_bg.jpg"></image>
|
||||
<image style="width: 100%;"
|
||||
src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/%E9%A6%96%E9%A1%B5_20230830213855.png">
|
||||
</image>
|
||||
<view class="center-box flex jc-sb ai-c">
|
||||
<view class="box-item flex ai-c jc-c">
|
||||
<view class="flex jc-c ai-c" style="width: 230rpx;height: 230rpx;background-image: url(../../../static/image/index/green_bg.png);background-size: 100% 100%;">
|
||||
<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">{{getDoNum}}/{{orderQuestion.length}}</text>
|
||||
</view>
|
||||
<view class="flex jc-c ai-c relative" style="width: 230rpx;height: 230rpx;" @tap="toAnswer('顺序答题',false)">
|
||||
<image style="width: 230rpx;height: 230rpx;position: absolute;left: 0;top: 0;"
|
||||
src="../../../static/image/index/green_bg.png"></image>
|
||||
<view class="btn-item flex ai-c jc-c">
|
||||
<view class="text-center cor-fff" style="line-height: 40rpx;">
|
||||
<view class="fs16">顺序练习</view>
|
||||
<text
|
||||
class="fs14">{{getDoNum}}/{{subject=='1'?orderQuestion_subject1.length:orderQuestion_subject4.length}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="box-item flex ai-c jc-c">
|
||||
<view class="flex jc-c ai-c" style="width: 230rpx;height: 230rpx;background-image: url(../../../static/image/index/orange_bg.png);background-size: 100% 100%;">
|
||||
<view class="btn2-item flex ai-c jc-c">
|
||||
<view class="text-center cor-fff" style="line-height: 40rpx;" @tap="toExams">
|
||||
<view class="fs16">模拟考试</view>
|
||||
<text class="fs14">去考试</text>
|
||||
</view>
|
||||
<view class="flex jc-c ai-c relative" style="width: 230rpx;height: 230rpx;" @tap="toExams('模拟考试')">
|
||||
<image style="width: 230rpx;height: 230rpx;position: absolute;left: 0;top: 0;"
|
||||
src="../../../static/image/index/orange_bg.png"></image>
|
||||
<view class="btn2-item flex ai-c jc-c">
|
||||
<view class="text-center cor-fff" style="line-height: 40rpx;">
|
||||
<view class="fs16">模拟考试</view>
|
||||
<text class="fs14">去考试</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view style="padding: 0 28rpx;margin-top: 60rpx;">
|
||||
<view style="padding: 0 28rpx;margin-top: calc(100% - 718rpx);">
|
||||
<view class="tabs-box">
|
||||
<view class="wp33 flex ai-c jc-c" @tap="toVip">
|
||||
<view class="text-center wp100">
|
||||
<image style="width: 72rpx;height: 72rpx;margin: 0 auto"
|
||||
src="../../static/image/index/vipicon.png">
|
||||
<image style="width: 72rpx;height: 72rpx;margin: 0 auto" src="../../static/image/index/vipicon.png">
|
||||
</image>
|
||||
<view class="mt5">VIP课程</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="wp33 flex ai-c jc-c" @tap="toAnswer('精简500题',true)">
|
||||
<view class="wp33 flex ai-c jc-c" @tap="toAnswer(`精简${titleNum}题`,true)">
|
||||
<view class="text-center wp100">
|
||||
<image style="width: 72rpx;height: 72rpx;margin: 0 auto"
|
||||
src="../../static/image/index/500icon.png">
|
||||
<image style="width: 72rpx;height: 72rpx;margin: 0 auto" src="../../static/image/index/500icon.png">
|
||||
</image>
|
||||
<view class="mt5">精简500题</view>
|
||||
<view class="mt5">精简{{titleNum}}题</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="wp33 flex ai-c jc-c" @tap="toExclusive">
|
||||
<view class="text-center wp100">
|
||||
<image style="width: 72rpx;height: 72rpx;margin: 0 auto"
|
||||
src="../../static/image/index/zxicon.png">
|
||||
<image style="width: 72rpx;height: 72rpx;margin: 0 auto" src="../../static/image/index/zxicon.png">
|
||||
</image>
|
||||
<view class="mt5">专项练习</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="wp33 flex ai-c jc-c" @tap="toTestRoom">
|
||||
<view class="text-center wp100">
|
||||
<image style="width: 72rpx;height: 72rpx;margin: 0 auto;"
|
||||
src="../../static/image/index/realicon.png"></image>
|
||||
<image style="width: 72rpx;height: 72rpx;margin: 0 auto;" src="../../static/image/index/realicon.png">
|
||||
</image>
|
||||
<view class="mt5">真实考场模拟</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="wp33 flex ai-c jc-c">
|
||||
<view class="wp33 flex ai-c jc-c" @tap="toExams('考前秘卷')">
|
||||
<view class="text-center wp100">
|
||||
<image style="width: 72rpx;height: 72rpx;margin: 0 auto"
|
||||
src="../../static/image/index/testbeforeicon.png"></image>
|
||||
<view class="mt5">考前密卷</view>
|
||||
<image style="width: 72rpx;height: 72rpx;margin: 0 auto" src="../../static/image/index/testbeforeicon.png">
|
||||
</image>
|
||||
<view class="mt5">考前秘卷</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="wp33 flex ai-c jc-c" @tap="toWrongList">
|
||||
<view class="text-center wp100">
|
||||
<image style="width: 72rpx;height: 72rpx;margin: 0 auto"
|
||||
src="../../static/image/index/worryicon.png"></image>
|
||||
<image style="width: 72rpx;height: 72rpx;margin: 0 auto" src="../../static/image/index/worryicon.png">
|
||||
</image>
|
||||
<view class="mt5">错题收藏</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view style="padding: 0 28rpx;margin-top: 30rpx;" @tap="toClass">
|
||||
<!-- <view style="padding: 0 28rpx;margin-top: 30rpx;" @tap="toClass">
|
||||
<view class="video-box">
|
||||
<view class="flex jc-sb ai-c wp100">
|
||||
<text style="color: #05C341;font-size: 36rpx;">科{{subject==1?'一':'四'}}精品视频课</text>
|
||||
<text class="cor-666 fs12">全部10节课 ></text>
|
||||
</view>
|
||||
<view class="flex ai-c mt20">
|
||||
<image class="contain-box" src="../../static/image/index/index_bg.jpg"></image>
|
||||
<view class="contain-box relative">
|
||||
<image class="contain-box" src="../../../static/image/index/jpsp.png"></image>
|
||||
<image class="play_btn_2" src="../../static/image/index/play.png" />
|
||||
</view>
|
||||
<view class="ml15 text-center">
|
||||
<u-button :customStyle="{width:'200rpx',height:'66rpx',borderRadius: '33rpx'}" iconColor="#fff"
|
||||
text="去看视频" color="linear-gradient(90deg, #11DF20 0%, #00B74F 100%)" icon="play-circle">
|
||||
<u-button :customStyle="{width:'200rpx',height:'66rpx',borderRadius: '33rpx'}" iconColor="#fff" text="去看视频"
|
||||
color="linear-gradient(90deg, #11DF20 0%, #00B74F 100%)" icon="play-circle">
|
||||
</u-button>
|
||||
<view class="cor-333 fs15 fw600 mt10">科{{subject==1?'一':'四'}}易错试题</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState,mapActions } from 'pinia' //引入映射函数
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import storage from '@/jtools/storage';
|
||||
import useQuestionStore from '@/jtools/store/question' //引入store
|
||||
import {
|
||||
querySysConfig,
|
||||
queryQuestionId,
|
||||
getTestQuestionId
|
||||
} from '@/jtools/api/question';
|
||||
export default {
|
||||
props:{
|
||||
subject:{
|
||||
type:[String,Number],
|
||||
props: {
|
||||
subject: {
|
||||
type: [String, Number],
|
||||
},
|
||||
rightList:{
|
||||
type:Array
|
||||
rightList: {
|
||||
type: Array
|
||||
},
|
||||
wrongList:{
|
||||
type:Array
|
||||
wrongList: {
|
||||
type: Array
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
allQuestionNum:0,
|
||||
titleNum:500,
|
||||
allQuestionNum: 0,
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
|
||||
mounted() {
|
||||
this.getTitle()
|
||||
},
|
||||
computed: {
|
||||
...mapState(useQuestionStore, ["orderQuestion"]) ,//映射函数,取出tagslist
|
||||
getDoNum(){
|
||||
return this.rightList.length+this.wrongList.length
|
||||
...mapState(useUserStore, ["vipOnList", "token"]),
|
||||
...mapState(useQuestionStore, ["orderQuestion_subject1", "orderQuestion_subject4", "version"]), //映射函数,取出tagslist
|
||||
getDoNum() {
|
||||
return this.rightList.length + this.wrongList.length
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toTestRoom(){
|
||||
uni.navigateTo({
|
||||
url:"/pages/index/testRoom"
|
||||
...mapActions(useUserStore, ['searchUserVip']),
|
||||
...mapActions(useQuestionStore, ['getOrderQuestion_sub1', 'getOrderQuestion_sub4', 'getAllQuestion']),
|
||||
getTitle(){
|
||||
const carId=storage.get('carType') || '1001'
|
||||
querySysConfig(carId,'SimplifyQuestionNum').then(resp=>{
|
||||
if(resp.code==='0000'){
|
||||
const list = JSON.parse(resp.data.configJson)
|
||||
this.titleNum=list.find(item=>item.subject==this.subject).num
|
||||
}
|
||||
})
|
||||
},
|
||||
toVip(){
|
||||
if(storage.get('token')){
|
||||
uni.navigateTo({
|
||||
url:"/pages/index/videoVip?subject="+this.subject
|
||||
async toTestRoom() {
|
||||
// uni.navigateTo({
|
||||
// url:"/pages/index/trueTest"
|
||||
// })
|
||||
if (this.token) {
|
||||
await this.searchUserVip()
|
||||
const res = this.vipOnList.some(item => item.subjects.includes(this.subject))
|
||||
if (!res) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/index/videoVip?subject=" + this.subject
|
||||
})
|
||||
} else {
|
||||
getTestQuestionId({
|
||||
versionId: this.version,
|
||||
carTypeId: storage.get('carType') || '1001',
|
||||
subject: this.subject,
|
||||
}).then(async (resp) => {
|
||||
if (resp.code === '0000') {
|
||||
if(resp.data&&resp.data.length){
|
||||
const arr = resp.data
|
||||
const listJson = JSON.stringify(arr)
|
||||
uni.navigateTo({
|
||||
url: "/pages/index/trueTest?subject="+ this.subject + "&questionIdList=" + listJson
|
||||
})
|
||||
}else{
|
||||
uni.showToast({
|
||||
title: '暂无题目',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} else if (resp.code === '4001') {
|
||||
uni.showToast({
|
||||
title: '当前题库非最新版,请更新~',
|
||||
icon: 'none'
|
||||
})
|
||||
this.getAllQuestion()
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.redirectTo({
|
||||
url: '/pages/login/login'
|
||||
});
|
||||
}
|
||||
},
|
||||
async toVip() {
|
||||
if (this.token) {
|
||||
await this.searchUserVip()
|
||||
const res = this.vipOnList.some(item => item.subjects.includes(this.subject))
|
||||
if (!res) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/index/videoVip?subject=" + this.subject
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: "/pages/me/vip"
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.redirectTo({
|
||||
url: '/pages/login/login'
|
||||
});
|
||||
}
|
||||
},
|
||||
toClass() {
|
||||
uni.showToast({
|
||||
title: '敬请期待',
|
||||
icon: 'none'
|
||||
})
|
||||
},
|
||||
toAnswer(title, val) {
|
||||
if (title == `精简${this.titleNum}题`) {
|
||||
queryQuestionId({
|
||||
versionId: this.version,
|
||||
carTypeId: storage.get('carType') || '1001',
|
||||
subject: this.subject,
|
||||
isVip: '1'
|
||||
}).then(async (resp) => {
|
||||
if (resp.code === '0000') {
|
||||
if (this.token) {
|
||||
await this.searchUserVip()
|
||||
const result = this.vipOnList.some(item => item.subjects.includes(this.subject))
|
||||
let arr = []
|
||||
if (result) {
|
||||
if(resp.data&&resp.data.length){
|
||||
const listJson = JSON.stringify(resp.data)
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/questionBank?navTitle=" + title + "&subject=" + this.subject +
|
||||
"&needVip=" + !result + "&questionIdList=" + listJson
|
||||
})
|
||||
}else{
|
||||
uni.showToast({
|
||||
title: '暂无题目',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (resp.data && resp.data.length > 3) {
|
||||
arr = resp.data.slice(0, 3)
|
||||
} else {
|
||||
arr = resp.data
|
||||
}
|
||||
if(arr&&arr.length){
|
||||
const listJson = JSON.stringify(arr)
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/questionBank?navTitle=" + title + "&subject=" + this.subject +
|
||||
"&needVip=" + !result + "&questionIdList=" + listJson
|
||||
})
|
||||
}else{
|
||||
uni.showToast({
|
||||
title: '暂无题目',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uni.redirectTo({
|
||||
url: '/pages/login/login'
|
||||
});
|
||||
}
|
||||
} else if (resp.code === '4001') {
|
||||
uni.showToast({
|
||||
title: '当前题库非最新版,请更新~',
|
||||
icon: 'none'
|
||||
})
|
||||
this.getAllQuestion()
|
||||
}
|
||||
})
|
||||
}else{
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url:'/pages/login/login'
|
||||
url: "/pages/questionBank/questionBank?navTitle=" + title + "&subject=" + this.subject + "&needVip=" +
|
||||
val
|
||||
})
|
||||
}
|
||||
},
|
||||
toClass(){
|
||||
if(storage.get('token')){
|
||||
uni.navigateTo({
|
||||
url:"/pages/questionBank/baseOperate"
|
||||
})
|
||||
}else{
|
||||
uni.navigateTo({
|
||||
url:'/pages/login/login'
|
||||
})
|
||||
}
|
||||
},
|
||||
toAnswer(title,val) {
|
||||
toExams(title) {
|
||||
if (storage.get('token')) {
|
||||
if(title=='模拟考试'){
|
||||
getTestQuestionId({
|
||||
versionId: this.version,
|
||||
carTypeId: storage.get('carType') || '1001',
|
||||
subject: this.subject,
|
||||
}).then(async (resp) => {
|
||||
if (resp.code === '0000') {
|
||||
const arr = resp.data
|
||||
const listJson = JSON.stringify(arr)
|
||||
uni.navigateTo({
|
||||
url: "/pages/index/testTip?subject=" + this.subject + "&questionIdList=" + listJson
|
||||
})
|
||||
} else if (resp.code === '4001') {
|
||||
uni.showToast({
|
||||
title: '当前题库非最新版,请更新~',
|
||||
icon: 'none'
|
||||
})
|
||||
this.getAllQuestion()
|
||||
}
|
||||
})
|
||||
}else if(title=='考前秘卷'){
|
||||
const param=this.subject=='1'?{isExam1: '1'}:{isExam2: '1'}
|
||||
queryQuestionId({
|
||||
versionId: this.version,
|
||||
carTypeId: storage.get('carType') || '1001',
|
||||
subject: this.subject,
|
||||
...param
|
||||
}).then(async (resp) => {
|
||||
if (resp.code === '0000') {
|
||||
let arr = []
|
||||
if (this.token) {
|
||||
await this.searchUserVip()
|
||||
const result = this.vipOnList.some(item => item.subjects.includes(this.subject))
|
||||
if (result) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/index/secretPapers?subject=" + this.subject
|
||||
})
|
||||
} else {
|
||||
if (resp.data && resp.data.length > 3) {
|
||||
arr = resp.data.slice(0, 3)
|
||||
} else {
|
||||
arr = resp.data
|
||||
}
|
||||
const listJson = JSON.stringify(arr)
|
||||
uni.navigateTo({
|
||||
url: "/pages/index/videoVip?subject=" + this.subject
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.redirectTo({
|
||||
url: '/pages/login/login'
|
||||
});
|
||||
}
|
||||
} else if (resp.code === '4001') {
|
||||
uni.showToast({
|
||||
title: '当前题库非最新版,请更新~',
|
||||
icon: 'none'
|
||||
})
|
||||
this.getAllQuestion()
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url:"/pages/questionBank/questionBank?navTitle="+title+"&subject="+this.subject+"&needVip="+val
|
||||
})
|
||||
},
|
||||
toExams(){
|
||||
if(storage.get('token')){
|
||||
uni.navigateTo({
|
||||
url:"/pages/questionBank/practiceExams?subject="+this.subject
|
||||
})
|
||||
}else{
|
||||
uni.navigateTo({
|
||||
url:'/pages/login/login'
|
||||
})
|
||||
}
|
||||
},
|
||||
toExclusive(){
|
||||
uni.navigateTo({
|
||||
url:"/pages/questionBank/exclusiveExercise"
|
||||
})
|
||||
},
|
||||
toWrongList(){
|
||||
uni.navigateTo({
|
||||
url:"/pages/questionBank/wrongQuestion?subject="+this.subject
|
||||
url: '/pages/login/login'
|
||||
})
|
||||
}
|
||||
},
|
||||
toExclusive() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/exclusiveExercise?subject=" + this.subject
|
||||
})
|
||||
},
|
||||
toWrongList() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/wrongQuestion?subject=" + this.subject
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.box-nav {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
height: 500rpx;
|
||||
}
|
||||
|
||||
.center-box {
|
||||
@@ -249,4 +439,12 @@
|
||||
background: #00B74F;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
.play_btn_2 {
|
||||
width: 65rpx;
|
||||
height: 65rpx;
|
||||
position: absolute;
|
||||
left: 165.5rpx;
|
||||
top: 78rpx
|
||||
}
|
||||
</style>
|
||||
@@ -1,151 +1,320 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="box-nav">
|
||||
<image style="width: 100%;" src="../../../static/image/index/index_bg.jpg"></image>
|
||||
<view style="width: 100%;position: absolute;top: 80px;left: 0;" class="flex jc-c">
|
||||
<image style="width: 694rpx" mode="widthFix" :src="subject=='2'?'../../../static/image/index/subject2_bg.png':'../../../static/image/index/subject3_bg.png'"></image>
|
||||
<view>
|
||||
<view class="box-nav">
|
||||
<image style="width: 100%;" src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/%E9%A6%96%E9%A1%B5_20230830213855.png"></image>
|
||||
<view style="width: 100%;position: absolute;top: 80px;left: 0;" class="flex jc-c" @tap="toVipVideo">
|
||||
<image style="width: 694rpx" mode="widthFix"
|
||||
:src="subject=='2'?'https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/%E7%A7%91%E4%BA%8C%E9%A6%96%E9%A1%B5banner_20230830214212.png':'https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/%E7%A7%91%E4%B8%89%E9%A6%96%E9%A1%B5banner_20230830214245.png'">
|
||||
</image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="p14lr" style="margin-top: -20px;">
|
||||
<view class="video_box">
|
||||
<view class="flex ai-c jc-sb mt5">
|
||||
<text class="fs18 cor-000">科{{subject=='2'?'二':'三'}}考试项目讲解</text>
|
||||
<view class="flex ai-c" style="height: 34rpx;line-height: 34rpx;" @tap="changeDiverType">
|
||||
<!-- <view class="flex ai-c" style="height: 34rpx;line-height: 34rpx;" @tap="changeDiverType">
|
||||
<text style="color:#05C341;font-size: 16px;">{{diverTypeList[diverTypeIndex]?.configItemName}}</text>
|
||||
<u-icon name="list" color="#05C341" size="18"></u-icon>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="flex ai-c jc-sb mt15">
|
||||
<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" @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 class="skill-sequence-panel-content-wrapper">
|
||||
<scroll-view class="skill-sequence-panel-content" scroll-x :scroll-into-view="intoindex">
|
||||
<view class="skill-sequence-skill-wrapper tab_iem m15tb" :class="videoIndex===index?'checked_tab':''"
|
||||
v-for="(item,index) of operateList" :key="index" :id='"text"+index' @tap="checkVideo(index)">
|
||||
{{item.description}}
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<swiper class="swiper" :current="videoIndex" style="height: 362rpx;" :autoplay="false"
|
||||
:disable-programmatic-animation="true" @change="onChange">
|
||||
<swiper-item v-for="(item,index) of operateList" :key="index" @tap="toVideo">
|
||||
<view class="p5lr wp100">
|
||||
<view class="wp100 relative hide"
|
||||
style="height: 362rpx;border-radius: 16rpx;overflow: hidden;">
|
||||
<image style="width: 100%;height: 362rpx;position: absolute;left: 0;top: 0;" mode="widthFix"
|
||||
:src="item.videoList[0].videoUrl+'?x-oss-process=video/snapshot,t_0,f_jpg'"></image>
|
||||
<image class="play_btn_2" src="../../static/image/index/play.png" />
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
<view class="video_box mt10">
|
||||
<view class="video_box mt10" v-if="subject=='2'">
|
||||
<view class="flex ai-c jc-sb">
|
||||
<text class="fs18 cor-000">基础操作讲解</text>
|
||||
<view class="flex cor-666" @tap="toVideo">
|
||||
<view class="flex cor-666" @tap="toDetail">
|
||||
<text>全部</text>
|
||||
<u-icon color="#666" name="arrow-right" size="18"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex p14lr p20tb bc-fff mt10" style="border-bottom: 1rpx solid #DDDCDC;;" v-for="(item,index) of operateList" :key="index" @tap="toDetail">
|
||||
<image class="pic" src="../../static/image/index/index_bg.jpg"></image>
|
||||
<view class="ml10">
|
||||
<text class="fs16 cor-000 fw600">上车、下车的方法</text>
|
||||
<view class="fs14 mt5 cor-666">上车、下车的方法</view>
|
||||
</view>
|
||||
<view class="flex p14lr p20tb bc-fff" style="border-bottom: 1rpx solid #DDDCDC;"
|
||||
v-for="(item,index) of videoList" :key="index" @click="toOperateDetail(item.videoId)">
|
||||
<view class="pic relative hide" style="overflow: hidden;">
|
||||
<image class="pic" style="position: absolute;left: 0;top: 0;" mode="widthFix" :src="item.videoUrl+'?x-oss-process=video/snapshot,t_0,f_jpg'"></image>
|
||||
<image class="play_btn_3" src="../../static/image/index/play.png" />
|
||||
</view>
|
||||
<view class="ml10">
|
||||
<text class="fs16 cor-000 fw600">{{baseList[0]?.description}}</text>
|
||||
<view class="fs14 mt5 cor-666">{{item.description}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import {
|
||||
querySysConfigList,
|
||||
queryProjectList
|
||||
} from '@/jtools/api/question';
|
||||
import storage from '@/jtools/storage';
|
||||
export default {
|
||||
name: "Subject2",
|
||||
props:{
|
||||
subject:{
|
||||
type:[String,Number]
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
diverTypeIndex:0,
|
||||
diverTypeList:[],
|
||||
videoIndex:0,
|
||||
projectId:undefined,
|
||||
operateList:[]
|
||||
}
|
||||
},
|
||||
async mounted(){
|
||||
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"
|
||||
})
|
||||
export default {
|
||||
name: "Subject2",
|
||||
props: {
|
||||
subject: {
|
||||
type: [String, Number]
|
||||
}
|
||||
},
|
||||
getVideoList(){
|
||||
console.log(this.subject);
|
||||
queryProjectList({
|
||||
"carTypeId": storage.get('carType') || '1001',
|
||||
"driveType": this.diverTypeList[this.diverTypeIndex].configItemCode,
|
||||
"subject": String(this.subject),
|
||||
"type": "1"
|
||||
}).then(resp=>{
|
||||
this.operateList=resp.data
|
||||
this.projectId=this.operateList[0]?.projectId
|
||||
})
|
||||
data() {
|
||||
return {
|
||||
intoindex: '',
|
||||
diverTypeIndex: 0,
|
||||
diverTypeList: [],
|
||||
videoIndex: 0,
|
||||
projectId: undefined,
|
||||
operateList: [],
|
||||
baseList: [],
|
||||
videoList: []
|
||||
}
|
||||
},
|
||||
getDiverType(){
|
||||
const carTypeId=storage.get('carType') || '1001'
|
||||
querySysConfigList(carTypeId,'DriveType').then(resp=>{
|
||||
if(resp.code==='0000'){
|
||||
this.diverTypeList=resp.data
|
||||
this.getVideoList()
|
||||
async mounted() {
|
||||
// await this.getDiverType()
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore, ["vipOnList", "token"])
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useUserStore, ['searchUserVip']),
|
||||
//vip视频页面
|
||||
async toVipVideo(){
|
||||
if (this.token) {
|
||||
await this.searchUserVip()
|
||||
const res = this.vipOnList.some(item => item.subjects.includes(this.subject))
|
||||
if (!res) {
|
||||
uni.navigateTo({
|
||||
url:"/pages/index/videoVip?subject="+this.subject
|
||||
})
|
||||
}else{
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/baseOperate?subject=" + this.subject+"&type=3"
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.redirectTo({
|
||||
url: '/pages/login/login'
|
||||
});
|
||||
}
|
||||
},
|
||||
onChange(e) {
|
||||
this.videoIndex = e.detail.current
|
||||
this.$nextTick(() => {
|
||||
const index = this.videoIndex - 1 < 0 ? 0 : this.videoIndex - 1
|
||||
this.intoindex = "text" + index
|
||||
});
|
||||
},
|
||||
getOperateList() {
|
||||
queryProjectList({
|
||||
"carTypeId": storage.get('carType') || '1001',
|
||||
"subject": String(this.subject),
|
||||
"type": "2"
|
||||
}).then(resp => {
|
||||
if (resp.code === '0000' && resp.data &&resp.data.length) {
|
||||
this.baseList = resp.data
|
||||
this.videoList = resp.data[0] && resp.data[0].videoList? resp.data[0].videoList.slice(0, 5) : []
|
||||
}
|
||||
})
|
||||
},
|
||||
changeDiverType(){
|
||||
this.diverTypeIndex=this.diverTypeIndex==0?1:0
|
||||
this.getVideoList()
|
||||
formateTime(time) {
|
||||
const h = parseInt(time / 3600)
|
||||
const minute = parseInt(time / 60 % 60)
|
||||
const second = Math.ceil(time % 60)
|
||||
const hours = h < 10 ? '0' + h : h
|
||||
const formatSecond = second > 59 ? 59 : second
|
||||
return `${hours > 0 ? `${hours}:` : ''}${minute < 10 ? '0' + minute : minute}:${formatSecond < 10 ? '0' + formatSecond : formatSecond}`
|
||||
},
|
||||
checkVideo(val){
|
||||
console.log(val);
|
||||
this.projectId=this.operateList[val]?.projectId
|
||||
this.videoIndex=val
|
||||
},
|
||||
toDetail(){
|
||||
uni.navigateTo({
|
||||
url:"/pages/questionBank/baseOperate"
|
||||
})
|
||||
async toVideo() {
|
||||
if (this.token) {
|
||||
await this.searchUserVip()
|
||||
const res = this.vipOnList.some(item => item.subjects.includes(this.subject))
|
||||
if (!res) {
|
||||
uni.navigateTo({
|
||||
url:"/pages/index/videoVip?subject="+this.subject
|
||||
})
|
||||
}else{
|
||||
let arr = JSON.parse(JSON.stringify(this.operateList))
|
||||
arr = arr.map(item => {
|
||||
return {
|
||||
...item,
|
||||
videoUrl: item.videoList[0]?.videoUrl,
|
||||
videoTime: this.formateTime(item.videoList[0]?.videoTime)
|
||||
}
|
||||
})
|
||||
let jsonString = JSON.stringify(arr)
|
||||
console.log('arr',jsonString);
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/videoDetail?videoList=" + jsonString + "&subject=" + this.subject +
|
||||
"&projectId=" + this.projectId + "&type=1&driveType=2"
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.redirectTo({
|
||||
url: '/pages/login/login'
|
||||
});
|
||||
}
|
||||
},
|
||||
toOperateDetail(val) {
|
||||
let arr = JSON.parse(JSON.stringify(this.baseList[0].videoList))
|
||||
arr = arr.map(item => {
|
||||
return {
|
||||
...item,
|
||||
projectId: item.videoId,
|
||||
subDesc: this.baseList[0].description,
|
||||
videoTime: this.formateTime(item.videoTime)
|
||||
}
|
||||
})
|
||||
let jsonString = JSON.stringify(arr)
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/videoDetail?videoList=" + jsonString + "&subject=" + this.subject +
|
||||
"&projectId=" + val + "&type=2"
|
||||
})
|
||||
},
|
||||
getVideoList() {
|
||||
queryProjectList({
|
||||
"carTypeId": storage.get('carType') || '1001',
|
||||
"driveType": '2',
|
||||
"subject": String(this.subject),
|
||||
"type": "1"
|
||||
}).then(resp => {
|
||||
if(resp.code==='0000'){
|
||||
this.operateList = resp.data
|
||||
this.projectId = this.operateList[0]?.projectId
|
||||
}
|
||||
})
|
||||
},
|
||||
getDiverType() {
|
||||
const carTypeId = storage.get('carType') || '1001'
|
||||
querySysConfigList(carTypeId, 'DriveType').then(resp => {
|
||||
if (resp.code === '0000') {
|
||||
this.diverTypeList = resp.data
|
||||
this.getVideoList()
|
||||
this.getOperateList()
|
||||
}
|
||||
})
|
||||
},
|
||||
changeDiverType() {
|
||||
this.diverTypeIndex = this.diverTypeIndex == 0 ? 1 : 0
|
||||
this.videoIndex = 0
|
||||
this.getVideoList()
|
||||
this.getOperateList()
|
||||
},
|
||||
checkVideo(val) {
|
||||
this.projectId = this.operateList[val]?.projectId
|
||||
this.videoIndex = val
|
||||
},
|
||||
toDetail() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/baseOperate?subject=" + this.subject+"&type=2"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.box-nav{
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.center-box{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
top: 170rpx;
|
||||
padding: 0 28rpx;
|
||||
}
|
||||
.video_box{
|
||||
width: 100%;
|
||||
background: #FFFFFF;
|
||||
border-radius: 16rpx;
|
||||
padding: 14px;
|
||||
}
|
||||
.tab_iem{
|
||||
width: 145rpx;
|
||||
height: 56rpx;
|
||||
line-height: 56rpx;
|
||||
text-align: center;
|
||||
background: #F5F5F5;
|
||||
border-radius: 10rpx;
|
||||
color:#333
|
||||
.box-nav {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.center-box {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
top: 170rpx;
|
||||
padding: 0 28rpx;
|
||||
}
|
||||
|
||||
.video_box {
|
||||
width: 100%;
|
||||
background: #FFFFFF;
|
||||
border-radius: 16rpx;
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.tab_iem {
|
||||
padding: 0 5px;
|
||||
height: 56rpx;
|
||||
line-height: 56rpx;
|
||||
text-align: center;
|
||||
background: #F5F5F5;
|
||||
border-radius: 10rpx;
|
||||
color: #333
|
||||
}
|
||||
|
||||
.checked_tab {
|
||||
background: linear-gradient(90deg, #11DF20 0%, #01B74F 100%);
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.pic {
|
||||
width: 300rpx;
|
||||
height: 169rpx;
|
||||
background: #00B74F;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.play_btn_3 {
|
||||
width: 65rpx;
|
||||
height: 65rpx;
|
||||
position: absolute;
|
||||
left: 117.5rpx;
|
||||
top: 52rpx
|
||||
}
|
||||
|
||||
.play_btn_2 {
|
||||
width: 65rpx;
|
||||
height: 65rpx;
|
||||
position: absolute;
|
||||
left: calc((100% - 65rpx)/2);
|
||||
top: 148.5rpx
|
||||
}
|
||||
|
||||
/*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;
|
||||
}
|
||||
|
||||
.hide {
|
||||
backface-visibility: hidden;
|
||||
transform: translate3d(0, 0, 0);
|
||||
-webkit-backface-visibility: hidden;
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
}
|
||||
.checked_tab{
|
||||
background: linear-gradient(90deg, #11DF20 0%, #01B74F 100%);
|
||||
color:#fff
|
||||
}
|
||||
.pic{
|
||||
width: 300rpx;
|
||||
height: 169rpx;
|
||||
background: #00B74F;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
226
src/pages/index/components/ggl/index.vue
Normal file
@@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<view style="padding-bottom: 50px;background-color: #9e0f00;">
|
||||
<image class="wp100" mode="widthFix" src="https://jwl-jiakao-bq.oss-cn-hangzhou.aliyuncs.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/ggl_header.png"></image>
|
||||
<view class="tip">您今日还剩{{actiNum}}次刮奖机会,共有{{total}}人参加活动</view>
|
||||
<view class="scraping">
|
||||
<scraping-card style="z-index: 20;" :result="result" watermark="刮一刮" title="刮一刮赢取大奖" ref="reset" @complete="handleComplete" >
|
||||
<cover-view v-if="showBtn" class="gj">
|
||||
<cover-view class="btn" @tap="handleScrap">
|
||||
{{btnText}}
|
||||
</cover-view>
|
||||
</cover-view>
|
||||
</scraping-card>
|
||||
</view>
|
||||
<view class="relative mt30 m20lr">
|
||||
<image class="wp100" mode="widthFix" src="/static/image/index/tip.png"></image>
|
||||
<view class="title">中奖名单</view>
|
||||
<view class="card">
|
||||
<view v-for="(item, index) in winningList" :key="index" class="card-item">
|
||||
<text class="item-text">{{ hidePhoneNumber(item.phone) }}</text>
|
||||
<text class="item-text">{{ item.awards }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="relative mt30 m20lr">
|
||||
<image class="wp100" mode="widthFix" src="/static/image/index/tip.png"></image>
|
||||
<view class="title">活动说明</view>
|
||||
<view class="card">
|
||||
<u-parse :content="activityRule"></u-parse>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import ScrapingCard from './scraping.vue'
|
||||
import { queryActivityDetail,queryLuckyNum,queryLuckyResult,saveWinner,getLuckyRecord } from '@/jtools/api/activity'
|
||||
export default {
|
||||
components: {
|
||||
ScrapingCard
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
detailId: undefined,
|
||||
result: '',
|
||||
btnText: '点我刮奖',
|
||||
showBtn: true,
|
||||
actiNum: 0,
|
||||
total: 0,
|
||||
winningList: [],
|
||||
activityRule: undefined
|
||||
}
|
||||
},
|
||||
onLoad(op) {
|
||||
this.detailId = op.detailId
|
||||
this.getActivityDetail()
|
||||
this.getActivityNum()
|
||||
this.searchWinningList()
|
||||
},
|
||||
methods: {
|
||||
handleScrap() {
|
||||
if(!this.actiNum) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '暂无抽奖机会'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
queryLuckyResult({
|
||||
detailId: this.detailId
|
||||
}).then(resp => {
|
||||
if(resp.code == 200) {
|
||||
this.result = resp.msg
|
||||
this.showBtn = !this.showBtn
|
||||
this.$refs.reset.init()
|
||||
}
|
||||
})
|
||||
},
|
||||
getActivityDetail() {
|
||||
queryActivityDetail({detailId: this.detailId}).then(resp => {
|
||||
if(resp.code == 200) {
|
||||
this.activityRule = resp.data.activity.activityRule
|
||||
}
|
||||
})
|
||||
},
|
||||
hidePhoneNumber(phoneNumber) {
|
||||
// 验证电话号码格式
|
||||
if (!/^\d{11}$/.test(phoneNumber)) {
|
||||
return "无效的电话号码";
|
||||
}
|
||||
|
||||
// 替换中间四位数字为星号
|
||||
return phoneNumber.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
||||
},
|
||||
getActivityNum() {
|
||||
queryLuckyNum({
|
||||
detailId: this.detailId,
|
||||
phone: useUserStore().userInfo?.phone || ''
|
||||
}).then(resp => {
|
||||
if(resp.code == 200) {
|
||||
this.actiNum = resp.data.drawNum
|
||||
this.total = resp.data.totalPeople
|
||||
}
|
||||
})
|
||||
},
|
||||
searchWinningList() {
|
||||
getLuckyRecord({
|
||||
detailId: this.detailId,
|
||||
pageSize: 8
|
||||
}).then(resp => {
|
||||
if(resp.code == 200) {
|
||||
this.winningList = resp.rows
|
||||
}
|
||||
})
|
||||
},
|
||||
handleComplete() {
|
||||
saveWinner({
|
||||
phone: useUserStore().userInfo?.phone || '',
|
||||
detailId: this.detailId,
|
||||
awards: this.result
|
||||
}).then(resp => {
|
||||
this.btnText = '再刮一次!'
|
||||
if(resp.code == 200) {
|
||||
this.getActivityNum()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: `恭喜获得${this.result}`
|
||||
})
|
||||
this.showBtn = true
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.tip {
|
||||
position: relative;
|
||||
margin-top: -80px;
|
||||
margin-left: 40px;
|
||||
margin-right: 40px;
|
||||
height: 52rpx;
|
||||
background: rgba(0,0,0,0.5);
|
||||
border-radius: 26rpx;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
line-height: 52rpx;
|
||||
}
|
||||
.scraping {
|
||||
position: relative;
|
||||
margin-top: 20rpx;
|
||||
margin-left: 40px;
|
||||
margin-right: 40px;
|
||||
background-color: #fff;
|
||||
border: 3px solid #9e0f00; /* 实线边框 */
|
||||
border-top: 3px dashed #9e0f00; /* 虚线边框 */
|
||||
border-right: 3px dashed #9e0f00; /* 虚线边框 */
|
||||
border-bottom: 3px dashed #9e0f00; /* 虚线边框 */
|
||||
border-left: 3px dashed #9e0f00; /* 虚线边框 */
|
||||
border-radius: 5px; /* 圆角 */
|
||||
padding: 10px; /* 内容与边框之间的空间 */
|
||||
}
|
||||
.gj {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 21;
|
||||
.btn {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: calc(50% - 100rpx);
|
||||
width: 200rpx;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
background-color: #BE1200;
|
||||
border-radius: 10rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
position: absolute;
|
||||
left: calc(50% - 160rpx);
|
||||
top: -14px;
|
||||
width: 320rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
background: linear-gradient(0deg, #ECB181, #FFEDD3);
|
||||
border: 6rpx solid #E32D1A;
|
||||
border-radius: 40rpx 40rpx 0 0;
|
||||
font-weight: 600;
|
||||
color: #BE1200;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.card {
|
||||
position: relative;
|
||||
margin-top: -40rpx;
|
||||
padding: 26rpx;
|
||||
min-height: 280rpx;
|
||||
background: #FFEDD3;
|
||||
border: 6rpx solid #E32D1A;
|
||||
border-radius: 24rpx;
|
||||
.card-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
border-bottom: 1px solid #ecd3ae;
|
||||
}
|
||||
.card-item:last-of-type {
|
||||
border-bottom: none;
|
||||
}
|
||||
.item-text {
|
||||
font-size: 28rpx;
|
||||
color: #BE1200;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
280
src/pages/index/components/ggl/scraping.vue
Normal file
@@ -0,0 +1,280 @@
|
||||
<template>
|
||||
<view class="scraping-happy" id="container">
|
||||
<canvas canvas-id="scraping-happy" class="scraping__canvas" :disable-scroll="true" @touchstart="touchstart"
|
||||
@touchmove="touchmove" @touchend="touchend" />
|
||||
<cover-view class="scraping__view">
|
||||
{{ showText }}
|
||||
</cover-view>
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/** @name 水印配置默认值 **/
|
||||
const WATERMARK = {
|
||||
text: '刮一刮',
|
||||
fontSize: 14,
|
||||
color: '#C5C5C5',
|
||||
}
|
||||
/** @name 标题配置默认值 **/
|
||||
const TITLE = {
|
||||
text: '刮一刮',
|
||||
fontSize: 16,
|
||||
color: '#333',
|
||||
}
|
||||
/**
|
||||
* @name 涂层配置默认值
|
||||
* @property { string } color 涂层颜色
|
||||
* @property { number } drawSize 清除涂层的画笔大小
|
||||
*/
|
||||
const MASK = {
|
||||
color: '#DDDDDD',
|
||||
drawSize: 20,
|
||||
}
|
||||
/** @name 容错值,解决部分机型涂层没有覆盖满的情况,主要原因是由于像素尺寸不同导致的,应尽可能让width与height保持整数 **/
|
||||
const TOLERANT = 3;
|
||||
|
||||
let ctx = null;
|
||||
|
||||
export default {
|
||||
props: {
|
||||
/** @name 涂层设置 **/
|
||||
mask: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** @name 水印设置 **/
|
||||
watermark: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** @name 提示文字 **/
|
||||
title: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** @name 刮开百分之多少直接消除图层,为0的时候不消除 **/
|
||||
percentage: {
|
||||
type: Number,
|
||||
default: 40,
|
||||
},
|
||||
result: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
width: 0,
|
||||
height: 0,
|
||||
touchX: 0,
|
||||
touchY: 0,
|
||||
showText: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
maskSetting() {
|
||||
return {
|
||||
...MASK,
|
||||
...(typeof this.mask === 'object' ? this.mask : {
|
||||
text: this.mask
|
||||
}),
|
||||
}
|
||||
},
|
||||
watermarkSetting() {
|
||||
return {
|
||||
...WATERMARK,
|
||||
...(typeof this.watermark === 'object' ? this.watermark : {
|
||||
text: this.watermark
|
||||
}),
|
||||
};
|
||||
},
|
||||
titleSetting() {
|
||||
return {
|
||||
...TITLE,
|
||||
...(typeof this.title === 'object' ? this.title : {
|
||||
text: this.title
|
||||
}),
|
||||
};
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 获取画布实例
|
||||
ctx = uni.createCanvasContext('scraping-happy', this);
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
/** @name 初始化 **/
|
||||
init() {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query
|
||||
.select('#container')
|
||||
.boundingClientRect(({
|
||||
width,
|
||||
height
|
||||
}) => {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
setTimeout(() => {
|
||||
this.initCanvas();
|
||||
this.showText = this.result
|
||||
}, 20)
|
||||
})
|
||||
.exec();
|
||||
},
|
||||
/** @name 初始化canvas状态 **/
|
||||
initCanvas() {
|
||||
const {
|
||||
width,
|
||||
height
|
||||
} = this;
|
||||
// 清空矩形内容
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
// 设置画笔颜色
|
||||
ctx.setFillStyle(this.maskSetting.color);
|
||||
// 绘制矩形
|
||||
ctx.fillRect(0, 0, width, height + TOLERANT);
|
||||
// 绘制水印
|
||||
this.drawWatermark();
|
||||
// 绘制提示文字
|
||||
this.drawTitle();
|
||||
// 绘制到canvas身上
|
||||
ctx.draw();
|
||||
},
|
||||
/** @name 绘制水印 **/
|
||||
drawWatermark() {
|
||||
if (!this.watermarkSetting.text) return;
|
||||
// 保存当前的绘图上下文
|
||||
ctx.save();
|
||||
// 旋转
|
||||
ctx.rotate((-10 * Math.PI) / 180);
|
||||
// 水印具体绘制过程
|
||||
const {
|
||||
width,
|
||||
height
|
||||
} = this;
|
||||
const watermarkWidth = this.watermarkSetting.text.length * this.watermarkSetting.fontSize;
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
let i = 0;
|
||||
while ((x <= width * 5 || y <= height * 5) && i < 300) {
|
||||
ctx.setFillStyle(this.watermarkSetting.color);
|
||||
ctx.setFontSize(this.watermarkSetting.fontSize);
|
||||
ctx.fillText(this.watermarkSetting.text, x, y);
|
||||
x += watermarkWidth + watermarkWidth * 1.6;
|
||||
if (x > width && y <= height) {
|
||||
x = -Math.random() * 100;
|
||||
y += this.watermarkSetting.fontSize * 3;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
ctx.restore();
|
||||
},
|
||||
/** @name 绘制提示文字 **/
|
||||
drawTitle() {
|
||||
if (!this.titleSetting.text) return;
|
||||
ctx.setTextAlign('center');
|
||||
ctx.setTextBaseline('middle');
|
||||
ctx.setFillStyle(this.titleSetting.color);
|
||||
ctx.setFontSize(this.titleSetting.fontSize);
|
||||
ctx.fillText(this.titleSetting.text, this.width / 2, this.height / 3);
|
||||
},
|
||||
/** @name 触摸事件 **/
|
||||
touchstart(e) {
|
||||
this.touchX = e.touches[0].x;
|
||||
this.touchY = e.touches[0].y;
|
||||
},
|
||||
async touchmove(e) {
|
||||
// 把画笔到画布中的指定点
|
||||
ctx.moveTo(this.touchX, this.touchY);
|
||||
// 清除涂层
|
||||
ctx.clearRect(this.touchX, this.touchY, this.maskSetting.drawSize, this.maskSetting.drawSize);
|
||||
ctx.draw(true);
|
||||
// 记录移动点位
|
||||
this.touchX = e.touches[0].x;
|
||||
this.touchY = e.touches[0].y;
|
||||
|
||||
// if (this.percentage > 0) {
|
||||
// const clearPercent = await this.getClearMaskPercent();
|
||||
// }
|
||||
},
|
||||
async touchend() {
|
||||
if (this.percentage > 0) {
|
||||
const clearPercent = await this.getClearMaskPercent();
|
||||
if (clearPercent >= this.percentage) {
|
||||
ctx.moveTo(0, 0);
|
||||
ctx.clearRect(0, 0, this.width, this.height);
|
||||
ctx.stroke();
|
||||
ctx.draw(true);
|
||||
this.$emit('complete')
|
||||
}
|
||||
}
|
||||
},
|
||||
/** @name 计算被清除的涂层百分比 **/
|
||||
getClearMaskPercent() {
|
||||
return new Promise(resolve => {
|
||||
uni.canvasGetImageData({
|
||||
canvasId: 'scraping-happy',
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
success: res => {
|
||||
// 区域内所有点的像素信息,它是一个数组,数组中每 "4" 项表示一个点的 rgba 值
|
||||
const allPointPixels = res.data;
|
||||
// 储存被清除的点-点的透明度
|
||||
const clearPoint = [];
|
||||
// 取透明度来判断,如果透明度值小于一半,则判断为该点已经被清除
|
||||
for (let i = 0; i < allPointPixels.length; i += 4) {
|
||||
if (allPointPixels[i + 3] < 128) {
|
||||
clearPoint.push(allPointPixels[i + 3]);
|
||||
}
|
||||
}
|
||||
// 已被清除的百分比 = 清除的点 / 全部的点
|
||||
const percent = (
|
||||
(clearPoint.length / (allPointPixels.length / 4)) *
|
||||
100
|
||||
).toFixed(2);
|
||||
resolve(percent);
|
||||
},
|
||||
fail: e => {
|
||||
console.log('canvasGetImageData', e);
|
||||
},
|
||||
}, this);
|
||||
});
|
||||
},
|
||||
/** @name 重置 **/
|
||||
reset() {
|
||||
this.initCanvas();
|
||||
this.touchX = 0;
|
||||
this.touchY = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.scraping-happy {
|
||||
width: 100%;
|
||||
height: 200rpx;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.scraping__canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
/* background-color: red; */
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.scraping__view {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
color: #f29100;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 8px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,70 +1,153 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-sticky bgColor="#fff">
|
||||
<u-tabs :list="categoryList" :scrollable="false" @change="changeCategory"></u-tabs>
|
||||
</u-sticky>
|
||||
<view style="height: 100vh;background-color: rgb(245, 245, 245);">
|
||||
<template v-if="tIndex===0 || tIndex===3">
|
||||
<Subject1 :subject="tIndex+1" :rightList="rightList" :wrongList="wrongList" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<subject2 :subject="tIndex+1" ref="subject2" />
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<!-- <view v-if="getLoading" class="wp100 relative" style="height: 100vh;">
|
||||
<image class="wp100" mode="widthFix"
|
||||
src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/%E8%80%83%E8%AF%95%E6%8F%90%E9%86%92_20230906135037.png">
|
||||
</image>
|
||||
<view class="wp100 flex ai-c jc-c" style="position: absolute;bottom: 0;left: 0;padding-bottom: 124rpx;">
|
||||
<image style="width: 452rpx;"
|
||||
src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/%E9%87%91%E6%AD%A6%E8%81%94_20230831123333.png"
|
||||
mode="widthFix"></image>
|
||||
</view>
|
||||
</view> -->
|
||||
<view v-if="!getLoading">
|
||||
<!-- <j-navbar :isBack="false">金武联驾考</j-navbar> -->
|
||||
<u-sticky bgColor="#fff">
|
||||
<u-tabs :list="categoryList" :current="curTab" :scrollable="false" @change="changeCategory"></u-tabs>
|
||||
</u-sticky>
|
||||
<view class="m10tb" v-if="activityList&&activityList.length">
|
||||
<u-swiper class="acticity" keyName="image" :list="activityList" @click="handleToActivity"></u-swiper>
|
||||
</view>
|
||||
<view style="background-color: rgb(245, 245, 245);">
|
||||
<template v-if="subject=='1' || subject=='4'">
|
||||
<Subject1 :subject="subject" :rightList="rightList" :wrongList="wrongList" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<Subject2 :subject="subject" ref="subjectRef" />
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { mapState,mapActions } from 'pinia' //引入映射函数
|
||||
import useQuestionStore from '@/jtools/store/question' //引入store
|
||||
import storage from '@/jtools/storage';
|
||||
import Subject1 from "./components/Subject1";
|
||||
import Subject2 from "./components/Subject2";
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import useQuestionStore from '@/jtools/store/question' //引入store
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import storage from '@/jtools/storage';
|
||||
import {
|
||||
querySysConfigList,
|
||||
} from '@/jtools/api/question';
|
||||
import Subject1 from "./components/Subject1";
|
||||
import Subject2 from "./components/Subject2";
|
||||
import {
|
||||
queryActivityList
|
||||
} from '@/jtools/api/activity';
|
||||
export default {
|
||||
components: {Subject1,Subject2},
|
||||
components: {
|
||||
Subject1,
|
||||
Subject2
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tIndex:0,
|
||||
searchValue:'',
|
||||
cityName:'',
|
||||
categoryList:[{
|
||||
name:'科目1'
|
||||
},{
|
||||
name:'科目2'
|
||||
},{
|
||||
name:'科目3'
|
||||
},{
|
||||
name:'科目4'
|
||||
}],
|
||||
rightList:storage.get(`rightList_subject${this.tIndex+1}`) || [],
|
||||
wrongList:storage.get(`wrongList_subject${this.tIndex+1}`) || [],
|
||||
};
|
||||
},
|
||||
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']),
|
||||
//切换科目
|
||||
changeCategory(val){
|
||||
this.tIndex=val.index
|
||||
if(this.tIndex==0){
|
||||
this.getOrderQuestion('1')
|
||||
}else if(this.tIndex==3){
|
||||
this.getOrderQuestion('4')
|
||||
}else{
|
||||
this.$refs.subject2.getDiverType()
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
return {
|
||||
getLoading: true,
|
||||
show: false,
|
||||
subject: storage.get('curSubject') || '1',
|
||||
curTab: 0,
|
||||
searchValue: '',
|
||||
cityName: '',
|
||||
categoryList: [],
|
||||
rightList: storage.get(`rightList_subject${this.subject}`) || [],
|
||||
wrongList: storage.get(`wrongList_subject${this.subject}`) || [],
|
||||
activityList: []
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
setTimeout(() => {
|
||||
this.getLoading = false
|
||||
this.show = true
|
||||
}, 100);
|
||||
this.getSubjectConfig()
|
||||
if (this.subject == '1' || this.subject == '4') {
|
||||
this.rightList = storage.get(`rightList_subject${this.subject}`) || []
|
||||
this.wrongList = storage.get(`wrongList_subject${this.subject}`) || []
|
||||
}
|
||||
if (this.subject == '2' || this.subject == '3') {
|
||||
this.$refs.subjectRef.getDiverType()
|
||||
}
|
||||
this.queryActivityList()
|
||||
},
|
||||
onHide() {
|
||||
this.show = false
|
||||
},
|
||||
computed: {
|
||||
...mapState(useQuestionStore, ["loading_subject4", "loading_subject1", "curSubject", "orderQuestion_subject1",
|
||||
"orderQuestion_subject4"
|
||||
]), //映射函数,取出tagslist
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useQuestionStore, ['getOrderQuestion_sub4', 'getOrderQuestion_sub1', 'changeSubject']),
|
||||
//获取科目配置
|
||||
getSubjectConfig() {
|
||||
const carTypeId = storage.get('carType') || '1001'
|
||||
querySysConfigList(carTypeId, 'Subject').then(resp => {
|
||||
if (resp.code === '0000') {
|
||||
this.categoryList = resp.data.map(item => {
|
||||
return {
|
||||
...item,
|
||||
name: item.configItemName
|
||||
}
|
||||
})
|
||||
this.subject = storage.get('curSubject') || '1',
|
||||
this.curTab = this.categoryList.findIndex(item => item.configItemCode == this.subject) || 0
|
||||
}
|
||||
})
|
||||
},
|
||||
//切换科目
|
||||
async changeCategory(val) {
|
||||
this.subject = val.configItemCode
|
||||
this.changeSubject(this.subject)
|
||||
if (this.subject == '1' || this.subject == '4') {
|
||||
this.rightList = storage.get(`rightList_subject${this.subject}`) || []
|
||||
this.wrongList = storage.get(`wrongList_subject${this.subject}`) || []
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.$refs.subjectRef.getDiverType()
|
||||
}, 100)
|
||||
}
|
||||
},
|
||||
//查询活动列表
|
||||
queryActivityList() {
|
||||
queryActivityList({
|
||||
schoolId: useUserStore().userInfo?.schoolId || ''
|
||||
}).then(resp => {
|
||||
this.activityList = resp.data.map(item => ({
|
||||
...item,
|
||||
image: 'https://jwl.ahduima.com' + item.image
|
||||
}));
|
||||
})
|
||||
},
|
||||
// 去活动
|
||||
handleToActivity(index) {
|
||||
let detailId;
|
||||
this.activityList.find((item, index1) => {
|
||||
if (index === index1) {
|
||||
detailId = item.detailId;
|
||||
}
|
||||
})
|
||||
uni.navigateTo({
|
||||
url: '/pages/index/activity?detailId=' + detailId,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .u-tabs__wrapper__nav__line {
|
||||
background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%) !important;
|
||||
bottom: 14rpx !important;
|
||||
}
|
||||
</style>
|
||||
::v-deep .u-tabs__wrapper__nav__line {
|
||||
background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%) !important;
|
||||
bottom: 14rpx !important;
|
||||
}
|
||||
</style>
|
||||
139
src/pages/index/secretPapers.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-loading-page :loading="getLoading" loading-text="题库更新中..."></u-loading-page>
|
||||
<view class="relative" v-if="!getLoading"
|
||||
style="width: 100%;background-image: url(https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/%E8%80%83%E5%89%8D%E5%AF%86%E5%8D%B7_20230904212623.png);background-size: 100% 100%;height: 100vh;">
|
||||
<view style="position: absolute;top: 320px;" class="wp100 p35lr flex jc-sb ai-c">
|
||||
<view class="paper_item" @tap="toExam({isExam1:'1'})">
|
||||
<view class="topTitle">
|
||||
秘卷一
|
||||
</view>
|
||||
<view class="bottom">
|
||||
<text class="wenzi">新规考点提炼</text>
|
||||
<view class="wp100 p5 mt15">
|
||||
<view class="btn">
|
||||
去考试
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="paper_item" @tap="toExam({isExam2:'1'})">
|
||||
<view class="topTitle">
|
||||
秘卷二
|
||||
</view>
|
||||
<view class="bottom">
|
||||
<text class="wenzi">精选高频考试</text>
|
||||
<view class="wp100 p5 mt15">
|
||||
<view class="btn">
|
||||
去考试
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import useQuestionStore from '@/jtools/store/question' //引入store
|
||||
import storage from '@/jtools/storage';
|
||||
import {
|
||||
queryQuestionId,
|
||||
getTestQuestionId
|
||||
} from '@/jtools/api/question';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
subject:'1'
|
||||
}
|
||||
},
|
||||
onLoad(op){
|
||||
if(op.subject){
|
||||
this.subject=op.subject
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useQuestionStore, ["loading_subject4", "loading_subject1", "curSubject","version"]), //映射函数,取出tagslist
|
||||
getLoading() {
|
||||
return this.loading_subject4 && this.loading_subject1
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useQuestionStore, ['getOrderQuestion_sub4', 'getOrderQuestion_sub1', 'changeSubject']),
|
||||
toExam(param) {
|
||||
queryQuestionId({
|
||||
versionId: this.version,
|
||||
carTypeId: storage.get('carType') || '1001',
|
||||
subject: this.subject,
|
||||
...param
|
||||
}).then(async (resp) => {
|
||||
if (resp.code === '0000') {
|
||||
const arr = resp.data
|
||||
const listJson = JSON.stringify(arr)
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/practiceExams?title=考前秘卷&subject=" + this.subject + "&questionIdList=" + listJson
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.paper_item {
|
||||
width: 287rpx;
|
||||
height: 320rpx;
|
||||
/* border: 4px solid #F8A42C; */
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.topTitle {
|
||||
width: 100%;
|
||||
height: 85rpx;
|
||||
line-height: 85rpx;
|
||||
text-align: center;
|
||||
background: linear-gradient(90deg, #E66501 0%, #F8A42C 100%);
|
||||
border-radius: 16rpx 16rpx 0rpx 0rpx;
|
||||
font-size: 48rpx;
|
||||
font-family: PingFang SC;
|
||||
font-weight: 600;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
padding-top: 15px;
|
||||
width: 100%;
|
||||
height: 235rpx;
|
||||
border-radius: 0rpx 0rpx 16rpx 16rpx;
|
||||
border-bottom: 4px solid #F8A42C;
|
||||
border-left: 4px solid #F8A42C;
|
||||
border-right: 4px solid #F8A42C;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wenzi {
|
||||
font-size: 40rpx;
|
||||
font-family: PingFang SC;
|
||||
font-weight: 600;
|
||||
color: #7D4310;
|
||||
line-height: 48rpx;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 246rpx;
|
||||
height: 76rpx;
|
||||
text-align: center;
|
||||
line-height: 76rpx;
|
||||
color: #fff;
|
||||
background: linear-gradient(0deg, #E66501 0%, #F8A42C 100%);
|
||||
box-shadow: 0rpx 2rpx 21rpx 0rpx #F7A12A;
|
||||
border-radius: 38rpx;
|
||||
}
|
||||
</style>
|
||||
83
src/pages/index/testTip.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<view class="bc-fff hp100">
|
||||
<view class="wp100 p14 flex ai-c jc-c">
|
||||
<view class="text-center">
|
||||
<view style="width: 64px;height: 64px;border-radius: 50%;overflow: hidden;margin-bottom: 10px;">
|
||||
<u-avatar class="br-p50 overflow-h" :size="64" mp-avatar shape="circle"></u-avatar>
|
||||
</view>
|
||||
<text class="fs18">{{user.userName}}{{ user.userId }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="p14">
|
||||
<view class="wp100 p14lr p20tb mb14" style="background-color: rgb(248, 248, 248);border-radius: 20rpx;">
|
||||
<view class="flex ai-c jc-sb pb10">
|
||||
<text style="color: rgb(175, 175, 175);">考试类型</text>
|
||||
<text>{{carName}}</text>
|
||||
</view>
|
||||
<view class="flex ai-c jc-sb pb10">
|
||||
<text style="color: rgb(175, 175, 175);">考试标准</text>
|
||||
<text>{{subject=='1'?100:50}}题/45分钟</text>
|
||||
</view>
|
||||
<view class="flex ai-c jc-sb pb10">
|
||||
<text style="color: rgb(175, 175, 175);">合格标准</text>
|
||||
<text>90分及格(满分100分)</text>
|
||||
</view>
|
||||
<view class="flex ai-c jc-sb">
|
||||
<text style="color: rgb(175, 175, 175);">出题规则</text>
|
||||
<text>根据公安部出题规则组卷</text>
|
||||
</view>
|
||||
</view>
|
||||
<text>模拟考试不能修改答案,每错1题扣{{subject=='1'?1:2}}分,错题累计超过{{subject=='1'?10:5}}道,考试不通过</text>
|
||||
</view>
|
||||
<view class="p14lr wp100" style="margin-top: 30px;">
|
||||
<u-button :customStyle="{width: '100%',borderRadius:'40rpx',backgroundColor:'#05C341',color:'#fff'}" text="开始考试"
|
||||
@click="submit" />
|
||||
</view>
|
||||
<view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import storage from '@/jtools/storage';
|
||||
import useQuestionStore from '@/jtools/store/question' //引入store
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
carName:storage.get('carName') ||'小车C1/C2/C3',
|
||||
questionList: '',
|
||||
subject:'1',
|
||||
}
|
||||
},
|
||||
onLoad(op) {
|
||||
if (op.questionIdList) {
|
||||
this.questionList = op.questionIdList
|
||||
}
|
||||
if(op.subject){
|
||||
this.subject = op.subject
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useQuestionStore, ["currentCarName"]), //映射函数,取出tagslist
|
||||
user() {
|
||||
return useUserStore().userInfo
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
submit(){
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/practiceExams?title=模拟考试&subject=" + this.subject + "&questionIdList=" + this.questionList
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
358
src/pages/index/trueTest.vue
Normal file
@@ -0,0 +1,358 @@
|
||||
<template>
|
||||
<view class="ml40 p10lr hp100 bc-f5" style="overflow-y: auto;">
|
||||
<view class="flex" style="align-items: stretch;">
|
||||
<view class="left hp100">
|
||||
<view class="fl1 flex" style="align-items: stretch;">
|
||||
<view class="info">
|
||||
<view class="flex ai-c jc-c mr10 fs16" style="border: 1px solid #999;height: 32px;">
|
||||
第01考台
|
||||
</view>
|
||||
<view class="mt10 p10tb" style="background-color: rgb(177, 222, 255);">
|
||||
<view style="margin: 0 auto;width: 64px;">
|
||||
<u-avatar :size="64" mp-avatar shape="circle"></u-avatar>
|
||||
</view>
|
||||
</view>
|
||||
<view class="p10" style="background-color: rgb(235, 235, 235);">
|
||||
<view class="flex ai-c">
|
||||
<text class="fs12 cor-333">姓名</text>
|
||||
<view class="fl1 info-box">{{ user.userName }}{{ user.userId }}</view>
|
||||
</view>
|
||||
<view class="flex ai-c mt5">
|
||||
<text class="fs12 cor-333">类型</text>
|
||||
<view class="fl1 info-box">小车</view>
|
||||
</view>
|
||||
<view class="flex ai-c mt5">
|
||||
<text class="fs12 cor-333">科目</text>
|
||||
<view class="fl1 info-box">科目一</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="fl1 question-box">
|
||||
<view class="fs14 cor-000">
|
||||
{{questionIndex}} {{question.question}}
|
||||
</view>
|
||||
<view v-if="question.type != 1" v-for="(item, idx) in question.optionList" :key="idx"
|
||||
class="mt5 fs14 cor-000">
|
||||
{{item.op}}: {{item.opDesc}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="ans-box">
|
||||
<view class="flex ai-c">
|
||||
<view class="time">
|
||||
<!-- <text class="mt7">45:00</text> -->
|
||||
<u-count-down ref="countDown" :time="timeCount" format="mm:ss" @change="e=>this.time=e"
|
||||
@finish="timeFinish"></u-count-down>
|
||||
</view>
|
||||
<view class="ml20 fs16 cor-333 fwb">
|
||||
您的答案:
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="question.type==1" class="flex">
|
||||
<button class="btn" :class="{ done: question.yourAnswer==1 }" @tap="handleAnswer(1)">√</button>
|
||||
<button class="btn" :class="{ done: question.yourAnswer==2 }" @tap="handleAnswer(2)">×</button>
|
||||
</view>
|
||||
<view v-else class="flex">
|
||||
<template v-for="(item,index) in question.optionList" :key="index">
|
||||
<button class="btn" :class="{ done: question.yourAnswer.includes(index+1) }"
|
||||
@tap="handleAnswer(index+1)">{{['A','B','C','D','E','F','G'][index]}}</button>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right" style="border: 1px solid #999;;">
|
||||
<u-grid border :col="subject==1?10:5">
|
||||
<u-grid-item v-for="(listItem,listIndex) in list" :key="listIndex" style="box-sizing: border-box;">
|
||||
<view class="q-item" :class="{ 'current-question': questionIndex==listIndex+1, done: listItem.yourAnswer }"
|
||||
@tap="questionIndex=listIndex+1">{{listIndex+1}}</view>
|
||||
</u-grid-item>
|
||||
</u-grid>
|
||||
</view>
|
||||
</view>
|
||||
<view class="operate-box">
|
||||
<view class="fl1">
|
||||
<view class="fs16" style="height: 20px;line-height: 20px;color: rgb(232, 72, 75);">
|
||||
操作提示:{{['','判断题','单选题','多选题'][question.type]}}
|
||||
</view>
|
||||
<view class="fs14 cor-333" style="height: 20px;line-height: 20px;">
|
||||
本题是{{getDesc(question.type)}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex">
|
||||
<button :disabled="questionIndex==1" class="btn" @tap="questionIndex--">上一题</button>
|
||||
<button :disabled="questionIndex==list.length" class="btn" @tap="questionIndex++">下一题</button>
|
||||
<button class="btn" @tap="handleConfirm">交卷</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="img-box">
|
||||
<image style="height: 100%;" mode="heightFix" :src="question.imageUrl"></image>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import useQuestionStore from '@/jtools/store/question' //引入store
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import {
|
||||
getTestQuestion,
|
||||
submitTest
|
||||
} from '@/jtools/api/question';
|
||||
import storage from '@/jtools/storage';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
subject:'1',
|
||||
questionIndex: 1,
|
||||
list: [],
|
||||
mutiAns: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useQuestionStore, ["orderQuestion_subject1", "orderQuestion_subject4", "version"]), //映射函数,取出tagslis
|
||||
user() {
|
||||
return useUserStore().userInfo
|
||||
},
|
||||
question() {
|
||||
if (this.questionIndex != 0 && this.list.length) {
|
||||
return this.list[this.questionIndex - 1]
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
timeCount() {
|
||||
return this.subject == 1 ? 60 * 60 * 1000 : 45 * 60 * 1000
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.fz()
|
||||
},
|
||||
onLoad(option) {
|
||||
this.subject = option.subject || 1
|
||||
if(option.questionIdList){
|
||||
const idList=JSON.parse(option.questionIdList)
|
||||
let arr = this[`orderQuestion_subject${this.subject}`].filter(qItem=>idList.includes(qItem.questionId))
|
||||
this.list = arr.map(it => ({
|
||||
...it,
|
||||
yourAnswer: ''
|
||||
}))
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fz() {
|
||||
wx.setPageOrientation({
|
||||
orientation: 'landscape'
|
||||
});
|
||||
},
|
||||
// _getList() {
|
||||
// getTestQuestion({
|
||||
// carTypeId: storage.get('carType') || '1001',
|
||||
// subject: this.subject
|
||||
// }).then(resp => {
|
||||
// if (resp.code === '0000') {
|
||||
// this.list = resp.data.map(it => ({
|
||||
// ...it,
|
||||
// yourAnswer: ''
|
||||
// }))
|
||||
// }
|
||||
// })
|
||||
// },
|
||||
handleAnswer(index) {
|
||||
// 如果是多选
|
||||
let q = this.list[this.questionIndex - 1]
|
||||
if (q.type == 3) {
|
||||
let arr = q.yourAnswer ? q.yourAnswer.split(',') : []
|
||||
arr.includes(index + '') ? arr = arr.filter(it => it != (index + '')) : arr.push(index)
|
||||
this.list[this.questionIndex - 1].yourAnswer = arr.join(',')
|
||||
} else {
|
||||
this.list[this.questionIndex - 1].yourAnswer = index + ''
|
||||
}
|
||||
},
|
||||
getDesc(type) {
|
||||
let tt1 = ['', '判断题,', '单选题,', '多选题,'][type]
|
||||
let tt2 = ['', '请判断对错!', '请在备选答案中选择你认为正确的答案!', '请在备选答案中选择多个你认为正确的答案!'][type]
|
||||
return tt1 + tt2
|
||||
},
|
||||
|
||||
handleConfirm() {
|
||||
const wdLength = this.list.filter(it => !it.yourAnswer).length
|
||||
if (wdLength) {
|
||||
uni.showModal({
|
||||
title: '考试确认窗口',
|
||||
content: `您还有${wdLength}题未答,是否确认交卷?`,
|
||||
confirmText: '确认交卷',
|
||||
cancelText: '继续考试',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
this.toSubmit()
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '考试确认窗口',
|
||||
content: `是否确认交卷?`,
|
||||
confirmText: '确认交卷',
|
||||
cancelText: '继续考试',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
this.toSubmit()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
timeFinish() {
|
||||
uni.showToast({
|
||||
title: "考试结束,将为您自动交卷~",
|
||||
icon: 'none'
|
||||
})
|
||||
setTimeout(() => {
|
||||
this.toSubmit()
|
||||
}, 1000)
|
||||
},
|
||||
toSubmit() {
|
||||
const restTime = this.time.hours * 60 * 60 + this.time.minutes * 60 + this.time.seconds
|
||||
const score = this.list.reduce((pre, cur) => {
|
||||
const isTrue = cur.trueAnswer == cur.yourAnswer.replace(/,-g/, '')
|
||||
let s = 0
|
||||
if (isTrue) {
|
||||
s = this.subject == 1 ? 1 : 2
|
||||
}
|
||||
return pre + s
|
||||
}, 0)
|
||||
submitTest({
|
||||
"carTypeId": storage.get('carType') || '1001',
|
||||
"score": score,
|
||||
"testTime": 60 * 60 - restTime,
|
||||
subject: this.subject
|
||||
}).then(resp => {
|
||||
uni.showToast({
|
||||
title: '考试结束!',
|
||||
icon: 'none',
|
||||
complete() {
|
||||
uni.navigateBack()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.left {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.info {
|
||||
width: 100px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.info-box {
|
||||
margin-left: 5px;
|
||||
padding-left: 5px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
box-shadow: inset 2px 2px 5px #babecc, inset -5px -5px 10px #fff;
|
||||
font-size: 10px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.question-box {
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
border-top: 1px solid #999;
|
||||
border-left: 1px solid #999;
|
||||
}
|
||||
|
||||
.ans-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 50px;
|
||||
border-top: 1px solid #999;
|
||||
|
||||
.time {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 90px;
|
||||
height: 32px;
|
||||
line-height: 16px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
border: 1px solid #999;
|
||||
|
||||
&::before {
|
||||
content: '剩余时间';
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
top: 0;
|
||||
background-color: #f5f5f5;
|
||||
font-size: 10px;
|
||||
color: #333;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 270px;
|
||||
|
||||
.q-item {
|
||||
width: 28px;
|
||||
height: 27px;
|
||||
font-size: 10px;
|
||||
line-height: 27px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.operate-box {
|
||||
padding-left: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
border-top: 2px solid rgb(43, 102, 167);
|
||||
border-bottom: 2px solid rgb(43, 102, 167);
|
||||
border-left: 1px solid #999;
|
||||
border-right: 1px solid #999;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-right: 10px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
// background-color: rgb(244, 243, 239);
|
||||
font-size: 14px;
|
||||
box-shadow:
|
||||
0 0 4px rgba(0, 0, 0, .4),
|
||||
// -7px -7px 12px rgba(255, 255, 255, .9);
|
||||
}
|
||||
|
||||
.img-box {
|
||||
height: 120px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
.current-question {
|
||||
background-color: #93F0E4;
|
||||
}
|
||||
|
||||
.done {
|
||||
background-color: #33FF66;
|
||||
}
|
||||
</style>
|
||||
@@ -1,38 +1,75 @@
|
||||
<template>
|
||||
<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-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.price}}</text>
|
||||
</view>
|
||||
<text class="fs12 cor-999">长期有效</text>
|
||||
<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 style="height: 100%;overflow: scroll;background-color: #fff;">
|
||||
<image style="width: 100%;height: 600rpx;" src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/vip%E9%A2%98%E5%BA%93_20230911211532.png"></image>
|
||||
<view style="margin-bottom: 100px;">
|
||||
<view class="flex jc-fa ai-c wp100 p14">
|
||||
<view style="width: 33.3%;" v-for="(item, index) of priceList" :key="index">
|
||||
<view class="option_tem relative" :class="checkedId === item.memberId ? 'checked_item' : ''" @click="checkPrice(item.memberId, item.price)">
|
||||
<text class="fw600 fs12 cor-333">{{ item.memberName }}</text>
|
||||
<view class="mt5" v-if="!isIOS">
|
||||
<text class="fs14" style="color: #FF6E02;">¥</text>
|
||||
<text class="fs30 fw600" style="color: #FF6E02;">{{ item.price }}</text>
|
||||
</view>
|
||||
<view v-else class="mt5">
|
||||
<text class="fs14" style="color: #FF6E02;">iOS暂不支持</text>
|
||||
</view>
|
||||
<text class="fs12 cor-999">一年有效</text>
|
||||
<!-- <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>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt15 intr_box">
|
||||
<view class="fw600 fs16 cor-000">免费获赠<text style="color: #FF6E02;">价值68元</text>的VIP题库</view>
|
||||
<view class="flex ai-c jc-sb mt15">
|
||||
<view class="flex ai-c">
|
||||
<image style="width: 63rpx;height: 63rpx;margin-right: 5px;" src="../../static/image/index/vip500.png"></image>
|
||||
<view class="vip_item">含精简500题</view>
|
||||
</view>
|
||||
<view class="flex ai-c">
|
||||
<image style="width: 63rpx;height: 63rpx;margin-right: 5px;" src="../../static/image/index/vipmijuan.png"></image>
|
||||
<view class="vip_item">含考前密卷2套</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="intr_box p14">
|
||||
<view class="fw600 fs16 cor-000">尊享以下权益</view>
|
||||
<view class="flex ai-c jc-sb mt15" v-if="subject == '1' || subject == '4'">
|
||||
<view class="text-center" style="width: 33%">
|
||||
<view class="wp100 flex ai-c jc-c mb5">
|
||||
<image style="width: 63rpx;height: 63rpx;margin-right: 5px;" src="../../static/image/index/vip500.png"></image>
|
||||
</view>
|
||||
<text>精简{{ titleNum }}题</text>
|
||||
</view>
|
||||
<view class="text-center" style="width: 33%;">
|
||||
<view class="wp100 flex ai-c jc-c mb5">
|
||||
<image style="width: 63rpx;height: 63rpx;margin-right: 5px;" src="../../static/image/index/vip_trueRoom.png"></image>
|
||||
</view>
|
||||
<text>真实考场模拟</text>
|
||||
</view>
|
||||
<view class="text-center" style="width: 33%;">
|
||||
<view class="wp100 flex ai-c jc-c mb5">
|
||||
<image style="width: 63rpx;height: 63rpx;margin-right: 5px;" src="../../static/image/index/vipmijuan.png"></image>
|
||||
</view>
|
||||
<text>考前密卷</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="flex ai-c jc-c mt15">
|
||||
<view class="flex ai-c">
|
||||
<image style="width: 63rpx;height: 63rpx;margin-right: 5px;" src="../../static/image/index/vip_ksxj.png"></image>
|
||||
<view class="vip_item">考试项目详解</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex ai-c mt20">
|
||||
<view class="contain-box relative">
|
||||
<image class="contain-box" src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/%E5%B0%8F%E8%BD%A6_20230911211545.png"></image>
|
||||
</view>
|
||||
<view class="ml15" style="text-align: left;">
|
||||
<view class="cor-333 fw600">考试项目详解</view>
|
||||
<view class="fs15 mt10" style="color: #9F826C ;">考试实操技巧讲解事半功倍</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="wp100 mt15" v-if="subject == '1' || subject == '4'">
|
||||
<image class="wp100" mode="widthFix" :src="picUrl"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="wp100 p14" style="position: absolute;left: 0;bottom:20px" @tap="handlePay()">
|
||||
</view>
|
||||
<view v-if="!isIOS" 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>
|
||||
<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>
|
||||
</view>
|
||||
</view>
|
||||
@@ -40,149 +77,197 @@
|
||||
</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{
|
||||
subject:'1',
|
||||
loading:true,
|
||||
nowPrice:168,
|
||||
checkedId:0,
|
||||
priceList:[],
|
||||
order:{
|
||||
money:0.01,
|
||||
description:'会员充值'
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(op){
|
||||
if(op.subject){
|
||||
this.subject=op.subject
|
||||
}
|
||||
this.loading=true
|
||||
this.getVipList()
|
||||
this.getWXOpenId()
|
||||
this.$set(this.order, 'userId', this.userInfo.userId);
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore, ["userInfo"])
|
||||
},
|
||||
methods:{
|
||||
handlePay(){
|
||||
console.log(this.order);
|
||||
if(this.loading){
|
||||
this.loading=false
|
||||
new Pay('wechat', this.order);
|
||||
}
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import { getVipList } from '@/jtools/api/vip'
|
||||
import { querySysConfig } from '@/jtools/api/question';
|
||||
import storage from '@/jtools/storage';
|
||||
import Pay from '@/jtools/pay/index.js';
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
picUrl: '',
|
||||
titleNum: 500,
|
||||
subject: '1',
|
||||
loading: true,
|
||||
nowPrice: 168,
|
||||
checkedId: 0,
|
||||
priceList: [],
|
||||
order: {
|
||||
money: 0,
|
||||
description: '会员充值'
|
||||
},
|
||||
getWXOpenId() {
|
||||
const that = this
|
||||
uni.login({
|
||||
success(res) {
|
||||
that.$set(that.order, 'code', res.code);
|
||||
}
|
||||
})
|
||||
},
|
||||
getVipList(){
|
||||
getVipList({
|
||||
currentCartype: storage.get('carType') || '1001',
|
||||
subject:this.subject
|
||||
}).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
|
||||
isIOS: true
|
||||
}
|
||||
},
|
||||
onLoad(op) {
|
||||
this.isIOS = this.$platform.device().includes('ios')
|
||||
if (op.subject) {
|
||||
this.subject = op.subject
|
||||
}
|
||||
this.loading = true
|
||||
this.getVipList()
|
||||
this.getWXOpenId()
|
||||
this.getTitle()
|
||||
this.getPic()
|
||||
this.$set(this.order, 'userId', this.userInfo.userId);
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore, ["userInfo"])
|
||||
},
|
||||
methods: {
|
||||
getPic() {
|
||||
const currentCartype = storage.get('carType') || '1001'
|
||||
querySysConfig(currentCartype, 'VipDescImageUrl').then(res => {
|
||||
this.picUrl = JSON.parse(res.data.configJson).url
|
||||
})
|
||||
},
|
||||
getTitle() {
|
||||
const carId = storage.get('carType') || '1001'
|
||||
querySysConfig(carId, 'SimplifyQuestionNum').then(resp => {
|
||||
if (resp.code === '0000') {
|
||||
const list = JSON.parse(resp.data.configJson)
|
||||
this.titleNum = list.find(item => item.subject == this.subject).num
|
||||
}
|
||||
})
|
||||
},
|
||||
async handlePay() {
|
||||
if (this.loading) {
|
||||
this.loading = false
|
||||
await this.getWXOpenId()
|
||||
new Pay('wechat', this.order);
|
||||
this.loading = true
|
||||
}
|
||||
},
|
||||
getWXOpenId() {
|
||||
const that = this
|
||||
uni.login({
|
||||
success(res) {
|
||||
that.$set(that.order, 'code', res.code);
|
||||
}
|
||||
})
|
||||
},
|
||||
getVipList() {
|
||||
getVipList({
|
||||
carTypeId: storage.get('carType') || '1001',
|
||||
subject: this.subject
|
||||
}).then(resp => {
|
||||
if (resp.code === '0000') {
|
||||
this.priceList = resp.data
|
||||
this.checkedId = this.priceList[0].memberId
|
||||
this.order.outTradeNo = this.priceList[0].memberId
|
||||
this.order.money = this.priceList[0].price
|
||||
this.nowPrice = this.priceList[0].price
|
||||
this.priceList.forEach(item => {
|
||||
if (item.subjects.length > 1) {
|
||||
item.all = true
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
checkPrice(val,price){
|
||||
this.checkedId=val
|
||||
this.order.outTradeNo=val
|
||||
this.nowPrice=price
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
checkPrice(val, price) {
|
||||
this.checkedId = val
|
||||
this.order.outTradeNo = val
|
||||
this.nowPrice = price
|
||||
this.order.money = price
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.option_tem{
|
||||
width: 220rpx;
|
||||
height: 241rpx;
|
||||
text-align: center;
|
||||
background: #FFFFFF;
|
||||
border: 2px solid #D8D8D8;
|
||||
border-radius: 16rpx 46rpx 16rpx 16rpx;
|
||||
padding: 14px;
|
||||
}
|
||||
.checked_item{
|
||||
width: 228rpx;
|
||||
background: #FFF0E5;
|
||||
border: 4px solid #FF6E02;
|
||||
}
|
||||
.bottom_box{
|
||||
width: 214rpx;
|
||||
height: 40rpx;
|
||||
line-height: 40rpx;
|
||||
text-align: center;
|
||||
background: rgb(239,239,239);
|
||||
border-radius: 0 0 16rpx 16rpx;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
.checked_bottom{
|
||||
width: 218rpx;
|
||||
border-radius: 0 0 16rpx 12rpx;
|
||||
background-color: #FF6E02;
|
||||
color:#fff
|
||||
}
|
||||
.tag{
|
||||
width: 122rpx;
|
||||
height: 36rpx;
|
||||
background: linear-gradient(90deg, #E66501 0%, #F8A42C 100%);
|
||||
border-radius: 8rpx 20rpx 8rpx 8rpx;
|
||||
line-height: 36rpx;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #FFFC27;
|
||||
position: absolute;
|
||||
left: 10rpx;
|
||||
top:-18rpx
|
||||
}
|
||||
.intr_box{
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 40rpx;
|
||||
background: #FFF0E5;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
.vip_item{
|
||||
width: 208rpx;
|
||||
height: 54rpx;
|
||||
line-height: 54rpx;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
background: #F3D7C2;
|
||||
border-radius: 0rpx 10rpx 10rpx 10rpx;
|
||||
}
|
||||
.sub_btn{
|
||||
width:100%;
|
||||
height: 110rpx;
|
||||
border: 4px solid #F59B26;
|
||||
background: linear-gradient(0deg, #E66501 0%, #F8A42C 100%);
|
||||
box-shadow: 0rpx 16rpx 20rpx 1rpx rgba(245,155,38,0.78);
|
||||
border-radius: 55rpx;
|
||||
padding: 14rpx;
|
||||
}
|
||||
.option_tem {
|
||||
width: 220rpx;
|
||||
height: 241rpx;
|
||||
text-align: center;
|
||||
background: #FFFFFF;
|
||||
border: 2px solid #D8D8D8;
|
||||
border-radius: 16rpx 46rpx 16rpx 16rpx;
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.checked_item {
|
||||
background: #FFF0E5;
|
||||
border: 4px solid #FF6E02;
|
||||
}
|
||||
|
||||
.bottom_box {
|
||||
width: 214rpx;
|
||||
height: 40rpx;
|
||||
line-height: 40rpx;
|
||||
text-align: center;
|
||||
background: rgb(239, 239, 239);
|
||||
border-radius: 0 0 16rpx 16rpx;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.checked_bottom {
|
||||
width: 218rpx;
|
||||
border-radius: 0 0 16rpx 5rpx;
|
||||
background-color: #FF6E02;
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.tag {
|
||||
padding: 0 5px;
|
||||
height: 36rpx;
|
||||
background: linear-gradient(90deg, #E66501 0%, #F8A42C 100%);
|
||||
border-radius: 8rpx 20rpx 8rpx 8rpx;
|
||||
line-height: 36rpx;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #FFFC27;
|
||||
position: absolute;
|
||||
left: 10rpx;
|
||||
top: -18rpx
|
||||
}
|
||||
|
||||
.intr_box {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 40rpx;
|
||||
background: #FFF0E5;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.vip_item {
|
||||
width: 208rpx;
|
||||
height: 54rpx;
|
||||
line-height: 54rpx;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
background: #F3D7C2;
|
||||
border-radius: 0rpx 10rpx 10rpx 10rpx;
|
||||
}
|
||||
|
||||
.sub_btn {
|
||||
width: 100%;
|
||||
height: 110rpx;
|
||||
border: 4px solid #F59B26;
|
||||
background: linear-gradient(0deg, #E66501 0%, #F8A42C 100%);
|
||||
box-shadow: 0rpx 16rpx 20rpx 1rpx rgba(245, 155, 38, 0.78);
|
||||
border-radius: 55rpx;
|
||||
padding: 14rpx;
|
||||
}
|
||||
|
||||
.contain-box {
|
||||
width: 344rpx;
|
||||
height: 196rpx;
|
||||
background: #00B74F;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.play_btn_2 {
|
||||
width: 65rpx;
|
||||
height: 65rpx;
|
||||
position: absolute;
|
||||
left: 165.5rpx;
|
||||
top: 78rpx
|
||||
}
|
||||
</style>
|
||||
@@ -1,19 +1,19 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="header">
|
||||
<image src="/static/image/login/logo.jpg" mode="widthFix"></image>
|
||||
<view class="mt21 fs16 cor-333 fwb text-center">欢迎使用金联武驾考!</view>
|
||||
<image src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/%E9%87%91%E6%AD%A6%E8%81%94_20230831123333.png" mode="widthFix"></image>
|
||||
<view class="mt21 fs16 cor-333 fwb text-center">欢迎使用金武联驾考!</view>
|
||||
</view>
|
||||
|
||||
<view class="list">
|
||||
<view class="list-call">
|
||||
<u-input class="sl-input" border="none" v-model="login.phone" type="number" maxlength="11"
|
||||
<u-input class="sl-input" border="none" v-model="loginForm.phone" type="number" maxlength="11"
|
||||
placeholder="输入手机号" />
|
||||
</view>
|
||||
<view class="list-call">
|
||||
<u-input class="sl-input" v-model="login.code" type="text" maxlength="6" border="none" placeholder="输入验证码">
|
||||
<u-input class="sl-input" v-model="loginForm.code" type="text" maxlength="6" border="none" placeholder="输入验证码">
|
||||
<template #suffix>
|
||||
<text class="fs14 mr10" style="color: #05C341;" @tap="getCode">{{countDown==0?'获取验证码':countDown}}</text>
|
||||
<text class="fs14 mr10" style="color: #05C341;" @tap="getCode">{{ countDown == 0 ? '获取验证码' : countDown }}</text>
|
||||
</template>
|
||||
</u-input>
|
||||
</view>
|
||||
@@ -27,136 +27,142 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
isPhone
|
||||
} from '@/jtools/utils/validate.js'
|
||||
import {
|
||||
getCode,
|
||||
login
|
||||
} from '@/jtools/api/login'
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
login: {
|
||||
phone: '',
|
||||
code: ''
|
||||
},
|
||||
countDown: 0,
|
||||
js: undefined
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
if(useUserStore().isLogin) {
|
||||
this.toHome()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCode() {
|
||||
if (isPhone(this.login.phone) && this.countDown == 0) {
|
||||
getCode({
|
||||
phone: this.login.phone
|
||||
}).then(resp => {
|
||||
// if (resp.code == '0000') {
|
||||
uni.showToast({
|
||||
title: '发送成功!',
|
||||
icon: 'none'
|
||||
})
|
||||
this.countDown = 60
|
||||
this.js = setInterval(() => {
|
||||
this.countDown--;
|
||||
if (this.countDown == 0) {
|
||||
this.clear()
|
||||
}
|
||||
}, 1000)
|
||||
// }
|
||||
import {
|
||||
isPhone
|
||||
} from '@/jtools/utils/validate.js'
|
||||
import {
|
||||
getCode,
|
||||
login
|
||||
} from '@/jtools/api/login'
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import storage from '@/jtools/storage';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loginForm: {
|
||||
phone: '',
|
||||
code: ''
|
||||
},
|
||||
countDown: 0,
|
||||
js: undefined
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
if (useUserStore().isLogin) {
|
||||
this.toHome()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCode() {
|
||||
if (isPhone(this.loginForm.phone) && this.countDown == 0) {
|
||||
getCode({
|
||||
phone: this.loginForm.phone
|
||||
}).then(resp => {
|
||||
// if (resp.code == '0000') {
|
||||
uni.showToast({
|
||||
title: '发送成功!',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
},
|
||||
clear() {
|
||||
clearInterval(js)
|
||||
this.js = null
|
||||
this.countDown = 0
|
||||
},
|
||||
bindLogin() {
|
||||
if(isPhone(this.login.phone) && this.login.code) {
|
||||
useUserStore().login(this.login).then(resp => {
|
||||
if(resp.userId) {
|
||||
this.toHome()
|
||||
this.countDown = 60
|
||||
this.js = setInterval(() => {
|
||||
this.countDown--;
|
||||
if (this.countDown == 0) {
|
||||
this.clear()
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
toHome() {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
}, 1000)
|
||||
// }
|
||||
})
|
||||
}
|
||||
},
|
||||
clear() {
|
||||
clearInterval(js)
|
||||
this.js = null
|
||||
this.countDown = 0
|
||||
},
|
||||
bindLogin() {
|
||||
if (isPhone(this.loginForm.phone) && this.loginForm.code) {
|
||||
let params = { ...this.loginForm }
|
||||
if (storage.get('companyId')) {
|
||||
params.id = storage.get('companyId')
|
||||
}
|
||||
useUserStore().login(params).then(resp => {
|
||||
if (resp.userId) {
|
||||
useUserStore().getUserInfo()
|
||||
useUserStore().searchUserVip()
|
||||
this.toHome()
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
toHome() {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background-color: #fff;
|
||||
}
|
||||
page {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-top: 166rpx;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
letter-spacing: 10rpx;
|
||||
}
|
||||
.header {
|
||||
margin-top: 166rpx;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
letter-spacing: 10rpx;
|
||||
}
|
||||
|
||||
.header image {
|
||||
width: 383rpx;
|
||||
}
|
||||
.header image {
|
||||
width: 383rpx;
|
||||
}
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-top: 120rpx;
|
||||
padding-left: 90rpx;
|
||||
padding-right: 90rpx;
|
||||
}
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-top: 120rpx;
|
||||
padding-left: 90rpx;
|
||||
padding-right: 90rpx;
|
||||
}
|
||||
|
||||
.list-call {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 100rpx;
|
||||
color: #333333;
|
||||
border-bottom: 0.5px solid #e2e2e2;
|
||||
}
|
||||
.list-call {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 100rpx;
|
||||
color: #333333;
|
||||
border-bottom: 0.5px solid #e2e2e2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.list-call .sl-input {
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
font-size: 32rpx;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
|
||||
.button-login {
|
||||
color: #FFFFFF;
|
||||
font-size: 34rpx;
|
||||
width: 560rpx;
|
||||
height: 100rpx;
|
||||
background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%);
|
||||
border-radius: 50rpx;
|
||||
line-height: 100rpx;
|
||||
text-align: center;
|
||||
margin-top: 100rpx;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.list-call .sl-input {
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
font-size: 32rpx;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
|
||||
.button-login {
|
||||
color: #FFFFFF;
|
||||
font-size: 34rpx;
|
||||
width: 560rpx;
|
||||
height: 100rpx;
|
||||
background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%);
|
||||
border-radius: 50rpx;
|
||||
line-height: 100rpx;
|
||||
text-align: center;
|
||||
margin-top: 100rpx;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
</style>
|
||||
99
src/pages/me/changeCarType.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="p14">
|
||||
<view class="wp100 p14lr p20tb bc-fff br8 mb10 relative" style="box-sizing: border-box;" :class="checkedCar==item.carTypeId?'checked':''" v-for="(item,index) of carTypeList" :key="index" @click="changeType(item)">{{item.carName}}{{item.remark}}
|
||||
<view class="p5 cor-fff fs12 br4" style="background-color:#05C341;position: absolute;right: -1rpx;top:-1rpx" v-if="checkedCar==item.carTypeId">已选</view>
|
||||
</view>
|
||||
<view class="wp100" style="margin-top: 40px;">
|
||||
<u-button :customStyle="{width: '100%',borderRadius:'40rpx',backgroundColor:'#05C341',color:'#fff'}" text="确定"
|
||||
@click="submit" />
|
||||
</view>
|
||||
<u-modal :show="show" title="提示" content="切换题库后上一个题库练习记录将会全部清空,确定要切换吗" showCancelButton @confirm="confirmSubmit" @cancel="cancel"></u-modal>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import {
|
||||
getCarTypeList,
|
||||
} from '@/jtools/api/index';
|
||||
import storage from '@/jtools/storage';
|
||||
import useQuestionStore from '@/jtools/store/question' //引入store
|
||||
export default{
|
||||
data() {
|
||||
return{
|
||||
show:false,
|
||||
carTypeList:[],
|
||||
checkedCar: storage.get('carType') ||'1001',
|
||||
checkedCarName:storage.get('carName') || '小车C1/C2/C3'
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getCarTypeList()
|
||||
},
|
||||
computed:{
|
||||
...mapState(useQuestionStore, ["loading_subject4", "loading_subject1","curSubject"]), //映射函数,取出tagslist
|
||||
getLoading() {
|
||||
return this.loading_subject4 && this.loading_subject1
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
getLoading(newVal){
|
||||
console.log(newVal);
|
||||
if(newVal){
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title:'切换成功!'
|
||||
})
|
||||
this.cancel()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getCarTypeList(){
|
||||
getCarTypeList().then(resp=>{
|
||||
if(resp.code==='0000'){
|
||||
this.carTypeList=resp.data
|
||||
}
|
||||
})
|
||||
},
|
||||
changeType(item){
|
||||
this.checkedCar=item.carTypeId
|
||||
this.checkedCarName=item.carName+item.remark
|
||||
},
|
||||
submit(){
|
||||
const id=storage.get('carType') ||'1001'
|
||||
if(this.checkedCar==id){
|
||||
uni.showToast({
|
||||
title:'当前已是该车型题库!',
|
||||
icon:'error'
|
||||
})
|
||||
}else{
|
||||
this.show=true
|
||||
}
|
||||
},
|
||||
cancel(){
|
||||
this.show=false
|
||||
},
|
||||
confirmSubmit(){
|
||||
storage.set('carType',this.checkedCar)
|
||||
storage.set('carName',this.checkedCarName)
|
||||
uni.showLoading({
|
||||
title: '加载中'
|
||||
});
|
||||
useQuestionStore().resetStorage()
|
||||
useQuestionStore().getAllQuestion()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.checked{
|
||||
border: 6rpx solid #05C341;
|
||||
}
|
||||
</style>
|
||||
@@ -2,16 +2,19 @@
|
||||
<view class="bc-f5">
|
||||
<!-- <view class="wp100" style="background-color: #333;height: 205px;"></view> -->
|
||||
<view class="relative" style="height: 205px;">
|
||||
<image src="/static/image/mine/mine_bg.png" mode="widthFix" style="width: 100%;"></image>
|
||||
<image src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/vip%E8%83%8C%E6%99%AF%E7%BB%BF_20230831010645.png" mode="widthFix" style="width: 100%;"></image>
|
||||
<view class="info flex ai-c" v-if="isLogin">
|
||||
<u-avatar class="br-p50 overflow-h" :size="64" mp-avatar shape="circle"></u-avatar>
|
||||
<view class="ml12">
|
||||
<view class="flex ai-c fs18 cor-333 fwb">
|
||||
<text class="mr10">{{ user.userName }}{{ user.userId }}</text>
|
||||
<image v-if="vipOn.length" src="/static/image/mine/vip.png" mode="widthFix" style="width: 18px;"></image>
|
||||
<image v-if="vipOn.length" src="../../static/image/mine/vip.png" mode="widthFix" style="width: 18px;"></image>
|
||||
</view>
|
||||
<view class="mt5 fs14 cor-666">陪您学车 第{{ user.days }}天</view>
|
||||
</view>
|
||||
<view v-if="canRecieve" class="ml20 p20" @tap="handleScan">
|
||||
<u-icon name="scan" size="40"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info flex ai-c" v-else @tap="toLogin">
|
||||
<u-avatar class="br-p50 overflow-h" :size="64" src="@/static/image/mine/default_avatar.png" shape="circle"></u-avatar>
|
||||
@@ -25,7 +28,7 @@
|
||||
</view>
|
||||
<view class="p15lr" style="transform: translateY(-90px);">
|
||||
<view class="relative mb10" @tap="handleVip">
|
||||
<image src="/static/image/mine/vip_bg.png" mode="widthFix" style="width: 100%;"></image>
|
||||
<image src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/vip%E8%83%8C%E6%99%AF%E9%BB%841_20230831010645.png" mode="widthFix" style="width: 100%;"></image>
|
||||
<view class="absolute p15lr p10tb flex ai-c jc-sb" style="left: 0;top: 0;right: 0;height: 40px;">
|
||||
<view class="flex ai-c">
|
||||
<view class="p3 br-p50" style="background-color: #873E1D;">
|
||||
@@ -40,7 +43,7 @@
|
||||
<view v-if="!isLogin || !vipOn.length" class="text-center">
|
||||
<view class="fs18 fwb" style="color: #7E4012FF;">开通VIP尊享以下权益</view>
|
||||
<view class="fs15" style="color: #7E4012FF;">精选500题 / 真是模考 / 考前密卷</view>
|
||||
<view class="study fs16 text-center" style="margin: 25px auto 0;color: #F6E99FFF;">立即开通</view>
|
||||
<view class="study fs16 text-center" style="margin: 25px auto 0;color: #F6E99FFF;">{{ isIOS ? 'iOS暂不可用' : '立即开通' }}</view>
|
||||
</view>
|
||||
<view v-else-if="vipOn.length" class="text-center">
|
||||
<view class="fs18 fwb" style="color: #7E4012FF;">{{ vipText }}</view>
|
||||
@@ -75,17 +78,27 @@
|
||||
<template #icon>
|
||||
<img src="/static/image/mine/wdzl.png" style="width: 24px;height: 24px;">
|
||||
</template>
|
||||
</u-cell>
|
||||
<u-cell size="large" title="我的奖品" isLink @tap="handleGift">
|
||||
<template #icon>
|
||||
<u-icon size="24" name="gift"></u-icon>
|
||||
</template>
|
||||
</u-cell>
|
||||
<u-cell size="large" title="我的体检" isLink @tap="handleTJ">
|
||||
<template #icon>
|
||||
<img src="/static/image/mine/wdtj.png" style="width: 24px;height: 24px;">
|
||||
</template>
|
||||
</u-cell>
|
||||
<u-cell size="large" title="我的题库" value="小车">
|
||||
<u-cell size="large" title="我的题库" :value="carName" @tap="toChangeCarType">
|
||||
<template #icon>
|
||||
<img src="/static/image/mine/wdtk.png" style="width: 24px;height: 24px;">
|
||||
</template>
|
||||
</u-cell>
|
||||
<u-cell size="large" title="联系我们" @tap="callPhoneNumber">
|
||||
<template #icon>
|
||||
<img src="/static/image/mine/callme.png" style="width: 24px;height: 24px;">
|
||||
</template>
|
||||
</u-cell>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
<view v-if="isLogin" class="flex ai-c jc-c mt12 br8 bc-fff" style="height: 50px;" @tap="handleLogout">
|
||||
@@ -96,8 +109,9 @@
|
||||
</template>
|
||||
<script>
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import storage from '@/jtools/storage';
|
||||
import { receiveWinner,canRecieveGift } from '@/jtools/api/activity'
|
||||
export default {
|
||||
components: {},
|
||||
computed: {
|
||||
isLogin() {
|
||||
return useUserStore().isLogin
|
||||
@@ -136,17 +150,46 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
carName: storage.get('carName') || '小车C1/C2/C3',
|
||||
isIOS: true,
|
||||
canRecieve: false
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.isIOS = this.$platform.device().includes('ios')
|
||||
this.carName = storage.get('carName') || '小车C1/C2/C3'
|
||||
this.searchActivityAuth()
|
||||
},
|
||||
methods: {
|
||||
searchActivityAuth() {
|
||||
canRecieveGift({
|
||||
phone: useUserStore().userInfo?.phone || ''
|
||||
}).then(resp => {
|
||||
if(resp.code == 200) {
|
||||
this.canRecieve = resp.data
|
||||
}
|
||||
})
|
||||
},
|
||||
// 拨打电话
|
||||
callPhoneNumber() {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: '15105693067'
|
||||
});
|
||||
},
|
||||
toChangeCarType() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/me/changeCarType"
|
||||
})
|
||||
},
|
||||
handleVip() {
|
||||
if (this.isIOS) {
|
||||
return
|
||||
}
|
||||
if (this.isLogin) {
|
||||
// if (this.vipOn.length) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/vip'
|
||||
})
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/vip'
|
||||
})
|
||||
// } else {
|
||||
// uni.navigateTo({
|
||||
// url: '/pages/index/videoVip'
|
||||
@@ -181,8 +224,12 @@ export default {
|
||||
},
|
||||
handleTJ() {
|
||||
if (this.isLogin) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/tijian'
|
||||
// uni.navigateTo({
|
||||
// url: '/pages/me/tijian'
|
||||
// })
|
||||
uni.showToast({
|
||||
title: '敬请期待',
|
||||
icon: 'none'
|
||||
})
|
||||
} else {
|
||||
this.toLogin()
|
||||
@@ -196,6 +243,30 @@ export default {
|
||||
handleLogout() {
|
||||
useUserStore().logout()
|
||||
},
|
||||
handleGift() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/myGift'
|
||||
})
|
||||
},
|
||||
handleScan() {
|
||||
uni.scanCode({
|
||||
scanType: ['qrCode'],
|
||||
success(res) {
|
||||
console.log('条码内容:' + res.result);
|
||||
receiveWinner({
|
||||
id: res.result,
|
||||
receiveUser: useUserStore().userInfo?.phone || []
|
||||
}).then(resp => {
|
||||
if(resp.code == 200) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '核销成功!'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,29 +1,50 @@
|
||||
<template>
|
||||
<view class="p15 bc-f5">
|
||||
<view class="br8 bc-fff p15lr">
|
||||
<view class="flex ai-c bb1" style="height: 110rpx;">
|
||||
<view class="flex jc-sb ai-c bb1" style="height: 110rpx;">
|
||||
<view class="title">联系电话</view>
|
||||
<view class="m30lr fs14 cor-333 fl1">15122305568</view>
|
||||
<u-icon name="arrow-right" color="#999" />
|
||||
<view class="flex">
|
||||
<view class="m30lr fs14 cor-333">15122305568</view>
|
||||
<u-icon name="arrow-right" color="#999" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex ai-c" style="height: 110rpx;">
|
||||
<view class="flex jc-sb ai-c bb1" style="height: 110rpx;">
|
||||
<view class="title">地址</view>
|
||||
<view class="m30lr fs14 cor-333 fl1">安徽省合肥市包河区</view>
|
||||
<u-icon name="arrow-right" color="#999" />
|
||||
<view class="flex">
|
||||
<view class="m30lr fs14 cor-333">安徽省合肥市包河区</view>
|
||||
<u-icon name="arrow-right" color="#999" />
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="flex jc-sb ai-c bb1" style="height: 110rpx;">
|
||||
<view class="title">身份证号</view>
|
||||
<view class="m30lr fs14 cor-333">{{sfzNum}}</view>
|
||||
</view>
|
||||
<view class="flex ai-c" style="height: 110rpx;" @tap="toUploadPic">
|
||||
<view class="title">证件照</view>
|
||||
<view class="m30lr fs14 cor-333 fl1"></view>
|
||||
<u-icon name="arrow-right" color="#999" />
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from '@/jtools/storage';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
sfzNum:storage.get('sfzNum') || ''
|
||||
}
|
||||
},
|
||||
onShow(){
|
||||
this.sfzNum=storage.get('sfzNum') || ''
|
||||
},
|
||||
methods: {
|
||||
|
||||
toUploadPic(){
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/uploadPic'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
89
src/pages/me/myGift.vue
Normal file
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<view class="p10lr p20tb">
|
||||
<u-list @scrolltolower="loadmore">
|
||||
<u-list-item v-for="(item, index) in list" :key="index" class="item">
|
||||
<view class="relative">
|
||||
<img src="/static/image/mine/giftitem.png" style="width: 100%;" mode="widthFix" alt="" />
|
||||
<view class="ab_full df ai-c jcc">{{item.awards}}</view>
|
||||
</view>
|
||||
<view class="df ai-c jcsb p20tb p10lr">
|
||||
<view class="item-label">
|
||||
<view>活动名称:{{ item.activityName }}</view>
|
||||
<view>参与时间:{{ item.createTime }}</view>
|
||||
<view>有效期至:{{ item.endTime }}</view>
|
||||
</view>
|
||||
<view class="ml20" style="width: 120rpx;">
|
||||
<img v-if="item.status" src="/static/image/mine/writeoff.png" style="width: 120rpx;height: 120rpx;" />
|
||||
<view v-else class="btn" @tap="handleWriteoff(item)">核销</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import { getLuckyRecord } from '@/jtools/api/activity'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pageNum: 1,
|
||||
list: []
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.pageNum = 1
|
||||
this.list = []
|
||||
this.handleSearch()
|
||||
},
|
||||
methods: {
|
||||
handleSearch() {
|
||||
getLuckyRecord({
|
||||
phone: useUserStore().userInfo.phone,
|
||||
pageSize: 10,
|
||||
pageNum: this.pageNum
|
||||
}).then(resp => {
|
||||
if(resp.code == 200) {
|
||||
if(resp.rows && resp.rows.length) {
|
||||
this.list = [...this.list, ...resp.rows]
|
||||
} else {
|
||||
this.pageNum = this.pageNum > 1 ? this.pageNum-1 : 1
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
loadmore() {
|
||||
this.handleSearch(this.pageNum++)
|
||||
},
|
||||
handleWriteoff(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/me/qrCode?id=${item.id}`
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.item {
|
||||
margin-bottom: 30rpx;
|
||||
border-radius: 36rpx;
|
||||
background-color: #fff;
|
||||
.item-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
line-height: 48rpx;
|
||||
}
|
||||
.btn {
|
||||
width: 120rpx;
|
||||
height: 68rpx;
|
||||
text-align: center;
|
||||
line-height: 68rpx;
|
||||
border-radius: 34rpx;
|
||||
background-color: #BE1200;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
26
src/pages/me/qrCode.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<view class="df jcc" style="padding-top: 100px;">
|
||||
<qrcode v-if="value" :value="value" :size="200"/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import qrcode from '/src/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.vue'
|
||||
export default {
|
||||
components: {
|
||||
qrcode
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.value = option.id
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -1,42 +1,214 @@
|
||||
<template>
|
||||
<view class="p15 bc-f5">
|
||||
<view class="br8 bc-fff p15lr">
|
||||
<view class="flex ai-c bb1" style="height: 110rpx;">
|
||||
<view class="title">体检结果</view>
|
||||
<view class="ml30 fs14 cor-333 fl1">通过</view>
|
||||
</view>
|
||||
<view class="flex ai-c" style="height: 110rpx;">
|
||||
<view class="title">体检时间</view>
|
||||
<view class="ml30 fs14 cor-333 fl1">2023-08-10 14:35:23</view>
|
||||
</view>
|
||||
<view class="flex ai-fs" style="height: 110rpx;">
|
||||
<view class="title">体检时间</view>
|
||||
<image class="ml30" src="/static/image/mine/tijian.png" style="width: 333rpx;" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="">
|
||||
<view class="wp100 bc-fff p14">
|
||||
<view class="title fontColor">第一步 上传学员图像</view>
|
||||
<view class="mt15">
|
||||
<!-- <u-upload width="165" height="165" :file-list=" fileList1" multiple :max-count="1" @afterRead="afterRead" @delete="deletePic" /> -->
|
||||
<!-- <u-upload ref="uUpload" class="mt25" :size-type="['compressed']" :file-list="fileList1" deletable :multiple="false" :max-count="1" width="165rpx" height="165rpx" @afterRead="afterRead" @delete="deletePic" /> -->
|
||||
<view style="width: 320rpx;height:300rpx;background-color: rgb(247, 255, 255);border-radius: 20rpx;">
|
||||
<view style="width: 320rpx;height:240rpx;" class="flex jc-c ai-c">
|
||||
<image v-if="fileList&&fileList.length" style="width: 240rpx;height: 240rpx;" :src="fileList[0].url">
|
||||
</image>
|
||||
<u-avatar v-else class="br-p50 overflow-h" :size="64" mp-avatar shape="circle"></u-avatar>
|
||||
</view>
|
||||
<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" multiple :maxCount="1" width="150"
|
||||
height="150">
|
||||
<view
|
||||
style="width: 320rpx;height:60rpx;line-height:60rpx;background-color: #05C341;border-radius: 0 0 20rpx 20rpx;"
|
||||
class="text-center cor-fff">
|
||||
点击
|
||||
</view>
|
||||
</u-upload>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt20">
|
||||
<view class="title fontColor">第二步 核实后再提交</view>
|
||||
<u--form labelPosition="left" labelWidth="80" :model="form" :rules="rules" ref="form1">
|
||||
<u-form-item label="姓名" :required="true" prop="idCardName" borderBottom ref="item1">
|
||||
<u--input v-model="form.idCardName" border="none"></u--input>
|
||||
</u-form-item>
|
||||
<u-form-item label="身份证号" :required="true" prop="sfzmhm" borderBottom ref="item2">
|
||||
<u--input v-model="form.sfzmhm" border="none"></u--input>
|
||||
</u-form-item>
|
||||
</u--form>
|
||||
</view>
|
||||
<view style="margin-top: 20px;">
|
||||
<u-button type="primary" :style="{width: '100%',borderRadius:'40rpx',backgroundColor:'#05C341'}" :disabled="saving" text="提交"
|
||||
@click="submit" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
import storage from '@/jtools/storage';
|
||||
import {
|
||||
addInfo,
|
||||
} from '@/jtools/api/index';
|
||||
export default {
|
||||
data() {
|
||||
const shenfenzhen = (rule, value, callback) => {
|
||||
/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value) ? callback() : callback(
|
||||
new Error('请输入正确的身份证号'))
|
||||
}
|
||||
return {
|
||||
form: {
|
||||
idCardName: '',
|
||||
sfzmhm: ''
|
||||
},
|
||||
driverLicenseImg:'',
|
||||
fileList:[],
|
||||
fileList1: [],
|
||||
uploadList: [],
|
||||
saving: false,
|
||||
rules: {
|
||||
idCardName: [{
|
||||
required: true,
|
||||
message: '请输入姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
sfzmhm: [{
|
||||
required: true,
|
||||
message: '请输入身份证号',
|
||||
trigger: ['blur', 'change']
|
||||
},{
|
||||
// 自定义验证函数,见上说明
|
||||
validator: shenfenzhen,
|
||||
message: '身份证号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['change', 'blur'],
|
||||
}]
|
||||
}
|
||||
};
|
||||
},
|
||||
onReady() {
|
||||
this.$refs.form1.setRules(this.rules);
|
||||
},
|
||||
methods: {
|
||||
// 删除图片
|
||||
deletePic(event) {
|
||||
this.fileList1.splice(event.index, 1);
|
||||
this.uploadList.splice(event.index, 1);
|
||||
},
|
||||
// 新增图片
|
||||
async afterRead(event) {
|
||||
let imageInfoObj = await uni.getImageInfo({src: event.file[0].url})
|
||||
console.log(imageInfoObj);
|
||||
if(imageInfoObj.width!=720&&imageInfoObj.height!=720){
|
||||
uni.showToast({
|
||||
icon:'error',
|
||||
title:'证件照尺寸有误'
|
||||
})
|
||||
this.fileList=[]
|
||||
return false
|
||||
}
|
||||
this.driverLicenseImg = this.urlTobase64(event.file[0].url)
|
||||
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
|
||||
const lists = [].concat(event.file);
|
||||
this.fileList=lists
|
||||
this.fileList1 = [];
|
||||
uni.showToast({
|
||||
title:'上传成功!'
|
||||
})
|
||||
},
|
||||
uploadFilePromise(url) {
|
||||
this.saving = true;
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
url: process.env.VUE_APP_BASE_API + 'mongodb/uploadFile', // 仅为示例,非真实的接口地址
|
||||
filePath: url,
|
||||
name: 'file',
|
||||
success: (res) => {
|
||||
// setTimeout(() => {
|
||||
resolve(JSON.parse(res.data).data);
|
||||
// }, 100);
|
||||
this.saving = false;
|
||||
},
|
||||
fail: () => {
|
||||
resolve(null);
|
||||
this.saving = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
// 提交
|
||||
submit() {
|
||||
this.$refs.form1.validate().then((valid) => {
|
||||
if (valid) {
|
||||
const param={
|
||||
driverLicenseImg:this.driverLicenseImg,
|
||||
...this.form,
|
||||
schoolOrgCode:'340103000700',
|
||||
operater:'1d08daf852cf4ee28f67cb583f538cbf'
|
||||
}
|
||||
addInfo(param).then(resp=>{
|
||||
uni.showToast({
|
||||
title:"提交成功!",
|
||||
duration:2000,
|
||||
})
|
||||
setTimeout(()=>{
|
||||
uni.navigateBack()
|
||||
},1000)
|
||||
})
|
||||
} else {
|
||||
console.log('验证失败');
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
urlTobase64(url){
|
||||
let base64=''
|
||||
console.log(url);
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.getFileSystemManager().readFile({
|
||||
filePath: url, //选择图片返回的相对路径
|
||||
encoding: 'base64', //编码格式
|
||||
success: res => { //成功的回调
|
||||
console.log(res);
|
||||
base64 = 'data:image/jpeg;base64,' + res.data //不加上这串字符,在页面无法显示的哦
|
||||
resolve(base64);
|
||||
},fail: (e) => {
|
||||
console.log("图片转换失败");
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.title {
|
||||
width: 120rpx;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
.bb1 {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
</style>
|
||||
.upload-img {
|
||||
width: 165rpx;
|
||||
height: 165rpx;
|
||||
border: 1px dashed #c4c4c4;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fontColor {
|
||||
color: #383838;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
::v-deep .u-textarea__count {
|
||||
background-color: #f9faf9 !important;
|
||||
}
|
||||
|
||||
::v-deep .u-upload__button>.u-icon>.u-icon__icon {
|
||||
font-size: 90rpx !important;
|
||||
}
|
||||
|
||||
::v-deep .u-button--square {
|
||||
border-radius: 40rpx !important;
|
||||
}
|
||||
::v-deep .u-button--primary{
|
||||
background-color: #05C341 !important;
|
||||
border-color: #05C341 !important;
|
||||
}
|
||||
</style>
|
||||
226
src/pages/me/uploadPic.vue
Normal file
@@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<view class="">
|
||||
<view class="wp100 bc-fff p14">
|
||||
<view class="title fontColor">第一步 上传学员图像</view>
|
||||
<view class="mt15">
|
||||
<!-- <u-upload width="165" height="165" :file-list=" fileList1" multiple :max-count="1" @afterRead="afterRead" @delete="deletePic" /> -->
|
||||
<!-- <u-upload ref="uUpload" class="mt25" :size-type="['compressed']" :file-list="fileList1" deletable :multiple="false" :max-count="1" width="165rpx" height="165rpx" @afterRead="afterRead" @delete="deletePic" /> -->
|
||||
<view style="width: 320rpx;height:300rpx;background-color: rgb(247, 255, 255);border-radius: 20rpx;">
|
||||
<view style="width: 320rpx;height:240rpx;" class="flex jc-c ai-c">
|
||||
<image v-if="fileList&&fileList.length" style="width: 240rpx;height: 240rpx;" :src="fileList[0].url">
|
||||
</image>
|
||||
<u-avatar v-else class="br-p50 overflow-h" :size="64" mp-avatar shape="circle"></u-avatar>
|
||||
</view>
|
||||
<u-upload :fileList="fileList1" :maxSize="500 * 1024" @oversize="oversize" @afterRead="afterRead"
|
||||
@delete="deletePic" multiple :maxCount="1" width="150" height="150">
|
||||
<view
|
||||
style="width: 320rpx;height:60rpx;line-height:60rpx;background-color: #05C341;border-radius: 0 0 20rpx 20rpx;"
|
||||
class="text-center cor-fff">
|
||||
点击
|
||||
</view>
|
||||
</u-upload>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt20">
|
||||
<view class="title fontColor">第二步 核实后再提交</view>
|
||||
<u--form labelPosition="left" labelWidth="80" :model="form" :rules="rules" ref="form1">
|
||||
<u-form-item label="姓名" :required="true" prop="idCardName" borderBottom ref="item1">
|
||||
<u--input v-model="form.idCardName" border="none"></u--input>
|
||||
</u-form-item>
|
||||
<u-form-item label="身份证号" :required="true" prop="sfzmhm" borderBottom ref="item2">
|
||||
<u--input v-model="form.sfzmhm" border="none"></u--input>
|
||||
</u-form-item>
|
||||
</u--form>
|
||||
</view>
|
||||
<view style="margin-top: 20px;">
|
||||
<u-button type="primary" :style="{width: '100%',borderRadius:'40rpx',backgroundColor:'#05C341'}"
|
||||
:disabled="saving" text="提交" @click="submit" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from '@/jtools/storage';
|
||||
import {
|
||||
addInfo,
|
||||
} from '@/jtools/api/index';
|
||||
export default {
|
||||
data() {
|
||||
const shenfenzhen = (rule, value, callback) => {
|
||||
/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value) ? callback() : callback(
|
||||
new Error('请输入正确的身份证号'))
|
||||
}
|
||||
return {
|
||||
form: {
|
||||
idCardName: '',
|
||||
sfzmhm: storage.get('sfzNum') || ''
|
||||
},
|
||||
driverLicenseImg: '',
|
||||
fileList: [],
|
||||
fileList1: [],
|
||||
uploadList: [],
|
||||
saving: false,
|
||||
rules: {
|
||||
idCardName: [{
|
||||
required: true,
|
||||
message: '请输入姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
sfzmhm: [{
|
||||
required: true,
|
||||
message: '请输入身份证号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数,见上说明
|
||||
validator: shenfenzhen,
|
||||
message: '身份证号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['change', 'blur'],
|
||||
}]
|
||||
}
|
||||
};
|
||||
},
|
||||
onReady() {
|
||||
this.$refs.form1.setRules(this.rules);
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 文件超出大小限制
|
||||
oversize() {
|
||||
uni.showToast({
|
||||
title: "图片最大不能超过500k",
|
||||
icon: 'none'
|
||||
})
|
||||
},
|
||||
// 删除图片
|
||||
deletePic(event) {
|
||||
this.fileList1.splice(event.index, 1);
|
||||
this.uploadList.splice(event.index, 1);
|
||||
},
|
||||
// 新增图片
|
||||
async afterRead(event) {
|
||||
let imageInfoObj = await uni.getImageInfo({
|
||||
src: event.file[0].url
|
||||
})
|
||||
console.log(imageInfoObj);
|
||||
if (imageInfoObj.width != 260 && imageInfoObj.height != 378) {
|
||||
uni.showToast({
|
||||
icon: 'error',
|
||||
title: '证件照尺寸有误'
|
||||
})
|
||||
this.fileList = []
|
||||
return false
|
||||
}
|
||||
this.driverLicenseImg = await this.urlTobase64(event.file[0].url)
|
||||
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
|
||||
const lists = [].concat(event.file);
|
||||
this.fileList = lists
|
||||
this.fileList1 = [];
|
||||
uni.showToast({
|
||||
title: '上传成功!'
|
||||
})
|
||||
},
|
||||
// 提交
|
||||
submit() {
|
||||
this.$refs.form1.validate().then((valid) => {
|
||||
if (valid) {
|
||||
const param = {
|
||||
driverLicenseImg: this.driverLicenseImg,
|
||||
...this.form,
|
||||
schoolOrgCode: '340103000700',
|
||||
operater: '1d08daf852cf4ee28f67cb583f538cbf'
|
||||
}
|
||||
storage.set('sfzNum', this.form.sfzmhm)
|
||||
uni.request({
|
||||
url: 'https://www.hfcgs.cn:20223/driver/addInfo',
|
||||
method: 'POST',
|
||||
data: param,
|
||||
success: res => {
|
||||
console.log(res);
|
||||
uni.showToast({
|
||||
title: "提交成功!",
|
||||
duration: 2000,
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1000)
|
||||
},
|
||||
fail: () => {},
|
||||
|
||||
});
|
||||
// addInfo(param).then(resp=>{
|
||||
// if(resp.code==='0000'){
|
||||
// uni.showToast({
|
||||
// title:"提交成功!",
|
||||
// duration:2000,
|
||||
// })
|
||||
// setTimeout(()=>{
|
||||
// uni.navigateBack()
|
||||
// },1000)
|
||||
// }
|
||||
// })
|
||||
} else {
|
||||
console.log('验证失败');
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
urlTobase64(url) {
|
||||
let base64 = ''
|
||||
console.log(url);
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.getFileSystemManager().readFile({
|
||||
filePath: url, //选择图片返回的相对路径
|
||||
encoding: 'base64', //编码格式
|
||||
success: res => { //成功的回调
|
||||
console.log(res);
|
||||
base64 = 'data:image/jpeg;base64,' + res.data //不加上这串字符,在页面无法显示的哦
|
||||
resolve(base64);
|
||||
},
|
||||
fail: (e) => {
|
||||
console.log("图片转换失败");
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.upload-img {
|
||||
width: 165rpx;
|
||||
height: 165rpx;
|
||||
border: 1px dashed #c4c4c4;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fontColor {
|
||||
color: #383838;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
::v-deep .u-textarea__count {
|
||||
background-color: #f9faf9 !important;
|
||||
}
|
||||
|
||||
::v-deep .u-upload__button>.u-icon>.u-icon__icon {
|
||||
font-size: 90rpx !important;
|
||||
}
|
||||
|
||||
::v-deep .u-button--square {
|
||||
border-radius: 40rpx !important;
|
||||
}
|
||||
|
||||
::v-deep .u-button--primary {
|
||||
background-color: #05C341 !important;
|
||||
border-color: #05C341 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -1,312 +1,398 @@
|
||||
<template>
|
||||
<view class="flex fld-c p15">
|
||||
<u-sticky>
|
||||
<view class="flex ai-c">
|
||||
<view v-for="(item, index) in vipAllList" :key="index" class="km-item" :class="{ actived: index == current }"
|
||||
@click="current = index">
|
||||
{{ getKmTitle(item.subjects) }}
|
||||
</view>
|
||||
</view>
|
||||
</u-sticky>
|
||||
<view class="mt15">
|
||||
<swiper class="swiper" :current="current" style="height: 120px;" :autoplay="false" :display-multiple-items="1.45"
|
||||
:disable-programmatic-animation="true" @change="onChange">
|
||||
<swiper-item v-for="(item, index) in vipAllList" :key="index">
|
||||
<view class="relative">
|
||||
<image src="../../static/image/mine/vip_card.png" mode="widthFix" style="width:95%;"></image>
|
||||
<view class="vip-info">
|
||||
<u-avatar class="br-p50 overflow-h" style="border: 3px solid #873E1D;" :size="35" mp-avatar></u-avatar>
|
||||
<view class="ml10">
|
||||
<view class="fs16 fwb" style="color: #7E4012;line-height: 16px;">
|
||||
{{ item.memberName }}
|
||||
</view>
|
||||
<view class="mt5 fs12" style="color: #7E4012;line-height: 12px;">
|
||||
{{ getExpireText(item) }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="vipHasOpened(item)" class="corner">
|
||||
VIP已开通
|
||||
</view>
|
||||
<view v-if="vipHasOpened(item)" class="renew">
|
||||
{{ item.price }}元立即续费
|
||||
</view>
|
||||
<view v-else class="buy">
|
||||
立即充值
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
<view class="mt20">
|
||||
<swiper class="swiper" :current="current" style="height: 300px;" :autoplay="false"
|
||||
:disable-programmatic-animation="true" @change="onChange">
|
||||
<swiper-item v-for="(item, index) in vipAllList" :key="index">
|
||||
<view v-if="index == 0 || index == 3" class="p15 br8 cor-fff">
|
||||
<view class="fs18 cor-000 fwb">
|
||||
3步轻松学{{ getKmTitle(item.subjects) }}
|
||||
</view>
|
||||
<view class="mt25 flex ai-c jc-sb">
|
||||
<view class="flex ai-c">
|
||||
<image src="../../static/image/mine/1.png" mode="widthFix" style="width:25px;"></image>
|
||||
<view class="ml7">
|
||||
<view class="fs16 cor-000 fwb" style="line-height: 16px;">
|
||||
精简500题
|
||||
</view>
|
||||
<view class="mt7 fs12 cor-666" style="line-height: 12px;">
|
||||
题目全部做对,视为完成
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="study" @tap="to500(item)">
|
||||
去学习
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt45 flex ai-c jc-sb">
|
||||
<view class="flex ai-c">
|
||||
<image src="../../static/image/mine/2.png" mode="widthFix" style="width:25px;"></image>
|
||||
<view class="ml7">
|
||||
<view class="fs16 cor-000 fwb" style="line-height: 16px;">
|
||||
真实考场模拟
|
||||
</view>
|
||||
<view class="mt7 fs12 cor-666" style="line-height: 12px;">
|
||||
10次95分以上,视为完成
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="study" @tap="toRealExam(item)">
|
||||
去学习
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt45 flex ai-c jc-sb">
|
||||
<view class="flex ai-c">
|
||||
<image src="../../static/image/mine/3.png" mode="widthFix" style="width:25px;"></image>
|
||||
<view class="ml7">
|
||||
<view class="fs16 cor-000 fwb" style="line-height: 16px;">
|
||||
考前密卷
|
||||
</view>
|
||||
<view class="mt7 fs12 cor-666" style="line-height: 12px;">
|
||||
2套试卷95分以上,视为完成
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="study" @tap="toSpecExam(item)">
|
||||
去学习
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else style="margin-top: 30rpx;">
|
||||
<view class="video-box">
|
||||
<view class="flex jc-sb ai-c wp100">
|
||||
<text style="color: #873E1D;font-size: 36rpx;">考场实况</text>
|
||||
<text class="cor-666 fs12">全部 ></text>
|
||||
</view>
|
||||
<view class="flex ai-c mt20">
|
||||
<image src="../../static/image/index/index_bg.png" mode="widthFix" style="flex: 1;border-radius: 33rpx;"></image>
|
||||
<view class="ml18 text-center">
|
||||
<u-button :customStyle="{ width: '200rpx', height: '66rpx', borderRadius: '33rpx' }" iconColor="#fff"
|
||||
text="去看视频" color="linear-gradient(90deg, #E66501 0%, #F8A42C 100%)" icon="play-circle" @click="toPlaceLive(item)">
|
||||
</u-button>
|
||||
<view class="cor-333 fs15 mt17">真实考场模拟</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<u-loading-page :loading="getLoading" loading-text="题库更新中..."></u-loading-page>
|
||||
<view class="flex fld-c p15" v-if="!getLoading">
|
||||
<u-sticky>
|
||||
<view class="flex ai-c">
|
||||
<view v-for="(item, index) in vipAllList" :key="index" class="km-item" :class="{ actived: index == current }"
|
||||
@click="current = index">
|
||||
{{ getKmTitle(item.subjects) }}
|
||||
</view>
|
||||
</view>
|
||||
</u-sticky>
|
||||
<view class="mt15">
|
||||
<swiper class="swiper" :current="current" style="height: 120px;" :autoplay="false"
|
||||
:display-multiple-items="1.45" :disable-programmatic-animation="true" @change="onChange">
|
||||
<swiper-item v-for="(item, index) in vipAllList" :key="index">
|
||||
<view class="relative"
|
||||
style="background-image: url(https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/vip%E8%83%8C%E6%99%AF_20230831010348.png);width: 95%;height: 204rpx;background-size: 100% 100%;">
|
||||
<!-- <image src="" mode="widthFix" style="width:95%;"></image> -->
|
||||
<view class="vip-info">
|
||||
<u-avatar class="br-p50 overflow-h" style="border: 3px solid #873E1D;" :size="35" mp-avatar></u-avatar>
|
||||
<view class="ml10">
|
||||
<view class="fs16 fwb" style="color: #7E4012;line-height: 16px;">
|
||||
{{ item.memberName }}
|
||||
</view>
|
||||
<view class="mt5 fs12" style="color: #7E4012;line-height: 12px;">
|
||||
{{ getExpireText(item) }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="vipHasOpened(item)" class="corner">
|
||||
VIP已开通
|
||||
</view>
|
||||
<view v-if="vipHasOpened(item)" @tap="chargeVip(item)" class="renew">
|
||||
{{ item.price }}元立即续费
|
||||
</view>
|
||||
<view v-else class="buy" @tap="chargeVip(item)">
|
||||
立即充值
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
<view class="mt20">
|
||||
<swiper class="swiper" :current="current" style="height: 300px;" :autoplay="false"
|
||||
:disable-programmatic-animation="true" @change="onChange">
|
||||
<swiper-item v-for="(item, index) in vipAllList" :key="index">
|
||||
<view v-if="index == 0 || index == 3" class="p15 br8 cor-fff bc-fff">
|
||||
<view class="fs18 cor-000 fwb">
|
||||
3步轻松学{{ getKmTitle(item.subjects) }}
|
||||
</view>
|
||||
<view class="mt25 flex ai-c jc-sb">
|
||||
<view class="flex ai-c">
|
||||
<image src="../../static/image/mine/1.png" mode="widthFix" style="width:25px;"></image>
|
||||
<view class="ml7">
|
||||
<view class="fs16 cor-000 fwb" style="line-height: 16px;">
|
||||
精简500题
|
||||
</view>
|
||||
<view class="mt7 fs12 cor-666" style="line-height: 12px;">
|
||||
题目全部做对,视为完成
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="study" @tap="to500(item)">
|
||||
去学习
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt45 flex ai-c jc-sb">
|
||||
<view class="flex ai-c">
|
||||
<image src="../../static/image/mine/2.png" mode="widthFix" style="width:25px;"></image>
|
||||
<view class="ml7">
|
||||
<view class="fs16 cor-000 fwb" style="line-height: 16px;">
|
||||
真实考场模拟
|
||||
</view>
|
||||
<view class="mt7 fs12 cor-666" style="line-height: 12px;">
|
||||
10次95分以上,视为完成
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="study" @tap="toRealExam(item)">
|
||||
去学习
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt45 flex ai-c jc-sb">
|
||||
<view class="flex ai-c">
|
||||
<image src="../../static/image/mine/3.png" mode="widthFix" style="width:25px;"></image>
|
||||
<view class="ml7">
|
||||
<view class="fs16 cor-000 fwb" style="line-height: 16px;">
|
||||
考前密卷
|
||||
</view>
|
||||
<view class="mt7 fs12 cor-666" style="line-height: 12px;">
|
||||
2套试卷95分以上,视为完成
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="study" @tap="toSpecExam(item)">
|
||||
去学习
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else style="margin-top: 30rpx;">
|
||||
<view class="video-box">
|
||||
<view class="flex jc-sb ai-c wp100">
|
||||
<text style="color: #873E1D;font-size: 36rpx;">考场实况</text>
|
||||
<text class="cor-666 fs12">全部 ></text>
|
||||
</view>
|
||||
<view class="flex ai-c mt20">
|
||||
<view class="contain-box relative">
|
||||
<image class="contain-box" src="../../../static/image/index/jpsp.png"></image>
|
||||
<image class="play_btn_2" src="../../static/image/index/play.png" />
|
||||
</view>
|
||||
<view class="ml15 text-center">
|
||||
<u-button :customStyle="{width:'200rpx',height:'66rpx',borderRadius: '33rpx'}" iconColor="#fff"
|
||||
text="去看视频" color="linear-gradient(90deg, #E66501 0%, #F8A42C 100%)" icon="play-circle"
|
||||
@click="toPlaceLive(item)">
|
||||
</u-button>
|
||||
<view class="cor-333 fs15 fw600 mt10">真实考场模拟</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
export default {
|
||||
computed: {
|
||||
vipAllList() {
|
||||
return useUserStore().vipAllList.filter(it => [1, 2, 3, 4].includes(Number(it.subjects)))
|
||||
},
|
||||
vipOnList() {
|
||||
return useUserStore().vipOnList
|
||||
},
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import useQuestionStore from '@/jtools/store/question' //引入store
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import {
|
||||
queryQuestionId,
|
||||
getTestQuestionId
|
||||
} from '@/jtools/api/question';
|
||||
import storage from '@/jtools/storage';
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(useQuestionStore, ["loading_subject4", "loading_subject1", "version"]), //映射函数,取出tagslist
|
||||
getLoading() {
|
||||
return this.loading_subject4 && this.loading_subject1
|
||||
},
|
||||
vipAllList() {
|
||||
return useUserStore().vipAllList.filter(it => [1, 2, 3, 4].includes(Number(it.subjects)))
|
||||
},
|
||||
vipOnList() {
|
||||
return useUserStore().vipOnList
|
||||
},
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
current: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange(e) {
|
||||
this.current = e.detail.current
|
||||
},
|
||||
getKmTitle(km) {
|
||||
return {
|
||||
'1': '科一',
|
||||
'2': '科二',
|
||||
'3': '科三',
|
||||
'4': '科四',
|
||||
}[km]
|
||||
},
|
||||
getExpireText(item) {
|
||||
const vipOn = this.vipOnList.find(it => it.memberId == item.memberId)
|
||||
if (vipOn) {
|
||||
return `${vipOn.endDate.split(' ')[0]}到期`
|
||||
} else {
|
||||
return '开通vip助您快速拿证'
|
||||
}
|
||||
},
|
||||
vipHasOpened(item) {
|
||||
return !!this.vipOnList.find(it => it.memberId == item.memberId)
|
||||
},
|
||||
// 去精选500题 item=> 当前科目vip信息
|
||||
to500(item) {
|
||||
// 当前vip是否已开通
|
||||
if (this.vipHasOpened(item)) {
|
||||
// 跳转
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: `请先充值${this.getKmTitle(item.subjects)}vip`,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
},
|
||||
// 去真实考场 item=> 当前科目vip信息
|
||||
toRealExam(item) {
|
||||
// 当前vip是否已开通
|
||||
if (this.vipHasOpened(item)) {
|
||||
// 跳转
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: `请先充值${this.getKmTitle(item.subjects)}vip`,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
},
|
||||
// 去秘卷 item=> 当前科目vip信息
|
||||
toSpecExam(item) {
|
||||
// 当前vip是否已开通
|
||||
if (this.vipHasOpened(item)) {
|
||||
// 跳转
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: `请先充值${this.getKmTitle(item.subjects)}vip`,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
},
|
||||
// 去考场实况 item=> 当前科目vip信息
|
||||
toPlaceLive(item) {
|
||||
// 当前vip是否已开通
|
||||
if (this.vipHasOpened(item)) {
|
||||
// 跳转
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: `请先充值${this.getKmTitle(item.subjects)}vip`,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
current: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useQuestionStore, ['getOrderQuestion_sub1', 'getOrderQuestion_sub4', 'getAllQuestion']),
|
||||
chargeVip(item) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/index/videoVip?subject=" + item.subjects
|
||||
})
|
||||
},
|
||||
onChange(e) {
|
||||
this.current = e.detail.current
|
||||
},
|
||||
getKmTitle(km) {
|
||||
return {
|
||||
'1': '科一',
|
||||
'2': '科二',
|
||||
'3': '科三',
|
||||
'4': '科四',
|
||||
} [km]
|
||||
},
|
||||
getExpireText(item) {
|
||||
const vipOn = this.vipOnList.find(it => it.memberId == item.memberId)
|
||||
if (vipOn) {
|
||||
return `${vipOn.endDate.split(' ')[0]}到期`
|
||||
} else {
|
||||
return '开通vip助您快速拿证'
|
||||
}
|
||||
},
|
||||
vipHasOpened(item) {
|
||||
;
|
||||
return !!this.vipOnList.some(it => it.subjects.includes(item.subjects))
|
||||
},
|
||||
// 去精选500题 item=> 当前科目vip信息
|
||||
to500(item) {
|
||||
// 当前vip是否已开通
|
||||
if (this.vipHasOpened(item)) {
|
||||
// 跳转
|
||||
queryQuestionId({
|
||||
versionId: this.version,
|
||||
carTypeId: storage.get('carType') || '1001',
|
||||
subject: item.subjects,
|
||||
isVip: '1'
|
||||
}).then(async (resp) => {
|
||||
if (resp.code === '0000') {
|
||||
const arr = resp.data
|
||||
if (arr && arr.length) {
|
||||
const listJson = JSON.stringify(arr)
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/questionBank?navTitle=精简500题&subject=" + item.subjects +
|
||||
"&questionIdList=" + listJson
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '暂无题目',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} else if (resp.code === '4001') {
|
||||
uni.showToast({
|
||||
title: '当前题库非最新版,请更新~',
|
||||
icon: 'none'
|
||||
})
|
||||
this.getAllQuestion()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: `请先充值${this.getKmTitle(item.subjects)}vip`,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
},
|
||||
// 去真实考场 item=> 当前科目vip信息
|
||||
toRealExam(item) {
|
||||
// 当前vip是否已开通
|
||||
if (this.vipHasOpened(item)) {
|
||||
// 跳转
|
||||
uni.navigateTo({
|
||||
url: "/pages/index/trueTest?subject=" + item.subjects
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: `请先充值${this.getKmTitle(item.subjects)}vip`,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
},
|
||||
// 去秘卷 item=> 当前科目vip信息
|
||||
toSpecExam(item) {
|
||||
// 当前vip是否已开通
|
||||
if (this.vipHasOpened(item)) {
|
||||
// 跳转
|
||||
uni.navigateTo({
|
||||
url: "/pages/index/secretPapers?subject=" + item.subjects
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: `请先充值${this.getKmTitle(item.subjects)}vip`,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
},
|
||||
// 去考场实况 item=> 当前科目vip信息
|
||||
toPlaceLive(item) {
|
||||
// 当前vip是否已开通
|
||||
if (this.vipHasOpened(item)) {
|
||||
// 跳转
|
||||
uni.showToast({
|
||||
title: '敬请期待',
|
||||
icon: 'none'
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: `请先充值${this.getKmTitle(item.subjects)}vip`,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.km-item {
|
||||
margin-right: 8px;
|
||||
width: 72px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
border-radius: 15px;
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
.km-item {
|
||||
margin-right: 8px;
|
||||
width: 72px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
border-radius: 15px;
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
|
||||
.actived {
|
||||
background: linear-gradient(90deg, #E66501 0%, #F8A42C 100%);
|
||||
color: #fff;
|
||||
}
|
||||
.actived {
|
||||
background: linear-gradient(90deg, #E66501 0%, #F8A42C 100%);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.km-item:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
.km-item:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.vip-info {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.vip-info {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.corner {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 77px;
|
||||
height: 23px;
|
||||
background: linear-gradient(0deg, #E66501 0%, #F8A42C 100%);
|
||||
opacity: 0.86;
|
||||
border-radius: 0px 8px 0px 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
}
|
||||
.corner {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 77px;
|
||||
height: 23px;
|
||||
background: linear-gradient(0deg, #E66501 0%, #F8A42C 100%);
|
||||
opacity: 0.86;
|
||||
border-radius: 0px 8px 0px 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.renew {
|
||||
position: absolute;
|
||||
right: 10%;
|
||||
bottom: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 185rpx;
|
||||
height: 52rpx;
|
||||
background: #873E1D;
|
||||
border-radius: 26rpx;
|
||||
font-size: 12px;
|
||||
color: #F6E99F;
|
||||
}
|
||||
.renew {
|
||||
position: absolute;
|
||||
right: 10%;
|
||||
bottom: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 185rpx;
|
||||
height: 52rpx;
|
||||
background: #873E1D;
|
||||
border-radius: 26rpx;
|
||||
font-size: 12px;
|
||||
color: #F6E99F;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.buy {
|
||||
position: absolute;
|
||||
left: 45%;
|
||||
transform: translateX(-50%);
|
||||
bottom: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 200rpx;
|
||||
height: 60rpx;
|
||||
background: #873E1D;
|
||||
border-radius: 30rpx;
|
||||
font-size: 14px;
|
||||
color: #F6E99F;
|
||||
}
|
||||
.buy {
|
||||
position: absolute;
|
||||
left: 45%;
|
||||
transform: translateX(-50%);
|
||||
bottom: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 200rpx;
|
||||
height: 60rpx;
|
||||
background: #873E1D;
|
||||
border-radius: 30rpx;
|
||||
font-size: 14px;
|
||||
color: #F6E99F;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.study {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 161rpx;
|
||||
height: 67rpx;
|
||||
background: #F6E99F;
|
||||
border-radius: 34rpx;
|
||||
font-size: 12px;
|
||||
color: #873E1D;
|
||||
}
|
||||
.study {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 161rpx;
|
||||
height: 67rpx;
|
||||
background: #F6E99F;
|
||||
border-radius: 34rpx;
|
||||
font-size: 12px;
|
||||
color: #873E1D;
|
||||
}
|
||||
|
||||
.video-box {
|
||||
padding: 20rpx;
|
||||
width: 694rpx;
|
||||
height: 369rpx;
|
||||
background: #F9F3E7;
|
||||
border: 2rpx solid #CF8B6D;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
.video-box {
|
||||
padding: 20rpx;
|
||||
width: 694rpx;
|
||||
height: 369rpx;
|
||||
background: #F9F3E7;
|
||||
border: 2rpx solid #CF8B6D;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.contain-box {
|
||||
width: 406rpx;
|
||||
height: 228rpx;
|
||||
background: #00B74F;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.play_btn_2 {
|
||||
width: 65rpx;
|
||||
height: 65rpx;
|
||||
position: absolute;
|
||||
left: 165.5rpx;
|
||||
top: 78rpx
|
||||
}
|
||||
</style>
|
||||
@@ -1,18 +1,22 @@
|
||||
<template>
|
||||
<view>
|
||||
<j-navbar>基本操作</j-navbar>
|
||||
<u-sticky bgColor="#fff">
|
||||
<!-- <u-sticky bgColor="#fff">
|
||||
<u-tabs :list="categoryList" :scrollable="false" @click="changeCategory"></u-tabs>
|
||||
</u-sticky>
|
||||
</u-sticky> -->
|
||||
<view class="p14">
|
||||
<view class="flex ai-c">
|
||||
<!-- <view class="flex ai-c">
|
||||
<view class="car_item mr10" v-for="(item,index) of carTypeList" :key="index" @tap="chooseCar(item.value)" :class="item.value===tCar?'checked_car':'unchecked_car'">{{item.label}}</view>
|
||||
</view>
|
||||
<view class="flex p14 bc-fff mt10" style="border-radius: 16rpx;" v-for="(item,index) of videoList" :key="index" @tap="toDetail">
|
||||
<image class="pic" src="../../static/image/index/index_bg.png"></image>
|
||||
</view> -->
|
||||
<view class="flex p14lr p20tb bc-fff mb10" style="border-radius: 10rpx;"
|
||||
v-for="(item,index) of videoList" :key="index" @tap="toOperateDetail(item.videoId)">
|
||||
<view class="pic relative hide" style="overflow: hidden;">
|
||||
<image class="pic" style="position: absolute;left: 0;top:0" mode="widthFix" :src="item.videoUrl+'?x-oss-process=video/snapshot,t_0,f_jpg'"></image>
|
||||
<image class="play_btn_2" src="../../static/image/index/play.png" />
|
||||
</view>
|
||||
<view class="ml10">
|
||||
<text class="fs16 cor-000 fw600">上车、下车的方法</text>
|
||||
<view class="fs14 mt5 cor-666">上车、下车的方法</view>
|
||||
<text class="fs16 cor-000 fw600">{{allVideoList[0]?.description}}</text>
|
||||
<view class="fs14 mt5 cor-666">{{item.description}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -20,42 +24,92 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
querySysConfigList,
|
||||
queryProjectList
|
||||
} from '@/jtools/api/question';
|
||||
import storage from '@/jtools/storage';
|
||||
export default {
|
||||
data(){
|
||||
return{
|
||||
type:'2',
|
||||
subject:'1',
|
||||
tCar:0,
|
||||
categoryList:[{
|
||||
name:'手动挡C1'
|
||||
},{
|
||||
name:'自动挡C2'
|
||||
}],
|
||||
carTypeList:[{
|
||||
label:'捷达',
|
||||
value:0
|
||||
},{
|
||||
label:'新桑塔纳',
|
||||
value:1
|
||||
},{
|
||||
label:'爱丽舍',
|
||||
value:2
|
||||
}],
|
||||
videoList:[{
|
||||
label:"111"
|
||||
},{
|
||||
label:'222'
|
||||
},{
|
||||
label:'333'
|
||||
},{
|
||||
label:'444'
|
||||
}]
|
||||
allVideoList:[],
|
||||
videoList:[]
|
||||
}
|
||||
},
|
||||
onLoad(op){
|
||||
if(op.subject){
|
||||
this.subject=op.subject
|
||||
}
|
||||
if(op.type){
|
||||
this.type=op.type
|
||||
}
|
||||
this.getDiverType()
|
||||
},
|
||||
methods:{
|
||||
formateTime(time) {
|
||||
const h = parseInt(time / 3600)
|
||||
const minute = parseInt(time / 60 % 60)
|
||||
const second = Math.ceil(time % 60)
|
||||
const hours = h < 10 ? '0' + h : h
|
||||
const formatSecond = second > 59 ? 59 : second
|
||||
return `${hours > 0 ? `${hours}:` : ''}${minute < 10 ? '0' + minute : minute}:${formatSecond < 10 ? '0' + formatSecond : formatSecond}`
|
||||
},
|
||||
toOperateDetail(val){
|
||||
let arr = JSON.parse(JSON.stringify(this.allVideoList[0].videoList))
|
||||
arr = arr.map(item => {
|
||||
return {
|
||||
...item,
|
||||
subDesc:this.allVideoList[0].description,
|
||||
projectId:item.videoId,
|
||||
videoTime:this.formateTime(item.videoTime)
|
||||
}
|
||||
})
|
||||
let jsonString = JSON.stringify(arr)
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/videoDetail?videoList=" + jsonString + "&subject=" + this.subject +
|
||||
"&projectId=" + val + "&type=2"
|
||||
})
|
||||
},
|
||||
getOperateList() {
|
||||
queryProjectList({
|
||||
"carTypeId": storage.get('carType') || '1001',
|
||||
"subject": String(this.subject),
|
||||
"type": this.type
|
||||
}).then(resp => {
|
||||
if(resp.code==='0000'){
|
||||
this.videoList=resp.data[0]?resp.data[0].videoList:[]
|
||||
this.allVideoList=resp.data
|
||||
}
|
||||
})
|
||||
},
|
||||
getDiverType() {
|
||||
const carTypeId = storage.get('carType') || '1001'
|
||||
querySysConfigList(carTypeId, 'DriveType').then(resp => {
|
||||
if (resp.code === '0000') {
|
||||
this.categoryList=resp.data.map(item=>{
|
||||
return {
|
||||
...item,
|
||||
name:item.configItemName
|
||||
}
|
||||
})
|
||||
this.getOperateList()
|
||||
}
|
||||
})
|
||||
},
|
||||
chooseCar(val){
|
||||
this.tCar=val
|
||||
},
|
||||
changeCategory(val){
|
||||
|
||||
this.tCar=val.index
|
||||
this.getOperateList()
|
||||
},
|
||||
toDetail(){
|
||||
uni.navigateTo({
|
||||
@@ -91,6 +145,19 @@
|
||||
width: 300rpx;
|
||||
height: 169rpx;
|
||||
background: #00B74F;
|
||||
border-radius: 8rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
.play_btn_2 {
|
||||
width: 65rpx;
|
||||
height: 65rpx;
|
||||
position: absolute;
|
||||
left: 117.5rpx;
|
||||
top: 52rpx
|
||||
}
|
||||
.hide {
|
||||
backface-visibility: hidden;
|
||||
transform: translate3d(0, 0, 0);
|
||||
-webkit-backface-visibility: hidden;
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
}
|
||||
</style>
|
||||
@@ -1,28 +1,78 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="chapter_item p14" v-for="(item,index) of chapterList" :key="index" @tap="toQuestion(item.configItemCode)">
|
||||
{{item.configItemName}}
|
||||
<u-loading-page :loading="getLoading" loading-text="题库更新中..."></u-loading-page>
|
||||
<view v-if="!getLoading">
|
||||
<view class="chapter_item p14" v-for="(item,index) of chapterList" :key="index" @tap="toQuestion(item.configItemCode)">
|
||||
{{item.configItemName}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
querySysConfigList
|
||||
querySysConfigList,
|
||||
queryQuestionId
|
||||
} from '@/jtools/api/question';
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import useQuestionStore from '@/jtools/store/question' //引入store
|
||||
import storage from '@/jtools/storage';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
chapterList:[]
|
||||
chapterList:[],
|
||||
subject:'1'
|
||||
}
|
||||
},
|
||||
onLoad(){
|
||||
onLoad(op){
|
||||
if(op.subject){
|
||||
this.subject=op.subject
|
||||
}
|
||||
this.getChapterList()
|
||||
},
|
||||
computed: {
|
||||
...mapState(useQuestionStore, ["loading_subject4", "loading_subject1", "version"]), //映射函数,取出tagslist
|
||||
getLoading() {
|
||||
return this.loading_subject4 && this.loading_subject1
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
...mapActions(useQuestionStore, ['getAllQuestion']),
|
||||
getQuestion(param,title) {
|
||||
queryQuestionId({
|
||||
versionId: this.version,
|
||||
carTypeId: storage.get('carType') || '1001',
|
||||
subject: this.subject,
|
||||
...param,
|
||||
}).then(async (resp) => {
|
||||
if (resp.code === '0000') {
|
||||
if(resp.data&&resp.data.length){
|
||||
const arr = resp.data
|
||||
const listJson = JSON.stringify(arr)
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/questionBank?navTitle=" + title + "&subject=" + this.subject + "&questionIdList=" + listJson
|
||||
})
|
||||
}else{
|
||||
uni.showToast({
|
||||
title: '暂无题目',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}else if (resp.code === '4001') {
|
||||
uni.showToast({
|
||||
title: '当前题库非最新版,请更新~',
|
||||
icon: 'none'
|
||||
})
|
||||
this.getAllQuestion()
|
||||
}
|
||||
})
|
||||
},
|
||||
getChapterList(){
|
||||
const carTypeId=storage.get('carType') || '1001'
|
||||
const key=this.subject=='1'?'ChapterOfSubjectOne':'ChapterOfSubjectFour'
|
||||
querySysConfigList(carTypeId,'ChapterOfSubjectOne').then(resp=>{
|
||||
if(resp.code==='0000'){
|
||||
this.chapterList=resp.data
|
||||
@@ -30,9 +80,7 @@
|
||||
})
|
||||
},
|
||||
toQuestion(code){
|
||||
uni.navigateTo({
|
||||
url:"/pages/questionBank/questionBank?navTitle=章节技巧&chapter="+code
|
||||
})
|
||||
this.getQuestion({chapter:code},'章节技巧')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
<view class="wp100 text-center" style="margin-top: -153rpx;">
|
||||
<text v-if="score>=90">太棒了!正确率很高了!</text>
|
||||
<text v-else>很遗憾!考试不及格</text>
|
||||
<button class="centerBtn">马上提分</button>
|
||||
<button class="centerBtn" @click="toVip">马上提分</button>
|
||||
<view class="flex ai-c jc-c mt10">
|
||||
<view class="text-center wp33">
|
||||
<view>{{doNotNum}}</view>
|
||||
<text>未做题</text>
|
||||
</view>
|
||||
<view class="text-center wp33" @tap="toQuestionBank">
|
||||
<view>{{wrongList.length}}</view>
|
||||
<view>{{wrongList?.length}}</view>
|
||||
<text>看错题</text>
|
||||
</view>
|
||||
<view class="text-center wp33 flex jc-c ai-c" style="flex-direction: column;" @tap="toExams">
|
||||
@@ -48,6 +48,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import GradesChart from "./components/GradesChart.vue"
|
||||
import storage from '@/jtools/storage';
|
||||
import {
|
||||
@@ -103,6 +108,7 @@
|
||||
this.doNotNum=op.doNotNum
|
||||
}
|
||||
if(op.wrongList){
|
||||
console.log(op.wrongList);
|
||||
this.wrongList=JSON.parse(op.wrongList) || []
|
||||
}
|
||||
if(op.score){
|
||||
@@ -119,7 +125,31 @@
|
||||
onReady() {
|
||||
this.getServerData();
|
||||
},
|
||||
onUnload() {
|
||||
//#ifdef MP-WEIXIN
|
||||
uni.reLaunch({
|
||||
url:"/pages/index/index"
|
||||
})
|
||||
//#endif
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore, ["vipOnList"])
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useUserStore, ['searchUserVip']),
|
||||
async toVip(){
|
||||
await this.searchUserVip()
|
||||
const res = this.vipOnList.some(item => item.subjects.includes(this.subject))
|
||||
if(res){
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/vip'
|
||||
})
|
||||
}else{
|
||||
uni.navigateTo({
|
||||
url:"/pages/index/videoVip?subject="+this.subject
|
||||
})
|
||||
}
|
||||
},
|
||||
getServerData() {
|
||||
testTotal({
|
||||
"carTypeId": storage.get('carType') || '1001',
|
||||
@@ -144,10 +174,17 @@
|
||||
})
|
||||
},
|
||||
toQuestionBank(){
|
||||
const list =JSON.stringify(this.wrongList)
|
||||
uni.navigateTo({
|
||||
url:"/pages/questionBank/questionBank?navTitle=错题&subject="+this.subject+"&questionList="+list
|
||||
})
|
||||
if(this.wrongList.length==0){
|
||||
uni.showToast({
|
||||
title:'当前无错题~',
|
||||
icon:'none'
|
||||
})
|
||||
}else{
|
||||
const list =JSON.stringify(this.wrongList)
|
||||
uni.navigateTo({
|
||||
url:"/pages/questionBank/questionBank?navTitle=错题&subject="+this.subject+"&questionList="+list
|
||||
})
|
||||
}
|
||||
},
|
||||
//重新考试
|
||||
toExams(){
|
||||
|
||||
@@ -1,42 +1,48 @@
|
||||
<template>
|
||||
<view class="p14">
|
||||
<view class="flex jc-sb">
|
||||
<view class="relative mr5" @tap="toIconSkill">
|
||||
<image style="width: 336rpx;height: 152rpx;" src="../../static/image/practice/errorprone_bg.png">
|
||||
</image>
|
||||
<view style="position: absolute;left: 0;top: 0;" class="p10">
|
||||
<view style="color: #04B13B;font-size: 18px;">图标技巧</view>
|
||||
<text style="color: #04B13B;font-size: 14px;">快速记忆</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="relative ml5" @tap="toChapterSkill">
|
||||
<image style="width: 363rpx;height: 170rpx;" src="../../static/image/practice/chapter_bg.png"></image>
|
||||
<view style="position: absolute;left: 0;top: 0;" class="p10">
|
||||
<view style="color: #FF6E02;font-size: 18px;">章节练习</view>
|
||||
<text style="color: #FF6E02;font-size: 14px;">共5章</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bc-fff pt14" style="border-radius: 20rpx;">
|
||||
<u-grid :border="false" col="4">
|
||||
<u-grid-item v-for="(listItem,listIndex) in list" :key="listIndex" @click="toAnswer(listItem.title)">
|
||||
<view style="width: 84rpx;height: 84rpx;">
|
||||
<image style="width: 84rpx;" mode="widthFix" :src="listItem.image"></image>
|
||||
<view>
|
||||
<u-loading-page :loading="getLoading" loading-text="题库更新中..."></u-loading-page>
|
||||
<view class="p14" v-if="!getLoading">
|
||||
<view class="flex jc-sb">
|
||||
<view class="relative mr5" @tap="toIconSkill">
|
||||
<image style="width: 336rpx;height: 152rpx;" src="../../static/image/practice/errorprone_bg.png">
|
||||
</image>
|
||||
<view style="position: absolute;left: 0;top: 0;" class="p10">
|
||||
<view style="color: #04B13B;font-size: 18px;">图标技巧</view>
|
||||
<text style="color: #04B13B;font-size: 14px;">快速记忆</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="relative ml5" @tap="toChapterSkill">
|
||||
<image style="width: 363rpx;height: 170rpx;" src="../../static/image/practice/chapter_bg.png"></image>
|
||||
<view style="position: absolute;left: 0;top: 0;" class="p10">
|
||||
<view style="color: #FF6E02;font-size: 18px;">章节练习</view>
|
||||
<text style="color: #FF6E02;font-size: 14px;">共{{chapterNum}}章</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bc-fff pt14" style="border-radius: 20rpx;">
|
||||
<u-grid :border="false" col="4">
|
||||
<u-grid-item v-for="(listItem,listIndex) in list" :key="listIndex"
|
||||
@click="toAnswer(listItem.title,listItem.isError,listItem.isNew)">
|
||||
<view class="mb5" style="width: 84rpx;height: 84rpx;">
|
||||
<image style="width: 84rpx;height:84rpx;" mode="heightFix" :src="listItem.image"></image>
|
||||
</view>
|
||||
<text class="grid-text fs14 cor-000">{{listItem.title}}</text>
|
||||
<text class="grid-text mb10 fs12 cor-999">{{listItem.subTitle}}</text>
|
||||
</u-grid-item>
|
||||
</u-grid>
|
||||
</view>
|
||||
<view class="mt14 p14 bc-fff" style="border-radius: 20rpx;">
|
||||
<text class="fs18 cor-000 fw600">常见考点</text>
|
||||
<view class="flex ai-c wp100 mt10" style="flex-wrap: wrap;">
|
||||
<view class="wp50 flex ai-c p15tb" style="border-bottom: 1rpx solid #DDDCDC;"
|
||||
v-for="(item,index) of testCenterList" :key="index" @tap="toQuestionBank(item)">
|
||||
<view class="dot_item">{{index+1}}</view>
|
||||
<text class="ml5 topic_cont_text" style="width: calc(100% - 65rpx);">{{item.configItemName}}</text>
|
||||
</view>
|
||||
<text class="grid-text fs14 cor-000">{{listItem.title}}</text>
|
||||
<text class="grid-text mb10 fs12 cor-999">{{listItem.subTitle}}</text>
|
||||
</u-grid-item>
|
||||
</u-grid>
|
||||
</view>
|
||||
<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 mb25" v-for="(item,index) of testCenterList" :key="index" @tap="toQuestionBank(item)">
|
||||
<view class="dot_item">{{index+1}}</view>
|
||||
<text class="ml5">{{item.configItemName}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -44,88 +50,260 @@
|
||||
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 danxuanIcon from "../../static/image/index/danxuan.png"
|
||||
import panduanIcon from "../../static/image/index/panduan.png"
|
||||
import tupianIcon from "../../static/image/index/tupian.png"
|
||||
import {
|
||||
querySysConfigList,
|
||||
querySpecialNum,
|
||||
queryQuestionId
|
||||
} from '@/jtools/api/question';
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import useQuestionStore from '@/jtools/store/question' //引入store
|
||||
import storage from '@/jtools/storage';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
chapterNum:0,
|
||||
errorIcon,
|
||||
newRulesIcon,
|
||||
neverWriteIcon,
|
||||
list:[{
|
||||
title:'新规题',
|
||||
subTitle:'392题',
|
||||
image:newRulesIcon
|
||||
},{
|
||||
title:'易错题',
|
||||
subTitle:'392题',
|
||||
image:errorIcon
|
||||
},{
|
||||
title:'未做题',
|
||||
subTitle:'392题',
|
||||
image:neverWriteIcon
|
||||
},{
|
||||
title:'单选题',
|
||||
subTitle:'392题',
|
||||
image:newRulesIcon
|
||||
},{
|
||||
title:'判断题',
|
||||
subTitle:'392题',
|
||||
image:errorIcon
|
||||
},{
|
||||
title:'图片题',
|
||||
subTitle:'392题',
|
||||
image:neverWriteIcon
|
||||
list: [{
|
||||
title: '新规题',
|
||||
subTitle: '392题',
|
||||
isNew: 1,
|
||||
isError: 0,
|
||||
image: newRulesIcon
|
||||
}, {
|
||||
title: '易错题',
|
||||
isNew: 0,
|
||||
isError: 1,
|
||||
subTitle: '392题',
|
||||
image: errorIcon
|
||||
}, {
|
||||
title: '单选题',
|
||||
subTitle: '392题',
|
||||
isNew: 0,
|
||||
isError: 0,
|
||||
image: danxuanIcon
|
||||
}, {
|
||||
title: '判断题',
|
||||
subTitle: '392题',
|
||||
isNew: 0,
|
||||
isError: 0,
|
||||
image: panduanIcon
|
||||
}, {
|
||||
title: '图片题',
|
||||
subTitle: '392题',
|
||||
isNew: 0,
|
||||
isError: 0,
|
||||
image: tupianIcon
|
||||
}],
|
||||
testCenterList:[]
|
||||
testCenterList: [],
|
||||
subject: '1'
|
||||
}
|
||||
},
|
||||
onLoad(){
|
||||
onLoad(op) {
|
||||
if (op.subject) {
|
||||
this.subject = op.subject
|
||||
}
|
||||
this.getExamPoint()
|
||||
this.getQuestionNum()
|
||||
this.getChapterList()
|
||||
},
|
||||
computed: {
|
||||
...mapState(useQuestionStore, ["loading_subject4", "loading_subject1", "version"]), //映射函数,取出tagslist
|
||||
getLoading() {
|
||||
return this.loading_subject4 && this.loading_subject1
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getExamPoint(){
|
||||
...mapActions(useQuestionStore, ['getAllQuestion']),
|
||||
getChapterList(){
|
||||
const carTypeId=storage.get('carType') || '1001'
|
||||
querySysConfigList(carTypeId,'ExamKeys').then(resp=>{
|
||||
if(resp.code==='0000'){
|
||||
this.testCenterList=resp.data
|
||||
const key=this.subject=='1'?'ChapterOfSubjectOne':'ChapterOfSubjectFour'
|
||||
querySysConfigList(carTypeId,'ChapterOfSubjectOne').then(resp=>{
|
||||
if(resp.code==='0000'&&resp.data){
|
||||
this.chapterNum=resp.data.length
|
||||
}
|
||||
})
|
||||
},
|
||||
toAnswer(title) {
|
||||
uni.navigateTo({
|
||||
url:"/pages/questionBank/questionBank?navTitle="+title
|
||||
getQuestionNum() {
|
||||
querySpecialNum({
|
||||
carTypeId: storage.get('carType') || '1001',
|
||||
subject: this.subject
|
||||
}).then(resp => {
|
||||
if (resp.code === '0000') {
|
||||
if (this.subject == '1') {
|
||||
this.list = [{
|
||||
title: '新规题',
|
||||
subTitle: resp.data.newQuestionNum + '题',
|
||||
isNew: 1,
|
||||
isError: 0,
|
||||
image: newRulesIcon,
|
||||
}, {
|
||||
title: '易错题',
|
||||
isNew: 0,
|
||||
isError: 1,
|
||||
subTitle: resp.data.errorQuestionNum + '题',
|
||||
image: errorIcon,
|
||||
}, {
|
||||
title: '单选题',
|
||||
subTitle: resp.data.radioQuestionNum + '题',
|
||||
isNew: 0,
|
||||
isError: 0,
|
||||
image: danxuanIcon,
|
||||
}, {
|
||||
title: '判断题',
|
||||
subTitle: resp.data.judgeQuestionNum + '题',
|
||||
isNew: 0,
|
||||
isError: 0,
|
||||
image: panduanIcon,
|
||||
}, {
|
||||
title: '图片题',
|
||||
subTitle: resp.data.imageQuestionNum + '题',
|
||||
isNew: 0,
|
||||
isError: 0,
|
||||
image: tupianIcon,
|
||||
}]
|
||||
} else {
|
||||
this.list = [{
|
||||
title: '新规题',
|
||||
subTitle: resp.data.newQuestionNum + '题',
|
||||
isNew: 1,
|
||||
isError: 0,
|
||||
image: newRulesIcon
|
||||
}, {
|
||||
title: '易错题',
|
||||
isNew: 0,
|
||||
isError: 1,
|
||||
subTitle: resp.data.errorQuestionNum + '题',
|
||||
image: errorIcon,
|
||||
}, {
|
||||
title: '单选题',
|
||||
subTitle: resp.data.radioQuestionNum + '题',
|
||||
isNew: 0,
|
||||
isError: 0,
|
||||
image: danxuanIcon,
|
||||
}, {
|
||||
title: '多选题',
|
||||
subTitle: resp.data.multipleChoiceQuestionNum + '题',
|
||||
isNew: 0,
|
||||
isError: 0,
|
||||
image: neverWriteIcon
|
||||
}, {
|
||||
title: '判断题',
|
||||
subTitle: resp.data.judgeQuestionNum + '题',
|
||||
isNew: 0,
|
||||
isError: 0,
|
||||
image: panduanIcon,
|
||||
}, {
|
||||
title: '图片题',
|
||||
subTitle: resp.data.imageQuestionNum + '题',
|
||||
isNew: 0,
|
||||
isError: 0,
|
||||
image: tupianIcon,
|
||||
}]
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
toQuestionBank(val){
|
||||
uni.navigateTo({
|
||||
url:"/pages/questionBank/questionBank?navTitle="+val.configItemName+"&examKey="+val.configItemCode
|
||||
getExamPoint() {
|
||||
const carTypeId = storage.get('carType') || '1001'
|
||||
const examKey = this.subject == '1' ? 'ExamKeysOfSubjectOne' : 'ExamKeysOfSubjectFour'
|
||||
querySysConfigList(carTypeId, examKey).then(resp => {
|
||||
if (resp.code === '0000') {
|
||||
this.testCenterList = resp.data
|
||||
}
|
||||
})
|
||||
},
|
||||
toIconSkill(){
|
||||
uni.navigateTo({
|
||||
url:"/pages/index/iconSkill"
|
||||
})
|
||||
},
|
||||
toChapterSkill(){
|
||||
uni.navigateTo({
|
||||
url:"/pages/questionBank/chapterExercise"
|
||||
})
|
||||
getQuestion(param,title) {
|
||||
queryQuestionId({
|
||||
versionId: this.version,
|
||||
carTypeId: storage.get('carType') || '1001',
|
||||
subject: this.subject,
|
||||
...param,
|
||||
}).then(async (resp) => {
|
||||
if (resp.code === '0000') {
|
||||
if(resp.data&&resp.data.length){
|
||||
const arr = resp.data
|
||||
const listJson = JSON.stringify(arr)
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/questionBank?navTitle=" + title + "&subject=" + this.subject + "&questionIdList=" + listJson
|
||||
})
|
||||
}else{
|
||||
uni.showToast({
|
||||
title: '暂无题目',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}else if (resp.code === '4001') {
|
||||
uni.showToast({
|
||||
title: '当前题库非最新版,请更新~',
|
||||
icon: 'none'
|
||||
})
|
||||
this.getAllQuestion()
|
||||
}
|
||||
})
|
||||
},
|
||||
toAnswer(title, isError, isNew) {
|
||||
if (title == '单选题') {
|
||||
this.getQuestion({type:'2'},title)
|
||||
} else if (title == '多选题') {
|
||||
this.getQuestion({type:'3'},title)
|
||||
} else if (title == '判断题') {
|
||||
this.getQuestion({type:'1'},title)
|
||||
} else if (title == '图片题') {
|
||||
this.getQuestion({isImage:'1'},title)
|
||||
} else {
|
||||
this.getQuestion({isNew:isNew,isError:isError},title)
|
||||
}
|
||||
},
|
||||
toQuestionBank(val) {
|
||||
this.getQuestion({examKey:val.configItemCode},val.configItemName)
|
||||
},
|
||||
toIconSkill() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/index/iconSkill"
|
||||
})
|
||||
},
|
||||
toChapterSkill() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/chapterExercise?subject="+this.subject
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dot_item{
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
line-height: 40rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background: #0BD032;
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
.dot_item {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
line-height: 41rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background: #0BD032;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.topic_cont_text {
|
||||
height: 45rpx;
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
/* break-all(允许在单词内换行。) */
|
||||
text-overflow: ellipsis;
|
||||
/* 超出部分省略号 */
|
||||
display: -webkit-box;
|
||||
/** 对象作为伸缩盒子模型显示 **/
|
||||
-webkit-box-orient: vertical;
|
||||
/** 设置或检索伸缩盒对象的子元素的排列方式 **/
|
||||
-webkit-line-clamp: 1;
|
||||
/** 显示的行数 **/
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -2,14 +2,21 @@
|
||||
<view>
|
||||
<!-- <u-navbar title="模拟考试" @rightClick="rightClick" :autoBack="true">
|
||||
</u-navbar> -->
|
||||
<j-navbar :isDefineBack="true" @toBack="toBack">模拟考试</j-navbar>
|
||||
<Question ref="question" :tabsList="tabsList" v-model:isSubmit="isSubmit" type="exam" :subject="subject" navTitle="模拟考试" />
|
||||
<j-navbar :isDefineBack="true" @toBack="toBack">{{title}}</j-navbar>
|
||||
<Question ref="question" :tabsList="tabsList" v-model:isSubmit="isSubmit" :type="type" :isShowAll="isShowAll" @changeTab="changeTab" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getTestQuestion
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import useQuestionStore from '@/jtools/store/question' //引入store
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import {
|
||||
getTestQuestion,
|
||||
queryQuestionId
|
||||
} from '@/jtools/api/question';
|
||||
import storage from '@/jtools/storage';
|
||||
import Question from './components/Question.vue';
|
||||
@@ -19,52 +26,96 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
subject:1,
|
||||
isSubmit:false,
|
||||
tabsList:[{
|
||||
label:"模拟考试",
|
||||
value:0
|
||||
},{
|
||||
label:"考前密卷",
|
||||
value:1
|
||||
type: '',
|
||||
collectList: storage.get(`collectList_subject${this.subject}`) || [],
|
||||
questionArr: [],
|
||||
isShowAll: true,
|
||||
title: "模拟考试",
|
||||
subject: 1,
|
||||
isSubmit: false,
|
||||
tabsList: [{
|
||||
label: "模拟考试",
|
||||
value: 0
|
||||
}, {
|
||||
label: "考前秘卷",
|
||||
value: 1
|
||||
}]
|
||||
}
|
||||
},
|
||||
onLoad(op) {
|
||||
if(op.subject){
|
||||
this.subject=op.subject
|
||||
getTestQuestion({
|
||||
carTypeId: storage.get('carType') || '1001',
|
||||
subject: this.subject
|
||||
}).then(resp=>{
|
||||
if(resp.code==='0000'){
|
||||
this.$refs.question.getQuestionList(JSON.stringify(resp.data))
|
||||
}
|
||||
if (op.title) {
|
||||
this.title = op.title
|
||||
}
|
||||
if (op.subject) {
|
||||
this.subject = op.subject
|
||||
const param = {}
|
||||
if (op.isExam1) {
|
||||
param.isExam1 = op.isExam1
|
||||
}
|
||||
if (op.needVip) {
|
||||
this.isShowAll = op.needVip
|
||||
}
|
||||
let arr = []
|
||||
arr = [...this[`orderQuestion_subject${this.subject}`]]
|
||||
let questionObj = {}
|
||||
arr.forEach(item => {
|
||||
item.isChoose = false
|
||||
questionObj[item.questionId] = item
|
||||
})
|
||||
if (op.questionIdList) {
|
||||
const idList = JSON.parse(op.questionIdList)
|
||||
if (idList && idList.length > 0) {
|
||||
idList.forEach(item => {
|
||||
this.questionArr.push(questionObj[item])
|
||||
})
|
||||
}
|
||||
}
|
||||
this.type = 'exam'
|
||||
this.$refs.question.getQuestionList(JSON.stringify(this.questionArr), this.title,this.subject)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore, ["vipOnList", "token"]),
|
||||
...mapState(useQuestionStore, ["orderQuestion_subject1", "orderQuestion_subject4", "version"]), //映射函数,取出tagslist
|
||||
},
|
||||
methods: {
|
||||
toBack(){
|
||||
...mapActions(useUserStore, ['searchUserVip']),
|
||||
toBack() {
|
||||
this.$refs.question.submitPaper()
|
||||
},
|
||||
async changeTab(val) {
|
||||
if (val == 1) {
|
||||
await this.searchUserVip()
|
||||
const result = this.vipOnList.some(item => item.subjects.includes(this.subject))
|
||||
if (result) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/index/secretPapers?subject=" + this.subject
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: "/pages/index/videoVip?subject=" + this.subject
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
::v-deep .u-count-down{
|
||||
::v-deep .u-count-down {
|
||||
font-size: 28rpx;
|
||||
color:#fff !important;
|
||||
color: #fff !important;
|
||||
display: inline-block !important;
|
||||
}
|
||||
::v-deep .u-count-down__text{
|
||||
|
||||
::v-deep .u-count-down__text {
|
||||
font-size: 28rpx;
|
||||
color:#fff !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
::v-deep .balckColor .u-count-down__text{
|
||||
|
||||
::v-deep .balckColor .u-count-down__text {
|
||||
font-size: 28rpx;
|
||||
color:#333 !important;
|
||||
color: #333 !important;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -6,7 +6,7 @@
|
||||
<GradesChart :titleName="rightPencentDesc" :actualValue="Number(rightPencent)" />
|
||||
<view class="top_box flex jc-c" style="flex-direction: column;">
|
||||
<view class="wp100 text-center" style="margin-top: -80px;">
|
||||
<text v-if="Number(rightPencent)>=90">太棒了!正确率很高了!</text>
|
||||
<text v-if="Number(rightPencent * 100)>=90">太棒了!正确率很高了!</text>
|
||||
<text v-else>继续努力吧,正确率有点低~</text>
|
||||
<view class="flex ai-c jc-c mt10">
|
||||
<view class="text-center wp50" @tap="toQuestionBank">
|
||||
@@ -88,13 +88,20 @@
|
||||
this.subject=op.subject
|
||||
this.allRightList=storage.get(`rightList_subject${this.subject}`) || []
|
||||
this.allWrongList=storage.get(`wrongList_subject${this.subject}`) || []
|
||||
this.percent=(((this.allRightList.length+this.wrongList.length) / this.orderQuestion.length)*100).toFixed(0)
|
||||
this.percent=(((this.allRightList.length+this.wrongList.length) / this[`orderQuestion_subject${this.subject}`].length)*100).toFixed(0)
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
//#ifdef MP-WEIXIN
|
||||
uni.reLaunch({
|
||||
url:"/pages/index/index"
|
||||
})
|
||||
//#endif
|
||||
},
|
||||
computed: {
|
||||
...mapState(useQuestionStore, ["orderQuestion"]), //映射函数,取出tagslist
|
||||
...mapState(useQuestionStore, ["orderQuestion_subject1","orderQuestion_subject4"]), //映射函数,取出tagslist
|
||||
getNotDoNum(){
|
||||
return this.orderQuestion.length-(this.allRightList.length+this.allWrongList.length)
|
||||
return this[`orderQuestion_subject${this.subject}`].length-(this.allRightList.length+this.allWrongList.length)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- <u-navbar :title="navTitle" @rightClick="rightClick" :autoBack="true">
|
||||
</u-navbar> -->
|
||||
<j-navbar>{{navTitle}}</j-navbar>
|
||||
<Question ref="question" :tabsList="tabsList" :isShowAll="isShowAll" :subject="subject" :navTitle="navTitle"
|
||||
@changeTab="changeTab"></Question>
|
||||
<u-loading-page :loading="loading" :loading-text="loadTxt"></u-loading-page>
|
||||
<view v-if="!loading">
|
||||
<j-navbar>{{navTitle}}</j-navbar>
|
||||
<Question ref="question" :tabsList="tabsList" :isShowAll="isShowAll" :subject="subject" :navTitle="navTitle"
|
||||
@changeTab="changeTab"></Question>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -17,7 +18,8 @@
|
||||
import useUserStore from '@/jtools/store/user'
|
||||
import Question from './components/Question.vue';
|
||||
import {
|
||||
queryQuestion
|
||||
queryQuestion,
|
||||
queryQuestionId
|
||||
} from '@/jtools/api/question';
|
||||
import storage from '@/jtools/storage';
|
||||
export default {
|
||||
@@ -26,6 +28,9 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loadTxt: '加载中...',
|
||||
collectList: storage.get(`collectList_subject${this.subject}`) || [],
|
||||
loading: false,
|
||||
isShowAll: true,
|
||||
needVip: false,
|
||||
subject: 1,
|
||||
@@ -41,80 +46,63 @@
|
||||
}
|
||||
},
|
||||
async onLoad(op) {
|
||||
this.loading = true
|
||||
if (op.needVip) {
|
||||
this.needVip = op.needVip
|
||||
}
|
||||
if (op && op.navTitle) {
|
||||
this.navTitle = op.navTitle
|
||||
const param = {}
|
||||
if (this.navTitle === '顺序答题' || this.navTitle === '精简500题') {
|
||||
this.questionArr = [...this.orderQuestion]
|
||||
if (this.needVip === 'true') {
|
||||
if (this.token) {
|
||||
await this.searchUserVip()
|
||||
const res = this.vipOnList.some(item => item.subjects == this.subject)
|
||||
if (!res) {
|
||||
this.questionArr = this.questionArr.slice(0, 3)
|
||||
this.isShowAll = false
|
||||
}
|
||||
} else {
|
||||
uni.redirectTo({
|
||||
url: '/pages/login/login'
|
||||
});
|
||||
}
|
||||
}
|
||||
this.$refs.question.getQuestionList(JSON.stringify(this.questionArr))
|
||||
} else {
|
||||
if (!storage.get('token')) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/login/login'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (this.navTitle === '错题本') {
|
||||
param.questionIdList = storage.get(`wrongList_subject${this.subject}`) || []
|
||||
} else if (this.navTitle === '收藏夹') {
|
||||
param.questionIdList = storage.get(`collectList_subject${this.subject}`) || []
|
||||
}
|
||||
if (op.questionList) {
|
||||
param.questionIdList = JSON.parse(op.questionList)
|
||||
}
|
||||
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
|
||||
this.$refs.question.getQuestionList(JSON.stringify(this.questionArr))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
if (op.subject) {
|
||||
this.subject = op.subject
|
||||
}
|
||||
if (op && op.navTitle) {
|
||||
this.navTitle = op.navTitle
|
||||
let arr = []
|
||||
let param = {}
|
||||
if (op.needVip) {
|
||||
this.isShowAll = !Boolean(op.needVip == 'true')
|
||||
}
|
||||
arr = [...this[`orderQuestion_subject${this.subject}`]]
|
||||
let questionObj={}
|
||||
arr.forEach(item => {
|
||||
item.isChoose=false
|
||||
questionObj[item.questionId]=item
|
||||
})
|
||||
if(op.navTitle==='顺序答题'){
|
||||
this.questionArr=arr
|
||||
}else if (op.questionIdList) {
|
||||
const idList = JSON.parse(op.questionIdList)
|
||||
if(idList&&idList.length>0){
|
||||
idList.forEach(item=>{
|
||||
this.questionArr.push(questionObj[item])
|
||||
})
|
||||
}
|
||||
}
|
||||
this.loading = false
|
||||
this.$refs.question.getQuestionList(JSON.stringify(this.questionArr), this.navTitle , this.subject)
|
||||
this.$refs.question.getOriginArr(JSON.stringify(this.questionArr))
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useQuestionStore, ["orderQuestion"]), //映射函数,取出tagslist
|
||||
...mapState(useUserStore, ["vipOnList", "token"])
|
||||
...mapState(useQuestionStore, ["orderQuestion_subject1", "orderQuestion_subject4", "version"]), //映射函数,取出tagslist
|
||||
...mapState(useUserStore, ["vipOnList", "token"]),
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useUserStore, ['searchUserVip']),
|
||||
...mapActions(useQuestionStore, ['getAllQuestion']),
|
||||
changeTab(val) {
|
||||
if (val == 1) {
|
||||
let list = JSON.parse(JSON.stringify(this.questionArr))
|
||||
list = list.map(item => {
|
||||
return {
|
||||
...item,
|
||||
clickAnswer: item.trueAnswer
|
||||
clickAnswer: item.trueAnswer,
|
||||
isChoose: true,
|
||||
}
|
||||
})
|
||||
this.$refs.question.getQuestionList(JSON.stringify(list))
|
||||
this.$refs.question.isShowBest(true)
|
||||
this.$refs.question.getQuestionList(JSON.stringify(list), this.navTitle)
|
||||
} else {
|
||||
this.$refs.question.getQuestionList(JSON.stringify(this.questionArr))
|
||||
this.$refs.question.isShowBest(false)
|
||||
this.$refs.question.getQuestionList()
|
||||
}
|
||||
},
|
||||
rightClick() {
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
<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" />
|
||||
<sunny-video style="width: 100%" videoHeight="422rpx" ref="sunny-video" :src="videoList[currentIndex].videoUrl" />
|
||||
<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>
|
||||
<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>
|
||||
<text class="fs18 fw600 cor-000">{{title}}</text>
|
||||
<view class="flex" @tap="popupShow=true" v-if="videoType!='test'">
|
||||
<text class="fs14 cor-666">更多</text>
|
||||
<u-icon color="#666" name="arrow-right" size="18"></u-icon>
|
||||
@@ -21,19 +19,22 @@
|
||||
<view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bc-fff pl14">
|
||||
<view class="bc-fff pl14 pb10">
|
||||
<view class="skill-sequence-panel-content-wrapper">
|
||||
<scroll-view class="skill-sequence-panel-content" scroll-x :scroll-left="164*currentIndex">
|
||||
<scroll-view class="skill-sequence-panel-content" scroll-x :scroll-left="getScrollLeft">
|
||||
<view class="skill-sequence-skill-wrapper" v-for="(item, index) in videoList" :key="index"
|
||||
@click="checkVideo(item.projectId)">
|
||||
@tap="checkVideo(item.projectId)">
|
||||
<view>
|
||||
<view class="mb10 relative">
|
||||
<image class="contain-box" src="../../static/image/index/index_bg.png"></image>
|
||||
<view class="mb10 relative contain-box hide" style="overflow: hidden;">
|
||||
<image class="contain-box" style="position: absolute;left: 0;top: 0;" mode="widthFix"
|
||||
:src="item.videoUrl+'?x-oss-process=video/snapshot,t_0,f_jpg'"></image>
|
||||
<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>
|
||||
<text style="position: absolute;right: 8rpx;bottom: 8rpx;color:#fff">{{item.videoTime}}</text>
|
||||
</view>
|
||||
<view class="topic_cont_text" :style="{color:projectId==item.projectId?'#FF6E02':'#333'}">
|
||||
{{item.description}}
|
||||
</view>
|
||||
<text :style="{color:projectId==item.projectId?'#FF6E02':'#333'}">{{item.description}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
@@ -45,16 +46,16 @@
|
||||
<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="pic relative">
|
||||
<image class="pic" src="../../static/image/index/index_bg.png"></image>
|
||||
<view class="flex bc-fff mb15" style="border-radius: 16rpx;" v-for="(item,index) of videoList" :key="index"
|
||||
@tap="checkVideo(item.projectId)">
|
||||
<view class="pic relative hide" style="overflow: hidden;">
|
||||
<image class="pic" style="position: absolute;left: 0;top: 0;" mode="widthFix" :src="item.videoUrl+'?x-oss-process=video/snapshot,t_0,f_jpg'"></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>
|
||||
<text style="position: absolute;right: 8rpx;bottom: 8rpx;color:#fff">{{item.videoTime}}</text>
|
||||
</view>
|
||||
<view class="ml10">
|
||||
<text class="fs16 cor-000 fw600">{{item.description}}</text>
|
||||
<view class="fs14 mt5 cor-666">上车、下车的方法</view>
|
||||
<view class="fs14 mt5 cor-666">{{item.subDesc}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -70,7 +71,8 @@
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
currentIndex:0,
|
||||
title: '',
|
||||
currentIndex: 0,
|
||||
videoIndex: 0,
|
||||
testList: [{
|
||||
label: "八一考场",
|
||||
@@ -94,6 +96,7 @@
|
||||
label: "庐江考场",
|
||||
value: 6
|
||||
}],
|
||||
driveType:'',
|
||||
videoType: '',
|
||||
popupShow: false,
|
||||
videoList: [{
|
||||
@@ -121,45 +124,93 @@
|
||||
time: '13:14',
|
||||
id: 5
|
||||
}],
|
||||
projectId:undefined,
|
||||
param:{}
|
||||
projectId: undefined,
|
||||
param: {}
|
||||
}
|
||||
},
|
||||
onLoad(op) {
|
||||
if(op.driveType){
|
||||
this.driveType=op.driveType
|
||||
this.param.driveType=op.driveType
|
||||
}
|
||||
if (op.type) {
|
||||
this.videoType = op.type
|
||||
}
|
||||
if(op.projectId){
|
||||
this.projectId=op.projectId
|
||||
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.subject){
|
||||
this.param.subject=op.subject
|
||||
if (op.type) {
|
||||
this.param.type = op.type
|
||||
this.getVideoList()
|
||||
}
|
||||
if(op.type){
|
||||
this.param.type=op.type
|
||||
if (op.type == '1') {
|
||||
if (this.param.subject == '2') {
|
||||
this.title = '科二基础项目讲解'
|
||||
} else {
|
||||
this.title = '科三基础项目讲解'
|
||||
}
|
||||
} else {
|
||||
this.title = '基础操作讲解'
|
||||
}
|
||||
|
||||
},
|
||||
computed: {
|
||||
getScrollLeft() {
|
||||
const index = this.currentIndex - 1 < 0 ? 0 : this.currentIndex - 1
|
||||
return 164 * index
|
||||
}
|
||||
this.getVieoList()
|
||||
},
|
||||
methods: {
|
||||
getVieoList(){
|
||||
formateTime(time) {
|
||||
const h = parseInt(time / 3600)
|
||||
const minute = parseInt(time / 60 % 60)
|
||||
const second = Math.ceil(time % 60)
|
||||
const hours = h < 10 ? '0' + h : h
|
||||
const formatSecond = second > 59 ? 59 : second
|
||||
return `${hours > 0 ? `${hours}:` : ''}${minute < 10 ? '0' + minute : minute}:${formatSecond < 10 ? '0' + formatSecond : formatSecond}`
|
||||
},
|
||||
getVideoList() {
|
||||
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)
|
||||
"carTypeId": storage.get('carType') || '1001',
|
||||
...this.param,
|
||||
}).then(resp => {
|
||||
if(resp.code==='0000'){
|
||||
let arr=[]
|
||||
if(this.param.type=='1'){
|
||||
arr = JSON.parse(JSON.stringify(resp.data))
|
||||
arr = arr.map(item => {
|
||||
return {
|
||||
...item,
|
||||
videoUrl: item.videoList[0]?.videoUrl,
|
||||
videoTime: this.formateTime(item.videoList[0]?.videoTime)
|
||||
}
|
||||
})
|
||||
}else{
|
||||
arr = JSON.parse(JSON.stringify(resp.data[0].videoList))
|
||||
arr = arr.map(item => {
|
||||
return {
|
||||
...item,
|
||||
projectId: item.videoId,
|
||||
subDesc: resp.data[0].description,
|
||||
videoTime: this.formateTime(item.videoTime)
|
||||
}
|
||||
})
|
||||
}
|
||||
this.videoList = arr
|
||||
this.currentIndex = this.videoList.findIndex(item => item.projectId == this.projectId)
|
||||
}
|
||||
})
|
||||
},
|
||||
checkTest(val) {
|
||||
this.videoIndex = val
|
||||
},
|
||||
checkVideo(val) {
|
||||
this.popupShow = false
|
||||
this.projectId = val
|
||||
this.currentIndex = this.videoList.findIndex(item => item.projectId == this.projectId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,6 +224,21 @@
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.topic_cont_text {
|
||||
width: 260rpx;
|
||||
height:45rpx;
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
/* break-all(允许在单词内换行。) */
|
||||
text-overflow: ellipsis;
|
||||
/* 超出部分省略号 */
|
||||
/* display: -webkit-box; */
|
||||
white-space: nowrap;
|
||||
-webkit-box-orient: vertical; /** 设置或检索伸缩盒对象的子元素的排列方式 **/
|
||||
-webkit-line-clamp:1; /** 显示的行数 **/
|
||||
|
||||
}
|
||||
|
||||
.playLogo {
|
||||
width: 90rpx;
|
||||
height: 40rpx;
|
||||
@@ -224,18 +290,27 @@
|
||||
background: linear-gradient(90deg, #11DF20 0%, #01B74F 100%);
|
||||
color: #fff
|
||||
}
|
||||
|
||||
/*scroll-view外层*/
|
||||
.skill-sequence-panel-content-wrapper{
|
||||
position: relative;
|
||||
white-space:nowrap;
|
||||
.skill-sequence-panel-content-wrapper {
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/*scroll-view本身*/
|
||||
.skill-sequence-panel-content{
|
||||
min-width:100%;
|
||||
.skill-sequence-panel-content {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
/*scroll-view内层*/
|
||||
.skill-sequence-skill-wrapper{
|
||||
display: inline-block;
|
||||
.skill-sequence-skill-wrapper {
|
||||
display: inline-block;
|
||||
margin-right: 15px;
|
||||
}
|
||||
.hide {
|
||||
backface-visibility: hidden;
|
||||
transform: translate3d(0, 0, 0);
|
||||
-webkit-backface-visibility: hidden;
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
}
|
||||
</style>
|
||||
@@ -1,144 +1,188 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-sticky bgColor="#fff">
|
||||
<u-tabs :list="categoryList" :scrollable="false" @click="tabChange"></u-tabs>
|
||||
<u-tabs :list="categoryList" :scrollable="false" @click="tabChange"></u-tabs>
|
||||
</u-sticky>
|
||||
<view class="p14">
|
||||
<view class="top_box">
|
||||
<view class="tip_box flex ai-c jc-sb" v-if="tIndex==0">
|
||||
<view class="flex ai-c">
|
||||
<u-icon name="error-circle-fill" color="#FF6E02" size="18"></u-icon>
|
||||
<text class="ml10 fs12" style="color: #FF6E02;">{{title}}</text>
|
||||
</view>
|
||||
<u-icon name="close" color="#FF6E02" size="18"></u-icon>
|
||||
<view class="tip_box flex ai-c jc-sb" v-if="tIndex==0&&showTip">
|
||||
<view class="flex ai-c">
|
||||
<u-icon name="error-circle-fill" color="#FF6E02" size="18"></u-icon>
|
||||
<text class="ml10 fs12" style="color: #FF6E02;">{{title}}</text>
|
||||
</view>
|
||||
<view class="p14">
|
||||
<text class="fs18 cor-000 fw600">{{tIndex==0?'错题':'收藏'}}情况</text>
|
||||
<view class="total_box mt10">
|
||||
<view class="flex ai-c jc-sb">
|
||||
<view class="text-center">
|
||||
<view style="width: 111rpx;" class="fs30 cor-000">{{tIndex==0?wrongList.length:collectList.length}}</view>
|
||||
</view>
|
||||
<view style="text-align: right;flex-direction: column;justify-content: right" class="flex ai-c" @tap="toPractice">
|
||||
<u-icon name="arrow-right" size="18"></u-icon>
|
||||
<u-icon name="close" color="#FF6E02" size="18" @tap="showTip=false"></u-icon>
|
||||
</view>
|
||||
<view class="p14">
|
||||
<text class="fs18 cor-000 fw600">{{tIndex==0?'错题':'收藏'}}情况</text>
|
||||
<view class="total_box mt10" @tap="toPractice">
|
||||
<view class="flex ai-c jc-sb">
|
||||
<view class="text-center">
|
||||
<view style="width: 111rpx;" class="fs30 cor-000">{{tIndex==0?wrongList.length:collectList.length}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex ai-c jc-sb mt5">
|
||||
<view class="text-center">
|
||||
<text class="fs14 cor-666">全部{{tIndex==0?'错题':'收藏'}}</text>
|
||||
</view>
|
||||
<view style="text-align: right;flex-direction: column;justify-content: right" class="flex ai-c">
|
||||
<text v-if="tIndex==0" class="fs14 cor-666">错{{wrongList.length}}/已做{{wrongList.length+rightList.length}}</text>
|
||||
</view>
|
||||
<view style="text-align: right;flex-direction: column;justify-content: right" class="flex ai-c">
|
||||
<u-icon name="arrow-right" size="18"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="yellow_box" v-if="tIndex==0&&getPercent>10">
|
||||
<view class="flex jc-sb ai-c">
|
||||
<view>
|
||||
<text class="fs24 fw600" style="color: #FF6E02;">{{getPercent}}%</text><text class="fs18 cor-000 fw600">错题率</text>
|
||||
<view class="fs14 cor-000">错题率有点高,快去提升吧</view>
|
||||
</view>
|
||||
<!-- <view style="width: 156rpx;">
|
||||
<view class="flex ai-c jc-sb mt5">
|
||||
<view class="text-center">
|
||||
<text class="fs14 cor-666">全部{{tIndex==0?'错题':'收藏'}}</text>
|
||||
</view>
|
||||
<view style="text-align: right;flex-direction: column;justify-content: right" class="flex ai-c">
|
||||
<text v-if="tIndex==0"
|
||||
class="fs14 cor-666">错{{wrongList.length}}/已做{{wrongList.length+rightList.length}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="yellow_box" v-if="tIndex==0&&getPercent>10">
|
||||
<view class="flex jc-sb ai-c">
|
||||
<view>
|
||||
<text class="fs24 fw600" style="color: #FF6E02;">{{getPercent}}%</text><text
|
||||
class="fs18 cor-000 fw600">错题率</text>
|
||||
<view class="fs14 cor-000">错题率有点高,快去提升吧</view>
|
||||
</view>
|
||||
<!-- <view style="width: 156rpx;">
|
||||
<button class="riseBtn">马上提升</button>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex jc-sb ai-c mt10" v-if="tIndex==0">
|
||||
<text>答对后自动移除错题</text>
|
||||
<u-switch v-model="isMoveWrong" activeColor="#0BD032" ></u-switch>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="flex jc-sb ai-c mt10" v-if="tIndex==0">
|
||||
<text>答对后自动移除错题</text>
|
||||
<u-switch v-model="isMoveWrong" activeColor="#0BD032"></u-switch>
|
||||
</view> -->
|
||||
</view>
|
||||
<!-- <view class="ml15 text-center">
|
||||
<u-button :customStyle="{width:'200rpx',height:'66rpx',borderRadius: '33rpx'}" iconColor="#fff"
|
||||
text="去看视频" color="linear-gradient(90deg, #11DF20 0%, #00B74F 100%)" icon="play-circle">
|
||||
</u-button>
|
||||
<view class="cor-333 fs15 fw600 mt10">科{{subject==1?'一':'四'}}易错试题</view>
|
||||
</view> -->
|
||||
|
||||
|
||||
</view>
|
||||
<view style="margin-top: 30rpx;" v-if="tIndex==0">
|
||||
<view class="video-box">
|
||||
<view class="flex jc-sb ai-c wp100">
|
||||
<text style="color: #05C341;font-size: 36rpx;">科{{subject==1?'一':'四'}}精品视频课</text>
|
||||
<text class="cor-666 fs12">全部10节课 ></text>
|
||||
</view>
|
||||
<view class="flex ai-c mt20">
|
||||
<image class="contain-box" src="../../static/image/index/index_bg.png"></image>
|
||||
<view class="ml15 text-center">
|
||||
<u-button :customStyle="{width:'200rpx',height:'66rpx',borderRadius: '33rpx'}" iconColor="#fff"
|
||||
text="去看视频" color="linear-gradient(90deg, #11DF20 0%, #00B74F 100%)" icon="play-circle">
|
||||
</u-button>
|
||||
<view class="cor-333 fs15 fw600 mt10">科{{subject==1?'一':'四'}}易错试题</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<view class="top_box mt15 p14">
|
||||
<view class="top_box mt15 p14" v-if="typeList&&typeList.length">
|
||||
<view class="flex jc-sb aic">
|
||||
<text class="fs18 cor-000 fw600">{{tIndex==0?'错题':'收藏题'}}分类</text>
|
||||
<u-icon name="arrow-right" size="18"></u-icon>
|
||||
<!-- <u-icon name="arrow-right" size="18"></u-icon> -->
|
||||
</view>
|
||||
<view class="flex ai-c jc-sb" style="flex-wrap: wrap;">
|
||||
<view v-for="(item,index) of typeList" :key="index" class="category_item p14 flex jc-sb ai-c mb10">
|
||||
<text class="cor-000">{{item.categoryName}}</text>
|
||||
<view class="flex ai-c jc-sb mt10" style="flex-wrap: wrap;">
|
||||
<!-- 这个点击效果没加 -->
|
||||
<view v-for="(item,index) of typeList" :key="index" class="category_item p14 flex jc-sb ai-c mb10" @tap="toCategoryQuestion(item)">
|
||||
<view class="topic_cont_text" style="max-width: 75%;">
|
||||
<text class="cor-000">{{item.categoryName}}</text>
|
||||
</view>
|
||||
<text class="cor-666">{{item.num}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'pinia' //引入映射函数
|
||||
import useQuestionStore from '@/jtools/store/question' //引入store
|
||||
import storage from '@/jtools/storage';
|
||||
import {
|
||||
questionCategory
|
||||
} from '@/jtools/api/question';
|
||||
export default{
|
||||
data(){
|
||||
return{
|
||||
collectList:[],
|
||||
rightList:storage.get(`rightList_subject${this.subject}`) || [],
|
||||
wrongList:storage.get(`wrongList_subject${this.subject}`) || [],
|
||||
subject:0,
|
||||
tIndex:0,
|
||||
isMoveWrong:true,
|
||||
title:'重要提示:所有错题做对,再去考试!',
|
||||
categoryList:[{
|
||||
name:'错题本'
|
||||
},{name:'收藏夹'}],
|
||||
typeList:[]
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showTip: true,
|
||||
collectList: [],
|
||||
rightList: storage.get(`rightList_subject${this.subject}`) || [],
|
||||
wrongList: storage.get(`wrongList_subject${this.subject}`) || [],
|
||||
subject: 0,
|
||||
tIndex: 0,
|
||||
isMoveWrong: true,
|
||||
title: '重要提示:所有错题做对,再去考试!',
|
||||
categoryList: [{
|
||||
name: '错题本'
|
||||
}, {
|
||||
name: '收藏夹'
|
||||
}],
|
||||
typeList: []
|
||||
}
|
||||
},
|
||||
onLoad(op){
|
||||
if(op.subject){
|
||||
this.subject=op.subject
|
||||
this.rightList=storage.get(`rightList_subject${this.subject}`) || []
|
||||
this.wrongList=storage.get(`wrongList_subject${this.subject}`) || []
|
||||
this.collectList=storage.get(`collectList_subject${this.subject}`) || []
|
||||
onLoad(op) {
|
||||
if (op.subject) {
|
||||
this.subject = op.subject
|
||||
this.rightList = storage.get(`rightList_subject${this.subject}`) || []
|
||||
this.wrongList = storage.get(`wrongList_subject${this.subject}`) || []
|
||||
this.collectList = storage.get(`collectList_subject${this.subject}`) || []
|
||||
this.getQuestionCategory()
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
getPercent(){
|
||||
return ((this.wrongList.length/(this.wrongList.length+this.rightList.length))*100).toFixed(0)
|
||||
computed: {
|
||||
...mapState(useQuestionStore, ["orderQuestion_subject1", "orderQuestion_subject4"]), //映射函数,取出tagslist
|
||||
getPercent() {
|
||||
return ((this.wrongList.length / (this.wrongList.length + this.rightList.length)) * 100).toFixed(0)
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getQuestionCategory(){
|
||||
const param={}
|
||||
if(this.tIndex==0){
|
||||
param.questionIdList=this.wrongList
|
||||
}else{
|
||||
param.questionIdList=this.collectList
|
||||
methods: {
|
||||
getQuestionCategory() {
|
||||
const param = {}
|
||||
if (this.tIndex == 0) {
|
||||
param.questionIdList = this.wrongList
|
||||
} else {
|
||||
param.questionIdList = this.collectList
|
||||
}
|
||||
questionCategory(param).then(resp=>{
|
||||
this.typeList=resp.data
|
||||
questionCategory(param).then(resp => {
|
||||
this.typeList = resp.data
|
||||
})
|
||||
},
|
||||
tabChange(val){
|
||||
this.tIndex=val.index
|
||||
tabChange(val) {
|
||||
this.tIndex = val.index
|
||||
this.getQuestionCategory()
|
||||
},
|
||||
toPractice(){
|
||||
const navTitle=this.tIndex==0?'错题本':'收藏夹'
|
||||
toCategoryQuestion(item){
|
||||
const jsonString = JSON.stringify(item.errorQuestionIdList)
|
||||
console.log(item);
|
||||
uni.navigateTo({
|
||||
url:"/pages/questionBank/questionBank?navTitle="+navTitle+"&subject="+this.subject
|
||||
url: "/pages/questionBank/questionBank?navTitle=" + item.categoryName + "&questionIdList=" + jsonString+"&subject="+this.subject
|
||||
})
|
||||
},
|
||||
toPractice() {
|
||||
const navTitle = this.tIndex == 0 ? '错题本' : '收藏夹'
|
||||
let arr=[]
|
||||
if (navTitle == '错题本') {
|
||||
arr = this.wrongList
|
||||
if (!this.wrongList.length) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '当前无错题,继续保持吧~',
|
||||
showCancel: false,
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
console.log('用户点击确定');
|
||||
}
|
||||
}
|
||||
});
|
||||
return
|
||||
}
|
||||
} else if (navTitle == '收藏夹') {
|
||||
arr=this.collectList
|
||||
if (!this.collectList.length) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '当前无收藏题~',
|
||||
showCancel: false,
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
console.log('用户点击确定');
|
||||
}
|
||||
}
|
||||
});
|
||||
return
|
||||
}
|
||||
}
|
||||
const listJson=JSON.stringify(arr)
|
||||
uni.navigateTo({
|
||||
url: "/pages/questionBank/questionBank?navTitle=" + navTitle + "&subject=" + this.subject+"&questionIdList="+listJson
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -147,65 +191,94 @@
|
||||
|
||||
<style scoped>
|
||||
::v-deep .u-tabs__wrapper__nav__line {
|
||||
background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%) !important;
|
||||
bottom: 14rpx !important;
|
||||
}
|
||||
.top_box{
|
||||
width: 100%;
|
||||
background: #FDFDFD;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
.tip_box{
|
||||
width: 100%;
|
||||
background: #FFE6D4;
|
||||
border-radius: 20rpx 20rpx 0rpx 0rpx;
|
||||
padding: 10px 14px;
|
||||
}
|
||||
.total_box{
|
||||
width: 100%;
|
||||
background: #F5F5F5;
|
||||
border-radius: 20rpx;
|
||||
padding: 14px;
|
||||
}
|
||||
.yellow_box{
|
||||
margin-top: 10px;
|
||||
padding: 14px;
|
||||
width: 100%;
|
||||
background: linear-gradient(90deg, #FBF2D4 0%, #F7E4B5 100%);
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
.riseBtn{
|
||||
width: 156rpx;
|
||||
height: 56rpx;
|
||||
text-align: center;
|
||||
line-height: 56rpx;
|
||||
font-size: 12px;
|
||||
background-color: #F7E4B5;
|
||||
border: 1px solid #FF6E02;
|
||||
color: #FF6E02;
|
||||
border-radius: 28rpx;
|
||||
}
|
||||
.video-box {
|
||||
padding: 20rpx;
|
||||
width: 694rpx;
|
||||
height: 369rpx;
|
||||
background: #DEEFE5;
|
||||
border: 2px solid #47DB87;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.contain-box {
|
||||
width: 406rpx;
|
||||
height: 228rpx;
|
||||
background: #00B74F;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
.category_item{
|
||||
width: 312rpx;
|
||||
height: 90rpx;
|
||||
text-align: center;
|
||||
line-height: 90rpx;
|
||||
background: #F5F5F5;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%) !important;
|
||||
bottom: 14rpx !important;
|
||||
}
|
||||
|
||||
.top_box {
|
||||
width: 100%;
|
||||
background: #FDFDFD;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.tip_box {
|
||||
width: 100%;
|
||||
background: #FFE6D4;
|
||||
border-radius: 20rpx 20rpx 0rpx 0rpx;
|
||||
padding: 10px 14px;
|
||||
}
|
||||
|
||||
.total_box {
|
||||
width: 100%;
|
||||
background: #F5F5F5;
|
||||
border-radius: 20rpx;
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.yellow_box {
|
||||
margin-top: 10px;
|
||||
padding: 14px;
|
||||
width: 100%;
|
||||
background: linear-gradient(90deg, #FBF2D4 0%, #F7E4B5 100%);
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.riseBtn {
|
||||
width: 156rpx;
|
||||
height: 56rpx;
|
||||
text-align: center;
|
||||
line-height: 56rpx;
|
||||
font-size: 12px;
|
||||
background-color: #F7E4B5;
|
||||
border: 1px solid #FF6E02;
|
||||
color: #FF6E02;
|
||||
border-radius: 28rpx;
|
||||
}
|
||||
|
||||
.video-box {
|
||||
padding: 20rpx;
|
||||
width: 694rpx;
|
||||
height: 369rpx;
|
||||
background: #DEEFE5;
|
||||
border: 2px solid #47DB87;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.contain-box {
|
||||
width: 406rpx;
|
||||
height: 228rpx;
|
||||
background: #00B74F;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.category_item {
|
||||
width: 310rpx;
|
||||
height: 90rpx;
|
||||
text-align: center;
|
||||
line-height: 90rpx;
|
||||
background: #F5F5F5;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.play_btn_2 {
|
||||
width: 65rpx;
|
||||
height: 65rpx;
|
||||
position: absolute;
|
||||
left: 165.5rpx;
|
||||
top: 78rpx
|
||||
}
|
||||
.topic_cont_text {
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
/* break-all(允许在单词内换行。) */
|
||||
text-overflow: ellipsis;
|
||||
/* 超出部分省略号 */
|
||||
display: -webkit-box;
|
||||
/** 对象作为伸缩盒子模型显示 **/
|
||||
-webkit-box-orient: vertical;
|
||||
/** 设置或检索伸缩盒对象的子元素的排列方式 **/
|
||||
-webkit-line-clamp: 1;
|
||||
/** 显示的行数 **/
|
||||
|
||||
}
|
||||
</style>
|
||||
BIN
src/static/image/index/danxuan.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 9.2 KiB |
BIN
src/static/image/index/jpsp.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
src/static/image/index/panduan.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 90 KiB |
BIN
src/static/image/index/tip.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src/static/image/index/tupian.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 46 KiB |
BIN
src/static/image/index/vip_ksxj.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
src/static/image/index/vip_trueRoom.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
src/static/image/mine/callme.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
src/static/image/mine/giftitem.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 9.6 KiB |
BIN
src/static/image/mine/writeoff.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 774 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 5.9 KiB |
11
src/uni_modules/g-preview-img/changelog.md
Normal file
@@ -0,0 +1,11 @@
|
||||
## 1.0.4(2022-12-07)
|
||||
修改:判断在APP端不监听document的滚动
|
||||
## 1.0.3(2022-12-05)
|
||||
新增:支持视频预览,视频图片混用
|
||||
新增:支持预览单张,handlePreviewImg方法直接传入图片或视频地址即可单张预览
|
||||
## 1.0.2(2022-12-05)
|
||||
|
||||
## 1.0.1(2022-12-05)
|
||||
文档错误修改
|
||||
## 1.0.0(2022-11-29)
|
||||
初始化插件
|
||||
@@ -0,0 +1,235 @@
|
||||
<template>
|
||||
<view class="pos">
|
||||
<uni-transition :mode-class="modeClass" :show="show">
|
||||
<!-- 多张图片预览 -->
|
||||
<view class="content" @tap="closedPreview">
|
||||
<swiper
|
||||
class="swiper"
|
||||
circular
|
||||
:current="curDot"
|
||||
@change="swiperChange"
|
||||
:indicator-dots="false"
|
||||
>
|
||||
<swiper-item v-for="(item, idx) in selfImgList" :key="idx">
|
||||
<movable-area scale-area>
|
||||
<movable-view
|
||||
:scale="!disabledScale"
|
||||
direction="all"
|
||||
scale="true"
|
||||
scale-min="0.5"
|
||||
scale-max="5"
|
||||
:scale-value="1"
|
||||
damping="150"
|
||||
friction="15"
|
||||
>
|
||||
<image v-if="isImg(item)" :src="item" mode="widthFix"></image>
|
||||
<view class="video-preview" v-else>
|
||||
<video
|
||||
:autoplay="true"
|
||||
:src="item"
|
||||
:enable-progress-gesture="false"
|
||||
:show-fullscreen-btn="false"
|
||||
></video>
|
||||
</view>
|
||||
</movable-view>
|
||||
</movable-area>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
<!-- 指示器 -->
|
||||
<slot name="indicator" v-if="imgList.length > 1 && !indicatorDotsType">
|
||||
<view class="current-dot">
|
||||
<view class="change-buttom" @tap.stop="previousImg">
|
||||
<uni-icons class="font-white" type="back" size="30"></uni-icons>
|
||||
</view>
|
||||
<view class="font-white cur">
|
||||
{{ curDot + 1 }}/{{ imgList.length }}
|
||||
</view>
|
||||
<view class="change-buttom" @tap.stop="nextImg">
|
||||
<uni-icons class="font-white" type="forward" size="30"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</slot>
|
||||
</uni-transition>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
// 过渡效果
|
||||
modeClass: {
|
||||
type: Array,
|
||||
default: ['fade', 'zoom-out'],
|
||||
},
|
||||
// 指示器类型 true 圆点 false 数字
|
||||
indicatorDotsType: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 图片列表
|
||||
imgList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 是否禁止放大缩小 禁止后swiper可以滑动切换
|
||||
disabledScale: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
curDot: 0,
|
||||
selfImgList: [],
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
isImg() {
|
||||
return (src) => {
|
||||
return src.indexOf('.mp4') === -1 ? true : false;
|
||||
};
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
//监听打开时阻止下面元素的滚动事件
|
||||
/* #ifdef APP-PLUS*/
|
||||
show(val) {
|
||||
if (val) {
|
||||
document
|
||||
.getElementsByClassName('pos')[0]
|
||||
.addEventListener('touchmove', function (e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
},
|
||||
/* #endif */
|
||||
imgList: {
|
||||
handler(val) {
|
||||
if (val.length) {
|
||||
this.selfImgList = val.concat();
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handlePreviewImg(param) {
|
||||
this.show = !this.show;
|
||||
if (typeof param === 'string') {
|
||||
this.selfImgList = [param];
|
||||
} else {
|
||||
if (param) {
|
||||
this.curDot = param;
|
||||
}
|
||||
}
|
||||
this.$emit('preview', this.show);
|
||||
},
|
||||
closedPreview() {
|
||||
this.show = !this.show;
|
||||
this.curDot = 0;
|
||||
this.$emit('preview', this.show);
|
||||
},
|
||||
swiperChange(e) {
|
||||
this.curDot = e.detail.current;
|
||||
this.$emit('changeImg', e.detail.current);
|
||||
},
|
||||
previousImg() {
|
||||
let num = this.imgList.length - 1;
|
||||
if (this.curDot <= 0) {
|
||||
this.curDot = num;
|
||||
} else {
|
||||
this.curDot--;
|
||||
}
|
||||
},
|
||||
nextImg() {
|
||||
let num = this.imgList.length - 1;
|
||||
if (this.curDot >= num) {
|
||||
this.curDot = 0;
|
||||
} else {
|
||||
this.curDot++;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
movable-view {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
movable-area {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
movable-view image {
|
||||
width: 100%;
|
||||
}
|
||||
.content {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #00000076;
|
||||
}
|
||||
.pos {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9999;
|
||||
}
|
||||
.swiper {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.current-dot {
|
||||
position: absolute;
|
||||
bottom: 10%;
|
||||
left: 25%;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
.change-buttom {
|
||||
padding: 10rpx;
|
||||
border-radius: 50%;
|
||||
background: #3f3f3f;
|
||||
}
|
||||
.cur {
|
||||
font-size: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.font-white {
|
||||
color: #fff !important;
|
||||
}
|
||||
::v-deep {
|
||||
.uni-swiper-dots-horizontal {
|
||||
bottom: 12%;
|
||||
}
|
||||
.uni-swiper-dot {
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
}
|
||||
|
||||
uni-video {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
}
|
||||
.video-preview {
|
||||
position: relative;
|
||||
.video-close {
|
||||
position: absolute;
|
||||
right: 50rpx;
|
||||
top: 50rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
84
src/uni_modules/g-preview-img/package.json
Normal file
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"id": "g-preview-img",
|
||||
"displayName": "g-preview-img一款兼容vue2,vue3的图片预览插件,视频预览,支持单张多张,左右滑动,放大缩小",
|
||||
"version": "1.0.4",
|
||||
"description": "g-preview-img一款兼容vue2,vue3的图片预览插件,视频预览,支持单张多张,左右滑动,放大缩小",
|
||||
"keywords": [
|
||||
"vue2",
|
||||
"vue3",
|
||||
"图片预览",
|
||||
"视频预览"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "component-vue",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "u",
|
||||
"阿里": "u",
|
||||
"百度": "u",
|
||||
"字节跳动": "u",
|
||||
"QQ": "u",
|
||||
"钉钉": "u",
|
||||
"快手": "u",
|
||||
"飞书": "u",
|
||||
"京东": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
64
src/uni_modules/g-preview-img/readme.md
Normal file
@@ -0,0 +1,64 @@
|
||||

|
||||
### 一款兼容vue2,vue3的图片预览插件,视频预览,支持图片视频混用,支持单张多张,左右滑动,放大缩小
|
||||
|
||||
### 基础使用方法
|
||||
|
||||
```javascript
|
||||
<template>
|
||||
|
||||
<image v-for="(item,idx) in imgList" :src="item" :key="idx" @tap="handleClick(idx)"></image>
|
||||
<g-preview-img :imgList="imgList" ref="preview"><g-preview-img>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
const preview = ref(null)
|
||||
const imgList = ['图片路径1','图片路径2']
|
||||
const handleClick = (idx)=>{
|
||||
// idx为要打开的图片的索引,也可以不传,默认打开第一张
|
||||
// handlePreviewImg的参数支持传入单张图片地址或单个视频地址
|
||||
preview.value.handlePreviewImg(idx)
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
| 属性名/事件 | 类型 | 默认值 | 说明 |
|
||||
| ----------------- | ------------ | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| modeClass | Array/String | \['fade', 'zoom-out'] | uni-transition组件过渡效果,可选值见 <https://uniapp.dcloud.net.cn/component/uniui/uni-transition.html#mode-class-%E5%86%85%E7%BD%AE%E8%BF%87%E6%B8%A1%E5%8A%A8%E7%94%BB%E7%B1%BB%E5%9E%8B%E8%AF%B4%E6%98%8E> |
|
||||
| indicatorDotsType | Boolean | false | 多张图片的指示器,ture为圆点,false数字,当图片列表只有一张图片时,默认不展示指示器 |
|
||||
| imgList | Array | | 图片列表 |
|
||||
| disabledScale | Boolean | false | 是否禁止双指放大缩小 |
|
||||
| @preview | 打开关闭事件 | | 接受一个参数,ture为开启,false为关闭 |
|
||||
| @changeImg | 图片切换的事件 | | 参数为当前的图片索引 |
|
||||
|
||||
#### 插槽,自定义翻页按钮
|
||||
|
||||
```js
|
||||
|
||||
<g-preview-img :imgList="imgList" ref="preview">
|
||||
<template>
|
||||
<!--你的翻页按钮-->
|
||||
<view @tap.stop="previousImg">上一页</view>
|
||||
<view @tap.stop="nextImg">下一页</view>
|
||||
</template>
|
||||
</g-preview-img>
|
||||
|
||||
<script>
|
||||
const preview = ref(null)
|
||||
//上一页的方法
|
||||
const previousImg = ()=>{
|
||||
preview.value.previousImg()
|
||||
}
|
||||
//下一页的方法
|
||||
const previousImg = ()=>{
|
||||
preview.value.nextImg()
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
#### 支持uniapp原生swiper的属性
|
||||
|
||||
插件内部swiper标签上绑定了$attrs,所以在使用时可以传入一些swiper的属性
|
||||
注意:不要传disable-touch这个属性,会有意想不到的错误
|
||||
|
||||
**插件bug会及时修复!!**
|
||||
25
src/uni_modules/lime-qrcode/changelog.md
Normal file
@@ -0,0 +1,25 @@
|
||||
## 0.1.2(2023-12-14)
|
||||
- fix: uvue 引入 API 自定义包出错
|
||||
## 0.1.1(2023-12-11)
|
||||
- chore: uvue的二维码API独立,需要单独下载
|
||||
## 0.1.0(2023-12-07)
|
||||
- fix: 修复因utssdk目录导致无法运行
|
||||
## 0.0.9(2023-12-06)
|
||||
- feat: 支持uvue
|
||||
## 0.0.8(2023-12-06)
|
||||
- feat: 支持uvue
|
||||
## 0.0.7(2023-12-06)
|
||||
- feat: 支持uvue
|
||||
## 0.0.6(2023-12-06)
|
||||
- feat: 支持uvue
|
||||
## 0.0.5(2023-07-30)
|
||||
- fix: 修复再次生成前没有清空,导致图形叠加
|
||||
## 0.0.4(2023-07-27)
|
||||
- fix: 修复相同尺寸无法再次生成
|
||||
## 0.0.3(2023-06-09)
|
||||
- feat: 支持通过`@vue/composition-api`在`vue2`上使用
|
||||
- chore: 更新文档
|
||||
## 0.0.2(2023-06-08)
|
||||
- chore: 更新文档
|
||||
## 0.0.1(2023-06-08)
|
||||
- 首次
|
||||
179
src/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.uvue
Normal file
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<view class="l-qrcode" ref="l-qrcode" :style="[styles]">
|
||||
<image class="l-qrcode__icon" v-if="icon !=''" :src="icon" :style="[iconStyle]"></image>
|
||||
</view>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { type PropType } from 'vue'
|
||||
import { QRCodeCanvas, QRCodePropsTypes , ImageSettings } from '@/uni_modules/lime-qrcodegen'
|
||||
// import { addUnit } from '@/uni_modules/lime-shared/addUnit'
|
||||
// import { unitConvert } from '@/uni_modules/lime-shared/unitConvert'
|
||||
import { addUnit, unitConvert } from './utils'
|
||||
import { TakeSnapshotFailCallback, TakeSnapshotCompleteCallback, TakeSnapshotSuccessCallback} from './type'
|
||||
|
||||
const name = 'l-qrcode'
|
||||
export default {
|
||||
name,
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
size: {
|
||||
type: Object,
|
||||
default: 160
|
||||
},
|
||||
iconSize: {
|
||||
type: Object,
|
||||
default: 40
|
||||
},
|
||||
marginSize: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#000'
|
||||
},
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: 'transparent'
|
||||
},
|
||||
bordered: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
errorLevel: {
|
||||
type: String as PropType<'L' | 'M' | 'Q' | 'H'>,
|
||||
default: 'M' // 'L' | 'M' | 'Q' | 'H'
|
||||
},
|
||||
useCanvasToTempFilePath: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
// status: {
|
||||
// type: String as PropType<'active'|'expired'|'loading'>,
|
||||
// default: 'active' // active | expired | loading
|
||||
// }
|
||||
},
|
||||
emits: ['success'],
|
||||
data() {
|
||||
return {
|
||||
qrcode: null as QRCodeCanvas | null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
styles() : Map<string, any> {
|
||||
const style = new Map<string, any>()
|
||||
const size = addUnit(this.size);
|
||||
style.set('width', size)
|
||||
style.set('height', size)
|
||||
style.set('background', this.bgColor)
|
||||
return style
|
||||
},
|
||||
iconStyle() : Map<string, any> {
|
||||
const style = new Map<string, any>()
|
||||
const size = addUnit(this.iconSize);
|
||||
style.set('width', size)
|
||||
style.set('height', size)
|
||||
return style
|
||||
},
|
||||
qrCodeProps() : QRCodePropsTypes {
|
||||
const param = {
|
||||
value: this.value,
|
||||
size: unitConvert(this.size),
|
||||
fgColor: this.color,
|
||||
level: ['L', 'M', 'Q', 'H'].includes(this.errorLevel) ? this.errorLevel : 'M',
|
||||
marginSize: this.marginSize,
|
||||
imageSettings: null,
|
||||
includeMargin: this.bordered,
|
||||
} as QRCodePropsTypes
|
||||
|
||||
if(this.iconSize != '' && this.icon != ''){
|
||||
const size = unitConvert(this.iconSize)
|
||||
param.imageSettings = {
|
||||
width: size,
|
||||
height: size,
|
||||
excavate: true
|
||||
} as ImageSettings
|
||||
}
|
||||
return param
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
canvasToTempFilePath(options :UTSJSONObject) : void {
|
||||
const el = (this.$refs['l-qrcode'] as Element);
|
||||
const format = options.getString('format') ?? 'png';
|
||||
const fail = options.get('fail') as TakeSnapshotFailCallback | null;
|
||||
const complete = options.get('complete') as TakeSnapshotCompleteCallback | null;
|
||||
const success = options.get('success') as TakeSnapshotSuccessCallback | null;
|
||||
const newOptions = {
|
||||
format,
|
||||
fail,
|
||||
complete,
|
||||
success,
|
||||
} as TakeSnapshotOptions
|
||||
el.takeSnapshot(newOptions)
|
||||
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const el = (this.$refs['l-qrcode'] as Element)
|
||||
const ctx = el.getDrawableContext();
|
||||
if (ctx == null) return
|
||||
this.qrcode = new QRCodeCanvas(ctx)
|
||||
const render = (v : QRCodePropsTypes) => {
|
||||
this.qrcode!.render(v);
|
||||
if (this.useCanvasToTempFilePath) {
|
||||
setTimeout(() => {
|
||||
this.canvasToTempFilePath({
|
||||
success: (res: TakeSnapshotSuccess) => {
|
||||
this.$emit('success', res.tempFilePath)
|
||||
},
|
||||
fail: (_: TakeSnapshotFail) => {
|
||||
uni.showToast({
|
||||
icon: 'error',
|
||||
title: '截图失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
// TakeSnapshotOptions
|
||||
},200)
|
||||
}
|
||||
}
|
||||
this.$watch('qrCodeProps', (v: QRCodePropsTypes) => {
|
||||
render(v)
|
||||
}, {immediate: true})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.l-qrcode {
|
||||
position: relative;
|
||||
background-color: aqua;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&-mask {
|
||||
position: absolute;
|
||||
// inset: 0;
|
||||
// inset-block-start: 0;
|
||||
// inset-inline-start: 0;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
line-height: 1.5714285714285714;
|
||||
background: rgba(255, 255, 255, 0.96);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
223
src/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.vue
Normal file
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<view class="l-qrcode" :style="[styles]">
|
||||
<!-- #ifndef APP-NVUE -->
|
||||
<canvas :style="styles" type="2d" :canvas-id="canvasId" :id="canvasId"></canvas>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<web-view
|
||||
ref="qrcodeRef"
|
||||
@pagefinish="onFinished"
|
||||
@error="onError"
|
||||
@onPostMessage="onMessage"
|
||||
:style="styles" src="/uni_modules/lime-qrcode/hybrid/html/index.html?v=1"></web-view>
|
||||
<!-- #endif -->
|
||||
<!-- <view class="l-qrcode-mask" v-if="['loading', 'expired'].includes(props.status)">
|
||||
<l-loading v-if="props.status == 'loading'"></l-loading>
|
||||
<view class="l-qrcode-expired" v-if="props.status == 'expired'">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
// @ts-nocheck
|
||||
import { computed, defineComponent, getCurrentInstance, watch, onUnmounted, onMounted } from '@/uni_modules/lime-shared/vue';
|
||||
import QRCodeProps from './props'
|
||||
// #ifndef APP-NVUE
|
||||
import { getCanvas, isCanvas2d } from './useCanvas'
|
||||
import { QRCodeCanvas } from './qrcode.js';
|
||||
// #endif
|
||||
import { addUnit } from '@/uni_modules/lime-shared/addUnit'
|
||||
import { createImage } from '@/uni_modules/lime-shared/createImage'
|
||||
import { unitConvert } from '@/uni_modules/lime-shared/unitConvert'
|
||||
import { isBase64 } from '@/uni_modules/lime-shared/isBase64'
|
||||
import { pathToBase64 } from '@/uni_modules/lime-shared/pathToBase64'
|
||||
import { debounce } from '@/uni_modules/lime-shared/debounce'
|
||||
const name = 'l-qrcode'
|
||||
export default defineComponent({
|
||||
name,
|
||||
props: QRCodeProps,
|
||||
emits: ['success'],
|
||||
setup(props, {emit}) {
|
||||
const context = getCurrentInstance();
|
||||
const canvasId = `l-qrcode${context.uid}`
|
||||
const styles = computed(() => `width: ${addUnit(props.size)}; height: ${addUnit(props.size)};`)
|
||||
let qrcode = null
|
||||
let canvas = null
|
||||
const qrCodeProps = computed(() => {
|
||||
const { value, icon, size, color, bgColor, bordered, iconSize, errorLevel, marginSize } = props
|
||||
const imageSettings = {
|
||||
src: icon,
|
||||
x: undefined,
|
||||
y: undefined,
|
||||
height: unitConvert(iconSize),
|
||||
width: unitConvert(iconSize),
|
||||
excavate: true,
|
||||
}
|
||||
return {
|
||||
value,
|
||||
size: unitConvert(size),
|
||||
level: errorLevel,
|
||||
bgColor,
|
||||
fgColor: color,
|
||||
imageSettings: icon ? imageSettings : undefined,
|
||||
includeMargin: bordered,
|
||||
marginSize: marginSize ?? 0
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// #ifdef APP-NVUE
|
||||
const stacks = new Map()
|
||||
// #endif
|
||||
const canvasToTempFilePath = debounce((args: UniNamespace.CanvasToTempFilePathRes) => {
|
||||
if(!canvas) return
|
||||
// #ifndef APP-NVUE
|
||||
const copyArgs = Object.assign({
|
||||
canvasId,
|
||||
canvas: null
|
||||
}, args)
|
||||
|
||||
if (isCanvas2d) {
|
||||
copyArgs.canvas = canvas
|
||||
}
|
||||
if ('toTempFilePath' in canvas) {
|
||||
canvas.toTempFilePath(copyArgs)
|
||||
} else {
|
||||
uni.canvasToTempFilePath(copyArgs, context);
|
||||
}
|
||||
// #endif
|
||||
// #ifdef APP-NVUE
|
||||
if(!stacks.size) {
|
||||
const flie = 'file-' + Math.random();
|
||||
const stack = {args, time: +new Date()}
|
||||
stacks.set(`${flie}`, stack)
|
||||
canvas.toDataURL(flie)
|
||||
setTimeout(() => {
|
||||
const stack = stacks.get(flie)
|
||||
if(stack && 'fail' in stack.args) {
|
||||
stack.args.fail({
|
||||
error: '超时'
|
||||
})
|
||||
stacks.delete(flie)
|
||||
}
|
||||
},5000)
|
||||
}
|
||||
// #endif
|
||||
})
|
||||
const useCanvasToTempFilePath = () => {
|
||||
if(props.useCanvasToTempFilePath) {
|
||||
canvasToTempFilePath({
|
||||
success(res: UniNamespace.CanvasToTempFilePathRes) {
|
||||
emit('success', res.tempFilePath)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// #ifdef APP-NVUE
|
||||
const onFinished = () => {
|
||||
const { pixelRatio } = uni.getSystemInfoSync()
|
||||
canvas = {
|
||||
toDataURL(flie: string) {
|
||||
const ref: any = context.refs['qrcodeRef'];
|
||||
if(ref) {
|
||||
ref?.evalJS(`toDataURL('${flie}')`)
|
||||
}
|
||||
}
|
||||
};
|
||||
qrcode = {
|
||||
async render(props: any) {
|
||||
const ref: any = context.refs['qrcodeRef'];
|
||||
const { src } = props.imageSettings || { };
|
||||
if(!ref) return
|
||||
if(src && !isBase64(src) && !/^http/.test(src) && /^\/static/.test(src)) {
|
||||
props.imageSettings.src = await pathToBase64(src)
|
||||
}
|
||||
const _props = JSON.stringify(Object.assign({}, props, {pixelRatio}));
|
||||
ref?.evalJS(`render(${_props})`);
|
||||
}
|
||||
}
|
||||
qrcode.render(qrCodeProps.value)
|
||||
useCanvasToTempFilePath()
|
||||
}
|
||||
const onError = () => {
|
||||
console.warn('lime-qrcode 加载失败')
|
||||
}
|
||||
const onMessage = (e: any) => {
|
||||
const {detail:{data: [res]}} = e
|
||||
if(res.event == 'toDataURL') {
|
||||
const {file, image, msg} = res.data;
|
||||
const stack = stacks.get(file)
|
||||
if(stack && image && 'success' in stack.args) {
|
||||
stack.args.success({tempFilePath: image})
|
||||
stacks.delete(file)
|
||||
} else if(stack && 'fails' in stack.args) {
|
||||
stack.args.fail({error: msg})
|
||||
stacks.delete(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
const propsWatch = watch(props, () => {
|
||||
if (qrcode) {
|
||||
qrcode.render(qrCodeProps.value)
|
||||
useCanvasToTempFilePath()
|
||||
}
|
||||
})
|
||||
onMounted(() => {
|
||||
// #ifndef APP-NVUE
|
||||
getCanvas(canvasId, { context }).then(res => {
|
||||
canvas = res
|
||||
qrcode = new QRCodeCanvas(res, {
|
||||
// #ifdef H5
|
||||
path2D: false,
|
||||
// #endif
|
||||
pixelRatio: isCanvas2d ? uni.getSystemInfoSync().pixelRatio : 1,
|
||||
createImage
|
||||
})
|
||||
qrcode.render(qrCodeProps.value)
|
||||
useCanvasToTempFilePath()
|
||||
})
|
||||
// #endif
|
||||
})
|
||||
onUnmounted(() => {
|
||||
propsWatch && propsWatch()
|
||||
})
|
||||
return {
|
||||
canvasId,
|
||||
styles,
|
||||
props,
|
||||
canvasToTempFilePath,
|
||||
|
||||
// #ifdef APP-NVUE
|
||||
onFinished,
|
||||
onError,
|
||||
onMessage
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.l-qrcode {
|
||||
position: relative;
|
||||
|
||||
&-mask {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
// inset-block-start: 0;
|
||||
// inset-inline-start: 0;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
line-height: 1.5714285714285714;
|
||||
background: rgba(255, 255, 255, 0.96);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
36
src/uni_modules/lime-qrcode/components/l-qrcode/props.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
// @ts-nocheck
|
||||
// import type { PropType } from './vue'
|
||||
export default {
|
||||
value: String,
|
||||
icon: String,
|
||||
size: {
|
||||
type: [Number, String],
|
||||
default: 160
|
||||
},
|
||||
iconSize: {
|
||||
type: [Number, String],
|
||||
default: 40
|
||||
},
|
||||
marginSize: Number,
|
||||
color: {
|
||||
type: String,
|
||||
default: '#000'
|
||||
},
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: 'transparent'
|
||||
},
|
||||
bordered: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
errorLevel: {
|
||||
type: String as PropType<'L'|'M'|'Q'|'H'>,
|
||||
default: 'M' // 'L' | 'M' | 'Q' | 'H'
|
||||
},
|
||||
useCanvasToTempFilePath: Boolean
|
||||
// status: {
|
||||
// type: String as PropType<'active'|'expired'|'loading'>,
|
||||
// default: 'active' // active | expired | loading
|
||||
// }
|
||||
}
|
||||
25
src/uni_modules/lime-qrcode/components/l-qrcode/type.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
export type ImageSettings = {
|
||||
width: number
|
||||
height: number
|
||||
x?: number
|
||||
y?: number
|
||||
excavate: boolean
|
||||
}
|
||||
export type QRCodePropsTypes = {
|
||||
value?: string
|
||||
size?: number
|
||||
fgColor?: string
|
||||
level?: string
|
||||
marginSize: number
|
||||
includeMargin: boolean
|
||||
imageSettings?: ImageSettings
|
||||
}
|
||||
|
||||
export type QRCodeCallback = (cells : boolean[][]) => void
|
||||
|
||||
export type Excavation = {
|
||||
x: number
|
||||
y: number
|
||||
h: number
|
||||
w: number
|
||||
}
|
||||
78
src/uni_modules/lime-qrcode/components/l-qrcode/useCanvas.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
|
||||
// @ts-nocheck
|
||||
import type { ComponentInternalInstance } from './vue'
|
||||
import { getRect } from '@/uni_modules/lime-shared/getRect'
|
||||
import { canIUseCanvas2d } from '@/uni_modules/lime-shared/canIUseCanvas2d'
|
||||
export const isCanvas2d = canIUseCanvas2d()
|
||||
|
||||
export async function getCanvas(canvasId: string, options: {context: ComponentInternalInstance}) {
|
||||
let { context } = options
|
||||
// #ifdef MP || VUE2
|
||||
if (context.proxy) context = context.proxy
|
||||
// #endif
|
||||
return getRect('#' + canvasId, {context, type: isCanvas2d ? 'fields': 'boundingClientRect'}).then(res => {
|
||||
if(res.node){
|
||||
return res.node
|
||||
} else {
|
||||
const ctx = uni.createCanvasContext(canvasId, context)
|
||||
return {
|
||||
getContext(type: string) {
|
||||
if(type == '2d') {
|
||||
return ctx
|
||||
}
|
||||
},
|
||||
width: res.width,
|
||||
height: res.height,
|
||||
}
|
||||
// #ifdef H5
|
||||
// canvas.value = context.proxy.$el.querySelector('#'+ canvasId)
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// #ifndef H5 || APP-NVUE
|
||||
class Image {
|
||||
currentSrc: string | null = null
|
||||
naturalHeight: number = 0
|
||||
naturalWidth: number = 0
|
||||
width: number = 0
|
||||
height: number = 0
|
||||
tagName: string = 'IMG'
|
||||
path: any = ''
|
||||
crossOrigin: any = ''
|
||||
referrerPolicy: any = ''
|
||||
onload: () => void
|
||||
onerror: () => void
|
||||
constructor() {}
|
||||
set src(src) {
|
||||
this.currentSrc = src
|
||||
uni.getImageInfo({
|
||||
src,
|
||||
success: (res) => {
|
||||
this.path = res.path
|
||||
this.naturalWidth = this.width = res.width
|
||||
this.naturalHeight = this.height = res.height
|
||||
this.onload()
|
||||
},
|
||||
fail: () => {
|
||||
this.onerror()
|
||||
}
|
||||
})
|
||||
}
|
||||
get src() {
|
||||
return this.currentSrc
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
export function createImage(canvas: WechatMiniprogram.Canvas) {
|
||||
if(canvas && canvas.createImage) {
|
||||
return canvas.createImage()
|
||||
} else if(typeof window != 'undefined' && window.Image) {
|
||||
return new window.Image()
|
||||
}
|
||||
// #ifndef H5 || APP-NVUE
|
||||
return new Image()
|
||||
// #endif
|
||||
}
|
||||
35
src/uni_modules/lime-qrcode/components/l-qrcode/utils.uts
Normal file
@@ -0,0 +1,35 @@
|
||||
export function addUnit(value: any|null):string{
|
||||
if(value == null){
|
||||
return ''
|
||||
}
|
||||
value = `${value}`
|
||||
return /^(-)?\d+(\\.\d+)?$/.test(value) ? `${value}px` : value
|
||||
}
|
||||
|
||||
export function unitConvert(value: any|null): number{
|
||||
if(typeof value == 'number'){
|
||||
return value as number
|
||||
}
|
||||
if(typeof value == 'string'){
|
||||
value = `${value}`
|
||||
if(/^(-)?\d+(\\.\d+)?$/.test(value)){
|
||||
return parseFloat(value);
|
||||
}
|
||||
|
||||
const reg = /^-?([0-9]+)?([.]{1}[0-9]+){0,1}(em|rpx|px|%)$/g;
|
||||
const results = reg.exec(value);
|
||||
if (results == null) {
|
||||
return 0;
|
||||
}
|
||||
const unit = results[3];
|
||||
const v = parseFloat(value);
|
||||
if (unit == 'rpx') {
|
||||
const { windowWidth } = uni.getWindowInfo()
|
||||
return windowWidth / 750 * v;
|
||||
}
|
||||
if (unit == 'px') {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<view class="demo-block">
|
||||
<text class="demo-block__title-text ultra">QRCode</text>
|
||||
<text class="demo-block__desc-text">QRCode</text>
|
||||
<view class="demo-block__body">
|
||||
<view class="demo-block">
|
||||
<text class="demo-block__title-text large">基础</text>
|
||||
<view class="demo-block__body">
|
||||
<l-qrcode value="https://limeui.qcoon.cn" size="300rpx"></l-qrcode>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="demo-block">
|
||||
<text class="demo-block__title-text large">icon</text>
|
||||
<view class="demo-block__body">
|
||||
<image v-if="image !=''" :src="image" style="width: 300rpx;" mode="widthFix"></image>
|
||||
<view style="flex-direction: row; justify-content: space-between">
|
||||
<l-qrcode ref="qrcodeRef" value="https://limeui.qcoon.cn" size="300rpx" icon="https://img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" iconSize="70rpx"></l-qrcode>
|
||||
<l-qrcode :useCanvasToTempFilePath="true" @success="success" value="https://limeui.qcoon.cn" size="300rpx" icon="https://img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" iconSize="70rpx"></l-qrcode>
|
||||
</view>
|
||||
<button @click="onClick">生成图片</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="demo-block">
|
||||
<text class="demo-block__title-text large">颜色</text>
|
||||
<view class="demo-block__body">
|
||||
<view style="flex-direction: row; justify-content: space-between">
|
||||
<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" color="rgb(82,196,26)"></l-qrcode>
|
||||
<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" color="rgb(22,119,255)" bgColor="rgb(245,245,245)"></l-qrcode>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="demo-block">
|
||||
<text class="demo-block__title-text large">纠错比例</text>
|
||||
<view class="demo-block__body">
|
||||
<l-qrcode value="img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" size="300rpx" :errorLevel="levels[index]"></l-qrcode>
|
||||
<button @click="onToggle">切换纠错等级:{{levels[index]}}</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="demo-block">
|
||||
<text class="demo-block__title-text large">动态</text>
|
||||
<view class="demo-block__body">
|
||||
<l-qrcode :value="text" size="300rpx" :marginSize="1" bgColor="white"></l-qrcode>
|
||||
<button @click="update">更新</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
// import {ComponentPublicInstance} from 'vue'
|
||||
export default {
|
||||
name: 'lime-qrcode',
|
||||
data() {
|
||||
return {
|
||||
text: 'qcoon.com.cn',
|
||||
image: '',
|
||||
index: 0,
|
||||
levels: ['L', 'M', 'Q', 'H']
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
success(src: string) {
|
||||
console.log(`src`, src)
|
||||
},
|
||||
update() {
|
||||
this.text = `qcoon.cn?v=${Math.random()}`
|
||||
},
|
||||
onToggle() {
|
||||
this.index++
|
||||
this.index = this.index % this.levels.length
|
||||
},
|
||||
onClick() {
|
||||
const el:LQrcodeComponentPublicInstance = this.$refs['qrcodeRef'] as LQrcodeComponentPublicInstance
|
||||
el.canvasToTempFilePath({
|
||||
success:(res: TakeSnapshotSuccess)=>{
|
||||
this.image = res.tempFilePath
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.demo-block {
|
||||
margin: 32px 20px 0;
|
||||
overflow: visible;
|
||||
&__title {
|
||||
margin: 0;
|
||||
margin-top: 8px;
|
||||
&-text {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
|
||||
&.large {
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
line-height: 26px;
|
||||
}
|
||||
&.ultra {
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&__desc-text {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
margin: 8px 16px 0 0;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
&__body {
|
||||
margin: 16px 0;
|
||||
overflow: visible;
|
||||
.demo-block {
|
||||
// margin-top: 0px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<demo-block title="QRCode" type="ultra">
|
||||
<demo-block title="基础">
|
||||
<l-qrcode value="https://limeui.qcoon.cn" size="300rpx"></l-qrcode>
|
||||
</demo-block>
|
||||
<demo-block title="icon">
|
||||
<view style="display: flex; gap: 10px">
|
||||
<image v-if="image" :src="image" style="width: 300rpx;" mode="widthFix"></image>
|
||||
<l-qrcode ref="qrcodeRef" value="https://limeui.qcoon.cn" size="300rpx" icon="https://img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" iconSize="70rpx"></l-qrcode>
|
||||
<l-qrcode useCanvasToTempFilePath @success="success" value="https://limeui.qcoon.cn" size="300rpx" icon="https://img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" iconSize="70rpx"></l-qrcode>
|
||||
</view>
|
||||
<button @click="onClick">生成图片</button>
|
||||
</demo-block>
|
||||
<demo-block title="颜色">
|
||||
<view style="display: flex; gap: 10px">
|
||||
<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" color="rgb(82,196,26)"></l-qrcode>
|
||||
<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" color="rgb(22,119,255)" bgColor="rgb(245,245,245)"></l-qrcode>
|
||||
</view>
|
||||
</demo-block>
|
||||
<demo-block title="纠错比例">
|
||||
<l-qrcode value="img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" size="300rpx" :errorLevel="levels[index]"></l-qrcode>
|
||||
<button @click="onToggle">切换纠错等级:{{levels[index]}}</button>
|
||||
</demo-block>
|
||||
<demo-block title="动态">
|
||||
<l-qrcode :value="text" size="300rpx" marginSize="20rpx" bgColor="white"></l-qrcode>
|
||||
<button @click="update">更新</button>
|
||||
</demo-block>
|
||||
</demo-block>
|
||||
</template>
|
||||
<script>
|
||||
import {ref, defineComponent} from '../l-qrcode/vue'
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const qrcodeRef = ref(null)
|
||||
const image = ref(null)
|
||||
const text = ref('qcoon.com.cn')
|
||||
const levels = ['L', 'M', 'Q', 'H']
|
||||
let index = ref(0)
|
||||
const onToggle = () => {
|
||||
index.value++
|
||||
index.value = index.value % levels.length
|
||||
}
|
||||
const onClick = () => {
|
||||
if(qrcodeRef.value) {
|
||||
qrcodeRef.value.canvasToTempFilePath({
|
||||
success(res) {
|
||||
image.value = res.tempFilePath
|
||||
console.log('success:::', res)
|
||||
},
|
||||
fail(err) {
|
||||
console.log('err:::', err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
const success = (res) => {
|
||||
console.log('res', res)
|
||||
}
|
||||
|
||||
const update = () =>{
|
||||
text.value = `qcoon.cn?v=${Math.random()}`
|
||||
}
|
||||
|
||||
return {
|
||||
levels,
|
||||
index,
|
||||
image,
|
||||
text,
|
||||
qrcodeRef,
|
||||
onClick,
|
||||
update,
|
||||
success,
|
||||
onToggle,
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
</style>
|
||||
77
src/uni_modules/lime-qrcode/hybrid/html/index.html
Normal file
@@ -0,0 +1,77 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>lime-qrcode</title>
|
||||
<style>
|
||||
html,body,canvas {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
/* background-color: rgba(255,0,0,0.1) */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="lime-qrcode"></canvas>
|
||||
<script type="text/javascript" src="./uni.webview.1.5.3.js"></script>
|
||||
<script type="text/javascript" src="./qrcode.min.js"></script>
|
||||
<script>
|
||||
var canvas = document.querySelector('#lime-qrcode')
|
||||
var pixelRatio = window.devicePixelRatio || 1
|
||||
function appendWatermark(image) {
|
||||
emit('append', mark.toDataURL())
|
||||
}
|
||||
|
||||
var qrcode = new lime.QRCodeCanvas(canvas, {
|
||||
pixelRatio,
|
||||
})
|
||||
function render(props) {
|
||||
if(props.pixelRatio) {
|
||||
pixelRatio = props.pixelRatio
|
||||
}
|
||||
if(qrcode) {
|
||||
qrcode.render(props)
|
||||
}
|
||||
}
|
||||
function toDataURL(file) {
|
||||
if(qrcode && canvas) {
|
||||
try{
|
||||
const image = canvas.toDataURL()
|
||||
emit('toDataURL', {
|
||||
file,
|
||||
image
|
||||
})
|
||||
}catch(e){
|
||||
emit('toDataURL', {
|
||||
file,
|
||||
msg: e
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
function emit(event, data) {
|
||||
postMessage({
|
||||
event,
|
||||
data
|
||||
});
|
||||
};
|
||||
function postMessage(data) {
|
||||
uni.postMessage({
|
||||
data
|
||||
});
|
||||
};
|
||||
// render({
|
||||
// content: ['Lime UI'],
|
||||
// // rotate: -22,
|
||||
// // baseSize: 2,
|
||||
// // fontGap: 3
|
||||
// })
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
6
src/uni_modules/lime-qrcode/hybrid/html/qrcode.min.js
vendored
Normal file
89
src/uni_modules/lime-qrcode/package.json
Normal file
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"id": "lime-qrcode",
|
||||
"displayName": "qrcode 二维码生成",
|
||||
"version": "0.1.2",
|
||||
"description": "全端二维码生成插件,draw api绘制。在H5,微信小程序,uvue,nvue上测试过,非uvue为vue3实现vue2需配置@vue/composition-api",
|
||||
"keywords": [
|
||||
"qrcode",
|
||||
"qr",
|
||||
"uvue",
|
||||
"生成图片",
|
||||
"二维码"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "component-vue",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": "305716444"
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [
|
||||
"lime-shared"
|
||||
],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y",
|
||||
"app-android": {
|
||||
"minVersion": "19"
|
||||
}
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "u",
|
||||
"Edge": "u",
|
||||
"Firefox": "u",
|
||||
"Safari": "u"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "u",
|
||||
"百度": "u",
|
||||
"字节跳动": "u",
|
||||
"QQ": "u",
|
||||
"钉钉": "u",
|
||||
"快手": "u",
|
||||
"飞书": "u",
|
||||
"京东": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
153
src/uni_modules/lime-qrcode/readme.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# lime-qrcode 二维码
|
||||
- uniapp vue3 生成二维码插件
|
||||
- 仅在H5、微信小程序、APP-NVUE测试过,如果你在其它端遇到问题或其它端也能跑,请告之
|
||||
- uvue 需要导入[lime-qrcodegen](https://ext.dcloud.net.cn/plugin?id=15838)
|
||||
|
||||
## 使用
|
||||
- 导入插件后直接使用
|
||||
- uvue 需要导入**[lime-qrcodegen](https://ext.dcloud.net.cn/plugin?id=15838)**
|
||||
|
||||
#### 基础使用
|
||||
|
||||
```html
|
||||
<l-qrcode value="http://lime.qcoon.cn" />
|
||||
```
|
||||
|
||||
|
||||
#### ICON
|
||||
- 带 Icon 的二维码
|
||||
|
||||
```html
|
||||
<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" icon="/static/logo.png" iconSize="70rpx"></l-qrcode>
|
||||
```
|
||||
|
||||
#### 颜色
|
||||
- 通过设置 `color` 自定义二维码颜色,通过设置 `bgColor` 自定义背景颜色。
|
||||
|
||||
```html
|
||||
<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" color="rgb(82,196,26)"></l-qrcode>
|
||||
<l-qrcode value="https://limeui.qcoon.cn" size="300rpx" color="rgb(22,119,255)" bgColor="rgb(245,245,245)"></l-qrcode>
|
||||
```
|
||||
|
||||
#### 纠错比例
|
||||
- 通过设置 `errorLevel` 调整不同的容错等级。
|
||||
|
||||
```html
|
||||
<l-qrcode value="img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" size="300rpx" errorLevel="H"></l-qrcode>
|
||||
```
|
||||
|
||||
#### 生成图片
|
||||
- 1、通过调用插件的`canvasToTempFilePath`方法生成图片。
|
||||
|
||||
```html
|
||||
<image v-if="image" :src="image" style="width: 300rpx;" mode="widthFix"></image>
|
||||
<l-qrcode ref="qrcodeRef" value="https://limeui.qcoon.cn" size="300rpx" icon="https://img10.360buyimg.com/img/jfs/t1/182127/16/37474/11761/64659c31F0cd84976/21f25b952f03a49a.jpg" iconSize="70rpx"></l-qrcode>
|
||||
<button @click="onClick">生成图片</button>
|
||||
```
|
||||
```js
|
||||
// vue3
|
||||
const qrcodeRef = ref(null)
|
||||
const onClick = () => {
|
||||
if(!qrcodeRef.value) return
|
||||
qrcodeRef.value.canvasToTempFilePath({
|
||||
success(res) {
|
||||
image.value = res.tempFilePath
|
||||
console.log('success:::', res)
|
||||
},
|
||||
fail(err) {
|
||||
console.log('err:::', err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// vue2
|
||||
const el = this.$refs['qrcodeRef']
|
||||
el.canvasToTempFilePath({
|
||||
success:(res)=>{
|
||||
this.image = res.tempFilePath
|
||||
},
|
||||
fail(err) {
|
||||
console.log('err:::', err)
|
||||
}
|
||||
})
|
||||
|
||||
// uvue
|
||||
const el:LQrcodeComponentPublicInstance = this.$refs['qrcodeRef'] as LQrcodeComponentPublicInstance
|
||||
el.canvasToTempFilePath({
|
||||
success:(res: TakeSnapshotSuccess)=>{
|
||||
this.image = res.tempFilePath
|
||||
},
|
||||
fail(err: TakeSnapshotFail) {
|
||||
console.log('err:::', err)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
- 2、通过设置`useCanvasToTempFilePath`在`success`事件里接收图片地址
|
||||
|
||||
```html
|
||||
<image v-if="image" :src="image" style="width: 300rpx;" mode="widthFix"></image>
|
||||
<l-qrcode useCanvasToTempFilePath @success="success" value="https://limeui.qcoon.cn"></l-qrcode>
|
||||
```
|
||||
```js
|
||||
const image = ref(null)
|
||||
const success = (img) => {
|
||||
image.value = img
|
||||
}
|
||||
```
|
||||
|
||||
### 关于vue2的使用方式
|
||||
- 插件使用了`composition-api`, 如果你希望在vue2中使用请按官方的教程[vue-composition-api](https://uniapp.dcloud.net.cn/tutorial/vue-composition-api.html)配置
|
||||
- 关键代码是: 在main.js中 在vue2部分加上这一段即可,官方是把它单独成了一个文件.
|
||||
|
||||
```js
|
||||
// main.js vue2
|
||||
import Vue from 'vue'
|
||||
import VueCompositionAPI from '@vue/composition-api'
|
||||
Vue.use(VueCompositionAPI)
|
||||
```
|
||||
另外插件也用到了TS,vue2可能会遇过官方的TS版本过低的问题,找到HX目录下的`compile-typescript`目录
|
||||
```cmd
|
||||
// \HBuilderX\plugins\compile-typescript
|
||||
yarn add typescript -D
|
||||
- or -
|
||||
npm install typescript -D
|
||||
```
|
||||
|
||||
### 查看示例
|
||||
- 导入后直接使用这个标签查看演示效果
|
||||
|
||||
```html
|
||||
// 代码位于 uni_modules/lime-qrcode/compoents/lime-qrcode
|
||||
<lime-qrcode />
|
||||
```
|
||||
|
||||
### 插件标签
|
||||
- 默认 l-qrcode 为 component
|
||||
- 默认 lime-qrcode 为 demo
|
||||
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --------------------------| ------------------------------------------------------------ | ---------------- | ------------ |
|
||||
| value | 扫描后的文本 | <em>string</em> | `-` |
|
||||
| icon | 二维码中图片的地址 | <em>string</em> | `-` |
|
||||
| size | 二维码大小 | <em>number,string</em> | `160` |
|
||||
| iconSize | 二维码中图片的大小 | <em>number,string</em> | `40` |
|
||||
| color | 二维码颜色 | <em>string</em> | `-` |
|
||||
| bgColor | 二维码背景颜色 | <em>string</em> | `-` |
|
||||
| errorLevel | 二维码纠错等级 | `'L' | 'M' | 'Q' | 'H' ` | `M` |
|
||||
| marginSize | 边距码大小,默认为0码点 | <em>number</em> | `0` |
|
||||
|
||||
### 常见问题
|
||||
- icon 是网络地址时,H5和Nvue需要解决跨域问题,小程序需要配置download
|
||||
|
||||
## 打赏
|
||||
|
||||
如果你觉得本插件,解决了你的问题,赠人玫瑰,手留余香。
|
||||

|
||||

|
||||
25
src/uni_modules/lime-shared/addUnit/index.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
// @ts-nocheck
|
||||
import {isNumeric} from '../isNumeric'
|
||||
import {isDef} from '../isDef'
|
||||
/**
|
||||
* 给一个值添加单位(像素 px)
|
||||
* @param value 要添加单位的值,可以是字符串或数字
|
||||
* @returns 添加了单位的值,如果值为 undefined 则返回 undefined
|
||||
*/
|
||||
export function addUnit(value?: string | number): string | undefined {
|
||||
if (!isDef(value)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
value = String(value); // 将值转换为字符串
|
||||
|
||||
// 如果值是数字,则在后面添加单位 "px",否则保持原始值
|
||||
return isNumeric(value) ? `${value}px` : value;
|
||||
}
|
||||
|
||||
|
||||
// console.log(addUnit(100)); // 输出: "100px"
|
||||
// console.log(addUnit("200")); // 输出: "200px"
|
||||
// console.log(addUnit("300px")); // 输出: "300px"(已经包含单位)
|
||||
// console.log(addUnit()); // 输出: undefined(值为 undefined)
|
||||
// console.log(addUnit(null)); // 输出: undefined(值为 null)
|
||||
63
src/uni_modules/lime-shared/arrayBufferToFile/index.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
// @ts-nocheck
|
||||
import {platform} from '../platform'
|
||||
/**
|
||||
* buffer转路径
|
||||
* @param {Object} buffer
|
||||
*/
|
||||
// @ts-nocheck
|
||||
export function arrayBufferToFile(buffer: ArrayBuffer | Blob, name?: string, format?:string):Promise<(File|string)> {
|
||||
return new Promise((resolve, reject) => {
|
||||
// #ifdef MP
|
||||
const fs = uni.getFileSystemManager()
|
||||
//自定义文件名
|
||||
if (!name && !format) {
|
||||
reject(new Error('ERROR_NAME_PARSE'))
|
||||
}
|
||||
const fileName = `${name || new Date().getTime()}.${format.replace(/(.+)?\//,'')}`;
|
||||
let pre = platform()
|
||||
const filePath = `${pre.env.USER_DATA_PATH}/${fileName}`
|
||||
fs.writeFile({
|
||||
filePath,
|
||||
data: buffer,
|
||||
success() {
|
||||
resolve(filePath)
|
||||
},
|
||||
fail(err) {
|
||||
console.error(err)
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
const file = new File([buffer], name, {
|
||||
type: format,
|
||||
});
|
||||
resolve(file)
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
|
||||
const base64 = uni.arrayBufferToBase64(buffer)
|
||||
bitmap.loadBase64Data(base64, () => {
|
||||
if (!name && !format) {
|
||||
reject(new Error('ERROR_NAME_PARSE'))
|
||||
}
|
||||
const fileNmae = `${name || new Date().getTime()}.${format.replace(/(.+)?\//,'')}`;
|
||||
const filePath = `_doc/uniapp_temp/${fileNmae}`
|
||||
bitmap.save(filePath, {},
|
||||
() => {
|
||||
bitmap.clear()
|
||||
resolve(filePath)
|
||||
},
|
||||
(error) => {
|
||||
bitmap.clear()
|
||||
reject(error)
|
||||
})
|
||||
}, (error) => {
|
||||
bitmap.clear()
|
||||
reject(error)
|
||||
})
|
||||
// #endif
|
||||
})
|
||||
}
|
||||
13
src/uni_modules/lime-shared/base64ToArrayBuffer/index.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
// @ts-nocheck
|
||||
// 未完成
|
||||
export function base64ToArrayBuffer(base64 : string) {
|
||||
const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64) || [];
|
||||
if (!format) {
|
||||
new Error('ERROR_BASE64SRC_PARSE')
|
||||
}
|
||||
if(uni.base64ToArrayBuffer) {
|
||||
return uni.base64ToArrayBuffer(bodyData)
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
76
src/uni_modules/lime-shared/base64ToPath/index.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
// @ts-nocheck
|
||||
import {platform} from '../platform'
|
||||
/**
|
||||
* base64转路径
|
||||
* @param {Object} base64
|
||||
*/
|
||||
export function base64ToPath(base64: string, filename?: string):Promise<string> {
|
||||
const [, format] = /^data:image\/(\w+);base64,/.exec(base64) || [];
|
||||
console.log('format', format)
|
||||
return new Promise((resolve, reject) => {
|
||||
// #ifdef MP
|
||||
const fs = uni.getFileSystemManager()
|
||||
//自定义文件名
|
||||
if (!filename && !format) {
|
||||
reject(new Error('ERROR_BASE64SRC_PARSE'))
|
||||
}
|
||||
// const time = new Date().getTime();
|
||||
const name = filename || `${new Date().getTime()}.${format}`;
|
||||
let pre = platform()
|
||||
const filePath = `${pre.env.USER_DATA_PATH}/${name}`
|
||||
fs.writeFile({
|
||||
filePath,
|
||||
data: base64.split(',')[1],
|
||||
encoding: 'base64',
|
||||
success() {
|
||||
resolve(filePath)
|
||||
},
|
||||
fail(err) {
|
||||
console.error(err)
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
// mime类型
|
||||
let mimeString = base64.split(',')[0].split(':')[1].split(';')[0];
|
||||
//base64 解码
|
||||
let byteString = atob(base64.split(',')[1]);
|
||||
//创建缓冲数组
|
||||
let arrayBuffer = new ArrayBuffer(byteString.length);
|
||||
//创建视图
|
||||
let intArray = new Uint8Array(arrayBuffer);
|
||||
for (let i = 0; i < byteString.length; i++) {
|
||||
intArray[i] = byteString.charCodeAt(i);
|
||||
}
|
||||
resolve(URL.createObjectURL(new Blob([intArray], {
|
||||
type: mimeString
|
||||
})))
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
|
||||
bitmap.loadBase64Data(base64, () => {
|
||||
if (!filename && !format) {
|
||||
reject(new Error('ERROR_BASE64SRC_PARSE'))
|
||||
}
|
||||
// const time = new Date().getTime();
|
||||
const name = filename || `${new Date().getTime()}.${format}`;
|
||||
const filePath = `_doc/uniapp_temp/${name}`
|
||||
bitmap.save(filePath, {},
|
||||
() => {
|
||||
bitmap.clear()
|
||||
resolve(filePath)
|
||||
},
|
||||
(error) => {
|
||||
bitmap.clear()
|
||||
reject(error)
|
||||
})
|
||||
}, (error) => {
|
||||
bitmap.clear()
|
||||
reject(error)
|
||||
})
|
||||
// #endif
|
||||
})
|
||||
}
|
||||
21
src/uni_modules/lime-shared/camelCase/index.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* 将字符串转换为 camelCase 或 PascalCase 风格的命名约定
|
||||
* @param str 要转换的字符串
|
||||
* @param isPascalCase 指示是否转换为 PascalCase 的布尔值,默认为 false
|
||||
* @returns 转换后的字符串
|
||||
*/
|
||||
export function camelCase(str: string, isPascalCase: boolean = false): string {
|
||||
// 将字符串分割成单词数组
|
||||
let words: string[] = str.split(/[\s_-]+/);
|
||||
|
||||
// 将数组中的每个单词首字母大写(除了第一个单词)
|
||||
let camelCased: string[] = words.map((word, index) => {
|
||||
if (index === 0 && !isPascalCase) {
|
||||
return word.toLowerCase(); // 第一个单词全小写
|
||||
}
|
||||
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
||||
});
|
||||
|
||||
// 将数组中的单词拼接成一个字符串
|
||||
return camelCased.join('');
|
||||
};
|
||||
58
src/uni_modules/lime-shared/canIUseCanvas2d/index.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
// @ts-nocheck
|
||||
// #ifdef MP-ALIPAY
|
||||
interface My {
|
||||
SDKVersion: string
|
||||
}
|
||||
declare var my: My
|
||||
// #endif
|
||||
|
||||
function compareVersion(v1:string, v2:string) {
|
||||
let a1 = v1.split('.');
|
||||
let a2 = v2.split('.');
|
||||
const len = Math.max(a1.length, a2.length);
|
||||
|
||||
while (a1.length < len) {
|
||||
a1.push('0');
|
||||
}
|
||||
while (a2.length < len) {
|
||||
a2.push('0');
|
||||
}
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
const num1 = parseInt(a1[i], 10);
|
||||
const num2 = parseInt(a2[i], 10);
|
||||
|
||||
if (num1 > num2) {
|
||||
return 1;
|
||||
}
|
||||
if (num1 < num2) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function gte(version: string) {
|
||||
let {SDKVersion} = uni.getSystemInfoSync();
|
||||
// #ifdef MP-ALIPAY
|
||||
SDKVersion = my.SDKVersion
|
||||
// #endif
|
||||
return compareVersion(SDKVersion, version) >= 0;
|
||||
}
|
||||
|
||||
/** 环境是否支持canvas 2d */
|
||||
export function canIUseCanvas2d() {
|
||||
// #ifdef MP-WEIXIN
|
||||
return gte('2.9.0');
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
return gte('2.7.0');
|
||||
// #endif
|
||||
// #ifdef MP-TOUTIAO
|
||||
return gte('1.78.0');
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO
|
||||
return false
|
||||
// #endif
|
||||
}
|
||||