92 Commits

Author SHA1 Message Date
3d6252d5cb Merge pull request '抽奖' (#34) from dev-qsh into jwl-gift
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/34
2024-01-25 09:07:54 +08:00
qsh
056ca965b3 抽奖 2024-01-25 08:59:04 +08:00
4fd6a21f35 Merge pull request 'dev-hxf' (#33) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/33
2023-11-07 20:58:25 +08:00
7b1db47383 提交 2023-11-07 20:50:15 +08:00
79236493e6 Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-10-30 20:29:32 +08:00
59c49bfdf2 提交 2023-10-30 20:29:18 +08:00
110e9d4adc Merge pull request '屏蔽Ios支付' (#32) from dev-qsh into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/32
2023-10-25 20:33:06 +08:00
qsh
b533581a5d 屏蔽Ios支付 2023-10-25 20:30:58 +08:00
ac8acdccda Merge pull request 'dev-hxf' (#31) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/31
2023-10-17 12:03:51 +08:00
f4b6f96649 Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-10-17 12:01:11 +08:00
9ba3f6ed48 提交 2023-10-17 12:00:58 +08:00
253ab2a80d Merge pull request 'dev-hxf' (#30) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/30
2023-10-10 18:07:01 +08:00
bfdbd3f7f3 Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-10-10 17:56:31 +08:00
e3544ee06e 提交 2023-10-10 17:56:20 +08:00
7e15974ea6 Merge pull request 'dev-hxf' (#29) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/29
2023-09-21 16:34:55 +08:00
46972d5bff Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-09-21 16:31:30 +08:00
851319e24c 提交 2023-09-21 16:30:36 +08:00
19616d56c5 Merge pull request 'dev-hxf' (#28) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/28
2023-09-20 22:32:22 +08:00
89c4b2148e 提交 2023-09-20 22:23:21 +08:00
e68a422cc8 Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-09-20 22:18:41 +08:00
2e93ad93e9 提交 2023-09-20 22:18:19 +08:00
c783ff969d Merge pull request 'dev-hxf' (#27) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/27
2023-09-18 21:44:49 +08:00
4526430a38 Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-09-18 21:43:29 +08:00
3a0545852f 提交 2023-09-18 21:42:50 +08:00
0410e5dda9 Merge pull request 'dev-hxf' (#26) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/26
2023-09-17 23:53:26 +08:00
0c230fa5f1 Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-09-17 23:49:59 +08:00
ded28b62fb 提交 2023-09-17 23:49:42 +08:00
6834b3f9fe Merge pull request 'dev-hxf' (#25) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/25
2023-09-17 13:23:02 +08:00
3379a9b18e Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-09-17 13:19:26 +08:00
9e871e4079 提交 2023-09-17 13:18:59 +08:00
728fefac03 Merge pull request 'dev-hxf' (#24) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/24
2023-09-07 09:55:25 +08:00
bf05f771f7 提交 2023-09-07 09:47:38 +08:00
287f123ac7 提交 2023-09-06 00:28:46 +08:00
89c72e336b Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-08-30 23:15:55 +08:00
135bcc71ee 提交 2023-08-30 23:15:41 +08:00
a09ef61e2f Merge pull request 'dev-hxf' (#23) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/23
2023-08-29 00:30:36 +08:00
d88f92a893 Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-08-29 00:24:59 +08:00
dc340c7f4d 提交 2023-08-29 00:24:24 +08:00
0c6182e6f5 Merge pull request '提交' (#22) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/22
2023-08-28 02:07:39 +08:00
f762ca430d 提交 2023-08-28 02:02:46 +08:00
37c5de0899 Merge pull request '科一真实考场' (#21) from dev-qsh into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/21
2023-08-27 02:38:45 +08:00
qsh
04a4a4781d 科一真实考场 2023-08-27 02:37:34 +08:00
741b5a1d29 Merge pull request '科一真实考场' (#20) from dev-qsh into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/20
2023-08-26 20:45:02 +08:00
qsh
f36cffdd37 Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-qsh 2023-08-26 20:42:47 +08:00
qsh
7db9e68e77 真实考场科目1 2023-08-26 20:42:42 +08:00
d82a84798c Merge pull request 'dev-hxf' (#19) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/19
2023-08-26 14:15:26 +08:00
4bfce94c24 Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-08-26 14:10:34 +08:00
c3e6002ca3 提交 2023-08-26 14:10:16 +08:00
fa6665d9f6 Merge pull request 'dev-hxf' (#18) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/18
2023-08-25 15:11:59 +08:00
77de5d5d6e Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-08-25 15:07:01 +08:00
9e4b78882e 提交 2023-08-25 15:06:46 +08:00
5640ef7f36 Merge pull request 'dev-hxf' (#17) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/17
2023-08-24 17:08:57 +08:00
d36b01a69f Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-08-24 17:07:58 +08:00
8a1d49b47f 提交 2023-08-24 17:07:43 +08:00
0b39b49a5d Merge pull request 'dev-hxf' (#16) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/16
2023-08-24 16:59:28 +08:00
9afe858077 Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-08-24 16:58:45 +08:00
5f6646ae4e 提交 2023-08-24 16:58:38 +08:00
3c137e8025 Merge pull request 'dev-hxf' (#15) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/15
2023-08-24 16:55:38 +08:00
3c4e11799b 提交 2023-08-24 16:53:11 +08:00
97547afc4d 提交 2023-08-24 15:26:02 +08:00
4c4bd6236d Merge pull request '修改' (#14) from dev-qsh into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/14
2023-08-24 15:19:47 +08:00
qsh
49abbc764b 修改 2023-08-24 15:18:49 +08:00
91b90c809e Merge pull request 'dev-hxf' (#13) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/13
2023-08-23 21:45:53 +08:00
1596959583 Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-08-23 21:44:22 +08:00
36f8a9b2cc 提交 2023-08-23 21:42:21 +08:00
fa9d6a8696 Merge pull request 'vip滑动Bug' (#12) from dev-qsh into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/12
2023-08-23 17:48:18 +08:00
qsh
78cf2fd9f7 vip滑动Bug 2023-08-23 17:47:45 +08:00
a7c7b410d3 Merge pull request 'dev-hxf' (#11) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/11
2023-08-22 17:33:52 +08:00
c0df8a314e 提交 2023-08-22 17:27:54 +08:00
d155bd8b2d Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-08-21 09:11:06 +08:00
7c54101dd6 提交 2023-08-21 09:10:50 +08:00
1368854459 Merge pull request 'dev-hxf' (#10) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/10
2023-08-20 02:02:34 +08:00
a90c28f6fd 提交 2023-08-20 01:59:40 +08:00
e635b5c431 Merge branch 'master' of http://114.55.169.15:3000/huxiaofeng666/jwl-applet into dev-hxf 2023-08-19 21:49:56 +08:00
02591755f0 提交 2023-08-19 21:49:44 +08:00
89e073098a Merge pull request '图片压缩' (#9) from dev-qsh into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/9
2023-08-19 18:16:31 +08:00
qsh
1f304a6895 图片压缩 2023-08-19 18:15:49 +08:00
4f252443f5 提交 2023-08-19 17:44:10 +08:00
741244ad8d Merge pull request '会员+驾校联调' (#8) from dev-qsh into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/8
2023-08-19 17:43:13 +08:00
qsh
55394e8487 会员+驾校联调 2023-08-19 17:42:47 +08:00
58928d301a Merge pull request '联调' (#7) from dev-qsh into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/7
2023-08-19 16:23:06 +08:00
qsh
129b9808fb 联调 2023-08-19 16:22:34 +08:00
d74abad722 Merge pull request 'dev-hxf' (#6) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/6
2023-08-19 16:21:16 +08:00
90ffd2e4ff 提交 2023-08-19 16:09:35 +08:00
b9d7228a90 提交 2023-08-19 14:04:52 +08:00
1f6080aa01 Merge pull request '登录相关' (#5) from dev-qsh into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/5
2023-08-19 00:54:08 +08:00
qsh
ae7e2bc17f 登录相关 2023-08-19 00:52:53 +08:00
266b7d4a0f Merge pull request 'dev-hxf' (#4) from dev-hxf into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/4
2023-08-18 01:47:06 +08:00
ea9137eb0c 提交 2023-08-18 01:41:17 +08:00
d8332a326b 提交 2023-08-17 21:52:45 +08:00
7e166ad8d5 Merge pull request '我的' (#3) from dev-qsh into master
Reviewed-on: http://114.55.169.15:3000/huxiaofeng666/jwl-applet/pulls/3
2023-08-17 01:19:03 +08:00
qsh
df910fb182 我的 2023-08-17 01:17:33 +08:00
182 changed files with 18104 additions and 2477 deletions

View File

@@ -5,7 +5,6 @@ VITE_APP_TITLE = 金武联驾校
VITE_APP_ENV = 'development'
# 金武联驾校/开发环境
VITE_APP_BASE_API = 'https://test.jd-mall.cn/dev/zongheng-api/'
VITE_APP_BASE_API = 'https://jwl.ahduima.com/'
#
VITE_WEB_BASE_URL = 'https://test.jd-mall.cn/dev/zongheng'
VITE_WEB_BASE_URL = 'https://jwl.ahduima.com'

View File

@@ -5,7 +5,7 @@ VITE_APP_TITLE = 金武联驾校
VITE_APP_ENV = 'production'
# 金武联驾校/开发环境
VITE_APP_BASE_API = 'https://i.equ-tech.com/zongheng-api/'
VITE_APP_BASE_API = 'https://jwl.ahduima.com/'
#
VITE_WEB_BASE_URL = 'https://i.equ-tech.com/zongheng'
VITE_WEB_BASE_URL = 'https://jwl.ahduima.com'

View File

@@ -1,5 +1,5 @@
{
"name": "OA",
"name": "jwl",
"version": "0.0.0",
"scripts": {
"dev:h5": "uni",
@@ -15,7 +15,7 @@
"@dcloudio/uni-h5": "3.0.0-alpha-3060420220922001",
"@dcloudio/uni-mp-weixin": "3.0.0-alpha-3060420220922001",
"jsencrypt-plus": "^0.1.0",
"pinia": "^2.0.36",
"pinia": "2.0.36",
"pinia-plugin-persist-uni": "^1.2.0",
"vue": "^3.2.37",
"vue-i18n": "^9.1.9"

View File

@@ -1,9 +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 () {
console.log('App Launch')
onLaunch: function (options) {
// 如果是二维码扫描过来的需要保存公司id
if (options.query?.scene) {
storage.set('companyId', options.query?.scene)
}
useUserStore().queryVipList()
if (useUserStore().isLogin) {
useUserStore().getUserInfo()
useUserStore().searchUserVip()
}
},
onShow: function () {
useQuestionStore().getAllQuestion()
console.log('App Show')
},
onHide: function () {
@@ -16,4 +28,8 @@ export default {
/*每个页面公共css */
@import "uni_modules/uview-plus/index.scss";
@import "static/style/index.scss";
button::after {
border: none;
}
</style>

View File

@@ -7,7 +7,7 @@
<view class="u-back-text u-line-1 u-m-l-20" v-if="backText" :style="[backTextStyle]">{{ backText || '' }}</view>
</view>
<slot name="left"></slot>
<view class="content fs32 fwb" :style="[{ top: statusBarHeight + 'px' }]"><slot></slot></view>
<view class="content fs16" :style="[{ top: statusBarHeight + 'px' }]"><slot></slot></view>
<view class="right">
<slot name="right"></slot>
</view>
@@ -109,14 +109,24 @@ export default {
backPath: {
type: String,
default: ''
},
isDefineBack:{
type:Boolean,
default:false
}
},
methods: {
goBack() {
if(this.backPath) {
this.$tools.routerTo(this.backPath)
} else {
uni.navigateBack();
if(this.isDefineBack){
this.$emit('toBack')
}else{
if(this.backPath) {
uni.switchTab({
url:this.backPath
})
} else {
uni.navigateBack();
}
}
}
}
@@ -130,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;

View File

@@ -0,0 +1,358 @@
<template>
<view class="liu-list">
<scroll-view class="liu-scroll-left" scroll-y="true" :scroll-with-animation="true"
:scroll-into-view="scrollIntoView">
<view class="liu-search" id="TOP">
<image class="liu-search-img" src="../../static/image/mine/search.png"></image>
<input class="liu-input" @input="search" v-model="searchStr" placeholder="请输入搜索信息" maxlength="50"
placeholder-class="liu-placeholder" />
</view>
<view class="left-list" v-for="(item,index) of scrollLeftObj" :key="index" :id="index!='#'?index:'BOTTOM'">
<view class="left-item-title" v-if="item && item.length">{{index}}</view>
<view class="left-item-card" v-for="(mess,inx) in item" @click.stop="chooseItem(mess)">
<view class="left-item-card-info"
:style="inx<item.length-1?'border-bottom: solid #F4F4F4 1rpx;':''">
<view class="left-item-card-name" :class="{ actived: mess[idKey] == current }">
{{mess[nameKey] || ''}}
</view>
<u-icon class="mr30" v-if="mess[idKey] == current" color="#05C341" size="16px" name="checkmark"></u-icon>
</view>
</view>
</view>
<view class="no-data" v-if="!hasData">
<image class="no-data-img" src="../../static/image/mine/noData.png"></image>
<view class="no-data-name">暂无数据</view>
</view>
</scroll-view>
<view class="liu-scroll-right" v-if="hasData">
<image class="liu-scroll-right-top" src="../../static/image/mine/top.png" @click.stop="scrollIntoView = 'TOP'"></image>
<view :class="{'liu-scroll-right-name':true,'liu-scroll-right-select':item==scrollIntoView}"
v-for="(item,index) in scrollRightList" :key="index" @click.stop="chooseType(item)">{{item}}
</view>
</view>
</view>
</template>
<script>
import {
pinyinUtil
} from './pinyinUtil.js';
export default {
props: {
//数据源
dataList: {
type: Array,
required: true,
default: () => {
return []
}
},
//显示的主键key值
idKey: {
type: String,
default: 'id'
},
//显示的名字key值
nameKey: {
type: String,
default: 'name'
},
//显示的电话key值
phoneKey: {
type: String,
default: 'phone'
},
//显示的头像key值
imgKey: {
type: String,
default: 'img'
},
//头像圆角(rpx、px、%)
radius: {
type: String,
default: '6rpx'
},
current: {
type: [String,Number],
default: ''
}
},
data() {
return {
searchStr: '',
scrollIntoView: '',
scrollLeftObj: {},
oldObj: {},
scrollRightList: [],
hasData: true
};
},
watch: {
dataList: {
immediate: true,
deep: true,
handler(newList) {
if (newList && newList.length) this.cleanData(newList)
},
},
},
methods: {
search() {
if (this.searchStr) {
let has = false
this.scrollLeftObj = JSON.parse(JSON.stringify(this.oldObj))
for (let i in this.scrollLeftObj) {
this.scrollLeftObj[i] = this.scrollLeftObj[i].filter(item => {
return (item[this.nameKey].indexOf(this.searchStr) != -1) || item[this.phoneKey]
.indexOf(this.searchStr) != -1
})
if (this.scrollLeftObj[i].length) has = true
}
if (has) this.hasData = true
else this.hasData = false
} else {
this.hasData = true
this.scrollLeftObj = JSON.parse(JSON.stringify(this.oldObj))
}
},
cleanData(list) {
this.scrollRightList = this.getLetter()
let newList = []
list.forEach(res => {
let initial = pinyinUtil.getFirstLetter(res[this.nameKey].trim())
let firsfirs = initial ? initial.substring(0, 1) : ''
if (!newList[firsfirs]) newList[firsfirs] = []
newList[firsfirs].push({
[this.idKey]: res[this.idKey] || '',
[this.nameKey]: res[this.nameKey].trim() || '',
[this.phoneKey]: res[this.phoneKey] || '',
[this.imgKey]: res[this.imgKey] || ''
})
})
this.scrollRightList.forEach(t => {
if (newList[t]) {
this.$set(this.scrollLeftObj, t, newList[t])
} else {
this.$set(this.scrollLeftObj, t, [])
}
})
let surplusList = []
for (var i in newList) {
let han = this.scrollRightList.find(v => {
return v == i
})
if (!han) surplusList.push(newList[i])
}
surplusList.forEach(item => {
this.scrollLeftObj['#'] = this.scrollLeftObj['#'].concat(item)
})
this.oldObj = JSON.parse(JSON.stringify(this.scrollLeftObj))
},
getLetter() {
let list = []
for (var i = 0; i < 26; i++) {
list.push(String.fromCharCode(65 + i))
}
list.push('#')
return list
},
chooseType(item) {
if (item == '#') item = 'BOTTOM'
this.scrollIntoView = item
},
preview(img) {
uni.previewImage({
current: 0,
urls: [img]
})
},
chooseItem(item) {
this.$emit('update:current', item[this.idKey])
this.$emit('click', item)
}
},
emits: ['update:current']
};
</script>
<style>
/deep/ ::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
display: none;
}
</style>
<style lang="scss" scoped>
.liu-list {
width: 100%;
height: 100vh;
background-color: #F4F4F4;
box-sizing: border-box;
padding-top: 1px;
.liu-scroll-left {
height: 100%;
.liu-search {
width: 100%;
height: 106rpx;
background-color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.liu-search-img {
width: 32rpx;
height: 32rpx;
position: absolute;
left: 64rpx;
}
.liu-input {
width: calc(100% - 64rpx);
height: 72rpx;
background: #EEEEEE;
border-radius: 36rpx;
padding: 0 32rpx 0 80rpx;
box-sizing: border-box;
color: #333333;
}
.liu-placeholder {
color: #777777;
}
}
.left-list {
height: auto;
.left-item-title {
width: calc(100% - 24rpx);
height: 60rpx;
padding-left: 24rpx;
text-align: left;
line-height: 60rpx;
font-size: 30rpx;
color: #666666;
}
.left-item-card {
width: 100%;
height: 112rpx;
background-color: #FFFFFF;
box-sizing: border-box;
padding-left: 24rpx;
display: flex;
align-items: center;
justify-content: flex-start;
.left-item-card-img {
width: 80rpx;
min-width: 80rpx;
height: 80rpx;
background-color: #CFCFCF;
display: flex;
align-items: center;
justify-content: center;
font-size: 36rpx;
font-weight: bold;
color: #FFFFFF;
}
.img-info {
background: none;
border: solid #f0f0f0 1rpx;
}
.left-item-card-info {
width: 100%;
margin-left: 32rpx;
height: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.left-item-card-name {
font-size: 30rpx;
line-height: 30rpx;
color: #333333;
}
.left-item-card-phone {
margin-top: 14rpx;
font-size: 28rpx;
line-height: 28rpx;
color: #999999;
}
}
}
}
.no-data {
width: 100%;
display: flex;
align-items: center;
justify-items: center;
flex-direction: column;
margin-top: 25%;
.no-data-img {
width: 200rpx;
height: 200rpx;
}
.no-data-name {
margin-top: 20rpx;
font-size: 28rpx;
color: #666666;
}
}
}
.liu-scroll-right {
position: fixed;
right: 0rpx;
top: 50%;
transform: translateY(-47%);
z-index: 999 !important;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.liu-scroll-right-top {
width: 32rpx;
height: 32rpx;
margin-right: 14rpx;
z-index: 999 !important;
}
.liu-scroll-right-name {
width: 32rpx;
padding-right: 14rpx;
height: 28rpx;
font-size: 22rpx;
color: #333333;
line-height: 22rpx;
margin-top: 8rpx;
display: flex;
align-items: center;
justify-content: center;
}
.liu-scroll-right-select {
padding: 0;
margin-right: 14rpx;
width: 28rpx;
height: 28rpx;
border-radius: 50%;
background: #2991FF;
color: #FFFFFF;
}
}
}
.actived {
color: #05C341 !important;
}
</style>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,39 @@
/**
* @description 用于获取用户传递值的px值 如果用户传递了"xxpx"或者"xxrpx",取出其数值部分,如果是"xxxrpx"还需要用过uni.upx2px进行转换
* @param {number|string} value 用户传递值的px值
* @param {boolean} unit
* @returns {number|string}
*/
export const getPx = (value, unit = false)=> {
if (testNumber(value)) {
return unit ? `${value}px` : Number(value)
}
// 如果带有rpx先取出其数值部分再转为px值
if (/(rpx|upx)$/.test(value)) {
return unit ? `${uni.upx2px(parseInt(value))}px` : Number(uni.upx2px(parseInt(value)))
}
return unit ? `${parseInt(value)}px` : parseInt(value)
}
/**
* @description 添加单位如果有rpxupx%px等单位结尾或者值为auto直接返回否则加上px单位结尾
* @param {string|number} value 需要添加单位的值
* @param {string} unit 添加的单位名 比如px
*/
export const addUnit =(value = 'auto', unit = 'px')=> {
value = String(value)
// 用uView内置验证规则中的number判断是否为数值
return testNumber(value) ? `${value}${unit}` : value
}
/**
* 验证十进制数字
*/
function testNumber(value) {
return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value)
}
/**
* @description 获取系统信息同步接口
* @link 获取系统信息同步接口 https://uniapp.dcloud.io/api/system/info?id=getsysteminfosync
*/
export const sys=()=> {
return uni.getSystemInfoSync()
}

View File

@@ -0,0 +1,345 @@
<template>
<view class="sunny-video">
<video class="video" :style="{height:elVideoHeight.strNum}" id="sunnyVideo" ref="sunnyVideo" :title="title" :src="src" :show-center-play-btn="false" :controls="isPlay" @timeupdate="timeupdate" enable-play-gesture :show-mute-btn="showMuteBtn" @play="play" @pause="pause" @ended="ended" @error="playError" @fullscreenchange="fullscreenchange">
<!-- <cover-view class="video-view">
<cover-image class="img" src="static/left.png" @click="onBack"></cover-image>
</cover-view> -->
<cover-view v-if="!isPlay" class="banner-view" :style="{height:elVideoHeight.strNum}">
<cover-image v-if="poster" class="banner" :style="{height:elVideoHeight.strNum}" :src="poster" mode="" @click="onPlayChange"></cover-image>
<cover-image class="imgPal" :style="{width:playBtnHeight.strNum,height:playBtnHeight.strNum,top:`${elVideoHeight.intNum/2}px`,transform:`translate(-${playBtnHeight.intNum/2}px,-${playBtnHeight.intNum/2}px)`}" @click="onPlayChange" :src="playImg"></cover-image>
</cover-view>
<cover-view v-if="isPlay&&!isShowRateBox" class="speedText" :style="{top:`${isFullScreen?(screenInfo.width/2) - 14.5 +'px':(elVideoHeight.intNum/2)- 14.5+'px'}`}" @click="isShowRateBox = true">
<!-- #ifndef MP-WEIXIN || APP-NVUE -->
<cover-view class="text" @click="isShowRateBox = true">{{rateText}}X</cover-view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<text class="text">{{rateText}}X</text>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
{{rateText}}X
<!-- #endif -->
</cover-view>
<cover-view v-if="isFullScreen&&isShowRateBox" class="vertical vertical-full" :style="{width:`${screenInfo.height}px`,height:`${isShowRateBox? screenInfo.width : screenInfo.width-40}px`}">
<!-- #ifdef APP-NVUE -->
<view class="options" :style="{width:`${screenInfo.height - screenInfo.options}px`,height:`${screenInfo.width}px`}" @click="isShowRateBox=false"></view>
<view class="speed-box" :style="{height:`${screenInfo.width}px`}">
<text class="speeds" :class="{act:item.isTo}" v-for="(item,index) in rateList" :key="item.name" @click="changeRate(item,index)">{{item.name}}X</text>
</view>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<cover-view class="options" :style="{width:`${screenInfo.height - screenInfo.options}px`,height:`${screenInfo.width}px`}" @click="isShowRateBox=false"></cover-view>
<cover-view class="speed-box" :style="{height:`${screenInfo.width}px`}">
<cover-view class="speeds" :class="{act:item.isTo}" v-for="(item,index) in rateList" :key="item.name" @click="changeRate(item,index)">{{item.name}}X</cover-view>
</cover-view>
<!-- #endif -->
</cover-view>
<cover-view v-if="!isFullScreen&&isShowRateBox" class="vertical" :style="{height:`${isShowRateBox ? elVideoHeight.intNum:elVideoHeight.intNum - 44}px`}">
<!-- #ifdef APP-NVUE -->
<view class="options" :style="{height:elVideoHeight.strNum}" @click="isShowRateBox=false"></view>
<view class="speed-box" :style="{height:elVideoHeight.strNum}">
<text class="speeds" :class="{act:item.isTo}" v-for="(item,index) in rateList" :key="item.name" @click="changeRate(item,index)">{{item.name}}X</text>
</view>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<cover-view class="options" :style="{height:elVideoHeight.strNum}" @click="isShowRateBox=false"></cover-view>
<cover-view class="speed-box" :style="{height:elVideoHeight.strNum}">
<cover-view class="speeds" :class="{act:item.isTo}" v-for="(item,index) in rateList" :key="item.name" @click="changeRate(item,index)">{{item.name}}X</cover-view>
</cover-view>
<!-- #endif -->
</cover-view>
</video>
</view>
</template>
<script>
import {getPx,addUnit,sys} from './function.js'
import playImgs from '../../static/image/index/play.png'
export default {
props:{
// 视频地址
src:{
type:String,
default:''
},
// 视频标题
title:{
type:String,
default:''
},
// 视频封面
poster:{
type:String,
default:''
},
// 视频高度
videoHeight:{
type: [String, Number],
default: '230px'
},
// 播放图片按钮宽高
playImgHeight:{
type: [String, Number],
default: '70rpx'
},
// 暂停按钮
playImg:{
type:String,
default:playImgs
},
// 是否显示静音按钮
showMuteBtn:{
type:Boolean,
default:false
},
// 播放完毕是否退出全屏
isExitFullScreen:{
type:Boolean,
default:true
}
},
data() {
return {
videoCtx:'', //视频上下文
isPlay:false,// 视频是否播放过
isShowRateBox:false,// 是否显示倍速盒子
rateText:'1.0',// 当前倍速
rateList: [{
name:'0.5',
isTo:false
},{
name:'0.8',
isTo:false
},{
name:'1.0',
isTo:true
},{
name:'1.25',
isTo:false
},{
name:'1.5',
isTo:false
}
// #ifdef MP-WEIXIN
,{
name:'2.0',
isTo:false
}
// #endif
], //倍数
isFullScreen: false, //全屏状态
// 屏幕信息
screenInfo:{
width:0,
height:0,
options:getPx('160rpx'),// 遮罩要减去的高度
}
}
},
computed:{
// 视频单位高度信息
elVideoHeight() {
return {
intNum:getPx(this.videoHeight ? this.videoHeight : 230),
strNum:addUnit(this.videoHeight ? this.videoHeight : 230)
}
},
// 播放图片按钮宽高信息
playBtnHeight(){
return {
intNum:getPx(this.playImgHeight ? this.playImgHeight : '70rpx'),
strNum:addUnit(this.playImgHeight ? this.playImgHeight : '70rpx')
}
}
},
mounted() {
this.videoCtx = uni.createVideoContext('sunnyVideo', this)
this.getScreenInfo()
},
methods: {
// 获取元素信息
getDomInfo(elId){
return new Promise(resolve => {
const view = uni.createSelectorQuery().select(`#${elId}`)
view.boundingClientRect(data=>{
resolve(data.height)
}).exec()
})
},
//监听开始播放
play(e){
this.isPlay=true
this.$emit('play')
},
// 监听视频暂停
pause(){
this.$emit('pause')
},
// 视屏播放出错
playError(e){
this.$emit('playError',e)
},
// 监听视频结束
ended(){
this.$emit('videoEnded')
if(!this.isExitFullScreen)return
this.videoCtx.exitFullScreen(); //退出全屏
},
onBack(){
uni.navigateBack()
},
// 播放进度
timeupdate(e) {
this.$emit('timeupdate',e)
},
// 切换倍速
changeRate(item,index){
if(item.isTo)return this.isShowRateBox = false
this.rateList.forEach((v,i)=>{
i==index?v.isTo=true:v.isTo=false
})
this.videoCtx.playbackRate(item.name*1)
this.rateText = item.name
this.isShowRateBox = false
},
// 播放视频
onPlayChange(){
this.$nextTick(()=>{
this.videoCtx.play()
/* this.rateText ='1.0'
this.videoCtx.playbackRate(1) */
})
},
// 全屏操作
fullscreenchange(){
this.isFullScreen=!this.isFullScreen
this.$emit('fullscreenchange',this.isFullScreen)
},
// 获取屏幕信息
getScreenInfo(){
const res = sys()
this.screenInfo.width = res.screenWidth
this.screenInfo.height = res.screenHeight
},
}
}
</script>
<style lang="scss">
$sunny-primary: #00B74F;
.sunny-video{
position: relative;
z-index: 0;
.speedText{
position: absolute;
top: 240rpx;
right: 30rpx;
z-index: 5;
padding: 10rpx;
padding-right: 0;
font-size: 30rpx;
color: $sunny-primary;
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
.text{
font-size: 30rpx;
color: $sunny-primary;
}
}
}
.video {
width: 750rpx;
height: 230px;
}
.video-view{
position: absolute;
z-index:999;
display: flex;
align-items: center;
justify-content: space-between;
width: 750rpx;
/* #ifndef APP-NVUE */
padding: var(--status-bar-height) 32rpx 0;
/* #endif */
.img{
width: 56rpx;
height: 56rpx;
}
}
.banner-view{
position: relative;
width: 750rpx;
height: 230px;
.banner{
width: 750rpx;
height: 230px;
}
.imgPal{
position: absolute;
z-index: 2;
top: 240rpx;
left: 375rpx;
transform: translate(-35rpx,-35rpx);
width: 70rpx;
height: 70rpx;
}
}
.vertical{
position: relative;
width: 750rpx;
height: 410rpx;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
&.vertical-full{
position: relative;
.speed-box{
padding: 50rpx 0;
}
}
.options{
width: 590rpx;
}
.speed-text{
position: absolute;
top: 240rpx;
right: 30rpx;
font-size: 30rpx;
color: #fff;
}
.speed-box{
position: absolute;
right: 0;
top: 0;
width: 160rpx;
height: 230px;
/* #ifndef APP-NVUE */
display: flex;
box-sizing: border-box;
/* #endif */
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 10px 0;
background-color: rgba(0, 0, 0, 0.7);
.speeds{
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
width: 160rpx;
text-align: center;
font-size: 28rpx;
color: #fff;
padding: 10px 0px;
&.act{
color: $sunny-primary;
}
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View 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>
```

View 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>

View File

@@ -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
});
}

View File

@@ -2,9 +2,40 @@ import request from '../request/index.js';
export function login(data) {
return request({
url: 'api-admin/pcLogin',
url: 'driver-api/tdSysUser/login',
method: 'POST',
data,
noToken: true
});
}
export function getCode(data) {
return request({
url: 'driver-api/tdSysUser/code',
method: 'get',
data,
noToken: true
});
}
export function logout() {
return request({
url: 'driver-api/tdSysUser/loginOut',
method: 'get'
});
}
export function getInfo() {
return request({
url: 'driver-api/tdSysUser/queryUserMessage',
method: 'get'
});
}
export function bindSchool(data) {
return request({
url: 'driver-api/tdSysUser/bindSchool',
method: 'post',
data
});
}

9
src/jtools/api/pay.js Normal file
View File

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

110
src/jtools/api/question.js Normal file
View File

@@ -0,0 +1,110 @@
import request from '../request/index.js';
export function queryQuestion(data) {
return request({
url: 'driver-api/tdQuestion/queryQuestion',
method: 'POST',
data,
noToken: true
});
}
export function questionCategory(data) {
return request({
url: 'driver-api/tdQuestion/questionCategory',
method: 'POST',
data,
noToken: true
});
}
export function getTestQuestion(data) {
return request({
url: 'driver-api/tdQuestion/getTestQuestion',
method: 'POST',
data
});
}
export function submitTest(data) {
return request({
url: 'driver-api/tdQuestionTest/testSubmit',
method: 'POST',
data
});
}
export function testTotal(data) {
return request({
url: 'driver-api/tdQuestionTest/testTotal',
method: 'POST',
data
});
}
//获取配置
export function querySysConfigList(carTypeId, configKey) {
return request({
url: 'driver-api/tdSysConfigList/querySysConfigList?configKey=' + configKey + '&carTypeId=' + carTypeId,
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,
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
});
}

18
src/jtools/api/vip.js Normal file
View File

@@ -0,0 +1,18 @@
import request from '../request/index.js';
export function queryVip(data) {
return request({
url: 'driver-api/tdMember/queryUserMember',
method: 'POST',
data
});
}
export function getVipList(data) {
return request({
url: 'driver-api/tdMember/queryMember',
method: 'POST',
data,
noToken: true
});
}

159
src/jtools/pay/index.js Normal file
View File

@@ -0,0 +1,159 @@
import request from '../request/index.js';
// #ifdef H5
// import wxsdk from '@/jtools/wechat/sdk'
// #endif
// import wechat from '@/jtools/wechat/wechat'
import $platform from '@/jtools/platform';
import {prePay} from '@/jtools/api/pay'
/**
* 支付
*
* @param {String} payment = ['wechat','alipay','wallet'] - 支付方式
* @param {Object} order = {} - 订单详情
* @param {String} orderType = ['goods','recharge'] - 订单类型
*/
export default class JtoolsPay {
// wxOfficialAccount wxMiniProgram App H5
// wechat 公众号JSSDK支付 小程序支付 微信开放平台支付 H5网页支付
// alipay 复制网址 复制网址 支付宝开放平台支付 直接跳转链接
// wallet v v v v
constructor(payment, order, orderType) {
this.payment = payment;
this.order = order;
this.orderType = orderType;
this.platform = $platform.get();
let payMehod = this.getPayMethod();
payMehod();
}
getPayMethod() {
var payMethod = {
'wxMiniProgram': {
'wechat': () => {
this.wxMiniProgramPay()
},
},
'App': {
'wechat': () => {
this.wechatPay()
},
'alipay': () => {
this.aliPay()
},
},
}
return payMethod[this.platform][this.payment];
}
// 预支付
prepay() {
let that = this;
return new Promise((resolve, reject) => {
const p = $platform.device()
const tradeInfoType = p == 'android' ? 'Android' : p == 'ios' ? 'iOS' : 'Wap'
let params = {
"code":this.order.code,
"description": this.order.description,
"money": this.order.money,
"outTradeNo": this.order.outTradeNo,
"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);
}
})
});
}
// 微信小程序支付
async wxMiniProgramPay() {
let that = this;
let result = await this.prepay();
const params = result.data
uni.requestPayment({
provider: 'wxpay',
...{
appId: params.appId, //公众号名称,由商户传入
timeStamp: params.timeStamp, //时间戳自1970年以来的秒数
nonceStr: params.nonceStr, //随机串
package: params.packageVal,
signType: params.signType, //微信签名方式:
paySign: params.paySign, //微信签名
},
success: res => {
console.log(res);
that.payResult('success', result.data.orderPayNo)
},
fail: err => {
console.log('支付取消或者失败:', err);
err.errMsg !== "requestPayment:fail cancel" && that.payResult('fail')
}
});
}
// 支付宝支付
async aliPay() {
let that = this;
let result = await this.prepay();
if (result.code === 1) {
uni.requestPayment({
provider: 'alipay',
orderInfo: result.data.pay_data, //支付宝订单数据
success: res => {
that.payResult('success')
},
fail: err => {
err.errMsg !== "requestPayment:fail cancel" && that.payResult('fail')
}
});
}
}
// 微信支付
async wechatPay() {
let that = this;
let result = await this.prepay();
console.log('微信支付');
if (result.code === 1) {
uni.requestPayment({
provider: 'wxpay',
orderInfo: JSON.parse(result.data.pay_data), //微信订单数据(官方说是string。实测为object)
success: res => {
that.payResult('success')
},
fail: err => {
err.errMsg !== "requestPayment:fail cancel" && that.payResult('fail')
console.log('支付取消或者失败:', err);
}
});
}
}
// 支付结果跳转,success:成功fail:失败
payResult(resultType, orderPayNo) {
const that = this;
let path = 'paySuccess'
uni.navigateTo({
url: path
})
}
}

View File

@@ -1,4 +1,6 @@
import storage from '../storage/index.js';
import useUserStore from '@/jtools/store/user'
//把配置项单独处理
let server_url = ' '; // 请求地址
let token = ' '; // 凭证
@@ -14,7 +16,7 @@ function service(options = {}) {
});
} else {
options.header = {
Authorization: `Bearer ${token}`
Authorization: `${token}`
};
}
}
@@ -24,14 +26,18 @@ function service(options = {}) {
if (res.data.code == 'E403') {
// 未登录
uni.showToast({
title: res.data.message,
title: res?.data?.message || '请重新登录',
icon: 'none'
});
uni.redirectTo({
url: '/pages/login/login'
});
useUserStore().logoutWithoutToken()
//请求成功
resolved(res.data);
} else if(res.data.code != '0000'&&res.data.code !='4001') {
uni.showToast({
title: res?.data?.message || '访问出错',
icon: 'none'
})
resolved(res.data)
} else {
//请求成功
resolved(res.data);

View File

@@ -1,20 +1,238 @@
import { defineStore } from 'pinia';
import {
defineStore
} from 'pinia';
import http from '@/jtools/request/index';
import constants from '@/jtools/constants';
import {
queryQuestion,
getVersion,
querySysConfig
} from '@/jtools/api/question';
import storage from '@/jtools/storage';
const question = defineStore({
id: 'question',
state: () => ({
orderQuestionList: [], //顺序做题
}),
id: 'question',
state: () => ({
currentCartype: storage.get('carType') || '1001',
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: {
// 获取顺序做题
getQuestionList(arr) {
this.orderQuestionList=[...arr]
},
actions: {
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)
}
})
}
})
},
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
}
}
});
export default question;
export default question;

View File

@@ -1,68 +1,92 @@
import { defineStore } from 'pinia';
import http from '@/jtools/request/index';
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';
const user = defineStore({
const useUserStore = defineStore({
id: 'user',
state: () => ({
token: storage.get('token'),
isLogin: storage.get('isLogin'), // 是否登陆
userInfo: storage.get('userInfo'), // 用户信息
currentCartype: storage.get('carType') || '1001',
vipOnList: [],
vipAllList: []
}),
actions: {
// 登录
showAuth() {
// router.replaceAll('/pages/login/login');
},
// 获取个人信息
async getInfo() {
const { error, data } = await userApi.profile();
if (error !== 0) return;
this.userInfo = data;
return Promise.resolve(data);
},
// 设置token
setToken(token = '') {
if (token === '') {
this.isLogin = false;
this.token = ''
this.userInfo = {}
storage.set('token', '');
storage.set('isLogin', false);
storage.set('userInfo', {});
} else {
this.isLogin = true;
this.token = token
storage.set('token', token);
storage.set('isLogin', true);
}
return this.isLogin;
},
// 重置用户默认数据
resetUserData() {
this.setToken();
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();
}
});
},
// 登出
async logout(force = false) {
if (!force) {
const { error } = await userApi.logout();
if (error === 0) {
this.resetUserData();
}
}
if (force) {
logout(force = false) {
return new Promise((resolve, reject) => {
this.resetUserData();
}
return !this.isLogin;
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);
}
});
},
resetUserData() {
this.isLogin = false;
this.token = '';
this.userInfo = {};
this.vipOnList = [];
storage.remove('isLogin');
storage.remove('token');
storage.remove('userInfo');
},
// 查询当前用户的vip开通情况
async searchUserVip() {
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() {
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 user;
export default useUserStore;

View File

@@ -0,0 +1,167 @@
/**
* 判断url是否是http或https
* @param {string} path
* @returns {Boolean}
*/
export function isHttp(url) {
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1;
}
/**
* 判断path是否为外链
* @param {string} path
* @returns {Boolean}
*/
export function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path);
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validUsername(str) {
const valid_map = ['admin', 'editor'];
return valid_map.indexOf(str.trim()) >= 0;
}
/**
* @param {string} url
* @returns {Boolean}
*/
export function isURL(url) {
const reg =
/^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
return reg.test(url);
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validLowerCase(str) {
const reg = /^[a-z]+$/;
return reg.test(str);
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validUpperCase(str) {
const reg = /^[A-Z]+$/;
return reg.test(str);
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validAlphabets(str) {
const reg = /^[A-Za-z]+$/;
return reg.test(str);
}
/**
* @param {string} email
* @returns {Boolean}
*/
export function isEmail(email) {
const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return reg.test(email);
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function isString(str) {
if (typeof str === 'string' || str instanceof String) {
return true;
}
return false;
}
export function isPhone(str) {
return str && /^1[3456789]\d{9}$/.test(str)
}
/**
* @param {Array} arg
* @returns {Boolean}
*/
export function isArray(arg) {
if (typeof Array.isArray === 'undefined') {
return Object.prototype.toString.call(arg) === '[object Array]';
}
return Array.isArray(arg);
}
// 是否纯英文
export function isAllEN(val) {
return /^[a-zA-Z]*$/.test(val);
}
// 是否纯中文
export function isAllCN(val) {
return /^[\u4E00-\u9FA5]*$/.test(val);
}
// 校验手机号
export function validPhone(rule, value, callback) {
if (value && !/^1[3456789]\d{9}$/.test(value)) {
return callback(new Error('请输入正确的11位号码'));
} else {
return callback();
}
}
// 校验固话和手机号
export function validPhoneAndMobile(rule, value, callback) {
if (value && !/^((0\d{2,3}-?\d{7,8})|(1[3465789]\d{9}))$/.test(value)) {
return callback(new Error('请输入正确的电话号码'));
} else {
return callback();
}
}
// 校验邮箱
export function validEmail(rule, value, callback) {
if (value && !isEmail(value)) {
return callback(new Error('请输入正确的邮箱'));
} else {
return callback();
}
}
// 校验纳税人识别号
export function validTaxpayer(rule, value, callback) {
if (value && !/^[A-Z0-9]{15}$|^[A-Z0-9]{18}$|^[A-Z0-9]{20}$/.test(value)) {
return callback(new Error('请输入正确的纳税人识别号'));
} else {
return callback();
}
}
// 校验是否网站
export function validUrl(rule, value, callback) {
if (value && !isURL(value)) {
return callback(new Error('请输入正确的网站'));
} else {
return callback();
}
}
// 校验银行卡
export function validBankCard(rule, value, callback) {
const strBin = '10,18,30,35,37,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,58,60,62,65,68,69,84,87,88,94,95,98,99';
if (!value) {
return callback();
} else if (!Number.isInteger(+value)) {
callback(new Error('银行卡号必须全为数字'));
} else if (value.trim().length < 8 || value.trim().length > 32) {
callback(new Error('银行卡号长度必须在8到32之间'));
} else {
callback();
}
}

261
src/jtools/wechat/wechat.js Normal file
View File

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

View File

@@ -5,7 +5,7 @@ import uviewPlus from './uni_modules/uview-plus'
import platform from '@/jtools/platform';
import constants from '@/jtools/constants';
import storage from '@/jtools/storage';
import { createPinia } from 'pinia'
import * as Pinia from 'pinia'
import App from "./App.vue";
export function createApp() {
const app = createSSRApp(App);
@@ -13,8 +13,9 @@ export function createApp() {
app.config.globalProperties.$constants=constants
app.config.globalProperties.$storage=storage
app.use(uviewPlus)
app.use(createPinia())
app.use(Pinia.createPinia())
return {
app,
Pinia
};
}

18
src/package.json Normal file
View File

@@ -0,0 +1,18 @@
{
"id": "yan-qr",
"name": "动态生成二维码",
"displayName": "动态生成二维码",
"version": "1.0.0",
"description": "动态生成二维码",
"keywords": [
"二维码",
"生成二维码",
"动态二维码"
],
"dcloudext": {
"category": [
"前端组件",
"通用组件"
]
}
}

View File

@@ -1,97 +1,229 @@
{
"easycom": {
"^u-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^j-(.*)": "@/components/j-$1/j-$1.vue"
},
"pages": [ //pages数组中第一项表示应用启动页参考https://uniapp.dcloud.io/collocation/pages
"easycom": {
"^u-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^j-(.*)": "@/components/j-$1/j-$1.vue"
},
"pages": [
//pages数组中第一项表示应用启动页参考https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},
{
"path": "pages/me/index",
"style": {
"navigationBarTitleText": "我的"
}
},
{
"path": "pages/questionBank/questionBank",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},
{
"path": "pages/questionBank/practiceResult",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},
{
"path": "pages/questionBank/practiceExams",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},
{
"path": "pages/questionBank/examResult",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},
{
"path": "pages/questionBank/exclusiveExercise",
"style": {
"navigationBarTitleText": "专项练习"
}
},
{
"path": "pages/questionBank/wrongQuestion",
"style": {
"navigationBarTitleText": "错题收藏"
}
},
{
"path": "pages/questionBank/baseOperate",
"style": {
"navigationStyle": "custom"
}
},
{
"path": "pages/questionBank/videoDetail",
"style": {
"navigationBarTitleText": "详情"
}
},
{
"path": "pages/me/vip",
"style": {
"navigationBarTitleText": "会员中心",
"enablePullDownRefresh": false
}
},
{
"path": "pages/me/info",
"style": {
"navigationBarTitleText": "我的资料",
"enablePullDownRefresh": false
}
},
{
"path": "pages/me/tijian",
"style": {
"navigationBarTitleText": "上传证件照",
"enablePullDownRefresh": false
}
},
{
"path": "pages/me/school",
"style": {
"navigationBarTitleText": "绑定驾校",
"enablePullDownRefresh": false
}
},
{
"path": "pages/index/videoVip",
"style": {
"navigationBarTitleText": "开通会员",
"enablePullDownRefresh": false
}
},
{
"path": "pages/index/index",
"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/me/uploadPic",
"style": {
"navigationBarTitleText": "金武联驾考"
"navigationBarTitleText": "上传证件照",
"enablePullDownRefresh": false
}
},
{
"path": "pages/me/index",
"path": "pages/index/secretPapers",
"style": {
"navigationBarTitleText": "我的"
}
}, {
"path": "pages/questionBank/questionBank",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},{
"path": "pages/questionBank/practiceResult",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
"navigationBarTitleText": "考前密卷",
"enablePullDownRefresh": false
}
},
{
"path": "pages/questionBank/practiceExams",
"path": "pages/me/changeCarType",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
"navigationBarTitleText": "切换车型",
"enablePullDownRefresh": false
}
},
{
"path": "pages/questionBank/examResult",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
"path" : "pages/index/activity",
"style" :
{
"navigationBarTitleText" : "活动",
"enablePullDownRefresh" : false
}
},
{
"path": "pages/questionBank/exclusiveExercise",
"style": {
"navigationBarTitleText": "专项练习"
}
"path" : "pages/me/myGift",
"style" :
{
"navigationBarTitleText" : "我的奖品",
"enablePullDownRefresh" : false
}
},
{
"path": "pages/questionBank/wrongQuestion",
"style": {
"navigationBarTitleText": "错题收藏"
}
},
{
"path": "pages/questionBank/baseOperate",
"style": {
"navigationStyle": "custom"
}
},{
"path": "pages/questionBank/videoDetail",
"style": {
"navigationBarTitleText": "详情"
}
"path" : "pages/me/qrCode",
"style" :
{
"navigationBarTitleText" : "核销二维码",
"enablePullDownRefresh" : false
}
}
],
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "通用模板",
"navigationBarBackgroundColor": "#FFF",
"backgroundColor": "#FFF"
},
"tabBar": {
"borderStyle": "white",
"selectedColor": "#333333",
"backgroundColor": "#FFFFFF",
"color": "#999999",
"list": [{
"pagePath": "pages/index/index",
"iconPath": "static/image/tabbar/tab-home.png",
"selectedIconPath": "static/image/tabbar/tab-home-selected.png",
"text": "首页"
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "通用模板",
"navigationBarBackgroundColor": "#FFF",
"backgroundColor": "#FFF"
},
"tabBar": {
"borderStyle": "white",
"selectedColor": "#05C341",
"backgroundColor": "#FFFFFF",
"color": "#999999",
"list": [{
"pagePath": "pages/index/index",
"iconPath": "static/image/tabbar/tab-home.png",
"selectedIconPath": "static/image/tabbar/tab-home-selected.png",
"text": "首页"
},
{
"pagePath": "pages/me/index",
"iconPath": "static/image/tabbar/tab-mine.png",
"selectedIconPath": "static/image/tabbar/tab-mine-selected.png",
"text": "我的"
}
]
}
}
{
"pagePath": "pages/me/index",
"iconPath": "static/image/tabbar/tab-mine.png",
"selectedIconPath": "static/image/tabbar/tab-mine-selected.png",
"text": "我的"
}
]
}
}

View 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>

View File

@@ -1,135 +1,382 @@
<template>
<view>
<view class="box-nav">
<image style="width: 100%;" src="../../static/image/index/index_bg.png"></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="btn-item flex ai-c jc-c">
<view class="text-center cor-fff" style="line-height: 40rpx;" @tap="toAnswer('顺序答题')">
<view class="fs16">顺序练习</view>
<text class="fs14">0/2344</text>
<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="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 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">
<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题')">
<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">
<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;">精品视频课</text>
<text class="cor-666 fs12">全部10节课 ></text>
<text style="color: #05C341;font-size: 36rpx;">{{subject==1?'一':'四'}}精品视频课</text>
</view>
<view class="flex ai-c mt20">
<image class="contain-box" src="../../static/image/index/index_bg.png"></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">易错试题</view>
<view class="cor-333 fs15 fw600 mt10">{{subject==1?'一':'四'}}易错试题</view>
</view>
</view>
</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
import {
querySysConfig,
queryQuestionId,
getTestQuestionId
} from '@/jtools/api/question';
export default {
props: {
subject: {
type: [String, Number],
},
rightList: {
type: Array
},
wrongList: {
type: Array
}
},
data() {
return {}
return {
titleNum:500,
allQuestionNum: 0,
}
},
mounted() {
this.getTitle()
},
computed: {
...mapState(useUserStore, ["vipOnList", "token"]),
...mapState(useQuestionStore, ["orderQuestion_subject1", "orderQuestion_subject4", "version"]), //映射函数取出tagslist
getDoNum() {
return this.rightList.length + this.wrongList.length
}
},
methods: {
toClass(){
uni.navigateTo({
url:"/pages/questionBank/baseOperate"
...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
}
})
},
toAnswer(title) {
uni.navigateTo({
url:"/pages/questionBank/questionBank?navTitle="+title
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'
})
},
toExams(){
uni.navigateTo({
url:"/pages/questionBank/practiceExams"
})
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 {
uni.navigateTo({
url: "/pages/questionBank/questionBank?navTitle=" + title + "&subject=" + this.subject + "&needVip=" +
val
})
}
},
toExclusive(){
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/exclusiveExercise"
})
},
toWrongList(){
uni.navigateTo({
url:"/pages/questionBank/wrongQuestion"
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 {
@@ -192,4 +439,12 @@
background: #00B74F;
border-radius: 16rpx;
}
</style>
.play_btn_2 {
width: 65rpx;
height: 65rpx;
position: absolute;
left: 165.5rpx;
top: 78rpx
}
</style>

View File

@@ -1,97 +1,320 @@
<template>
<view>
<view class="box-nav">
<image style="width: 100%;" src="../../static/image/index/index_bg.png"></image>
<view style="width: 100%;position: absolute;top: 80px;left: 0;" class="flex jc-c">
<image style="width: 694rpx;" mode="widthFix" src="../../../static/image/index/vipAds.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">
<text class="fs18 cor-000">考试项目讲解</text>
<view class="flex ai-c" style="height: 34rpx;line-height: 34rpx;">
<text style="color:#05C341;font-size: 16px;">自动挡</text>
<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">
<text style="color:#05C341;font-size: 16px;">{{diverTypeList[diverTypeIndex]?.configItemName}}</text>
<u-icon name="list" color="#05C341" size="18"></u-icon>
</view> -->
</view>
<view class="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" v-if="subject=='2'">
<view class="flex ai-c jc-sb">
<text class="fs18 cor-000">基础操作讲解</text>
<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 ai-c jc-sb mt15">
<view class="tab_iem" :class="videoIndex===item.value?'checked_tab':''" v-for="(item,index) of operateList" :key="index" @tap="checkVideo(item.value)">{{item.label}}</view>
</view>
<view class="mt15">
<video style="width: 100%;height: 362rpx;border-radius: 16rpx;" id="myVideo" src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4"></video>
</view>
</view>
<view class="video_box">
<view class="flex ai-c jc-sb">
<text class="fs18 fw600 cor-000">合肥科三真实考场</text>
<view>
<text class="fs14 cor-666">全部8个考场</text>
<u-icon color="#666" name="arrow-right" size="16"></u-icon>
<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>
export default {
name: "Subject2",
data(){
return{
videoIndex:0,
operateList:[{
label:"侧方停车",
value:0,
},{
label:"倒车入库",
value:1
},{
label:"曲线行驶",
value:2
},{
label:"直角转弯",
value:3
}]
}
},
methods:{
checkVideo(val){
this.videoIndex=val
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 {
intoindex: '',
diverTypeIndex: 0,
diverTypeList: [],
videoIndex: 0,
projectId: undefined,
operateList: [],
baseList: [],
videoList: []
}
},
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) : []
}
})
},
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}`
},
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
}
</style>

View File

@@ -0,0 +1,147 @@
<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">您今日还剩1次刮奖机会共有999人参加活动</view>
<view class="scraping">
<scraping-card :result="result" watermark="刮一刮" title="刮一刮赢取大奖" ref="reset" ></scraping-card>
<view v-if="showBtn" class="gj">
<view class="btn" @tap="handleScrap">
点我刮奖
</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">
<view v-for="(item, index) in winningList" :key="index" class="card-item">
<text class="item-text">188****8888</text>
<text class="item-text">一等奖</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">
<view class="item-text">1. 中奖率100%</view>
<view class="item-text">2. 报名后可获得一次抽奖机会</view>
<view class="item-text">3. 中奖用户请于"我的-我的奖品"中查看并核销</view>
</view>
</view>
</view>
</template>
<script>
import ScrapingCard from './scraping.vue'
export default {
components: {
ScrapingCard
},
data() {
return {
result: '特等奖',
showBtn: true,
winningList: [1,2,3,4,5,6,7,8]
}
},
methods: {
handleScrap() {
this.showBtn = !this.showBtn
}
},
mounted() {
}
}
</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>

View File

@@ -0,0 +1,266 @@
<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>
</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: 60,
},
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);
}
}
},
/** @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;
}
</style>

View File

@@ -0,0 +1,18 @@
<template>
<view>
<web-view :src="webviewPath"></web-view>
</view>
</template>
<script>
export default {
data() {
return{
webviewPath:'https://jtbz.ahduima.com/index'
}
}
}
</script>
<style>
</style>

View File

@@ -1,357 +1,137 @@
<template>
<view>
<u-sticky bgColor="#fff">
<u-tabs :list="categoryList" :scrollable="false" @click="changeCategory"></u-tabs>
</u-sticky>
<view style="height: 100vh;background-color: rgb(245, 245, 245);">
<template v-if="tIndex===0 || tIndex===3">
<Subject1 />
<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">
<u-swiper :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 />
<Subject2 :subject="subject" ref="subjectRef" />
</template>
</view>
</view>
</view>
</view>
</template>
<script>
import { mapState,mapActions } from 'pinia' //引入映射函数
import {
mapState,
mapActions
} from 'pinia' //引入映射函数
import useQuestionStore from '@/jtools/store/question' //引入store
import storage from '@/jtools/storage';
import {
querySysConfigList,
} from '@/jtools/api/question';
import Subject1 from "./components/Subject1";
import Subject2 from "./components/Subject2";
export default {
components: {Subject1,Subject2},
data() {
export default {
components: {
Subject1,
Subject2
},
data() {
return {
tIndex:0,
searchValue:'',
cityName:'',
categoryList:[{
name:'科目1'
},{
name:'科目2'
},{
name:'科目3'
},{
name:'科目4'
}]
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: ['https://cdn.uviewui.com/uview/swiper/swiper1.png']
};
},
onLoad() {
this.getAllQuestion()
},
methods:{
...mapActions(useQuestionStore, ['getQuestionList']), //映射action
//切换科目
changeCategory(val){
this.tIndex=val.index
console.log(this.tIndex);
},
//获取全部题库
getAllQuestion(){
const arr = [{
questionId: 0,
questionTypeDesc: '单选',
questionDesc: '第一题,在实习期内驾驶机动车的,应当在车身后部粘贴或者悬挂哪种标志?',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'C',
}, {
questionId: 1,
questionTypeDesc: '单选',
questionDesc: '第二题,在实习期内驾驶机动车的,应当在车身后部粘贴或者悬挂哪种标志?',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'B',
}, {
questionId: 2,
questionTypeDesc: '单选',
questionDesc: '第三题,在实习期内驾驶机动车的,应当在车身后部粘贴或者悬挂哪种标志?',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'A',
},
{
questionId: 3,
questionTypeDesc: '单选',
questionDesc: '第四题,在实习期内驾驶机动车的,应当在车身后部粘贴或者悬挂哪种标志?',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'A',
}, {
questionId: 4,
questionTypeDesc: '单选',
questionDesc: '第5题在实习期内驾驶机动车的应当在车身后部粘贴或者悬挂哪种标志',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'A',
},
{
questionId: 5,
questionTypeDesc: '单选',
questionDesc: '第6题在实习期内驾驶机动车的应当在车身后部粘贴或者悬挂哪种标志',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'A',
}, {
questionId: 6,
questionTypeDesc: '单选',
questionDesc: '第7题在实习期内驾驶机动车的应当在车身后部粘贴或者悬挂哪种标志',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'A',
}, {
questionId: 7,
questionTypeDesc: '单选',
questionDesc: '第8题在实习期内驾驶机动车的应当在车身后部粘贴或者悬挂哪种标志',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'A',
}, {
questionId: 8,
questionTypeDesc: '单选',
questionDesc: '第9题在实习期内驾驶机动车的应当在车身后部粘贴或者悬挂哪种标志',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'C',
}, {
questionId: 9,
questionTypeDesc: '单选',
questionDesc: '第10题在实习期内驾驶机动车的应当在车身后部粘贴或者悬挂哪种标志',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'B',
}, {
questionId: 10,
questionTypeDesc: '单选',
questionDesc: '第11题在实习期内驾驶机动车的应当在车身后部粘贴或者悬挂哪种标志',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'A',
},
{
questionId: 11,
questionTypeDesc: '单选',
questionDesc: '第12题在实习期内驾驶机动车的应当在车身后部粘贴或者悬挂哪种标志',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'A',
}, {
questionId: 12,
questionTypeDesc: '单选',
questionDesc: '第13题在实习期内驾驶机动车的应当在车身后部粘贴或者悬挂哪种标志',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'A',
},
{
questionId: 13,
questionTypeDesc: '单选',
questionDesc: '第14题在实习期内驾驶机动车的应当在车身后部粘贴或者悬挂哪种标志',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'A',
}, {
questionId: 14,
questionTypeDesc: '单选',
questionDesc: '第15题在实习期内驾驶机动车的应当在车身后部粘贴或者悬挂哪种标志',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'A',
}, {
questionId: 15,
questionTypeDesc: '单选',
questionDesc: '第16题在实习期内驾驶机动车的应当在车身后部粘贴或者悬挂哪种标志',
optionList: [{
op: 'A',
opDesc: '注意新手标志'
}, {
op: 'B',
opDesc: '注意新手标志'
}, {
op: 'C',
opDesc: '注意新手标志'
}, {
op: 'D',
opDesc: '注意新手标志'
}],
rightOp: 'A',
}
]
this.getQuestionList(arr)
},
}
onShow() {
this.show=true
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()
}
},
onHide(){
this.show=false
},
computed: {
...mapState(useQuestionStore, ["loading_subject4", "loading_subject1","curSubject","orderQuestion_subject1","orderQuestion_subject4"]), //映射函数取出tagslist
getLoading() {
return this.loading_subject4 && this.loading_subject1
}
},
watch:{
getLoading(newVal){
if(this.show){
if(newVal){
if(this.loading_subject4 && this.loading_subject1){
uni.hideTabBar();
}
}else{
uni.showTabBar()
}
}
}
},
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)
}
})
},
//切换科目
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)
}
},
// 去活动
handleToActivity(index) {
uni.navigateTo({
url: '/pages/index/activity'
})
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .u-tabs__wrapper__nav__line {
::v-deep .u-tabs__wrapper__nav__line {
background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%) !important;
bottom: 14rpx !important;
}
</style>
</style>

View File

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

View 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>

View File

@@ -0,0 +1,100 @@
<template>
<view>
<u-sticky bgColor="#fff">
<u-tabs :list="categoryList" :scrollable="false" @click="changeCategory"></u-tabs>
</u-sticky>
<view class="p14">
<view class="flex ai-c" v-if="carTypeList&&carTypeList.length">
<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" 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 class="ml10" style="width: calc(100% - 320rpx);">
<text class="fs16 cor-000 fw600">八一考场</text>
<view class="fs14 mt40 cor-666 flex jc-sb ai-c wp100" >
<text>共9条路线视频</text>
<text>蜀山区</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data(){
return{
tCar:0,
categoryList:[{
name:'全部'
},{
name:'蜀山区'
},{
name:'长丰县'
},{
name:'瑶海区'
},{
name:'肥东县'
},{
name:'庐江县'
}],
carTypeList:[],
videoList:[{
label:"111"
},{
label:'222'
},{
label:'333'
},{
label:'444'
}]
}
},
methods:{
chooseCar(val){
this.tCar=val
},
changeCategory(val){
},
toDetail(){
uni.navigateTo({
url:'/pages/questionBank/videoDetail?type=test'
})
}
}
}
</script>
<style scoped>
::v-deep .u-tabs__wrapper__nav__line {
background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%) !important;
bottom: 14rpx !important;
}
.car_item{
font-size: 28rpx;
padding:0 34rpx;
height: 58rpx;
line-height: 58rpx;
border-radius: 29rpx;
}
.checked_car{
background-color: #05C341;
color: #fff;
}
.unchecked_car{
border: 1px solid #DDD;
color: #666;
box-sizing: border-box;
}
.pic{
width: 300rpx;
height: 169rpx;
background: #00B74F;
border-radius: 8rpx;
}
::v-deep .u-tabs__wrapper__nav__item{
padding: 0 !important;
}
</style>

View 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>

View 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>

View File

@@ -0,0 +1,273 @@
<template>
<view class="relative" style="height: 100vh;">
<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="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 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>
<image style="width: 276rpx;height: 88rpx;margin-top: -5px;" src="../../static/image/index/buy.png"></image>
</view>
</view>
</view>
</template>
<script>
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: '会员充值'
},
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
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 {
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>

View File

@@ -1,27 +0,0 @@
<template>
<view>
<web-view :webview-styles="webviewStyles" :src="articleurl"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
articleurl: '',
webviewStyles: {
progress: {
color: '#FF7200'
}
}
};
},
onLoad(options) {
this.articleurl = 'http://www.baidu.com/';
}
}
</script>
<style>
</style>

View File

@@ -1,255 +0,0 @@
<template>
<view class="content">
<view class="list">
<view class="tishi">若您忘记了密码可在此重新设置新密码</view>
<view class="list-call">
<u-icon name="phone" color="#EE2626" size="40"></u-icon>
<input class="sl-input" type="number" v-model="phone" maxlength="11" placeholder="请输入手机号" />
</view>
<view class="list-call">
<u-icon name="lock" color="#EE2626" size="40"></u-icon>
<input class="sl-input" type="text" v-model="password" maxlength="32" placeholder="请输入新密码"
:password="!showPassword" />
<u-icon @click="display" :name="showPassword?'eye-off':'eye-fill'" color="#EE2626" size="40"></u-icon>
</view>
<view class="list-call">
<u-icon name="checkmark-circle" color="#EE2626" size="40"></u-icon>
<input class="sl-input" type="number" v-model="code" maxlength="4" placeholder="验证码" />
<view class="yzm" :class="{ yzms: second>0 }" @tap="getcode">{{yanzhengma}}</view>
</view>
</view>
<view class="button-login" hover-class="button-hover" @tap="bindLogin()">
<text>修改密码</text>
</view>
</view>
</template>
<script>
var _this, js;
export default {
data() {
return {
phone: '',
second: 0,
code: "",
showPassword: false,
password: ''
}
},
onLoad() {
_this = this;
},
computed: {
yanzhengma() {
if (this.second == 0) {
return '获取验证码';
} else {
if (this.second < 10) {
return '重新获取0' + this.second;
} else {
return '重新获取' + this.second;
}
}
}
},
onUnload() {
this.clear()
},
methods: {
display() {
this.showPassword = !this.showPassword
},
clear() {
clearInterval(js)
js = null
this.second = 0
},
getcode() {
if (this.phone.length != 11) {
uni.showToast({
icon: 'none',
title: '手机号不正确'
});
return;
}
if (this.second > 0) {
return;
}
_this.second = 60;
js = setInterval(function() {
_this.second--;
if (_this.second == 0) {
_this.clear()
}
}, 1000)
uni.request({
url: 'http://***/getPassWord', //仅为示例,并非真实接口地址。
data: {
phone: this.phone,
type: 'forget'
},
method: 'POST',
dataType: 'json',
success: (res) => {
if (res.data.code != 200) {
uni.showToast({
title: res.data.msg,
icon: 'none'
});
_this.second = 0;
} else {
uni.showToast({
title: res.data.msg
});
_this.second = 60;
js = setInterval(function() {
_this.second--;
if (_this.second == 0) {
_this.clear()
}
}, 1000)
}
},
fail() {
this.clear()
}
});
},
bindLogin() {
if (this.phone.length != 11) {
uni.showToast({
icon: 'none',
title: '手机号不正确'
});
return;
}
if (this.password.length < 6) {
uni.showToast({
icon: 'none',
title: '密码不正确'
});
return;
}
if (this.code.length != 4) {
uni.showToast({
icon: 'none',
title: '验证码不正确'
});
return;
}
uni.request({
url: 'http://***/forget',
data: {
phone: this.phone,
password: this.password,
code: this.code
},
method: 'POST',
dataType: 'json',
success: (res) => {
if (res.data.code != 200) {
uni.showToast({
title: res.data.msg,
icon: 'none'
});
} else {
uni.showToast({
title: res.data.msg
});
setTimeout(function() {
uni.navigateBack();
}, 1500)
}
}
});
}
}
}
</script>
<style>
page {
background-color: #fff;
}
.content {
display: flex;
flex-direction: column;
justify-content: center;
}
.tishi {
color: #999999;
font-size: 28rpx;
line-height: 50rpx;
margin-bottom: 50rpx;
}
.list {
display: flex;
flex-direction: column;
padding-top: 50rpx;
padding-left: 70rpx;
padding-right: 70rpx;
}
.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: 470rpx;
height: 100rpx;
background: linear-gradient(-90deg, rgba(193, 25, 32, 1), rgba(238, 38, 38, 1));
border-radius: 50rpx;
line-height: 100rpx;
text-align: center;
margin-left: auto;
margin-right: auto;
margin-top: 100rpx;
}
.button-hover {
background: linear-gradient(-90deg, rgba(193, 25, 32, 0.8), rgba(238, 38, 38, 0.8));
}
.yzm {
color: #FF7D13;
font-size: 24rpx;
line-height: 64rpx;
padding-left: 10rpx;
padding-right: 10rpx;
width: auto;
height: 64rpx;
border: 1rpx solid rgba(255, 131, 30, 1);
border-radius: 50rpx;
}
.yzms {
color: #999999 !important;
border: 1rpx solid #999999;
}
</style>

View File

@@ -1,140 +1,168 @@
<template>
<view class="content">
<view class="header">
<image src="/static/images/login/logo.jpg"></image>
</view>
<view class="content">
<view class="header">
<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-icon name="phone" color="#EE2626" size="40"></u-icon>
<input class="sl-input" v-model="login.phone" type="number" maxlength="11" placeholder="输入手机号" />
</view>
<view class="list-call">
<u-icon name="lock" color="#EE2626" size="40"></u-icon>
<input class="sl-input" v-model="login.password" type="text" maxlength="32" placeholder="输入密码"
password="true" />
</view>
<view class="list">
<view class="list-call">
<u-input class="sl-input" border="none" v-model="login.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="输入验证码">
<template #suffix>
<text class="fs14 mr10" style="color: #05C341;" @tap="getCode">{{ countDown == 0 ? '获取验证码' : countDown }}</text>
</template>
</u-input>
</view>
</view>
</view>
<view class="button-login" @tap="bindLogin()">
<text>登录</text>
</view>
<view class="button-login" hover-class="button-hover" @tap="bindLogin()">
<text>登录</text>
</view>
<view class="agreenment">
<navigator url="/pages/login/forget" open-type="navigate">忘记密码</navigator>
<text>|</text>
<navigator url="/pages/login/reg" open-type="navigate">注册账户</navigator>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
login: {
phone: '',
password: ''
}
};
},
methods: {
bindLogin() {
}
}
}
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 {
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)
// }
})
}
},
clear() {
clearInterval(js)
this.js = null
this.countDown = 0
},
bindLogin() {
if (isPhone(this.login.phone) && this.login.code) {
let params = { ...this.login }
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 {
width: 161rpx;
height: 161rpx;
border-radius: 50%;
margin-top: 30rpx;
margin-left: auto;
margin-right: auto;
}
.header {
margin-top: 166rpx;
margin-left: auto;
margin-right: auto;
letter-spacing: 10rpx;
}
.header image {
width: 161rpx;
height: 161rpx;
border-radius: 50%;
}
.header image {
width: 383rpx;
}
.list {
display: flex;
flex-direction: column;
padding-top: 50rpx;
padding-left: 70rpx;
padding-right: 70rpx;
}
.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;
}
.list-call .sl-input {
flex: 1;
text-align: left;
font-size: 32rpx;
margin-left: 16rpx;
}
.button-login {
color: #FFFFFF;
font-size: 34rpx;
width: 470rpx;
height: 100rpx;
background: linear-gradient(-90deg, rgba(193, 25, 32, 1), rgba(238, 38, 38, 1));
border-radius: 50rpx;
line-height: 100rpx;
text-align: center;
margin-left: auto;
margin-right: auto;
margin-top: 100rpx;
}
.button-hover {
background: linear-gradient(-90deg, rgba(193, 25, 32, 0.8), rgba(238, 38, 38, 0.8));
}
.agreenment {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
font-size: 30rpx;
margin-top: 80rpx;
color: #FFA800;
text-align: center;
height: 40rpx;
line-height: 40rpx;
}
.agreenment text {
font-size: 24rpx;
margin-left: 15rpx;
margin-right: 15rpx;
}
</style>
.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>

View File

@@ -1,303 +0,0 @@
<template>
<view class="content">
<view class="header">
<image src="/static/images/login/logo.jpg"></image>
</view>
<view class="list">
<view class="list-call">
<u-icon name="phone" color="#EE2626" size="40"></u-icon>
<input class="sl-input" v-model="phone" type="number" maxlength="11" placeholder="手机号" />
</view>
<view class="list-call">
<u-icon name="lock" color="#EE2626" size="40"></u-icon>
<input class="sl-input" v-model="password" type="text" maxlength="32" placeholder="登录密码"
:password="!showPassword" />
<u-icon @click="display" :name="showPassword?'eye-off':'eye-fill'" color="#EE2626" size="40"></u-icon>
</view>
<view class="list-call">
<u-icon name="checkmark-circle" color="#EE2626" size="40"></u-icon>
<input class="sl-input" v-model="code" type="number" maxlength="4" placeholder="验证码" />
<view class="yzm" :class="{ yzms: second>0 }" @tap="getcode">{{yanzhengma}}</view>
</view>
</view>
<view class="button-login" hover-class="button-hover" @tap="bindLogin">
<text>注册</text>
</view>
<view class="agreement">
<image @tap="agreementSuccess"
:src="agreement==true?'/static/images/login/ty1.png':'/static/images/login/ty0.png'"></image>
<text @tap="agreementSuccess"> 同意</text>
<navigator url="/pages/login/agreement?id=1" open-type="navigate">软件用户协议</navigator>
</view>
</view>
</template>
<script>
var _this, js;
export default {
onLoad() {
_this = this;
},
onUnload() {
clearInterval(js)
this.second = 0;
},
data() {
return {
phone: '',
password: '',
code: '',
agreement: true,
showPassword: false,
second: 0
};
},
computed: {
yanzhengma() {
if (this.second == 0) {
return '获取验证码';
} else {
if (this.second < 10) {
return '重新获取0' + this.second;
} else {
return '重新获取' + this.second;
}
}
}
},
onUnload() {
this.clear()
},
methods: {
clear() {
clearInterval(js)
js = null
this.second = 0
},
display() {
this.showPassword = !this.showPassword
},
agreementSuccess() {
this.agreement = !this.agreement;
},
getcode() {
if (this.phone.length != 11) {
uni.showToast({
icon: 'none',
title: '手机号不正确'
});
return;
}
if (this.second > 0) {
return;
}
this.second = 60;
//请求业务
js = setInterval(function() {
_this.second--;
if (_this.second == 0) {
_this.clear()
}
}, 1000)
// uni.request({
// url: 'http://***/getcode.html', //仅为示例,并非真实接口地址。
// data: {
// phone: this.phone,
// type: 'reg'
// },
// method: 'POST',
// dataType: 'json',
// success: (res) => {
// if (res.data.code != 200) {
// uni.showToast({
// title: res.data.msg,
// icon: 'none'
// });
// } else {
// uni.showToast({
// title: res.data.msg
// });
// js = setInterval(function() {
// _this.second--;
// if (_this.second == 0) {
// _this.clear()
// }
// }, 1000)
// }
// },
// fail() {
// this.second == 0
// }
// });
},
bindLogin() {
if (this.agreement == false) {
uni.showToast({
icon: 'none',
title: '请先阅读《软件用户协议》'
});
return;
}
if (this.phone.length != 11) {
uni.showToast({
icon: 'none',
title: '手机号不正确'
});
return;
}
if (this.password.length < 6) {
uni.showToast({
icon: 'none',
title: '密码不正确'
});
return;
}
if (this.code.length != 4) {
uni.showToast({
icon: 'none',
title: '验证码不正确'
});
return;
}
uni.request({
url: 'http://***/reg.html',
data: {
phone: this.phone,
password: this.password,
code: this.code,
},
method: 'POST',
dataType: 'json',
success: (res) => {
if (res.data.code != 200) {
uni.showToast({
title: res.data.msg,
icon: 'none'
});
} else {
uni.showToast({
title: res.data.msg
});
setTimeout(function() {
uni.navigateBack();
}, 1500)
}
}
});
}
}
}
</script>
<style>
page {
background-color: #fff;
}
.content {
display: flex;
flex-direction: column;
justify-content: center;
}
.header {
width: 161rpx;
height: 161rpx;
border-radius: 50%;
margin-top: 30rpx;
margin-left: auto;
margin-right: auto;
}
.header image {
width: 161rpx;
height: 161rpx;
border-radius: 50%;
}
.list {
display: flex;
flex-direction: column;
padding-top: 50rpx;
padding-left: 70rpx;
padding-right: 70rpx;
}
.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;
}
.yzm {
color: #FF7D13;
font-size: 24rpx;
line-height: 64rpx;
padding-left: 10rpx;
padding-right: 10rpx;
width: auto;
height: 64rpx;
border: 1rpx solid #FFA800;
border-radius: 50rpx;
}
.yzms {
color: #999999 !important;
border: 1rpx solid #999999;
}
.button-login {
color: #FFFFFF;
font-size: 34rpx;
width: 470rpx;
height: 100rpx;
line-height: 100rpx;
background: linear-gradient(-90deg, rgba(193, 25, 32, 1), rgba(238, 38, 38, 1));
border-radius: 50rpx;
text-align: center;
margin-left: auto;
margin-right: auto;
margin-top: 100rpx;
}
.button-hover {
background: linear-gradient(-90deg, rgba(193, 25, 32, 0.8), rgba(238, 38, 38, 0.8));
}
.agreement {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
font-size: 30rpx;
margin-top: 80rpx;
color: #FFA800;
text-align: center;
height: 40rpx;
line-height: 40rpx;
}
.agreement image {
width: 40rpx;
height: 40rpx;
}
</style>

View 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>

View File

@@ -2,80 +2,240 @@
<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>
<view class="info flex ai-c">
<u-avatar class="br-p50 overflow-h" :size="64" :src="user.avatar" mp-avatar shape="circle"></u-avatar>
<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="fs18 cor-333 fwb">{{user.name}}</view>
<view class="mt5 fs14 cor-666">陪您学车 {{user.count}}</view>
<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>
</view>
<view class="mt5 fs14 cor-666">陪您学车 {{ user.days }}</view>
</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>
<view class="ml12">
<view class="flex ai-c fs18 cor-333 fwb">
<text class="mr10">立即登录</text>
</view>
<view class="mt5 fs14 cor-666">登录后获得更多学车信息</view>
</view>
</view>
</view>
<view class="p15lr" style="transform: translateY(-90px);">
<view class="mb10" v-if="user.vip">
<image src="/static/image/mine/vip_bg.png" mode="widthFix" style="width: 100%;"></image>
</view>
<view class="br8 bc-fff p15 z-index2">
<text class="fs16 cor-333">我的驾校</text>
<div class="mt12 flex ai-c jc-sb">
<text class="fs18 cor-000 fwb">合肥八一驾校</text>
<u-button text="切换驾校" shape="circle"></u-button>
</div>
<u-line margin="14px 0 18px 0"></u-line>
<view class="flex ai-c">
<view class="flex ai-c jc-c phone">
<img src="/static/image/mine/phone.png" style="width: 12px;height: 12px;">
<text class="ml2 fs12 cor-fff">客服热线</text>
<view class="relative mb10" @tap="handleVip">
<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;">
<image src="/static/image/mine/vip.png" mode="widthFix" style="width: 18px;height: 15px;"></image>
</view>
<text class="ml5 fs16 fwb" style="color: #7E4012FF;">VIP会员</text>
</view>
<text class="ml5 fs26 cor-333 fwb" style="line-height: 26px;">0551-12345678</text>
<text v-if="!isLogin || !vipOn.length" class="fs12" style="color: #7E4012FF;">您还不是VIP会员</text>
<text v-else-if="vipOn.length" class="fs12" style="color: #7E4012FF;">{{ expireTime }}到期</text>
</view>
<view class="absolute flex ai-c jc-c" style="left: 0;top: 40px;right: 0;bottom: 0;">
<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;">{{ isIOS ? 'iOS暂不可用' : '立即开通' }}</view>
</view>
<view v-else-if="vipOn.length" class="text-center">
<view class="fs18 fwb" style="color: #7E4012FF;">{{ vipText }}</view>
<view class="study fs16 text-center" style="margin: 25px auto 0;color: #F6E99FFF;">马上学习</view>
</view>
</view>
</view>
<view v-if="isLogin" class="br8 bc-fff p15 z-index2">
<text class="fs16 cor-333">我的驾校</text>
<view v-if="user?.schoolId">
<div class="mt12 flex ai-c jc-sb">
<text class="fs18 cor-000 fwb">{{ user.schoolName }}</text>
<u-button text="切换驾校" shape="circle" @click="handleChangeSchool"></u-button>
</div>
<u-line margin="14px 0 18px 0"></u-line>
<view class="flex ai-c" @tap="handleCallPhone">
<view class="flex ai-c jc-c phone">
<img src="/static/image/mine/phone.png" style="width: 12px;height: 12px;">
<text class="ml2 fs12 cor-fff">客服热线</text>
</view>
<text class="ml5 fs26 cor-333 fwb" style="line-height: 26px;">{{ user.schoolPhone }}</text>
</view>
</view>
<view v-else class="p15tb flex ai-c jc-sb">
<view class="fs20 cor-333 fwb">尚未绑定驾校</view>
<u-button text="绑定驾校" shape="circle" @click="handleChangeSchool"></u-button>
</view>
</view>
<view class="mt12 bc-fff br8">
<u-cell-group>
<u-cell size="large" title="我的资料" value="修改" isLink>
<u-cell size="large" title="我的资料" isLink @tap="handleInfo">
<template #icon>
<img src="/static/image/mine/wdzl.png" style="width: 24px;height: 24px;">
</template>
</u-cell>
<u-cell size="large" title="我的体检" value="查看报告" isLink>
<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 class="flex ai-c jc-c mt12 br8 bc-fff" style="height: 50px;">
<view v-if="isLogin" class="flex ai-c jc-c mt12 br8 bc-fff" style="height: 50px;" @tap="handleLogout">
<text class="fs16" style="color: #A09F9F;">退出登录</text>
</view>
</view>
</view>
</template>
<script>
export default {
components: {},
data() {
return {
user: {
avatar: '',
name: '帅帅的黑啤酒',
count: '215'
}
};
import useUserStore from '@/jtools/store/user'
import storage from '@/jtools/storage';
export default {
components: {},
computed: {
isLogin() {
return useUserStore().isLogin
},
user() {
return useUserStore().userInfo
},
vipOn() {
return useUserStore().vipOnList
},
expireTime() {
if (this.vipOn.length) {
const t = this.vipOn.reduce((pre, cur) => {
if (Date.parse(pre) > Date.parse(cur.endDate)) {
return cur.endDate
}
return pre
}, '2099-12-31')
return t.split(' ')[0]
} else {
return ''
}
},
vipText() {
if (this.vipOn.length) {
const t = this.vipOn.reduce((pre, cur) => {
return [...pre, ...cur.subjects.split(',').map(it => ['', '一', '二', '三', '四'][it])]
}, [])
let val = Array.from(new Set(t))
val = val.length == 4 ? val.join('') + '全部' : val.join('')
return `尊享科目${val}付费权益`
} else {
return ''
}
}
},
data() {
return {
carName: storage.get('carName') || '小车C1/C2/C3',
isIOS: true
}
},
onShow() {
this.isIOS = this.$platform.device().includes('ios')
this.carName = storage.get('carName') || '小车C1/C2/C3'
},
methods: {
// 拨打电话
callPhoneNumber() {
uni.makePhoneCall({
phoneNumber: '15105693067'
});
},
onShow() {
//加载
},
onLoad() {
},
methods: {
}
}
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'
})
// } else {
// uni.navigateTo({
// url: '/pages/index/videoVip'
// })
// }
} else {
this.toLogin()
}
},
handleCallPhone() {
uni.makePhoneCall({
phoneNumber: this.user.schoolPhone
})
},
handleChangeSchool() {
if (this.isLogin) {
uni.navigateTo({
url: '/pages/me/school'
})
} else {
this.toLogin()
}
},
handleInfo() {
if (this.isLogin) {
uni.navigateTo({
url: '/pages/me/info'
})
} else {
this.toLogin()
}
},
handleTJ() {
if (this.isLogin) {
// uni.navigateTo({
// url: '/pages/me/tijian'
// })
uni.showToast({
title: '敬请期待',
icon: 'none'
})
} else {
this.toLogin()
}
},
toLogin() {
uni.navigateTo({
url: '/pages/login/login'
})
},
handleLogout() {
useUserStore().logout()
},
handleGift() {
uni.navigateTo({
url: '/pages/me/myGift'
})
}
}
}
</script>
<style lang="scss" scoped>
@@ -84,10 +244,19 @@
top: 32px;
left: 27px;
}
.phone {
width: 75px;
height: 26px;
background: #05C341;
border-radius: 16px 16px 0px 16px;
}
.study {
width: 200px;
height: 35px;
line-height: 35px;
background: #7E4012;
border-radius: 35px;
}
</style>

61
src/pages/me/info.vue Normal file
View File

@@ -0,0 +1,61 @@
<template>
<view class="p15 bc-f5">
<view class="br8 bc-fff p15lr">
<view class="flex jc-sb ai-c bb1" style="height: 110rpx;">
<view class="title">联系电话</view>
<view class="flex">
<view class="m30lr fs14 cor-333">15122305568</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="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>
<style lang="scss" scoped>
.title {
width: 120rpx;
font-size: 14px;
color: #666;
}
.bb1 {
border-bottom: 1px solid #eee;
}
</style>

67
src/pages/me/myGift.vue Normal file
View File

@@ -0,0 +1,67 @@
<template>
<view class="p10lr p20tb">
<view 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">一等奖</view>
</view>
<view class="df ai-c jcsb p20tb p10lr">
<view class="item-label">
<view>活动名称幸运刮刮乐开心赢大奖</view>
<view>参与时间2024-01-01 08:00</view>
<view>有效期至2024-03-01 08:00</view>
</view>
<view class="ml20" style="width: 120rpx;">
<img v-if="index%2==0" src="/static/image/mine/writeoff.png" style="width: 120rpx;height: 120rpx;" />
<view v-else class="btn" @tap="handleWriteoff(item)">核销</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
list: []
}
},
onShow() {
this.handleSearch()
},
methods: {
handleSearch() {
this.list = [1,2,3,4,5]
},
handleWriteoff(item) {
uni.navigateTo({
url: `/pages/me/qrCode?item=${item}`
})
}
}
}
</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>

29
src/pages/me/qrCode.vue Normal file
View File

@@ -0,0 +1,29 @@
<template>
<view class="df jcc" style="padding-top: 100px;">
<qrcode value="123" :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.item
},
methods: {
}
}
</script>
<style>
</style>

58
src/pages/me/school.vue Normal file
View File

@@ -0,0 +1,58 @@
<template>
<view>
<IndexList :dataList="dataList" nameKey="schoolName" idKey="schoolId" v-model:current="current" @click="click"></IndexList>
</view>
</template>
<script>
import IndexList from '@/components/liu-indexed-list/liu-indexed-list.vue'
import { bindSchool } from '@/jtools/api/login.js'
import useUserStore from '@/jtools/store/user.js'
export default {
components: {
IndexList
},
data() {
return {
current: useUserStore().userInfo.schoolId,
dataList: []
}
},
created() {
this._getSchoolOptions()
},
methods: {
_getSchoolOptions() {
uni.request({
url: 'https://xueche.ahduima.com/duima/applet/school/list'
}).then(resp => {
if(resp.data.code == 200) {
this.dataList = resp.data.data
}
})
},
click() {
// 设置用户驾校
const {schoolId,schoolName,phone } = this.dataList.find(it=>it.schoolId == this.current)
const params = {schoolId, schoolName, schoolPhone: phone}
bindSchool(params).then(resp => {
if(resp.code == '0000') {
useUserStore().userInfo.schoolId = schoolId
useUserStore().userInfo.schoolName = schoolName
useUserStore().userInfo.schoolPhone = phone
uni.showToast({
title: '绑定驾校成功!',
icon: 'none'
})
// 然后返回
uni.navigateBack()
}
})
}
}
}
</script>
<style>
</style>

214
src/pages/me/tijian.vue Normal file
View File

@@ -0,0 +1,214 @@
<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" @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: ''
},
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>
.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
View 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>

398
src/pages/me/vip.vue Normal file
View File

@@ -0,0 +1,398 @@
<template>
<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 {
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: {
...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;
}
.actived {
background: linear-gradient(90deg, #E66501 0%, #F8A42C 100%);
color: #fff;
}
.km-item:last-of-type {
margin-right: 0;
}
.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;
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;
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;
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;
}
.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>

View File

@@ -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>

View File

@@ -0,0 +1,97 @@
<template>
<view>
<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,
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:[],
subject:'1'
}
},
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
}
})
},
toQuestion(code){
this.getQuestion({chapter:code},'章节技巧')
}
}
}
</script>
<style scoped>
.chapter_item{
border-bottom: 1px solid rgb(210,209,214);
background-color: #fff;
}
.chapter_item:hover{
background-color: rgb(210,209,214);
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +1,24 @@
<template>
<view>
<!-- <u-navbar title="本次成绩" @rightClick="rightClick" :autoBack="true"></u-navbar> -->
<j-navbar>本次成绩</j-navbar>
<j-navbar backPath="/pages/index/index">本次成绩</j-navbar>
<view class="p14 wp100">
<GradesChart color="#FF6E02" titleName="32分" :actualValue="0.32" />
<GradesChart color="#FF6E02" :titleName="score+'分'" :actualValue="Number(scorePrecent)" />
<view class="top_box flex jc-c" style="flex-direction: column;">
<view class="wp100 text-center" style="margin-top: -153rpx;">
<text>太棒了正确率很高了</text>
<button class="centerBtn">马上提分</button>
<view class="flex ai-c jc-c">
<text v-if="score>=90">太棒了正确率很高了</text>
<text v-else>很遗憾考试不及格</text>
<button class="centerBtn" @click="toVip">马上提分</button>
<view class="flex ai-c jc-c mt10">
<view class="text-center wp33">
<view>99</view>
<view>{{doNotNum}}</view>
<text>未做题</text>
</view>
<view class="text-center wp33">
<view>12</view>
<view class="text-center wp33" @tap="toQuestionBank">
<view>{{wrongList?.length}}</view>
<text>看错题</text>
</view>
<view class="text-center wp33 flex jc-c ai-c" style="flex-direction: column;">
<view class="text-center wp33 flex jc-c ai-c" style="flex-direction: column;" @tap="toExams">
<u-icon name="edit-pen" size="28"></u-icon>
<text>重新考试</text>
</view>
@@ -39,18 +40,36 @@
<text style="color: #00B74F;position: absolute;right:33px;top:-13px">及格线</text>
</view>
</view>
<view class="wp100 text-center bc-fff pb10">
<text>近五次模考成绩</text>
</view>
</view>
</view>
</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 {
testTotal
} from '@/jtools/api/question';
export default {
components: {
GradesChart
},
data() {
return {
navTitle:"模拟考试",
subject:1,
doNotNum:0,
wrongList:undefined,
score:0,
scorePrecent:0,
chartData: {},
//您可以通过修改 config-ucharts.js 文件中下标为 ['line'] 的节点来配置全局默认参数,如都是默认参数,此处可以不传 opts 。实际应用过程中 opts 只需传入与全局默认参数中不一致的【某一个属性】即可实现同类型的图表显示不同的样式,达到页面简洁的需求。
opts: {
@@ -84,26 +103,96 @@
}
};
},
onLoad(op){
if(op.doNotNum){
this.doNotNum=op.doNotNum
}
if(op.wrongList){
console.log(op.wrongList);
this.wrongList=JSON.parse(op.wrongList) || []
}
if(op.score){
this.score=op.score
this.scorePrecent=(this.score/100).toFixed(2)
}
if(op.subject){
this.subject=op.subject
}
if(op.navTitle){
this.navTitle=op.navTitle
}
},
onReady() {
this.getServerData();
},
onUnload() {
//#ifdef MP-WEIXIN
uni.reLaunch({
url:"/pages/index/index"
})
//#endif
},
computed: {
...mapState(useUserStore, ["vipOnList"])
},
methods: {
getServerData() {
//模拟从服务器获取数据时的延时
setTimeout(() => {
//模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
let res = {
categories: ["2018","2019","2020","2021","2022","2023"],
series: [{
name: "",
data: [90]
},
]
};
this.chartData = JSON.parse(JSON.stringify(res));
}, 500);
...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',
"subject": this.subject
}).then(resp=>{
if(resp.code==='0000'){
if(resp.data&&resp.data.recentTestList&&resp.data.recentTestList.length){
const scoreList =resp.data.recentTestList.map(item=>{
return item.score
})
let res = {
categories: ["第一次","第二次","第三次","第四次","第五次"],
series: [{
name: "",
data: scoreList
},
]
};
this.chartData = JSON.parse(JSON.stringify(res));
}
}
})
},
toQuestionBank(){
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(){
uni.navigateTo({
url:"/pages/questionBank/practiceExams?subject="+this.subject
})
},
},
}
</script>
@@ -118,6 +207,7 @@
width: 349rpx;
height: 76rpx;
background: #DEEFE5;
border:none;
border-radius: 38rpx;
line-height: 76rpx;
text-align: center;

View File

@@ -1,42 +1,48 @@
<template>
<view class="p14">
<view class="flex jc-sb">
<view class="relative mr5">
<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">
<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 mt10" style="flex-wrap: wrap;">
<view class="wp50 flex ai-c mb10" v-for="(item,index) of testCenterList" :key="index">
<view class="dot_item">{{index+1}}</view>
<text class="ml5">{{item.label}}</text>
</view>
</view>
</view>
</view>
</template>
@@ -44,66 +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:[
{label:'驾驶证申请相关'},
{label:'驾驶证申请相关'},
{label:'驾驶证登记处罚'},
{label:'机动车强制报废'},
{label:'其他考点'},
{label:'驾驶证登记处罚'},
{label:'机动车强制报废'},
{label:'其他考点'}]
testCenterList: [],
subject: '1'
}
},
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: {
toAnswer(title) {
uni.navigateTo({
url:"/pages/questionBank/questionBank?navTitle="+title
...mapActions(useQuestionStore, ['getAllQuestion']),
getChapterList(){
const carTypeId=storage.get('carType') || '1001'
const key=this.subject=='1'?'ChapterOfSubjectOne':'ChapterOfSubjectFour'
querySysConfigList(carTypeId,'ChapterOfSubjectOne').then(resp=>{
if(resp.code==='0000'&&resp.data){
this.chapterNum=resp.data.length
}
})
},
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,
}]
}
}
})
},
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
}
})
},
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>

View File

@@ -2,8 +2,8 @@
<view>
<!-- <u-navbar title="模拟考试" @rightClick="rightClick" :autoBack="true">
</u-navbar> -->
<j-navbar>模拟考试</j-navbar>
<Question :tabsList="tabsList" v-model:isSubmit="isSubmit" type="exam" />
<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>
@@ -13,6 +13,12 @@
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';
export default {
components: {
@@ -20,42 +26,96 @@
},
data() {
return {
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() {
console.log(this.orderQuestionList);
onLoad(op) {
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(useQuestionStore, ["orderQuestionList"]) //映射函数取出tagslist
...mapState(useUserStore, ["vipOnList", "token"]),
...mapState(useQuestionStore, ["orderQuestion_subject1", "orderQuestion_subject4", "version"]), //映射函数取出tagslist
},
methods: {
rightClick() {
console.log('返回');
...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>

View File

@@ -1,18 +1,19 @@
<template>
<view>
<!-- <u-navbar title="本次练题结果" @rightClick="rightClick" :autoBack="true"></u-navbar>-->
<j-navbar>本次练题结果</j-navbar>
<j-navbar backPath="/pages/index/index">本次练题结果</j-navbar>
<view class="p14 wp100">
<GradesChart />
<GradesChart :titleName="rightPencentDesc" :actualValue="Number(rightPencent)" />
<view class="top_box flex jc-c" style="flex-direction: column;">
<view class="wp100 text-center" >
<text>太棒了正确率很高了</text>
<view class="wp100 text-center" style="margin-top: -80px;">
<text v-if="Number(rightPencent * 100)>=90">太棒了正确率很高了</text>
<text v-else>继续努力吧正确率有点低~</text>
<view class="flex ai-c jc-c mt10">
<view class="text-center wp50">
<view>1/3</view>
<view class="text-center wp50" @tap="toQuestionBank">
<view>{{wrongList.length}}/{{allDoNum}}</view>
<text>本次错题</text>
</view>
<view class="text-center wp50 flex jc-c ai-c" style="flex-direction: column;">
<view class="text-center wp50 flex jc-c ai-c" style="flex-direction: column;" @tap="toContiune">
<u-icon name="file-text" size="28"></u-icon>
<text>继续做题</text>
</view>
@@ -25,12 +26,12 @@
<view class="flex ai-c jc-sb">
<view>
<text class="fs18 cor-000 fw600">累计练题</text>
<text class="fs14 cor-666 ml10">33</text>
<text class="fs14 cor-666 ml10">{{allRightList.length+allWrongList.length}}</text>
</view>
<text class="fs14 cor-666">未做题2311</text>
<text class="fs14 cor-666">未做题{{getNotDoNum}}</text>
</view>
<view class="mt10">
<u-line-progress :percentage="20" activeColor="#05C341" height="16"></u-line-progress>
<u-line-progress :percentage="percent" activeColor="#05C341" height="16"></u-line-progress>
</view>
<view class="p14 mt10 flex ai-c jc-sb" style="border-radius: 20rpx;background-color: rgb(253,249,238);">
<view>
@@ -38,7 +39,7 @@
<text class="fs16 cor-000 fw600">精简500题</text>
</view>
<view style="width: 220rpx;">
<button style="background-color:rgb(246,211,115);height: 80rpx;border-radius: 40rpx;width: 220rpx;color:rgb(102,65,0)">开始答题</button>
<button style="background-color:rgb(246,211,115);height: 80rpx;border-radius: 40rpx;width: 220rpx;color:rgb(102,65,0)">开始答题</button>
</view>
</view>
</view>
@@ -47,6 +48,12 @@
</template>
<script>
import {
mapState,
mapActions
} from 'pinia' //引入映射函数
import storage from '@/jtools/storage';
import useQuestionStore from '@/jtools/store/question' //引入store
import GradesChart from "./components/GradesChart.vue"
export default {
components: {
@@ -54,11 +61,61 @@
},
data() {
return {
rightPencent:0,
rightPencentDesc:'',
allDoNum:0,
wrongList:[],
subject:1,
allRightList:[],
allWrongList:[],
percent:undefined,
navTitle:'顺序练习',
}
},
onLoad(op){
if(op.allDoNum){
this.allDoNum=op.allDoNum
}
if(op.navTitle){
this.navTitle=op.navTitle
}
if(op.wrongList){
this.wrongList=JSON.parse(op.wrongList)
this.rightPencent=this.allDoNum>0?((this.allDoNum-this.wrongList.length)/this.allDoNum).toFixed(2):0
this.rightPencentDesc=(this.rightPencent*100).toFixed(0)+'%'
}
if(op.subject){
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_subject${this.subject}`].length)*100).toFixed(0)
}
},
onUnload() {
//#ifdef MP-WEIXIN
uni.reLaunch({
url:"/pages/index/index"
})
//#endif
},
computed: {
...mapState(useQuestionStore, ["orderQuestion_subject1","orderQuestion_subject4"]), //映射函数取出tagslist
getNotDoNum(){
return this[`orderQuestion_subject${this.subject}`].length-(this.allRightList.length+this.allWrongList.length)
}
},
methods: {
toQuestionBank(){
const list =JSON.stringify(this.wrongList)
uni.navigateTo({
url:"/pages/questionBank/questionBank?navTitle=错题&subject="+this.subject+"&questionList="+list
})
},
toContiune(){
uni.navigateTo({
url:"/pages/questionBank/questionBank?navTitle="+this.navTitle+"&subject="+this.subject
})
}
}
}
</script>

View File

@@ -1,9 +1,11 @@
<template>
<view>
<!-- <u-navbar :title="navTitle" @rightClick="rightClick" :autoBack="true">
</u-navbar> -->
<j-navbar>{{navTitle}}</j-navbar>
<Question :tabsList="tabsList" />
<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>
@@ -13,39 +15,103 @@
mapActions
} from 'pinia' //引入映射函数
import useQuestionStore from '@/jtools/store/question' //引入store
import useUserStore from '@/jtools/store/user'
import Question from './components/Question.vue';
import {
queryQuestion,
queryQuestionId
} from '@/jtools/api/question';
import storage from '@/jtools/storage';
export default {
components: {
Question
},
data() {
return {
navTitle:'',
tabsList:[{
label:"答题",
value:0
},{
label:"背题",
value:1
}]
loadTxt: '加载中...',
collectList: storage.get(`collectList_subject${this.subject}`) || [],
loading: false,
isShowAll: true,
needVip: false,
subject: 1,
navTitle: '',
tabsList: [{
label: "答题",
value: 0
}, {
label: "背题",
value: 1
}],
questionArr: []
}
},
onLoad(op) {
if(op&&op.navTitle){
this.navTitle=op.navTitle
async onLoad(op) {
this.loading = true
if (op.needVip) {
this.needVip = op.needVip
}
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, ["orderQuestionList"]) //映射函数取出tagslist
...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,
isChoose: true,
}
})
this.$refs.question.isShowBest(true)
this.$refs.question.getQuestionList(JSON.stringify(list), this.navTitle)
} else {
this.$refs.question.isShowBest(false)
this.$refs.question.getQuestionList()
}
},
rightClick() {
console.log('返回');
}
},
}
}
</script>
<style>
<style scoped>
</style>
</style>

View File

@@ -1,27 +1,316 @@
<template>
<view>
<video style="width: 100%;height: 422rpx;" id="myVideo" src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4"></video>
<view class="p14 bc-fff">
<view class="flex ai-c jc-sb mt10">
<text class="fs18 fw600 cor-000">C1捷达-基础操作视频讲解</text>
<view class="flex">
<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>
</scroll-view>
</view>
<view class="flex ai-c jc-sb mt10 wp100 p14">
<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>
</view>
<view v-else class="fs14 cor-666">共9条路线</view>
</view>
<view>
</view>
</view>
<view class="bc-fff pl14 pb10">
<view class="skill-sequence-panel-content-wrapper">
<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"
@tap="checkVideo(item.projectId)">
<view>
<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">{{item.videoTime}}</text>
</view>
<view class="topic_cont_text" :style="{color:projectId==item.projectId?'#FF6E02':'#333'}">
{{item.description}}
</view>
</view>
</view>
</scroll-view>
</view>
</view>
<u-popup :show="popupShow" mode="bottom" :closeOnClickOverlay="true" @close="popupShow=false">
<view class="p14 flex ai-c jc-sb">
<text class="fs16 fw600 cor-000">课程目录</text>
<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 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">{{item.videoTime}}</text>
</view>
<view class="ml10">
<text class="fs16 cor-000 fw600">{{item.description}}</text>
<view class="fs14 mt5 cor-666">{{item.subDesc}}</view>
</view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default{
data(){
return{
import {
queryProjectList
} from '@/jtools/api/question';
import storage from '@/jtools/storage';
export default {
data() {
return {
title: '',
currentIndex: 0,
videoIndex: 0,
testList: [{
label: "八一考场",
value: 0,
}, {
label: "富凯考场",
value: 1
}, {
label: "新亚考场",
value: 2
}, {
label: "庐江考场",
value: 3
}, {
label: "富凯考场",
value: 4
}, {
label: "新亚考场",
value: 5
}, {
label: "庐江考场",
value: 6
}],
driveType:'',
videoType: '',
popupShow: false,
videoList: [{
title: '正确的驾驶姿势',
time: '13:14',
id: 0
}, {
title: '正确的驾驶姿势',
time: '13:14',
id: 1
}, {
title: '正确的驾驶姿势',
time: '13:14',
id: 2
}, {
title: '正确的驾驶姿势',
time: '13:14',
id: 3
}, {
title: '正确的驾驶姿势',
time: '13:14',
id: 4
}, {
title: '正确的驾驶姿势',
time: '13:14',
id: 5
}],
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.subject) {
this.param.subject = op.subject
}
if (op.type) {
this.param.type = op.type
this.getVideoList()
}
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
}
},
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}`
},
getVideoList() {
queryProjectList({
"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)
}
}
}
</script>
<style>
<style scoped>
.contain-box {
width: 260rpx;
height: 146rpx;
background: #00B74F;
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;
background: #FF6E02;
border-radius: 8rpx 0rpx 8rpx 0rpx;
line-height: 40rpx;
text-align: center;
color: #fff;
font-size: 12px;
position: absolute;
left: 0;
top: 0
}
.play_btn {
width: 65rpx;
height: 65rpx;
position: absolute;
left: 97.5rpx;
top: 39.5rpx
}
.play_btn_2 {
width: 65rpx;
height: 65rpx;
position: absolute;
left: 117.5rpx;
top: 52rpx
}
.pic {
width: 300rpx;
height: 169rpx;
background: #00B74F;
border-radius: 8rpx;
}
.tab_iem {
width: 145rpx;
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
}
/*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);
}
</style>

View File

@@ -1,128 +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">4</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">错4/已做100</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">
<view class="flex jc-sb ai-c">
<view>
<text class="fs24 fw600" style="color: #FF6E02;">32%</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>
<!-- <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;">科一精品视频课</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">科一易错试题</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.typeName}}</text>
<text class="cor-666">{{item.typeNum}}</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>
export default{
data(){
return{
tIndex:0,
isMoveWrong:true,
title:'重要提示:所有错题做对,再去考试!',
categoryList:[{
name:'错题本'
},{name:'收藏夹'}],
typeList:[{
typeName:'驾驶证审验注销',
typeNum:1
},{
typeName:'机动车强制报废',
typeNum:2
},{
typeName:'驾驶证审验注销',
typeNum:1
},{
typeName:'机动车强制报废',
typeNum:2
},{
typeName:'驾驶证审验注销',
typeNum:1
},{
typeName:'机动车强制报废',
typeNum:2
}]
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 {
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: []
}
},
methods:{
tabChange(val){
this.tIndex=val.index
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: {
...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
}
questionCategory(param).then(resp => {
this.typeList = resp.data
})
},
toPractice(){
const navTitle=this.tIndex==0?'错题本':'收藏夹'
tabChange(val) {
this.tIndex = val.index
this.getQuestionCategory()
},
toCategoryQuestion(item){
const jsonString = JSON.stringify(item.errorQuestionIdList)
console.log(item);
uni.navigateTo({
url:"/pages/questionBank/questionBank?navTitle="+navTitle
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
})
}
}
@@ -131,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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 332 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
src/static/image/mine/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
src/static/image/mine/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
src/static/image/mine/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 292 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Some files were not shown because too many files have changed in this diff Show More