提交 1bf3bc11 authored 作者: lihuihui's avatar lihuihui
...@@ -13,18 +13,6 @@ module.exports = { ...@@ -13,18 +13,6 @@ module.exports = {
}, },
devServer: { devServer: {
proxy: { proxy: {
// '/api/passport': {
// target: 'https://passport.ezijing.com',
// pathRewrite: {
// '^/api/passport': '/' // 需要rewrite重写的
// }
// },
// '/usercenter': {
// target: 'https://api-usercenter.ezijing.com',
// pathRewrite: {
// '^/usercenter': '/' // 需要rewrite重写的
// }
// }
/* 多个代理 */ /* 多个代理 */
// '/api': { // '/api': {
// target: $GLOBAL.webConf.url, // target: $GLOBAL.webConf.url,
...@@ -45,5 +33,7 @@ module.exports = { ...@@ -45,5 +33,7 @@ module.exports = {
} }
}, },
ProvidePlugin: {}, ProvidePlugin: {},
others: {} others: {
WECHAT_REDIRECT_URL: 'https://passport2.ezijing.com'
}
} }
...@@ -5,18 +5,16 @@ module.exports = { ...@@ -5,18 +5,16 @@ module.exports = {
isUploadStatic: false, isUploadStatic: false,
webpack: { webpack: {
externals: { externals: {
'CKEDITOR': 'window.CKEDITOR', CKEDITOR: 'window.CKEDITOR',
'Base64': 'window.Base64', Base64: 'window.Base64',
'md5': 'window.md5', md5: 'window.md5',
'regeneratorRuntime': 'window.regeneratorRuntime', regeneratorRuntime: 'window.regeneratorRuntime',
'wx': 'window.wx', wx: 'window.wx',
'WeixinJSBridge': 'window.WeixinJSBridge' WeixinJSBridge: 'window.WeixinJSBridge'
} }
}, },
ProvidePlugin: { ProvidePlugin: {},
},
others: { others: {
WECHAT_REDIRECT_URL: 'https://passport.ezijing.com'
} }
} }
...@@ -5,18 +5,16 @@ module.exports = { ...@@ -5,18 +5,16 @@ module.exports = {
isUploadStatic: false, isUploadStatic: false,
webpack: { webpack: {
externals: { externals: {
'CKEDITOR': 'window.CKEDITOR', CKEDITOR: 'window.CKEDITOR',
'Base64': 'window.Base64', Base64: 'window.Base64',
'md5': 'window.md5', md5: 'window.md5',
'regeneratorRuntime': 'window.regeneratorRuntime', regeneratorRuntime: 'window.regeneratorRuntime',
'wx': 'window.wx', wx: 'window.wx',
'WeixinJSBridge': 'window.WeixinJSBridge' WeixinJSBridge: 'window.WeixinJSBridge'
} }
}, },
ProvidePlugin: { ProvidePlugin: {},
},
others: { others: {
WECHAT_REDIRECT_URL: 'https://passport2.ezijing.com'
} }
} }
...@@ -37,7 +37,8 @@ export default class API { ...@@ -37,7 +37,8 @@ export default class API {
/* 具体执行请求失败后业务逻辑前,先执行该方法 */ /* 具体执行请求失败后业务逻辑前,先执行该方法 */
const beforeFail = _config.beforeFail ? _config.beforeFail : this._reqFail const beforeFail = _config.beforeFail ? _config.beforeFail : this._reqFail
const headers = { const headers = {
tenant: 'transport' tenant: 'transport',
'Content-Type': 'application/x-www-form-urlencoded'
} }
_config.headers = _.assignIn(_config.headers, headers) _config.headers = _.assignIn(_config.headers, headers)
/* 判别 传输方式 */ /* 判别 传输方式 */
......
...@@ -6,7 +6,8 @@ export default class Before { ...@@ -6,7 +6,8 @@ export default class Before {
async update(to, from, next) { async update(to, from, next) {
if (to.meta.requiredLogin) { if (to.meta.requiredLogin) {
const isLogin = await store.dispatch('checkLogin') const isLogin =
store.state.isLogin || (await store.dispatch('checkLogin'))
if (isLogin) { if (isLogin) {
next() next()
} else { } else {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" /> <meta http-equiv="Expires" content="0" />
<title></title> <title>道路安全考证宝典</title>
<meta name="viewport" id="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, shrink-to-fit=no, viewport-fit=cover"> <meta name="viewport" id="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, shrink-to-fit=no, viewport-fit=cover">
<!-- <script src="https://cdn.jsdelivr.net/npm/vconsole@3.3.4/dist/vconsole.min.js"></script> --> <!-- <script src="https://cdn.jsdelivr.net/npm/vconsole@3.3.4/dist/vconsole.min.js"></script> -->
</head> </head>
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
</form> </form>
</div> </div>
</div> </div>
<div class="backtop" @click="scrollTop" v-show="showBacktop"></div>
</div> </div>
</template> </template>
...@@ -47,7 +48,8 @@ export default { ...@@ -47,7 +48,8 @@ export default {
return { return {
detail: { chapters: [] }, detail: { chapters: [] },
messageList: [], // {id:'', type: 1, payload: {}} messageList: [], // {id:'', type: 1, payload: {}}
searchValue: '' searchValue: '',
showBacktop: false
} }
}, },
watch: { watch: {
...@@ -149,10 +151,27 @@ export default { ...@@ -149,10 +151,27 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
window.scrollTo(0, document.body.scrollHeight) window.scrollTo(0, document.body.scrollHeight)
}) })
},
// 滚到到顶部
scrollTop() {
window.scrollTo(0, 0)
},
handleScroll() {
const scrollTop =
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop
this.showBacktop = scrollTop >= 10
} }
}, },
beforeMount() { beforeMount() {
this.getCourseTagList() this.getCourseTagList()
},
mounted() {
window.addEventListener('scroll', this.handleScroll)
},
destroyed() {
window.removeEventListener('scroll', this.handleScroll)
} }
} }
</script> </script>
...@@ -178,4 +197,15 @@ export default { ...@@ -178,4 +197,15 @@ export default {
background-color: #fff; background-color: #fff;
} }
} }
.backtop {
position: fixed;
right: 15px;
bottom: 64px;
width: 46px;
height: 46px;
background: url('../../../assets/images/icon_backtop.png') no-repeat;
background-size: contain;
cursor: pointer;
margin-bottom: env(safe-area-inset-bottom);
}
</style> </style>
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
<div class="inner"> <div class="inner">
<ul> <ul>
<li @click="toExamPage">去测试</li> <li @click="toExamPage">去测试</li>
<li @click="toExamPage" v-if="detail.has_video">相关视频</li>
</ul> </ul>
<ul> <ul>
<li @click="getCourseTag(detail.last)" v-if="detail.last">上一点</li> <li @click="getCourseTag(detail.last)" v-if="detail.last">上一点</li>
...@@ -144,7 +145,8 @@ export default { ...@@ -144,7 +145,8 @@ export default {
display: inline-block; display: inline-block;
height: 35px; height: 35px;
margin-left: 10px; margin-left: 10px;
padding: 0 30px; // padding: 0 30px;
padding: 0 10px;
font-size: 13px; font-size: 13px;
color: #fff; color: #fff;
line-height: 35px; line-height: 35px;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
<div class="tools"> <div class="tools">
<ul> <ul>
<li @click="toExamPage">知识点考试</li> <li @click="toExamPage">知识点考试</li>
<li @click="toCourseVideo" v-if="data.has_video">相关视频</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -27,6 +28,7 @@ ...@@ -27,6 +28,7 @@
export default { export default {
name: 'TagMessage', name: 'TagMessage',
props: { props: {
courseId: { type: String },
data: { type: Object } data: { type: Object }
}, },
data() { data() {
...@@ -82,6 +84,16 @@ export default { ...@@ -82,6 +84,16 @@ export default {
} else { } else {
this.$router.push({ path }) this.$router.push({ path })
} }
},
// 去课程视频页面
toCourseVideo() {
if (this.isWeapp) {
wx.miniProgram.navigateTo({
url: `/pages/course/item?id=${this.courseId}`
})
} else {
window.alert('请在微信小程序中打开')
}
} }
}, },
mounted() { mounted() {
......
<template>
<div class="download">
<h2>学习资料</h2>
<h3>请您自行下载</h3>
<p>下载链接:https://pan.baidu.com</p>
<p>提取码:mp91</p>
</div>
</template>
<script>
export default {
metaInfo: { title: '下载资料' },
data() {
return {}
},
methods: {}
}
</script>
<style lang="scss" scoped>
.download {
min-height: 100vh;
padding: 5.04rem 20px 0;
background: url('../../assets/images/download_bg.png') no-repeat center top;
background-size: 100%;
box-sizing: border-box;
h2 {
font-size: 0.3rem;
font-weight: bold;
color: #f7a746;
text-align: center;
}
h3 {
margin-top: 40px;
font-size: 0.3rem;
font-weight: bold;
color: #222;
}
p {
margin-top: 40px;
font-size: 0.3rem;
color: #222;
}
}
</style>
...@@ -60,7 +60,7 @@ export default { ...@@ -60,7 +60,7 @@ export default {
name: 'Index', name: 'Index',
components: { SearchBar, Card, FreeCourseItem }, components: { SearchBar, Card, FreeCourseItem },
metaInfo: { metaInfo: {
title: '道路运输安全知识线上课' title: '道路安全考证宝典'
}, },
data() { data() {
return { return {
......
...@@ -137,10 +137,7 @@ export default { ...@@ -137,10 +137,7 @@ export default {
}, },
wechatLogin() { wechatLogin() {
const appId = 'wxc6044475caf2805a' const appId = 'wxc6044475caf2805a'
const wechatRedirectURL = const wechatRedirectURL = webConf.others.WECHAT_REDIRECT_URL
webConf.isDev === 'production'
? 'https://passport.ezijing.com'
: 'https://passport2.ezijing.com'
// 回调地址 // 回调地址
const redirectURI = `${wechatRedirectURL}/rest/wechat/oauth-callback?needCheck=false&identity=transport&redirectUrl=${window.location.href}` const redirectURI = `${wechatRedirectURL}/rest/wechat/oauth-callback?needCheck=false&identity=transport&redirectUrl=${window.location.href}`
// 微信的地址 // 微信的地址
......
import BaseAPI from '@/api/base_api'
const httpRequest = new BaseAPI(webConf)
/**
* 获取课程提醒列表
*/
export function getAlarmList() {
return httpRequest.get('/zy/v2/education/alarm/list')
}
/**
* 获取课程提醒详情
*/
export function getAlarm(id) {
return httpRequest.get(`/zy/v2/education/alarm/detail/${id}`)
}
/**
* 添加课程提醒
*/
export function addAlarm(data) {
return httpRequest.post('/zy/v2/education/alarm/add', data)
}
/**
* 更新课程提醒
*/
export function updateAlaram(data) {
return httpRequest.post('/zy/v2/education/alarm/edit', data)
}
/**
* 删除课程提醒
*/
export function deleteAlaram(id) {
return httpRequest.delete(`/zy/v2/education/alarm/delete/${id}`)
}
/**
* 检查是否关注微信公众号
*/
export function checkFollowWechat(id) {
return httpRequest.get('/zy/v2/education/hasguanzhu')
}
<template>
<div class="alarm-item">
<div class="alarm-item-left" @click="$emit('click-edit', data)">
<h4 class="alarm-item__title">{{data.time}}</h4>
<p class="alarm-item__text">{{showText}}</p>
</div>
<div class="alarm-item-right">
<van-switch
v-model="checked"
size="18px"
active-color="#2B7CE9"
:loading="switchLoading"
@change="onChange"
/>
<van-icon name="delete" @click="onRemove" />
</div>
</div>
</template>
<script>
import * as api from '../api'
export default {
name: 'AlarmItem',
props: {
data: {
type: Object,
default() {
return {}
}
}
},
data() {
return {
checked: false,
switchLoading: false
}
},
watch: {
'data.status': {
immediate: true,
handler(value) {
this.checked = value === '1'
}
}
},
computed: {
showText() {
const type = parseInt(this.data.type)
if (type === 1) {
return '每天'
} else if (type === 3) {
return '工作日'
} else {
return this.selectedWeek.length
? '每周' + this.selectedWeek.join('、')
: '永不'
}
},
selectedWeek() {
const weeks = ['一', '二', '三', '四', '五', '六', '日']
const nums = this.data.week_json ? JSON.parse(this.data.week_json) : []
return nums.map(item => weeks[item - 1])
}
},
methods: {
onChange() {
this.switchLoading = true
const params = Object.assign({}, this.data)
params.status = this.checked ? 1 : 0
api.updateAlaram(params).finally(() => {
this.switchLoading = false
})
},
onRemove() {
this.$emit('remove', this.data)
api.deleteAlaram(this.data.id).then(response => {
this.$toast('删除成功')
this.$emit('update')
})
}
}
}
</script>
<style lang="scss" scoped>
.alarm-item {
display: flex;
align-items: center;
padding: 20px 0;
}
.alarm-item-left {
flex: 1;
}
.alarm-item__title {
font-size: 20px;
font-weight: bold;
line-height: 1;
}
.alarm-item__text {
margin-top: 5px;
font-size: 13px;
line-height: 1;
color: #666;
}
.alarm-item-right {
margin-left: 20px;
font-size: 0;
::v-deep .van-icon {
margin-left: 20px;
font-size: 20px;
color: #ccc;
}
}
</style>
<template>
<div class="alarm-update">
<div class="alarm-title">{{title}}</div>
<div class="alarm-form">
<div class="alarm-form-time">
<div class="alarm-form-time__lable">提醒时间</div>
<van-picker
v-model="ruleForm.time"
:columns="timeColumns"
:item-height="30"
:default-index="defaultIndex"
@change="onChangeTime"
/>
</div>
<div class="alarm-form-item">
<div class="alarm-form-item-hd">
<div class="alarm-form-item-hd__lable">重复</div>
<div class="alarm-form-item-hd__aside">{{selectedResultText}}</div>
</div>
<div class="alarm-form-item-content">
<van-checkbox-group v-model="ruleForm.week_json" direction="horizontal">
<van-checkbox v-for="(item, index) in weeks" :name="index + 1" :key="index">{{item}}</van-checkbox>
</van-checkbox-group>
</div>
</div>
<van-button type="primary" @click="onSubmit">确定</van-button>
</div>
</div>
</template>
<script>
import { isEqual } from 'lodash'
import * as api from '../api'
export default {
name: 'AlarmUpdate',
props: {
isUpdate: { type: Boolean, default: false },
data: {
type: Object,
default() {
return {}
}
}
},
data() {
return {
ruleForm: {
time: '06:30',
week_json: [],
status: 1
},
weeks: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
defaultIndex: 13
}
},
watch: {
data: {
immediate: true,
handler(data) {
if (!data || !this.isUpdate) {
return
}
const weeks = data.week_json ? JSON.parse(data.week_json) : []
this.defaultIndex = this.timeColumns.findIndex(
item => item === data.time
)
this.ruleForm = Object.assign({}, this.ruleForm, data, {
week_json: weeks
})
}
}
},
computed: {
title() {
return this.isUpdate ? '修改提醒时间' : '新增提醒时间'
},
// 时间选择项
timeColumns() {
return this.genTimeColumns()
},
// 重复类型
selectedResultType() {
const weeks = this.ruleForm.week_json.sort()
if (isEqual(weeks, [1, 2, 3, 4, 5, 6, 7])) {
return 1
} else if (isEqual(weeks, [1, 2, 3, 4, 5])) {
return 3
} else {
return 2
}
},
// 重复类型显示文本
selectedResultText() {
if (this.selectedResultType === 1) {
return '每天'
} else if (this.selectedResultType === 3) {
return '工作日'
} else {
return this.selectedWeek.length
? '每周' + this.selectedWeek.join('、')
: '永不'
}
},
selectedWeek() {
const weeks = ['一', '二', '三', '四', '五', '六', '日']
const nums = this.ruleForm.week_json
return nums.map(item => weeks[item - 1])
}
},
methods: {
onSubmit() {
this.isUpdate ? this.handleUpdate() : this.handleAdd()
},
// 添加
handleAdd() {
const params = Object.assign({}, this.ruleForm)
params.type = this.selectedResultType
params.week_json = JSON.stringify(this.ruleForm.week_json.sort())
api.addAlarm(params).then(response => {
if (response.success) {
this.handleSuccess(response)
} else {
this.$toast(JSON.stringify(response.errors))
}
})
},
// 更新
handleUpdate() {
const params = Object.assign({}, this.ruleForm)
params.type = this.selectedResultType
params.week_json = JSON.stringify(this.ruleForm.week_json.sort())
api.updateAlaram(params).then(response => {
if (response.success) {
this.handleSuccess(response)
} else {
this.$toast(JSON.stringify(response.errors))
}
})
},
handleSuccess(response) {
this.$emit('success', response)
},
filter(type, options) {
if (type === 'minute') {
return options.filter(option => option % 30 === 0)
}
return options
},
// 生成提醒时间数据
genTimeColumns() {
const columns = []
for (let i = 0; i <= 23; i++) {
const temp = i < 10 ? `0${i}` : i
columns.push(`${temp}:00`)
columns.push(`${temp}:30`)
}
return columns
},
onChangeTime(picker, value, index) {
this.ruleForm.time = value
}
}
}
</script>
<style lang="scss" scoped>
.alarm-update {
padding: 20px;
}
.alarm-title {
margin-bottom: 20px;
font-size: 18px;
color: #222;
line-height: 1;
text-align: center;
}
.alarm-form {
padding-bottom: env(safe-area-inset-bottom);
}
.alarm-form-time {
position: relative;
margin-bottom: 20px;
}
.alarm-form-time__lable {
position: absolute;
top: 0;
left: 0;
bottom: 0;
z-index: 100;
display: flex;
align-items: center;
font-size: 15px;
line-height: 1;
}
.alarm-form-item {
margin-bottom: 20px;
}
.alarm-form-item-hd {
display: flex;
justify-content: space-between;
padding-bottom: 20px;
}
.alarm-form-item-hd__lable {
font-size: 15px;
}
.alarm-form-item-hd__aside {
font-size: 15px;
color: #a7a6a7;
}
::v-deep .van-picker__frame {
display: none;
}
::v-deep .van-checkbox {
width: 34px;
height: 34px;
justify-content: center;
font-size: 12px;
text-align: center;
border: 1px solid #eee;
border-radius: 50%;
box-sizing: border-box;
&:last-child {
margin-right: 0;
}
}
::v-deep .van-checkbox[aria-checked='true'] {
background-color: #2b7ce9;
border: 0;
.van-checkbox__label {
color: #fff;
}
}
::v-deep .van-checkbox__icon {
display: none;
}
::v-deep .van-checkbox__label {
margin: 0;
color: #a7a6a7;
}
::v-deep .van-button {
margin-top: 40px;
display: block;
width: 100%;
height: 40px;
background-color: #2b7ce9;
border: 0;
border-radius: 6px;
}
</style>
<template>
<div class="list">
<alarm-item
v-for="item in list"
:data="item"
:key="item.id"
@click-edit="onUpdate"
@update="refersh"
></alarm-item>
<div class="add-button">
<div class="inner" @click="popupVisible = true"></div>
</div>
<!-- 添加/修改 -->
<van-popup v-model="popupVisible" position="bottom" @closed="onClosed">
<alarm-update
:isUpdate="isUpdate"
:data="activeItem"
@success="onSuccess"
v-if="popupVisible"
></alarm-update>
</van-popup>
<van-popup v-model="followPopupVisible" style="border-radius:6px;">
<div class="qrcode">
<p>开启学习提醒功能,需先关注紫荆职教公众号。</p>
<img src="../../../assets/images/wechat_mp_qrcode.png" />
<h5>保存二维码图片,扫码关注</h5>
</div>
</van-popup>
</div>
</template>
<script>
import * as api from './api'
import AlarmItem from './components/alarmItem.vue'
import AlarmUpdate from './components/update.vue'
export default {
name: 'AlarmIndex',
components: { AlarmItem, AlarmUpdate },
metaInfo: {
title: '学习提醒'
},
data() {
return {
list: [],
popupVisible: false,
isUpdate: false,
activeItem: null,
followPopupVisible: false
}
},
methods: {
// 检查是否关注公众号
checkFollowWechat() {
api.checkFollowWechat().then(response => {
this.followPopupVisible = !response.flag
})
},
// 获取提醒列表
getAlarmList() {
api.getAlarmList().then(response => {
this.list = response
})
},
refersh() {
this.getAlarmList()
},
onUpdate(data) {
this.isUpdate = true
this.activeItem = data
this.popupVisible = true
},
onSuccess() {
this.popupVisible = false
this.refersh()
},
onClosed() {
this.isUpdate = false
this.activeItem = null
}
},
beforeMount() {
this.checkFollowWechat()
this.getAlarmList()
}
}
</script>
<style lang="scss" scoped>
.list {
padding: 20px 0;
margin: 0 20px;
}
.add-button {
height: 64px;
margin-bottom: 50px;
.inner {
position: fixed;
left: 50%;
bottom: 50px;
transform: translateX(-50%);
width: 64px;
height: 64px;
background: url('../../../assets/images/icon_remind_add.png') no-repeat;
background-size: 100%;
}
}
.qrcode {
width: 5.9rem;
padding: 0.4rem;
box-sizing: border-box;
img {
margin: 10px 0;
width: 100%;
}
p {
font-size: 15px;
color: #222;
}
h5 {
font-size: 15px;
color: #222;
font-weight: bold;
text-align: center;
}
}
</style>
import BaseAPI from '@/api/base_api'
const httpRequest = new BaseAPI(webConf)
/**
* 获取免费课程列表
*/
export function getFreeCourseList() {
return httpRequest.get('/zy/v2/education/freecourse')
}
<template>
<div class="learned"></div>
</template>
<script>
export default {
metaInfo: {
title: '已学课程'
},
data() {
return {}
},
methods: {}
}
</script>
<style lang="scss" scoped>
</style>
...@@ -147,6 +147,19 @@ export default [ ...@@ -147,6 +147,19 @@ export default [
{ {
path: '/pay', path: '/pay',
name: 'pay', name: 'pay',
component: () => import('../pages/pay/index.vue') component: () => import('../pages/pay/index.vue'),
meta: { requiredLogin: true }
},
{
path: '/download',
name: 'download',
component: () => import('../pages/download/index.vue'),
meta: { requiredLogin: true }
},
{
path: '/my/alarm',
name: 'MyAlarm',
component: () => import('../pages/my/alarm/index.vue'),
meta: { requiredLogin: true }
} }
] ]
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论