first commit

This commit is contained in:
编码猿
2024-09-27 02:06:13 +08:00
commit 852d94fbb9
36760 changed files with 3274413 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
<template lang="pug">
#app
v-navbar(v-if="isShowNavbar" :title="NavBarTitle")
div(:class=" isHaveContent ? 'content': 'welcome' ")
router-view
v-tabbar(v-if="isShowTabbar" @getTitle="SetTitle")
</template>
<script>
import NavBar from "./components/tpl/NavBar"
import TabBar from "./components/tpl/Tabbar"
export default {
data() {
return {
isHaveContent: true,
isShowNavbar: true,
isShowTabbar: true,
NavBarTitle: '驾考神器'
}
},
methods: {
SetTitle (tit) {
this.NavBarTitle = tit
}
},
components: {
'v-navbar' : NavBar,
'v-tabbar' : TabBar
}
}
</script>
<style>
@import "./assets/less/lib/normalize.less";
.content {
margin-top: 46px;
overflow: scroll;
padding-bottom: 50px;
}
.van-radio__label--disabled {
color: #4c4c4c;
}
</style>

View File

@@ -0,0 +1,24 @@
import axios from "axios";
axios.defaults.baseURL = 'http://127.0.0.1:3000';
export default {
get (options) {
return new Promise(function(resolve,reject) {
axios.get(options.url, {
params: options.data
})
.then(function (response) {
resolve(response.data);
})
.catch(function (error) {
reject(error);
});
});
},
post () {
}
}

View File

@@ -0,0 +1,8 @@
import index from "./server/index"
import user from "./server/user"
export default {
index: index,
user: user
}

View File

@@ -0,0 +1,8 @@
import http from "../index"
import config from "../../config"
export default {
async getQuery(params) {
return await http.get({ url: config.httpApi.query, data: params });
}
}

View File

@@ -0,0 +1,11 @@
import http from "../index"
import config from "../../config"
export default {
async Login(params) {
return await http.get({ url: config.httpApi.login, data: params });
},
async Reg(params) {
return await http.get({ url: config.httpApi.reg, data: params });
}
}

View File

@@ -0,0 +1,7 @@
.exam {
img {
width: 80%;
margin: 10px auto;
display: block;
}
}

View File

@@ -0,0 +1,5 @@
@import "../lib/index.less";
.index {
}

View File

@@ -0,0 +1,65 @@
@import "../lib/index.less";
.ipage {
.adv {
width: 100%;
}
.list {
display: flex;
justify-content: space-around;
height: 80px;
background: @item;
.list-item {
display: flex;
align-items: center;
justify-content: space-evenly;
width: 50%;
.item-text {
h3 {
color: #333;
font-size: 14px;
margin-bottom: 10px;
}
p {
color: #999;
font-size: 12px;
}
}
img {
width: 35px;
height: 35px;
}
}
}
.gird-list {
padding: 15px 0;
margin-top: 10px;
position: relative;
background: @item;
ul {
display: flex;
justify-content: space-around;
li {
text-align: center;
&:nth-child(3) .icon,
&:nth-child(4) .icon {
width: 0.8em !important;
height: 0.8em !important;
margin-bottom: 7px;
}
.icon {
font-size: 38px;
}
p {
font-size: 14px;
color: #333;
}
}
}
}
.news-list{
background: @item;
margin-top: 10px;
}
}

View File

@@ -0,0 +1,104 @@
@import "../lib/index.less";
.base_page (@color:#fff) {
width: 100%;
height: 80%;
background-color: @color;
display: flex;
justify-content: center;
align-items: center;
}
.base_bottom_page(@color) {
width: 100%;
height: 20%;
text-align: center;
color: @color;
}
.welcome {
.active {
background: #f6f6f6;
}
width: 100%;height: 100%;
.swiper-slide{
width: 100%;
height: 100%;
}
.swiper-slide {
.welpage {
width: 100%;
height: 100%;
.pageimg1{
.base_page(@welcomeBgcolor1)
}
.pageimg2{
.base_page(@welcomeBgcolor2)
}
.pageimg3{
.base_page(@welcomeBgcolor3)
}
.pageimg4 {
.base_page();
flex-direction: column;
h2 {
}
.infos {
}
ul {
margin-top: 20px;
display: flex;
li {
text-align: center;
padding: 0 10px;
img {
}
p {
}
.jztype {
color: #a7a5a5;
padding-top: 0;
}
}
}
}
}
img {
width: 50%;
}
.welpage {
p{
// padding-top: 1rem;
// font-size: .875rem
}
span{
font-size: .625rem
}
.title1{
.base_bottom_page(@welcomeBgcolor1)
}
.title2{
.base_bottom_page(@welcomeBgcolor2)
}
.title3{
.base_bottom_page(@welcomeBgcolor3)
}
button{
width: 3.25rem;
height: 1.5rem;
background-color: @welcomeBgcolor3;
font-size: .75rem;
color: #fff;
border: none;
display: block;
margin: 0 auto;
margin-top: 1rem;
}
}
}
}
.swiper-container{
width: 100%;
height: 100%;
}

View File

@@ -0,0 +1,5 @@
@color: red;
@welcomeBgcolor1: #5eadef;
@welcomeBgcolor2: #bfeafa;
@welcomeBgcolor3: #ffd33f;
@item: #fff;

View File

@@ -0,0 +1,3 @@
@import "normalize.less";
@import "color.less";
@import "mixins.less";

View File

@@ -0,0 +1,9 @@
.bottom-line::after {
content: " ";
position: absolute;
bottom: 0;
width: 100%;
height: 1px;
background: #ebedf0;
transform: scaleY(0.5);
}

View File

@@ -0,0 +1,21 @@
body, ul,li,h1,h2,h3,h4,h5,h6,p {
margin: 0;
padding: 0;
}
html,body,#app, .content,.welcome {
height: 100%;
}
body {
background: #f5f5f5;
}
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.van-nav-bar--fixed {
z-index: 9999 !important;
}

View File

@@ -0,0 +1,24 @@
<template lang="pug">
.navbar
van-nav-bar(:title='title' :border="false" :fixed="true")
van-icon(name="friends-o" slot="left")
</template>
<script>
export default {
props: {
title: null
},
data() {
return {
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,34 @@
<template lang="pug">
.tabbar
van-tabbar(v-model='active')
van-tabbar-item(:icon='item.icon'
:to="item.path"
@click="changeTitle(item.name)"
v-for="(item,index) in items" :key="index") {{item.name}}
</template>
<script>
export default {
data() {
return {
active: 0,
items: [
{ icon: 'logistics', path: '/index', name: '驾考' },
{ icon: 'paid', path: '/car', name: '买车' },
{ icon: 'chart-trending-o', path: '/message', name: '资讯' },
{ icon: 'friends-o', path: '/my', name: '我的' }
]
}
},
methods: {
changeTitle (title) {
title == "驾考" ? title = "驾考神器" : title;
this.$emit("getTitle", title)
}
}
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,73 @@
<template lang="pug">
.ipage
a(:href="imgurl.href")
img.adv(:src="imgurl.url")
.list
.list-item(@click="startExam('rand')")
.item-text
h3 模拟考试
p 练习和模拟考试
img(src="../../../static/img/item-1.png")
.list-item(@click="startExam('order')")
.item-text
h3 驾考题库
p 按章节练习
img(src="../../../static/img/item-2.png")
.gird-list.bottom-line
ul
li
svg.icon(aria-hidden='true')
use(xlink:href='#icon-che')
p 找车
li
svg.icon(aria-hidden='true')
use(xlink:href='#icon-luntanzixun')
p 咨询
li
svg.icon(aria-hidden='true')
use(xlink:href='#icon-errorList')
p 错题
li
svg.icon(aria-hidden='true')
use(xlink:href='#icon-shoucang')
p 收藏
.news-list
van-card(num="2"
v-for="item in 10" :key="item"
price="2.00"
desc="描述信息"
title="商品标题"
thumb="https://img.yzcdn.cn/vant/t-thirt.jpg")
</template>
<script>
export default {
props: {
list: null,
imgurl: {
href: null,
url: null
},
subject: null
},
data () {
return {
}
},
created() {
console.log(this.subject)
},
methods: {
startExam (types) {
this.$router.push({ name: 'exam', params: { type: types, subject: this.subject } })
}
}
}
</script>
<style lang="less" scoped>
@import "../../assets/less/components/ipage.less";
</style>

View File

@@ -0,0 +1,19 @@
<template lang="pug">
.car
h2 买车
</template>
<script>
export default {
data () {
return {
}
}
}
</script>
<style lang="less" scoped>
</style>

View File

@@ -0,0 +1,145 @@
<template lang="pug">
.exam
van-swipe(@change='onChange' :loop="false", ref="mySwiper")
van-swipe-item(v-for="(item,index) in examListData" :key="index")
p.title {{ item.question }}
img(v-if="item.url.length != 0" :src="item.url")
van-radio-group(v-model='radio' :disabled="isAgClick ? false : true ")
van-radio(v-for="(ans,i) in item.answerList",
:name='i',:key="i",
@click="isAgClick ? verAnswer(i) : '' ") {{ ans.name }}
div.error-tips(v-if="showError")
div(v-html="item.explains")
</template>
<script>
export default {
data () {
return {
startIndex: 0,
endIndex: null,
showError: false,
radio: 'r323424',
currentIndex: 0,
newData: [],
examListData: [],
errorAnswer: [],
count: 0,
isAgClick: true,
model: this.$utils.getLocalStorage('carType').type.split("/")[0].toLowerCase()
}
},
created () {
if (this.$route.params.type == "rand") {
this.getData()
} else {
if (this.$route.params.subject == 4) {
if (this.$utils.getLocalStorage("km4") == null ) {
this.getData()
} else {
this.AsyncSetData("km4")
}
} else {
if (this.$utils.getLocalStorage("km1") == null) {
this.getData()
} else {
this.AsyncSetData("km1")
}
}
}
},
methods: {
async getData () {
let data = await this.$api.index.getQuery({
subject: this.$route.params.subject,
model: this.model,
testType: this.$route.params.type
});
let result = data.result;
let answerList = [];
result.forEach((val,index) => {
answerList = []
for(var keyName in val) {
if (keyName.indexOf('item') > -1) {
if(val[keyName].length != 0) {
answerList.push({
name: val[keyName]
})
}
delete val[keyName];
}
}
val.answerList = answerList
});
if (this.$route.params.type == "order") {
if (this.$route.params.subject == 4) {
this.$utils.setLocalStorage("km4", result)
} else {
this.$utils.setLocalStorage("km1", result)
}
}
this.examListData = result
},
AsyncSetData(type) {
this.endIndex = this.startIndex * 100 + 99;
for (var i = this.startIndex * 100;i <= this.endIndex; i++) {
this.newData.push(this.$utils.getLocalStorage(type)[i])
}
this.examListData = this.newData
},
verAnswer(ans){
this.isAgClick = false
let a = (this.examListData[this.currentIndex].answer) -1
if(a == ans) {
this.$refs.mySwiper.swipeTo(this.currentIndex + 1)
this.count += 1;
} else {
this.showError = true;
this.errorAnswer.push(this.currentIndex)
console.log("答错了")
}
},
onChange(index) {
this.isAgClick = true
if (this.$route.params.type == "order") {
if (index == this.endIndex) {
this.startIndex += 1
this.$route.params.subject == 4 ? this.AsyncSetData("km4") : this.AsyncSetData("km1")
this.$refs.mySwiper.swipeTo(this.startIndex * 100)
}
} else {
if (index >= 3) {
alert(`题目答完了,分数: ${this.count},错题${this.errorAnswer.length}, 未做题:${100-(this.count +this.errorAnswer.length)}`)
}
}
this.showError = false;
this.radio = '3243243'
this.currentIndex = index
}
},
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$parent.$data.isShowTabbar = false
})
},
beforeRouteLeave (to, from, next) {
this.$parent.$data.isShowTabbar = true
next()
}
}
</script>
<style lang="less" scoped>
@import "../../assets/less/components/exam.less";
</style>

View File

@@ -0,0 +1,42 @@
<template lang="pug">
.index
van-tabs(v-model='active' @change="changeTabs" swipeable animated)
van-tab(title="科目一")
v-page(:list="PropSPage", :imgurl="AdvObj", :subject="currentSubject")
van-tab(title="科目四")
v-page(:list="PropSPage", :imgurl="AdvObj", :subject="currentSubject")
</template>
<script>
import Ipage from "../tpl/ipage"
export default {
data () {
return {
currentSubject: 1,
active: 0,
PropSPage: [],
AdvObj: {
href: 'http://m.jiakaobaodian.com/school/key.html?from=m29',
url: '../../../static/img/baner.jpeg'
}
}
},
created () {
},
methods: {
changeTabs(index) {
index == 0 ? this.currentSubject = 1 : this.currentSubject = 4;
}
},
components: {
'v-page' : Ipage
}
}
</script>
<style lang="less" scoped>
@import "../../assets/less/components/index.less";
</style>

View File

@@ -0,0 +1,19 @@
<template lang="pug">
.message
h2 资讯
</template>
<script>
export default {
data () {
return {
}
}
}
</script>
<style lang="less" scoped>
</style>

View File

@@ -0,0 +1,19 @@
<template lang="pug">
.my
h2 我的
</template>
<script>
export default {
data () {
return {
}
}
}
</script>
<style lang="less" scoped>
</style>

View File

@@ -0,0 +1,88 @@
<template lang="pug">
.user
.login(v-if="ChangePage")
van-cell-group
van-field(v-model='login.name', required='', clearable='',
label='用户名', right-icon='question-o', placeholder='请输入用户名',
@click-right-icon="$toast('question')")
van-field(v-model='login.pwd', type='password', label='密码',
placeholder='请输入密码', required='')
van-button(type="primary" size="large", @click="UserLogin") 登 录
.reg(v-else)
van-cell-group
van-field(v-model='reg.name', required='', clearable='',
label='用户名', right-icon='question-o', placeholder='请输入用户名',
@click-right-icon="$toast('question')")
van-field(v-model='reg.phone', type='password', label='密码',
placeholder='请输入密码', required='')
van-field(v-model='reg.pwd', label='手机号', placeholder='请输入手机号',
error-message='手机号格式错误')
van-button(type="primary", size="large", @click="UserReg") 注 册
span(@click="change") {{ changeText }}
</template>
<script>
export default {
data () {
return {
login: {
name: null,
pwd: null,
},
reg : {
name: null,
pwd: null,
phone: null
},
ChangePage: true,
changeText: '注 册 '
}
},
methods: {
change () {
this.ChangePage = !this.ChangePage
this.ChangePage ? this.changeText = '注 册' : this.changeText = '登 录'
},
async UserLogin () {
let result = await this.$api.user.Login(this.login)
if(result.status == 200) {
this.$utils.setLocalStorage("status",result.data[0])
this.$router.push({ path: this.$route.query.form })
} else {
this.$toast.fail(result.message);
}
},
async UserReg () {
let result = await this.$api.user.Reg(this.reg)
if(result.status == 200) {
this.ChangePage = false
} else {
this.$toast.loading({
mask: true,
message: '注册失败'
});
}
}
},
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$parent.$data.isShowNavbar = false
vm.$parent.$data.isShowTabbar = false
vm.$parent.$data.isHaveContent = false
})
},
beforeRouteLeave (to, from, next) {
this.$parent.$data.isShowNavbar = true
this.$parent.$data.isShowTabbar = true
this.$parent.$data.isHaveContent = true
next()
}
}
</script>
<style lang="less" scoped>
</style>

View File

@@ -0,0 +1,97 @@
<template lang="pug">
.welcome
swiper(:options='swiperOption', ref='mySwiper')
swiper-slide
.welpage
.pageimg1
img(src="../../../static/img/welcome1.png")
.title1
p 驾考手册
swiper-slide
.welpage
.pageimg2
img(src="../../../static/img/welcome2.png")
.title2
p 专业分类
span 驾考车型全覆盖
swiper-slide
.welpage
.pageimg3
img(src="../../../static/img/welcome3.png")
.title3
p 全真练习
span 模拟考试,错题汇总
swiper-slide
.welpage
.pageimg4
h2 请选择您要开始的题库
p.infos 驾驶证/资格证(当前类型:{{ currentTitle }})
ul
li(v-for="(item,index) in typeList" :key="index"
@click="choiceType(item,index)"
:class="index == current ? 'active' : '' ")
img(:src="item.icon")
p {{ item.name }}
p.jztype {{ item.type }}
.title2
button(@click='EnterIndex()') 开始
.swiper-pagination(slot='pagination')
</template>
<script>
export default {
data() {
return {
current: 0,
currentTitle: '小车',
swiperOption: {
pagination: {
el: '.swiper-pagination'
}
},
typeList: [
{ name: '小车', type: 'C1/C2', icon: '../../../static/img/xiaoche.png' },
{ name: '货车', type: 'A2/B2', icon: '../../../static/img/huoche.png' },
{ name: '客车', type: 'A1/B1', icon: '../../../static/img/keche.png' }
]
}
},
methods: {
choiceType(item,index) {
this.current = index;
this.currentTitle = item.name
},
EnterIndex () {
this.$utils.setLocalStorage('carType', this.typeList[this.current])
this.$router.replace({ name: 'index' })
},
},
mounted() {
this.swiper.slideTo(0, 1000, false)
},
computed: {
swiper() {
return this.$refs.mySwiper.swiper
}
},
beforeRouteEnter (to, from, next) {
next(vm => {
vm.$parent.$data.isShowNavbar = false
vm.$parent.$data.isShowTabbar = false
vm.$parent.$data.isHaveContent = false
})
},
beforeRouteLeave (to, from, next) {
this.$parent.$data.isShowNavbar = true
this.$parent.$data.isShowTabbar = true
this.$parent.$data.isHaveContent = true
next()
}
}
</script>
<style scoped lang="less">
@import "../../assets/less/components/welcome.less";
</style>

View File

@@ -0,0 +1,8 @@
export default {
baseURL: 'http://127.0.0.1:3000/',
httpApi: {
query: '/query',
login: '/user/login',
reg: '/user/reg'
}
}

View File

@@ -0,0 +1,30 @@
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import Vant from 'vant'
import 'vant/lib/index.css'
import VueAwesomeSwiper from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
import server from "./api/server"
import utils from "./utils"
Vue.use(VueAwesomeSwiper)
Vue.use(Vant)
Vue.prototype.$api = server
Vue.prototype.$utils = utils
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})

View File

@@ -0,0 +1,96 @@
import Vue from 'vue'
import Router from 'vue-router'
import Index from '@/components/view/index'
import Car from '@/components/view/car'
import Message from '@/components/view/message'
import My from '@/components/view/my'
import User from '@/components/view/user'
import Exam from '@/components/view/exam'
import Welcome from '@/components/view/welcome'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/',
name: 'welcome',
component: Welcome,
meta: {
isLogin: false
}
},
{
path: '/index',
name: 'index',
component: Index,
meta: {
isLogin: false
}
},
{
path: '/message',
name: 'message',
component: Message,
meta: {
isLogin: false
}
},
{
path: '/car',
name: 'car',
component: Car,
meta: {
isLogin: false
}
},
{
path: '/my',
name: 'my',
component: My,
meta: {
isLogin: true
}
},
{
path: '/exam/:type/:subject',
name: 'exam',
component: Exam,
meta: {
isLogin: true
}
},
{
path: '/user',
name: 'user',
component: User,
meta: {
isLogin: false
}
}
//
]
})
router.beforeEach((to, from, next) => {
if(to.meta.isLogin) {
// 判断 status 是否存在,并且是否合法
if(localStorage.getItem('status') == null) {
next({
path: '/user',
query: {
form: from.path
}
})
} else {
next()
}
} else {
next()
}
});
export default router

View File

@@ -0,0 +1,8 @@
export default {
setLocalStorage (name,value) {
localStorage.setItem(name, JSON.stringify(value))
},
getLocalStorage(name) {
return JSON.parse(localStorage.getItem(name))
}
}