提交 0e68c1f7 编写于 作者: guangjun.yang's avatar guangjun.yang

Merge branch 'dev-coursedetail-0817' into 'release'

CME、职称考页面,样式优化等   code reviewer:杨广俊

CME、职称考页面,样式优化等   code reviewer:杨广俊

See merge request !1
{
"presets": ["env", "es2015", "stage-2"],
"presets": [
"@babel/preset-env"
],
"plugins": [
"add-module-exports",
"transform-runtime",
"add-module-exports",
[
"@babel/plugin-transform-runtime",
{
"corejs": 2
}
],
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-import-meta",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-json-strings",
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
"@babel/plugin-proposal-function-sent",
"@babel/plugin-proposal-export-namespace-from",
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-throw-expressions"
],
"comments": false,
"comments": false
}
......@@ -55,4 +55,4 @@ exports.styleLoaders = function(options) {
})
}
return output
}
\ No newline at end of file
}
......@@ -40,7 +40,7 @@ module.exports = {
loader: 'vue'
}, {
test: /\.js$/,
loader: 'babel',
loader: 'babel-loader',
include: projectRoot,
exclude: /node_modules/
}, {
......@@ -69,7 +69,16 @@ module.exports = {
postcss: [
require('autoprefixer')({
browsers: ['last 10 versions']
}),
require('postcss-pxtorem')({
rootValue: 37.5,
unitPrecision: 5,
propWhiteList: [],
selectorBlackList: [/^html$/],
replace: true,
mediaQuery: false,
minPixelValue: 2
})
]
}
}
\ No newline at end of file
}
因为 它太大了无法显示 源差异 。您可以改为 查看blob
......@@ -15,40 +15,41 @@
"build:pro": "cross-env BUILD_ENV=pro node build/build.js"
},
"dependencies": {
"@babel/polyfill": "^7.2.5",
"@babel/polyfill": "^7.10.4",
"axios": "0.16.2",
"better-scroll": "^0.1.15",
"clipboard": "^2.0.6",
"echarts": "^4.2.0-rc.2",
"fastclick": "^1.0.6",
"img-vuer": "^0.17.2",
"install": "^0.13.0",
"iscroll": "^5.2.0",
"js-cookie": "^2.2.0",
"npm": "^6.14.6",
"pdfjs-dist": "^2.4.456",
"pica-topic-stencil": "^1.0.8",
"showdown": "^1.6.4",
"vant": "^2.2.15",
"vconsole": "^3.3.4",
"vue": "^2.1.0",
"vue-router": "^2.1.1",
"vuex": "^2.0.0",
"web-buried-point": "^2.1.0"
"web-buried-point": "^2.1.0",
"weixin-js-sdk": "^1.4.0-test"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.0.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/register": "^7.0.0",
"@babel/runtime-corejs2": "^7.0.0",
"autoprefixer": "^6.4.0",
"autoprefixer-loader": "^3.2.0",
"babel-core": "^6.0.0",
"babel-loader": "^6.0.0",
"babel-core": "^7.0.0-bridge.0",
"babel-loader": "7.1.1",
"babel-plugin-add-module-exports": "^1.0.0",
"babel-plugin-component": "^1.1.1",
"babel-plugin-import": "^1.11.0",
"babel-plugin-transform-runtime": "^6.0.0",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.0.0",
"babel-preset-stage-2": "^6.0.0",
"babel-register": "^6.0.0",
"babel-runtime": "^6.23.0",
"chalk": "^1.1.3",
"connect-history-api-fallback": "^1.1.0",
"cross-env": "^5.0.0",
......@@ -64,13 +65,9 @@
"less": "^2.7.1",
"less-loader": "^2.2.3",
"node-gyp": "^3.4.0",
"node-sass": "^4.9.2",
"opn": "^4.0.2",
"ora": "^0.3.0",
"sass": "^0.5.0",
"sass-loader": "^4.1.1",
"scss": "^0.2.4",
"scss-loader": "0.0.1",
"postcss-pxtorem": "^5.1.1",
"semver": "^5.3.0",
"shelljs": "^0.7.4",
"style-loader": "^0.13.1",
......
<template>
<div>
<div class="router-container">
<transition name="router-fade" mode="out-in">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
</transition>
<transition name="router-fade" mode="out-in">
</transition>
<transition name="router-fade" mode="out-in">
<router-view v-if="!$route.meta.keepAlive"></router-view>
</transition>
<!-- <svg-icon></svg-icon> -->
......@@ -22,7 +22,7 @@
</script>
<style lang="scss">
<style lang="less">
@import './style/mixin';
@import './style/common';
@import './style/global';
......@@ -32,4 +32,7 @@
.router-fade-enter, .router-fade-leave-active {
opacity: 0;
}
.router-container{
height: 100%;
}
</style>
......@@ -44,15 +44,14 @@ export default {
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.back-btn {
position: fixed;
width: px2rem(35px);
height: px2rem(35px);
right: px2rem(15px);
width: 35px;
height: 35px;
right: 15px;
z-index: 100;
bottom: px2rem(80px);
bottom: 80px;
img {
width: 100%;
height: 100%;
......
<template>
<!-- 项目组件列表项 -->
<section>
<div
class="cell-detail"
v-for="(component , index) in projectComponent"
:key="index">
<van-collapse v-model="activeNames" @change="changeCollapse">
<van-collapse-item
v-for="(portalModule, index) in component.portalModuleDTOS"
:key="index"
:title="(parseInt(index) + 1) + '.' + portalModule.moduleName | shortName(19)"
:name="portalModule.expandKey"
:value="portalModule.value"
:disabled="portalModule.disabled"
@click.native="chooseItem(portalModule)"
>
<!-- @click.native="chooseItem(item)" -->
<article @click.stop="deleteFlow()" class="cell-container">
<span class="" v-for="(item, index) in portalModule.contentList" :key="index">
<div v-if="index > 0 && portalModule.contentList[index].templetId!= portalModule.contentList[index-1].templetId" class="bottom-line"></div>
<div class="cell-container-item" >
<div class="name">
<div class="name-img">
<img v-if="item.type == 1 && item.useFlag == 1" class="img-icon" src="../../images/exam.png">
<img v-if="item.type == 1 && item.useFlag == 2" class="img-icon" src="../../images/exam-dark.png">
<img v-if="item.type == 2 && item.useFlag == 1" class="img-icon" src="../../images/learn.png">
<img v-if="item.type == 2 && item.useFlag == 2" class="img-icon" src="../../images/learn-dark.png">
</div>
<p class="name-title" :class="{'name-title-no': item.useFlag == 2}">{{item.name | shortName(30)}}</p>
</div>
<span
v-if="!logged"
@click="gotoExamOrCourse(item)"
class="text-action text-action-no"
>
<!-- :class="{'text-action-no': item.useFlag == 2}" -->
{{getActionText(item.status, item.type)}}
</span>
<span
v-else-if="!hasBindCard && item.type == 2 && cmeType == 2"
@click="gotoExamOrCourse(item)"
class="text-action"
style="background: #f28662;border: none;color: #fff;"
>
<!-- :class="{'text-action-no': item.useFlag == 2}" -->
去试看
</span>
<span
v-else
@click="gotoExamOrCourse(item)"
class="text-action"
:class="{'text-action-no': item.useFlag == 2}"
>
{{getActionText(item.status, item.type)}}
</span>
<!-- <img @click="toastToBuy" class="key" v-show="!hasBindCard" src="../../images/cme/phrase2/key.png" alt=""> -->
<div class="foot-line"
v-if="index+1 < portalModule.contentList.length && portalModule.contentList[index].templetId == portalModule.contentList[index+1].templetId">
</div>
</div>
<span v-if="item.certificateFlag == 2">
<img class="cert-img" :class="{'space2': item.height == 2 }" src="../../images/has-cert-new.png">
</span>
</span>
</article>
</van-collapse-item>
</van-collapse>
</div>
<van-dialog
v-model="dialogState"
title="标题"
>
</van-dialog>
</section>
</template>
<script>
import MergeTitle from "@/components/business/merge-title";
import NoMoreContent from "@/components/business/no-more-content";
import CertShow from "@/components/business/cert-show";
import { Collapse, CollapseItem, Dialog, Toast } from 'vant';
import { mapGetters } from "vuex";
import { getAppVersion, getWebPageUrl } from "@/utils";
import vueFilters from '@/utils/filter';
const actionMap = {
11: "去考试",
12: "再考一次",
13: "已通过",
14: "已完成",
15: "已通过",
16: "未通过",
21: "去学习",
22: "继续学习",
23: "去复习"
};
const sendBuriedDataMap = {
// 11: "8824",
// 12: "211013",
21: "8821",
22: "8822",
23: "8823"
}
export default {
name: "cell-list-item",
data() {
return {
appVersion: "200",
hocImg: require("../../images/has-owner-cert.png"),
activeNames: [1],
dialogState: false,
projectId: 1
};
},
props: {
hasBindCard: {
type: Boolean,
default: false
},
projectComponent: {
type: Array,
default: () => []
},
actionList: {
type: Array,
default: () => []
},
detailNum: {
type: Number | String,
default: 0
},
courseRequire: {
type: Number | String,
default: 0,
},
limitTimes: {
type: Number | String,
default: 0,
},
cmeType: {
type: Number | String,
default: 0,
},
logged: {
type: Boolean,
default: false
}
},
computed: {
...mapGetters(["userInfo"])
},
components: {
MergeTitle,
CertShow,
NoMoreContent,
Dialog,
},
watch:{
actionList: {
immediate: true,
handler (val) {
this.activeNames = val;
}
}
},
mounted() {
},
created() {
this.projectId = this.$route.query.id;
},
methods: {
// 跳转到考试或课程 type 1: 考试; 2: 课程
// 如果是考试,将根据appVersion判断是新考试还是老考试,如果是301或之前的,都是老考试
gotoExamOrCourse(item) {
this.$parent.$refs.tcPlayerRef && this.$parent.$refs.tcPlayerRef.pause();
if(!this.logged) {
Toast('登陆后可学习课程');
return;
}
// 埋点:去学习、继续学习、复习、去考试、重考
// let actionCode = sendBuriedDataMap[item.status];
// if(actionCode) {
// this.$sendBuriedData({
// component_tag: `882#${actionCode}#${this.projectId}`
// });
// }
if (item.useFlag == 2) {
if(item.type == 1) {
Toast('尚未完成所有课程学习');
} else if(item.type == 2){
Toast('尚未完成相关考试');
}
return;
};
if (item.type == 1) {
this.gotoExam(item.id);
} else if (item.type == 2) {
this.gotoCourse(item.id);
}
},
// 跳转到课程
gotoCourse: function(courseId) {
let token = localStorage.getItem('token');
let jumpUrl = getWebPageUrl(`profexam/#/course-detail?courseId=${courseId}&projectId=${this.projectId}&token=${token}`);
window.location.href = jumpUrl;
},
// 跳转到考试
gotoExam: function(examId) {
Toast('请前往云鹊医APP参加考试');
},
getActionText(status, type) {
let actionText = actionMap[status];
if(!actionText) {
actionText = type == 1 ? '去考试' : '去学习';
}
if(!this.hasBindCard && type == 2) {
actionText = '去试看'
}
return actionText;
},
changeCollapse(activeNames) {
console.log('activeNames',activeNames);
let param = {
expandKeys: activeNames,
setEntry: true,
token: this.userInfo.userToken,
}
this.POST("portal/portalApp/updateExpandStatus?projectId="+this.projectId, param).then(res => {
});
},
deleteFlow() {
},
chooseItem(item) {
let _this = this;
if(item.disabled === true) {
console.log('item',item);
Toast('尚未开始,敬请期待');
}
},
// 弹框提示
toastToBuy() {
Toast('购买后可学习课程');
}
}
};
</script>
<style lang="less">
.van-dialog {
transform: translate(-50%,-50%);
width: 300px;
border-radius: 3px;
.van-dialog__header {
padding-top: 30px;
font-size: 18px;
color: #333333;
}
.van-dialog__content {
.van-dialog__message--has-title {
padding-top: 14px;
text-align: left;
color: #676869;
font-weight:400;
}
}
.van-dialog__footer {
.van-button {
.van-button__text {
color: #449284;
font-size: 17px;
}
}
}
}
.van-toast {
// background: #000000;
div {
font-size:12px;
color: #FFFFFF;
}
}
.van-toast--text {
padding: 7px 8px;
}
.no-more-bottom {
position: relative;
width: 100%;
height: 40px;
}
.cell-detail {
.van-hairline--top::after , .van-hairline--top-bottom::after {
border-width: 0px;
}
.van-collapse-item {
.van-cell {
margin: 9px auto 0 auto;
// width: 345px;
width: 100%;
min-height: 48px;
border-radius: 6px;
}
.van-collapse-item__title {
background: #F8F9FA;
.van-cell__title {
max-width: 200px;
vertical-align: middle;
line-height: 30px;
flex: auto;
span {
color: #373839;
font-weight:500;
font-size: 15px;
height: 15px;
line-height: 15px;
}
}
.van-cell__value {
// max-width: 80px;
line-height: 30px;
span {
color: #979899;
font-weight:500;
font-size: 14px;
line-height: 14px;
}
}
.van-icon {
margin-top: 3px;
color: #999999;
}
}
.van-collapse-item__title--expanded {
background: #E3EFED;
.van-cell__title {
span {
color: #449284;
font-weight:500;
font-size: 15px;
line-height: 15px;
}
}
.van-cell__value {
span {
color: #449284;
font-weight:500;
font-size: 14px;
line-height: 14px;
}
}
.van-icon {
color: #449284;
}
}
.van-collapse-item__title--disabled {
.van-cell__right-icon {
display: none;
}
.van-cell__title , .van-cell__value{
span {
color: #979899;
}
}
}
.van-collapse-item__content {
padding: 0;
}
}
.line-component {
position: relative;
margin-top: 20px;
margin-left: 0;
width: 373px;
height: 6px;
background: #F8F9FA;
}
}
.cell-container {
display: flex;
flex-direction: column;
margin: 20px 0px -28px 0px;
&-item {
position: relative;
display: flex;
flex-direction: row;
margin-bottom: 39px;
line-height: 51px;
font-size: 15px;
justify-content: space-between;
align-items: center;
.name {
display: flex;
align-items: center;
flex: 1;
width: 100px;
.name-img {
position: relative;
z-index: 9;
margin-right: 6px;
width: 20px;
height: 20px;
float: left;
.img-icon {
position: absolute;
top: 0;
left: 0;
width: 20px;
height: 20px;
}
}
&-logo {
position: relative;
z-index: 9;
margin-right: 6px;
width: 20px;
height: 20px;
text-align: center;
background:rgba(68,146,132,1);
font-size: 12px;
font-weight: 700;
color: #FFFFFF;
border-radius: 50%;
float: left;
line-height: 22px;
// display:table;
// overflow:hidden;
// span {
// color: #FFFFFF;
// font-size: 12px;
// font-weight: 700;
// display: table-cell;
// text-align: center;
// vertical-align: middle;
// line-height: 20px;
// }
// &::before {
// position: absolute;
// top: -6px;
// left: 8px;
// display: inline-block;
// height: 6px;
// width: 4px;
// background: #FFFFFF;
// content: "";
// }
// &::after {
// position: absolute;
// top: 20px;
// left: 8px;
// display: inline-block;
// height: 6px;
// width: 4px;
// background: #FFFFFF;
// content: "";
// }
}
&-learn {
background:rgba(246, 131, 103, 1);
}
&-logo-no {
background:rgba(231, 232, 233, 1);
}
&-title {
flex: 1;
// font-family: "PingFangSC-Medium", "PingFangSC", "Microsoft Yahei";
// width: 231px;
font-size: 15px;
font-weight: 700;
line-height: 22px;
color: #333333;
// float: left;
}
&-title-no {
color: #979899;
}
// &::before {
// position: relative;
// top: 3px;
// display: inline-block;
// width: 4px;
// content: "";
// margin-right: 5px;
// height: 16px;
// background: #449284;
// border-radius: 3px;
// }
// span {
// img {
// margin-top: 4px;
// position: relative;
// top: 2px;
// width: 70px;
// height: 20px;
// }
// }
}
.text-action {
width: 68px;
height: 25px;
line-height: 25px;
text-align: center;
font-size: 12px;
font-weight: 700;
border-radius: 15px;
border: 1px solid rgba(68, 146, 132, 0.6);
color: rgba(68, 146, 132, 1);
img {
position: relative;
left: 2px;
top: 3px;
width: 8px;
height: 12px;
}
&-no {
border: 1px solid #c7c8c9;
color: #c7c8c9;
}
}
.key {
width: 15px;
height: 15px;
}
}
span {
.cert-img {
margin-left: 26px;
position: relative;
top: -34px;
width: 70px;
height: 20px;
}
.space2 {
top: -34px;
}
}
.connect-line {
position: absolute;
// top: 32px;
top: 3px;
left: 8.5px;
height: 42px;
width: 3px;
background: #F8F9FA;
// border: 0.5px dashed rgba(240, 241, 244, 1);
}
.line-complete {
background: #E3EFED;
}
.len4 {
// height: 100px;
height: 106px;
}
.len3 {
// height: 82px;
height: 88px;
}
.len2 {
// height: 82px;
height: 88px;
}
.len1 {
// height: 62px;
height: 68px;
}
.bottom-line {
position: relative;
margin: -19px 0 20px 0;
bottom: 0px;
width: 100%;
height: 6px;
background: #F8F9FA;
border-radius: 2px;
// border-bottom: 0.5px solid #F0F1F2;
}
.foot-line {
position: absolute;
width: 311px;
margin-left: 34.5px;
height: 1px;
background: #E7E8E9;
// border-bottom: 0.5px solid #E7E8E9;
transform: scaleY(0.5);
bottom: -20px;
}
}
.bg-13 {
background: #abcec7;
}
</style>
\ No newline at end of file
<template>
<!-- 项目组件列表项 -->
<section>
<div
class="cell-detail"
v-for="(component , index) in projectComponent"
:key="index">
<van-collapse v-model="activeNames" @change="changeCollapse">
<van-collapse-item
v-for="(portalModule, index) in component.portalModuleDTOS"
:key="index"
:title="(parseInt(index) + 1) + '.' + portalModule.moduleName | shortName(19)"
:name="portalModule.expandKey"
:value="portalModule.value"
@click.native="chooseItem(portalModule)"
>
<!-- :disabled="portalModule.disabled" -->
<article @click.stop="deleteFlow()" class="cell-container">
<span class="" v-for="(item, index) in portalModule.contentList" :key="index">
<div v-if="index > 0 && portalModule.contentList[index].templetId!= portalModule.contentList[index-1].templetId" class="bottom-line"></div>
<div class="cell-container-item" >
<div class="name">
<div class="name-img">
<img v-if="item.type == 1 && item.useFlag == 1" class="img-icon" src="../../images/exam.png">
<img v-if="item.type == 1 && item.useFlag == 2" class="img-icon" src="../../images/exam-dark.png">
<img v-if="item.type == 2 && item.useFlag == 1" class="img-icon" src="../../images/learn.png">
<img v-if="item.type == 2 && item.useFlag == 2" class="img-icon" src="../../images/learn-dark.png">
</div>
<p class="name-title" :class="{'name-title-no': item.useFlag == 2}">{{item.name | shortName(30)}}</p>
</div>
<span
v-if="!logged"
@click="gotoExamOrCourse(item)"
class="text-action text-action-no"
>
{{getActionText(item.status, item.type)}}
</span>
<span
v-else-if="!item.id"
class="text-action text-action-no"
@click="toastToBuy('敬请期待')"
>
更新中
</span>
<img class="key" v-else-if="!hasBindCard && item.trySeeFlag == 1 && !item.trySeeTime" @click="toastToBuy('激活/购买后可学习课程')" src="../../images/cme/phrase2/key.png" alt="">
<span
v-else-if="!hasBindCard && item.trySeeFlag == 1"
@click="gotoExamOrCourse(item)"
class="text-action"
>
去试看
</span>
<span
v-else
@click="gotoExamOrCourse(item)"
class="text-action"
:class="{'text-action-no': item.useFlag == 2}"
>
{{getActionText(item.status, item.type)}}
</span>
<div class="foot-line"
v-if="index+1 < portalModule.contentList.length && portalModule.contentList[index].templetId == portalModule.contentList[index+1].templetId">
</div>
</div>
</span>
</article>
</van-collapse-item>
</van-collapse>
</div>
</section>
</template>
<script>
import MergeTitle from "@/components/business/merge-title";
import NoMoreContent from "@/components/business/no-more-content";
import { Collapse, CollapseItem, Dialog, Toast } from 'vant';
import { mapGetters } from "vuex";
import { getAppVersion, getWebPageUrl, isWeiXin } from "@/utils";
import vueFilters from '@/utils/filter';
const actionMap = {
11: "去考试",
12: "再考一次",
13: "已通过",
14: "已完成",
15: "已通过",
16: "未通过",
21: "去学习",
22: "继续学习",
23: "去复习"
};
const sendBuriedDataMap = {
// 11: "8824",
// 12: "211013",
21: "8821",
22: "8822",
23: "8823"
}
export default {
name: "cell-list-item",
data() {
return {
appVersion: "200",
hocImg: require("../../images/has-owner-cert.png"),
activeNames: [1],
token: '',
};
},
props: {
hasBindCard: {
type: Boolean,
default: false
},
projectComponent: {
type: Array,
default: () => []
},
actionList: {
type: Array,
default: () => []
},
detailNum: {
type: Number | String,
default: 0
},
courseRequire: {
type: Number | String,
default: 0,
},
limitTimes: {
type: Number | String,
default: 0,
},
logged: {
type: Boolean,
default: false
},
projectId: {
type: Number | String,
default: 0
}
},
components: {
MergeTitle,
NoMoreContent,
Dialog,
},
watch:{
actionList: {
immediate: true,
handler (val) {
this.activeNames = val;
}
}
},
mounted() {
},
created() {
this.token = this.$store.state.user.token;
},
methods: {
// 跳转到考试或课程 type 1: 考试; 2: 课程
// 如果是考试,将根据appVersion判断是新考试还是老考试,如果是301或之前的,都是老考试
gotoExamOrCourse(item) {
if(!isWeiXin()) {
if(item.type == 1) {
Toast('请前往云鹊医APP参加考试');
} else if(item.type == 2){
Toast('请前往云鹊医APP学习课程');
}
return;
}
if(!this.logged) {
if(item.type == 1) {
Toast('请前往云鹊医APP参加考试');
} else if(item.type == 2){
Toast('登陆后可学习课程');
}
return;
}
// 埋点:去学习、继续学习、复习、去考试、重考
// let actionCode = sendBuriedDataMap[item.status];
// if(actionCode) {
// this.$sendBuriedData({
// component_tag: `882#${actionCode}#${this.projectId}`
// });
// }
let logId = null;
if (item.useFlag == 2) {
if(item.type == 1) {
// Toast('尚未完成所有课程学习');
Toast('请前往云鹊医APP参加考试');
} else if(item.type == 2){
Toast('尚未完成相关考试');
}
return;
};
if (item.type == 1) {
this.gotoExam(item.id);
logId = '882#88206';
} else if (item.type == 2) {
this.gotoCourse(item);
logId = '882#88205';
}
// if (trySee) {
// logId = '882#88204';
// }
// logId && this.$sendBuriedData({
// component_tag: logId
// });
},
// 跳转到课程
gotoCourse(item) {
let param = {
token: this.token,
setEntry: true
};
this.GET("campaign/admin/task/checkToken", param).then(res => {
if (res.code !== "000000") {
Toast('登陆后可学习课程');
} else {
this.jumpToCourse(item);
}
});
},
// 跳转到课程
jumpToCourse: function(item) {
if(!isWeiXin()) {
Toast('请前往云鹊医APP学习课程');
return;
}
let jumpUrl = getWebPageUrl(`profexam/#/course-detail?courseId=${item.id}&projectId=${this.projectId}&token=${this.token}`);
window.location.href = jumpUrl;
},
// 跳转到考试
gotoExam: function(examId) {
Toast('请前往云鹊医APP参加考试');
},
// 获取按钮文案
getActionText(status, type) {
let actionText = actionMap[status];
if(!actionText) {
actionText = type == 1 ? '去考试' : '去学习';
}
return actionText;
},
// 折叠与展开模块
changeCollapse(activeNames) {
console.log('activeNames',activeNames);
let param = {
expandKeys: activeNames,
setEntry: true,
token: this.token,
}
this.POST("portal/portalApp/updateExpandStatus?projectId="+this.projectId, param).then(res => {
});
},
deleteFlow() {
},
chooseItem(item) {
let _this = this;
// if(item.disabled === true) {
// console.log('item',item);
// Toast('尚未开始,敬请期待');
// }
},
// 弹框提示
toastToBuy(toastMsg) {
Toast(toastMsg);
}
}
};
</script>
<style lang="less">
.van-dialog {
transform: translate(-50%,-50%);
width: 300px;
border-radius: 3px;
.van-dialog__header {
padding-top: 30px;
font-size: 18px;
color: #333333;
}
.van-dialog__content {
.van-dialog__message--has-title {
padding-top: 14px;
text-align: left;
color: #676869;
font-weight:400;
}
}
.van-dialog__footer {
.van-button {
.van-button__text {
color: #449284;
font-size: 17px;
}
}
}
}
.van-toast {
// background: #000000;
div {
font-size:12px;
color: #FFFFFF;
}
}
.van-toast--text {
padding: 7px 8px;
}
.no-more-bottom {
position: relative;
width: 100%;
height: 40px;
}
.cell-detail {
.van-hairline--top::after , .van-hairline--top-bottom::after {
border-width: 0px;
}
.van-collapse-item {
.van-cell {
margin: 9px auto 0 auto;
width: 100%;
min-height: 48px;
border-radius: 6px;
}
.van-collapse-item__title {
background: #F8F9FA;
.van-cell__title {
max-width: 200px;
vertical-align: middle;
line-height: 30px;
flex: auto;
span {
color: #373839;
font-weight:500;
font-size: 15px;
height: 15px;
line-height: 15px;
}
}
.van-cell__value {
// max-width: 80px;
line-height: 30px;
span {
color: #979899;
font-weight:500;
font-size: 14px;
line-height: 14px;
}
}
.van-icon {
margin-top: 3px;
color: #999999;
}
}
.van-collapse-item__title--expanded {
background: #E3EFED;
.van-cell__title {
span {
color: #449284;
font-weight:500;
font-size: 15px;
line-height: 15px;
}
}
.van-cell__value {
span {
color: #449284;
font-weight:500;
font-size: 14px;
line-height: 14px;
}
}
.van-icon {
color: #449284;
}
}
.van-collapse-item__title--disabled {
.van-cell__right-icon {
display: none;
}
.van-cell__title , .van-cell__value{
span {
color: #979899;
}
}
}
.van-collapse-item__content {
padding: 0;
}
}
.line-component {
position: relative;
margin-top: 20px;
margin-left: 0;
width: 373px;
height: 6px;
background: #F8F9FA;
}
}
.cell-container {
display: flex;
flex-direction: column;
margin: 20px 0px -28px 0px;
&-item {
position: relative;
display: flex;
flex-direction: row;
margin-bottom: 39px;
line-height: 51px;
font-size: 15px;
justify-content: space-between;
align-items: center;
.name {
display: flex;
align-items: center;
flex: 1;
width: 100px;
.name-img {
position: relative;
z-index: 9;
margin-right: 6px;
width: 20px;
height: 20px;
float: left;
.img-icon {
position: absolute;
top: 0;
left: 0;
width: 20px;
height: 20px;
}
}
&-logo {
position: relative;
z-index: 9;
margin-right: 6px;
width: 20px;
height: 20px;
text-align: center;
background:rgba(68,146,132,1);
font-size: 12px;
font-weight: 700;
color: #FFFFFF;
border-radius: 50%;
float: left;
line-height: 22px;
// display:table;
// overflow:hidden;
// span {
// color: #FFFFFF;
// font-size: 12px;
// font-weight: 700;
// display: table-cell;
// text-align: center;
// vertical-align: middle;
// line-height: 20px;
// }
// &::before {
// position: absolute;
// top: -6px;
// left: 8px;
// display: inline-block;
// height: 6px;
// width: 4px;
// background: #FFFFFF;
// content: "";
// }
// &::after {
// position: absolute;
// top: 20px;
// left: 8px;
// display: inline-block;
// height: 6px;
// width: 4px;
// background: #FFFFFF;
// content: "";
// }
}
&-learn {
background:rgba(246, 131, 103, 1);
}
&-logo-no {
background:rgba(231, 232, 233, 1);
}
&-title {
flex: 1;
// font-family: "PingFangSC-Medium", "PingFangSC", "Microsoft Yahei";
font-size: 15px;
font-weight: 700;
line-height: 22px;
padding-right: 10px;
color: #333333;
}
&-title-no {
color: #979899;
}
// &::before {
// position: relative;
// top: 3px;
// display: inline-block;
// width: 4px;
// content: "";
// margin-right: 5px;
// height: 16px;
// background: #449284;
// border-radius: 3px;
// }
// span {
// img {
// margin-top: 4px;
// position: relative;
// top: 2px;
// width: 70px;
// height: 20px;
// }
// }
}
.text-action {
width: 68px;
height: 25px;
line-height: 25px;
text-align: center;
font-size: 12px;
font-weight: 700;
border-radius: 15px;
border: 1px solid rgba(68, 146, 132, 0.6);
color: rgba(68, 146, 132, 1);
img {
position: relative;
left: 2px;
top: 3px;
width: 8px;
height: 12px;
}
&-no {
border: 1px solid #c7c8c9;
color: #c7c8c9;
}
}
.key {
width: 15px;
height: 15px;
margin-right: 20px;
}
}
span {
.cert-img {
margin-left: 26px;
position: relative;
top: -34px;
width: 70px;
height: 20px;
}
.space2 {
top: -34px;
}
}
.connect-line {
position: absolute;
// top: 32px;
top: 3px;
left: 8.5px;
height: 42px;
width: 3px;
background: #F8F9FA;
// border: 0.5px dashed rgba(240, 241, 244, 1);
}
.line-complete {
background: #E3EFED;
}
.len4 {
// height: 100px;
height: 106px;
}
.len3 {
// height: 82px;
height: 88px;
}
.len2 {
// height: 82px;
height: 88px;
}
.len1 {
// height: 62px;
height: 68px;
}
.bottom-line {
position: relative;
margin: -19px 0 20px 0;
bottom: 0px;
width: 100%;
height: 6px;
background: #F8F9FA;
border-radius: 2px;
// border-bottom: 0.5px solid #F0F1F2;
}
.foot-line {
position: absolute;
width: 311px;
margin-left: 34.5px;
height: 1px;
background: #E7E8E9;
// border-bottom: 0.5px solid #E7E8E9;
transform: scaleY(0.5);
bottom: -20px;
}
}
.bg-13 {
background: #abcec7;
}
</style>
......@@ -366,20 +366,19 @@ export default {
};
</script>
<style lang="scss">
@import "../../style/mixin";
<style lang="less">
.van-dialog {
transform: translate(-50%,-50%);
width: px2rem(300px);
border-radius: px2rem(3px);
width: 300px;
border-radius: 3px;
.van-dialog__header {
padding-top: px2rem(30px);
font-size: px2rem(18px);
padding-top: 30px;
font-size: 18px;
color: #333333;
}
.van-dialog__content {
.van-dialog__message--has-title {
padding-top: px2rem(14px);
padding-top: 14px;
text-align: left;
color: #676869;
font-weight:400;
......@@ -389,7 +388,7 @@ export default {
.van-button {
.van-button__text {
color: #449284;
font-size: px2rem(17px);
font-size: 17px;
}
}
}
......@@ -397,17 +396,17 @@ export default {
.van-toast {
// background: #000000;
div {
font-size:px2rem(12px);
font-size:12px;
color: #FFFFFF;
}
}
.van-toast--text {
padding: px2rem(7px) px2rem(8px);
padding: 7px 8px;
}
.no-more-bottom {
position: relative;
width: 100%;
height: px2rem(40px);
height: 40px;
}
.cell-detail {
.van-hairline--top::after , .van-hairline--top-bottom::after {
......@@ -415,38 +414,39 @@ export default {
}
.van-collapse-item {
.van-cell {
margin: px2rem(9px) auto 0 auto;
width: px2rem(345px);
min-height: px2rem(48px);
border-radius: px2rem(6px);
margin: 9px auto 0 auto;
// width: 345px;
width: 100%;
min-height: 48px;
border-radius: 6px;
}
.van-collapse-item__title {
background: #F8F9FA;
.van-cell__title {
max-width: px2rem(200px);
max-width: 200px;
vertical-align: middle;
line-height: px2rem(30px);
line-height: 30px;
flex: auto;
span {
color: #373839;
font-weight:500;
font-size: px2rem(15px);
height: px2rem(15px);
line-height: px2rem(15px);
font-size: 15px;
height: 15px;
line-height: 15px;
}
}
.van-cell__value {
// max-width: px2rem(80px);
line-height: px2rem(30px);
// max-width: 80px;
line-height: 30px;
span {
color: #979899;
font-weight:500;
font-size: px2rem(14px);
line-height: px2rem(14px);
font-size: 14px;
line-height: 14px;
}
}
.van-icon {
margin-top: px2rem(3px);
margin-top: 3px;
color: #999999;
}
}
......@@ -456,16 +456,16 @@ export default {
span {
color: #449284;
font-weight:500;
font-size: px2rem(15px);
line-height: px2rem(15px);
font-size: 15px;
line-height: 15px;
}
}
.van-cell__value {
span {
color: #449284;
font-weight:500;
font-size: px2rem(14px);
line-height: px2rem(14px);
font-size: 14px;
line-height: 14px;
}
}
.van-icon {
......@@ -488,84 +488,88 @@ export default {
}
.line-component {
position: relative;
margin-top: px2rem(20px);
margin-top: 20px;
margin-left: 0;
width: px2rem(373px);
height: px2rem(6px);
width: 373px;
height: 6px;
background: #F8F9FA;
}
}
.cell-container {
display: flex;
flex-direction: column;
margin: px2rem(20px) px2rem(0px) px2rem(-28px) px2rem(0px);
margin: 20px 0px -28px 0px;
&-item {
position: relative;
display: flex;
flex-direction: row;
margin-bottom: px2rem(39px);
line-height: px2rem(51px);
font-size: px2rem(15px);
margin-bottom: 39px;
line-height: 51px;
font-size: 15px;
justify-content: space-between;
align-items: center;
.name {
display: flex;
align-items: center;
flex: 1;
width: 100px;
.name-img {
position: relative;
z-index: 9;
margin-right: px2rem(6px);
width: px2rem(20px);
height: px2rem(20px);
margin-right: 6px;
width: 20px;
height: 20px;
float: left;
.img-icon {
position: absolute;
top: 0;
left: 0;
width: px2rem(20px);
height: px2rem(20px);
width: 20px;
height: 20px;
}
}
&-logo {
position: relative;
z-index: 9;
margin-right: px2rem(6px);
width: px2rem(20px);
height: px2rem(20px);
margin-right: 6px;
width: 20px;
height: 20px;
text-align: center;
background:rgba(68,146,132,1);
font-size: px2rem(12px);
font-size: 12px;
font-weight: 700;
color: #FFFFFF;
border-radius: 50%;
float: left;
line-height: px2rem(22px);
line-height: 22px;
// display:table;
// overflow:hidden;
// span {
// color: #FFFFFF;
// font-size: px2rem(12px);
// font-size: 12px;
// font-weight: 700;
// display: table-cell;
// text-align: center;
// vertical-align: middle;
// line-height: px2rem(20px);
// line-height: 20px;
// }
// &::before {
// position: absolute;
// top: px2rem(-6px);
// left: px2rem(8px);
// top: -6px;
// left: 8px;
// display: inline-block;
// height: px2rem(6px);
// width: px2rem(4px);
// height: 6px;
// width: 4px;
// background: #FFFFFF;
// content: "";
// }
// &::after {
// position: absolute;
// top: px2rem(20px);
// left: px2rem(8px);
// top: 20px;
// left: 8px;
// display: inline-block;
// height: px2rem(6px);
// width: px2rem(4px);
// height: 6px;
// width: 4px;
// background: #FFFFFF;
// content: "";
// }
......@@ -577,86 +581,88 @@ export default {
background:rgba(231, 232, 233, 1);
}
&-title {
flex: 1;
// font-family: "PingFangSC-Medium", "PingFangSC", "Microsoft Yahei";
width: px2rem(231px);
font-size: px2rem(15px);
// width: 231px;
font-size: 15px;
font-weight: 700;
line-height: px2rem(22px);
line-height: 22px;
color: #333333;
float: left;
padding-right: 10px;
// float: left;
}
&-title-no {
color: #979899;
}
// &::before {
// position: relative;
// top: px2rem(3px);
// top: 3px;
// display: inline-block;
// width: px2rem(4px);
// width: 4px;
// content: "";
// margin-right: px2rem(5px);
// height: px2rem(16px);
// margin-right: 5px;
// height: 16px;
// background: #449284;
// border-radius: px2rem(3px);
// border-radius: 3px;
// }
// span {
// img {
// margin-top: px2rem(4px);
// margin-top: 4px;
// position: relative;
// top: px2rem(2px);
// width: px2rem(70px);
// height: px2rem(20px);
// top: 2px;
// width: 70px;
// height: 20px;
// }
// }
}
.text-action {
width: px2rem(68px);
height: px2rem(25px);
line-height: px2rem(25px);
width: 68px;
height: 25px;
line-height: 25px;
text-align: center;
font-size: px2rem(12px);
font-size: 12px;
font-weight: 700;
border-radius: px2rem(15px);
border: px2rem(1px) solid rgba(68, 146, 132, 0.6);
border-radius: 15px;
border: 1px solid rgba(68, 146, 132, 0.6);
color: rgba(68, 146, 132, 1);
img {
position: relative;
left: px2rem(2px);
top: px2rem(3px);
width: px2rem(8px);
height: px2rem(12px);
left: 2px;
top: 3px;
width: 8px;
height: 12px;
}
&-no {
border: px2rem(1px) solid #c7c8c9;
border: 1px solid #c7c8c9;
color: #c7c8c9;
}
}
.key {
width: px2rem(15px);
height: px2rem(15px);
margin-right: px2rem(20px);
width: 15px;
height: 15px;
margin-right: 20px;
}
}
span {
.cert-img {
margin-left: px2rem(26px);
margin-left: 26px;
position: relative;
top: px2rem(-34px);
width: px2rem(70px);
height: px2rem(20px);
top: -34px;
width: 70px;
height: 20px;
}
.space2 {
top: px2rem(-34px);
top: -34px;
}
}
.connect-line {
position: absolute;
// top: px2rem(32px);
top: px2rem(3px);
left: px2rem(8.5px);
height: px2rem(42px);
width: px2rem(3px);
// top: 32px;
top: 3px;
left: 8.5px;
height: 42px;
width: 3px;
background: #F8F9FA;
// border: 0.5px dashed rgba(240, 241, 244, 1);
}
......@@ -664,40 +670,40 @@ export default {
background: #E3EFED;
}
.len4 {
// height: px2rem(100px);
height: px2rem(106px);
// height: 100px;
height: 106px;
}
.len3 {
// height: px2rem(82px);
height: px2rem(88px);
// height: 82px;
height: 88px;
}
.len2 {
// height: px2rem(82px);
height: px2rem(88px);
// height: 82px;
height: 88px;
}
.len1 {
// height: px2rem(62px);
height: px2rem(68px);
// height: 62px;
height: 68px;
}
.bottom-line {
position: relative;
margin: px2rem(-19px) 0 px2rem(20px) 0;
margin: -19px 0 20px 0;
bottom: 0px;
width: 100%;
height: px2rem(6px);
height: 6px;
background: #F8F9FA;
border-radius: px2rem(2px);
border-radius: 2px;
// border-bottom: 0.5px solid #F0F1F2;
}
.foot-line {
position: absolute;
width: px2rem(311px);
margin-left: px2rem(34.5px);
height: px2rem(1px);
width: 311px;
margin-left: 34.5px;
height: 1px;
background: #E7E8E9;
// border-bottom: 0.5px solid #E7E8E9;
transform: scaleY(0.5);
bottom: px2rem(-20px);
bottom: -20px;
}
}
.bg-13 {
......
......@@ -179,70 +179,69 @@ export default {
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.cell-container {
display: flex;
flex-direction: column;
margin: 0 px2rem(15px);
margin: 0 15px;
&-item {
position: relative;
display: flex;
flex-direction: row;
// margin: px2rem(6px) px2rem(0px);
// height: px2rem(51px);
margin-bottom: px2rem(32px);
line-height: px2rem(51px);
font-size: px2rem(15px);
// padding: px2rem(0px) px2rem(15px);
// margin: 6px 0px;
// height: 51px;
margin-bottom: 32px;
line-height: 51px;
font-size: 15px;
// padding: 0px 15px;
// background: rgba(248, 249, 250, 1);
// border-bottom: 1px solid #f0f0f0;
// border-radius: px2rem(6px);
// border-radius: 6px;
justify-content: space-between;
align-items: center;
.name {
&-logo {
position: relative;
z-index: 9;
margin-right: px2rem(6px);
width: px2rem(20px);
height: px2rem(20px);
margin-right: 6px;
width: 20px;
height: 20px;
text-align: center;
background:rgba(68,146,132,1);
font-size: px2rem(12px);
font-size: 12px;
font-weight: 700;
color: #FFFFFF;
border-radius: 50%;
float: left;
line-height: px2rem(22px);
line-height: 22px;
// display:table;
// overflow:hidden;
// span {
// color: #FFFFFF;
// font-size: px2rem(12px);
// font-size: 12px;
// font-weight: 700;
// display: table-cell;
// text-align: center;
// vertical-align: middle;
// line-height: px2rem(20px);
// line-height: 20px;
// }
&::before {
position: absolute;
top: px2rem(-6px);
left: px2rem(8px);
top: -6px;
left: 8px;
display: inline-block;
height: px2rem(6px);
width: px2rem(4px);
height: 6px;
width: 4px;
background: #FFFFFF;
content: "";
}
&::after {
position: absolute;
top: px2rem(20px);
left: px2rem(8px);
top: 20px;
left: 8px;
display: inline-block;
height: px2rem(6px);
width: px2rem(4px);
height: 6px;
width: 4px;
background: #FFFFFF;
content: "";
}
......@@ -254,57 +253,59 @@ export default {
background:rgba(231, 232, 233, 1);
}
&-title {
flex: 1;
// font-family: "PingFangSC-Medium", "PingFangSC", "Microsoft Yahei";
width: px2rem(231px);
font-size: px2rem(15px);
// width: 231px;
font-size: 15px;
font-weight: 700;
line-height: px2rem(21px);
line-height: 21px;
color: #373839;
float: left;
padding-right: 10px;
// float: left;
}
&-title-no {
color: rgba(151, 152, 153, 1);
}
// &::before {
// position: relative;
// top: px2rem(3px);
// top: 3px;
// display: inline-block;
// width: px2rem(4px);
// width: 4px;
// content: "";
// margin-right: px2rem(5px);
// height: px2rem(16px);
// margin-right: 5px;
// height: 16px;
// background: #449284;
// border-radius: px2rem(3px);
// border-radius: 3px;
// }
// span {
// img {
// margin-top: px2rem(4px);
// margin-top: 4px;
// position: relative;
// top: px2rem(2px);
// width: px2rem(70px);
// height: px2rem(20px);
// top: 2px;
// width: 70px;
// height: 20px;
// }
// }
}
.text-action {
width: px2rem(68px);
height: px2rem(25px);
line-height: px2rem(25px);
width: 68px;
height: 25px;
line-height: 25px;
text-align: center;
font-size: px2rem(12px);
font-size: 12px;
font-weight: 700;
border-radius: px2rem(15px);
border-radius: 15px;
// font-family: "PingFangSC-Medium", "PingFangSC", "Microsoft Yahei";
// opacity: 0.45;
border: 0.5px solid rgba(68, 146, 132, 0.6);
color: rgba(68, 146, 132, 1);
img {
position: relative;
left: px2rem(2px);
top: px2rem(3px);
width: px2rem(8px);
height: px2rem(12px);
left: 2px;
top: 3px;
width: 8px;
height: 12px;
}
&-no {
border: 0.5px solid #c7c8c9;
......@@ -317,40 +318,40 @@ export default {
}
span {
img {
margin-left: px2rem(26px);
margin-left: 26px;
position: relative;
top: px2rem(-28px);
width: px2rem(70px);
height: px2rem(20px);
top: -28px;
width: 70px;
height: 20px;
}
.space2 {
top: px2rem(-26px);
top: -26px;
}
}
.connect-line {
position: absolute;
// top: px2rem(32px);
top: px2rem(3px);
left: px2rem(9.5px);
height: px2rem(42px);
// top: 32px;
top: 3px;
left: 9.5px;
height: 42px;
width: 0.5px;
border: 0.5px dashed rgba(240, 241, 244, 1);
}
.len4 {
height: px2rem(100px);
height: 100px;
}
.len3 {
height: px2rem(82px);
height: 82px;
}
.len2 {
height: px2rem(82px);
height: 82px;
}
.len1 {
height: px2rem(62px);
height: 62px;
}
.bottom-line {
position: relative;
margin: px2rem(6px) 0 px2rem(28px) 0;
margin: 6px 0 28px 0;
bottom: 0px;
width: 100%;
border-bottom: 0.5px solid #F0F1F2;
......
......@@ -173,26 +173,25 @@ export default {
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.mater-container {
position: relative;
margin: px2rem(0px) px2rem(15px);
margin: 0px 15px;
}
.mater-item {
display: flex;
// width: 100%;
height: px2rem(80px);
height: 80px;
border-bottom: 1px solid #f0f0f0;
background: #fff;
flex-direction: row;
justify-content: space-between;
align-items: center;
img {
width: px2rem(35px);
height: px2rem(37px);
margin-right: px2rem(10px);
border-radius: px2rem(3px) px2rem(2px) px2rem(2px) px2rem(3px);
width: 35px;
height: 37px;
margin-right: 10px;
border-radius: 3px 2px 2px 3px;
}
&-left {
display: flex;
......@@ -201,40 +200,40 @@ export default {
}
&-right {
display: flex;
// width: px2rem(215px);
// width: 215px;
flex: 1;
flex-direction: column;
padding-top: px2rem(4px);
padding-top: 4px;
&-title {
// height: px2rem(50px);
line-height: px2rem(23px);
font-size: px2rem(15px);
// height: 50px;
line-height: 23px;
font-size: 15px;
font-weight: 700;
color: rgba(55, 56, 57, 1);
}
&-other {
height: px2rem(22px);
line-height: px2rem(20px);
font-size: px2rem(13px);
height: 22px;
line-height: 20px;
font-size: 13px;
font-weight: 400;
color: rgba(151, 152, 153, 1);
}
}
.mater-details {
position: relative;
right: px2rem(-10px);
right: -10px;
display: flex;
flex-direction: row;
align-items: center;
span {
// font-family: "PingFangSC-Medium", "PingFangSC", "Microsoft Yahei";
font-size: px2rem(14px);
font-size: 14px;
font-weight: 700;
color: #666;
}
img {
width: px2rem(15px);
height: px2rem(16px);
width: 15px;
height: 16px;
}
}
}
......
......@@ -97,52 +97,52 @@ export default {
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.comp-title-container {
margin-top: px2rem(17px);
padding-left: px2rem(15px);
margin-top: 17px;
padding-left: 15px;
// display: flex;
// flex-direction: row;
// justify-content: space-between;
.comp-text {
position: relative;
width: px2rem(345px);
// width: 345px;
width: 100%;
overflow: hidden;
}
}
.comp-title {
position: relative;
width: px2rem(238px);
width: 238px;
float: left;
line-height: px2rem(30px);
line-height: 30px;
}
.comp-title-explain {
position: relative;
float: right;
// margin-right: px2rem(15px);
margin-top: px2rem(3px);
// margin-right: 15px;
margin-top: 3px;
span {
font-size: px2rem(14px);
font-size: 14px;
font-weight: 400;
color: rgba(12, 21, 39, 0.4);
// margin-right: px2rem(3px);
line-height: px2rem(18px);
height: px2rem(18px);
// margin-right: 3px;
line-height: 18px;
height: 18px;
vertical-align: middle;
}
img {
width: px2rem(8px);
height: px2rem(12px);
width: 8px;
height: 12px;
vertical-align: middle;
}
}
.cert-img {
margin-top: px2rem(1px);
margin-top: 1px;
.banner-img {
width: px2rem(70px);
height: px2rem(20px);
padding-top: px2rem(2px);
width: 70px;
height: 20px;
padding-top: 2px;
}
}
</style>
\ No newline at end of file
</style>
......@@ -24,27 +24,26 @@ export default {
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.nc-container {
display: flex;
width: 100%;
flex-direction: column;
justify-content: center;
align-content: center;
margin-top: px2rem(100px);
margin-bottom: px2rem(20px);
margin-top: 100px;
margin-bottom: 20px;
text-align: center;
// margin: 0 auto;
&-img {
margin-left: px2rem(100px);
width: px2rem(150px);
height: px2rem(150px);
margin-left: 100px;
width: 150px;
height: 150px;
}
&-text {
height: px2rem(21px);
line-height: px2rem(21px);
font-size: px2rem(15px);
height: 21px;
line-height: 21px;
font-size: 15px;
font-weight: 400;
color: rgba(153, 153, 153, 1);
}
......
<template>
<!-- 到底了 -->
<section class="nc-container">
<img class="nc-container-content"
<img class="nc-container-content"
:src="nmcImg">
</section>
</template>
......@@ -17,13 +17,12 @@
}
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.nc-container {
display: flex;
&-content {
width: 100%;
height: px2rem(62px);
height: 62px;
}
}
</style>
......
......@@ -41,62 +41,61 @@ export default {
this.marginTop = '10px';
this.imgMarginTop = '-3px'
} else if(newVal == 3){
this.marginTop = '-2px';
this.marginTop = '-2px';
}
}
},
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.item-notice-wrapper {
.content {
display: flex;
flex-direction: row;
height: px2rem(32px);
line-height: px2rem(32px);
padding: 0 px2rem(15px);
height: 32px;
line-height: 32px;
padding: 0 15px;
text-align: left;
align-items: center;
background: #FEFAF5;
img {
width: px2rem(12px);
height: px2rem(12px);
line-height: px2rem(32px);
width: 12px;
height: 12px;
line-height: 32px;
}
span {
font-size: px2rem(13px);
font-size: 13px;
text-align: left;
&.gg {
// width: px2rem(30px);
padding: px2rem(1px) px2rem(5px) 0;
font-size: px2rem(13px);
// width: 30px;
padding: 1px 5px 0;
font-size: 13px;
font-weight: 700;
color: #835800;
}
&.vtc-line {
margin-top: px2rem(0px);
width: px2rem(1px);
height: px2rem(15px);
margin-top: 0px;
width: 1px;
height: 15px;
background: #835800;
}
&.content {
display: block;
flex: 1;
padding-top: px2rem(1px);
// padding-left: px2rem(5px) !important;
padding: 0 px2rem(10px) 0 px2rem(5px);
height: px2rem(32px);
line-height: px2rem(32px);
padding-top: 1px;
// padding-left: 5px !important;
padding: 0 10px 0 5px;
height: 32px;
line-height: 32px;
text-align: left;
font-size: px2rem(13px);
font-size: 13px;
font-weight: 700;
color: #E6A23C;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
......
......@@ -40,7 +40,7 @@ export default {
noticeContent: "",
noticeId: '',
noticeTitle: "",
readFlag: 0
readFlag: 0
}
}
}
......@@ -60,8 +60,7 @@ export default {
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.pop-notice-wrapper {
position: fixed;
width: 100%;
......@@ -69,7 +68,7 @@ export default {
left: 0;
top: 0;
z-index: 110;
font-size: px2rem(20px);
font-size: 20px;
.mask {
position: absolute;
background: rgba(0, 0, 0, 0.5);
......@@ -82,19 +81,19 @@ export default {
left: 50%;
top: 50%;
z-index: 112;
width: px2rem(300px);
// height: px2rem(185px);
margin: px2rem(-150px) 0 0 px2rem(-150px);
border-radius: px2rem(3px);
width: 300px;
// height: 185px;
margin: -150px 0 0 -150px;
border-radius: 3px;
text-align: center;
background: #fff;
.top {
padding: px2rem(30px);
padding: 30px;
.title {
display: inline-block;
font-size: px2rem(18px);
line-height: px2rem(28px);
font-size: 18px;
line-height: 28px;
word-break: break-all;
font-weight: 400;
color: #333333;
......@@ -103,10 +102,10 @@ export default {
text-align: left;
word-break: break-all;
display: inline-block;
margin: px2rem(14px) 0;
font-size: px2rem(14px);
height: px2rem(21px);
line-height: px2rem(21px);
margin: 14px 0;
font-size: 14px;
height: 21px;
line-height: 21px;
font-weight: 400;
color: #676869;
.b {
......@@ -115,18 +114,18 @@ export default {
}
}
.line {
width: px2rem(300px);
height: px2rem(1px);
width: 300px;
height: 1px;
background: rgba(240, 241, 242, 1);
}
.bottom {
text-align: center;
font-size: px2rem(17px);
height: px2rem(50px);
line-height: px2rem(50px);
font-size: 17px;
height: 50px;
line-height: 50px;
font-weight: 400;
span {
font-size: px2rem(17px);
font-size: 17px;
color: #449284;
}
}
......
......@@ -31,8 +31,7 @@ export default {
}
}
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.dialog-mask-container{
position: fixed;
top: 0;
......@@ -54,24 +53,24 @@ export default {
top: 50%;
left: 50%;
overflow: hidden;
width: px2rem(300px);
font-size: px2rem(18px);
width: 300px;
font-size: 18px;
-webkit-transition: .3s;
transition: .3s;
border-radius: px2rem(4px);
border-radius: 4px;
background-color: #fff;
-webkit-transform: translate3d(-50%,-50%,0);
transform: translate3d(-50%,-50%,0);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
.dialog-content{
padding: px2rem(30px) px2rem(22px);
padding: 30px 22px;
text-align: center;
font-size: px2rem(18px);
font-size: 18px;
color: #373839;
}
.dialog-footer{
height: px2rem(50px);
height: 50px;
display: flex;
align-items: center;
&.v-hairline-top::after{
......@@ -80,9 +79,9 @@ export default {
span{
display: inline-block;
width: 50%;
height: px2rem(50px);
line-height: px2rem(50px);
font-size: px2rem(17px);
height: 50px;
line-height: 50px;
font-size: 17px;
text-align: center;
color: #979899;
&.v-hairline-left::after{
......
......@@ -64,37 +64,36 @@ export default {
},
projectName: {
type: String,
default: ""
default: ""
}
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.basic-container {
padding-bottom: px2rem(20px);
margin: px2rem(30px) px2rem(15px) 0px;
border-bottom: px2rem(1px) solid #e7e8e9;
padding-bottom: 20px;
margin: 30px 15px 0px;
border-bottom: 1px solid #e7e8e9;
.basic-title {
font-size: px2rem(18px);
line-height: px2rem(18px);
font-size: 18px;
line-height: 18px;
color: #373839;
font-weight: 700;
}
.pro-name {
display: flex;
flex-direction: row;
margin-top: px2rem(16px);
font-size: px2rem(14px);
margin-top: 16px;
font-size: 14px;
span {
display: flex;
font-size: px2rem(14px);
font-size: 14px;
align-items: center;
line-height: px2rem(22px);
line-height: 22px;
align-content: flex-start;
text-align: justify;
&.title {
width: px2rem(84px);
width: 84px;
color: #979899;
}
&.name {
......@@ -104,20 +103,20 @@ export default {
}
}
.content {
margin-top: px2rem(16px);
height: px2rem(16px);
line-height: px2rem(0px);
margin-top: 16px;
height: 16px;
line-height: 0px;
span {
display: inline-block;
font-size: px2rem(14px);
font-size: 14px;
.split {
display: inline-block;
position: relative;
top: px2rem(2px);
top: 2px;
left: 0;
width: px2rem(1px);
height: px2rem(13px);
margin: 0 px2rem(2px);
width: 1px;
height: 13px;
margin: 0 2px;
background: #676869;
}
}
......@@ -125,36 +124,36 @@ export default {
color: #979899;
}
span:last-child {
margin-left: px2rem(15px);
margin-left: 15px;
color: #676869;
}
}
.remind {
line-height: px2rem(14px);
margin-top: px2rem(10px);
line-height: 14px;
margin-top: 10px;
span {
position: relative;
display: inline-block;
padding: px2rem(5px) px2rem(10px);
margin-left: px2rem(78px);
font-size: px2rem(14px);
padding: 5px 10px;
margin-left: 78px;
font-size: 14px;
color: #fb5b52;
background: #fceeed;
border-radius: px2rem(4px);
border-radius: 4px;
}
span:after {
content: "";
position: absolute;
left: px2rem(10px);
bottom: px2rem(20px);
left: 10px;
bottom: 20px;
width: 0;
height: 0;
border-width: 0 px2rem(8px) px2rem(8px);
border-width: 0 8px 8px;
border-style: solid;
border-color: transparent transparent #fceeed;
}
}
}
</style>
\ No newline at end of file
</style>
<template>
<section class="bind-cart-wrapper">
<article class="left">
<div class="top">
<!-- <span class="discount">{{cardInfo.costPrice | formatMoney}}</span> -->
<span class="discount">{{(cardInfo.couponPrice || cardInfo.preferentialPrice || cardInfo.costPrice) | formatMoney}}</span>
<span v-show="cardInfo.couponPrice || cardInfo.preferentialPrice" class="price">
<del>原价¥{{cardInfo.costPrice | formatMoney}}</del>
</span>
</div>
<div class="bottom">
<img src="../../images/cme/phrase2/info.png" />
<span>激活或购买后可学习课程</span>
</div>
</article>
<article class="right">
<span class="left" @click="download">APP购买更优惠</span>
</article>
</section>
</template>
<script>
export default {
props: {
cardInfo: {
type: Object,
default: () => {}
}
},
data() {
return {};
},
methods: {
download() {
window.location.href =
"https://a.app.qq.com/o/simple.jsp?pkgname=com.picahealth.yunque";
},
}
};
</script>
<style lang="less" scoped>
.bind-cart-wrapper {
position: fixed;
left: 0;
bottom: 0;
z-index: 100;
width: 100%;
display: flex;
flex-direction: row;
height: 60px;
line-height: 1;
justify-content: space-between;
padding: 10px 15px;
font-size: 14px;
background: rgba(255, 255, 255, 1);
box-shadow: 0px -2px 10px 0px rgba(0, 0, 0, 0.1);
.left {
display: flex;
flex-direction: column;
height: 40px;
line-height: 1;
font-size: 12px;
// align-items: ;
.top {
margin-top: 3px;
height: 24px;
.discount {
color: #fb5b52;
font-size: 18px;
font-weight: 700;
margin-right: 4px;
}
.price {
color: #979899;
}
}
.bottom {
display: flex;
flex-direction: row;
img {
width: 12px;
height: 12px;
margin-left: 1px;
margin-right: 4px;
}
color: #979899;
}
}
.right {
display: flex;
flex-direction: row;
span {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 138px;
font-size: 14px;
font-weight: 700;
text-align: center;
&.left {
// border: 1px solid rgba(255, 122, 75, 1);
// border-right-style: none;
color: #FFFFFF;
background:linear-gradient(137deg,rgba(255,166,95,1) 0%,rgba(255,122,75,1) 100%);
border-radius: 20px;
}
}
}
}
</style>
......@@ -39,8 +39,7 @@ export default {
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.bind-cart-wrapper {
position: fixed;
left: 0;
......@@ -49,28 +48,28 @@ export default {
width: 100%;
display: flex;
flex-direction: row;
height: px2rem(60px);
height: 60px;
line-height: 1;
justify-content: space-between;
padding: px2rem(10px) px2rem(15px);
font-size: px2rem(14px);
padding: 10px 15px;
font-size: 14px;
background: rgba(255, 255, 255, 1);
box-shadow: 0px -2px 10px 0px rgba(0, 0, 0, 0.1);
.left {
display: flex;
flex-direction: column;
height: px2rem(40px);
height: 40px;
line-height: 1;
font-size: 12px;
// align-items: ;
.top {
margin-top: px2rem(3px);
height: px2rem(24px);
margin-top: 3px;
height: 24px;
.discount {
color: #fb5b52;
font-size: px2rem(18px);
font-size: 18px;
font-weight: 700;
margin-right: px2rem(4px);
margin-right: 4px;
}
.price {
color: #979899;
......@@ -80,10 +79,10 @@ export default {
display: flex;
flex-direction: row;
img {
width: px2rem(12px);
height: px2rem(12px);
width: 12px;
height: 12px;
margin-left: 1px;
margin-right: px2rem(4px);
margin-right: 4px;
}
color: #979899;
}
......@@ -96,12 +95,12 @@ export default {
flex-direction: row;
align-items: center;
justify-content: center;
width: px2rem(80px);
font-size: px2rem(14px);
width: 80px;
font-size: 14px;
font-weight: 700;
text-align: center;
&.left {
border-radius: px2rem(20px) 0px 0px px2rem(20px);
border-radius: 20px 0px 0px 20px;
border: 1px solid rgba(255, 122, 75, 1);
border-right-style: none;
color: #ff7a4b;
......@@ -112,10 +111,10 @@ export default {
rgba(255, 166, 95, 1) 0%,
rgba(255, 122, 75, 1) 100%
);
border-radius: 0px px2rem(20px) px2rem(20px) 0px;
border-radius: 0px 20px 20px 0px;
color: #fff;
}
}
}
}
</style>
\ No newline at end of file
</style>
......@@ -67,45 +67,44 @@ export default {
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.card-banner-wrapper {
width: 100%;
height: px2rem(40px);
height: 40px;
display: flex;
flex-direction: row;
padding: 0 px2rem(15px);
padding: 0 15px;
justify-content: space-between;
align-items: center;
background: #fefaf5;
.left {
display: flex;
height: px2rem(40px);
height: 40px;
flex-direction: row;
align-items: center;
img {
width: px2rem(13px);
height: px2rem(13px);
margin-right: px2rem(4px);
width: 13px;
height: 13px;
margin-right: 4px;
&.is-android {
width: px2rem(12px);
height: px2rem(13px);
margin-bottom: px2rem(2px);
width: 12px;
height: 13px;
margin-bottom: 2px;
}
}
span {
font-size: px2rem(13px);
font-size: 13px;
color: #e6a23c;
}
}
.right {
height: px2rem(25px);
line-height: px2rem(25px);
font-size: px2rem(12px);
padding: 0 px2rem(10px);
height: 25px;
line-height: 25px;
font-size: 12px;
padding: 0 10px;
background: rgba(230, 162, 60, 1);
border-radius: px2rem(25px);
border: px2rem(1px) solid rgba(230, 162, 60, 1);
border-radius: 25px;
border: 1px solid rgba(230, 162, 60, 1);
color: #ffffff;
}
}
......
......@@ -113,13 +113,12 @@ export default {
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.bind-cart-wrapper {
width: 100%;
display: flex;
line-height: 1;
padding: px2rem(10px) px2rem(15px);
padding: 10px 15px;
display: flex;
flex-direction: column;
background: rgba(255, 255, 255, 1);
......@@ -132,40 +131,40 @@ export default {
align-items: center;
justify-content: center;
width: 100%;
margin-top: px2rem(20px);
margin-top: 20px;
img {
position: relative;
top: 0;
right: px2rem(-120px);
width: px2rem(12px);
height: px2rem(12px);
right: -120px;
width: 12px;
height: 12px;
}
}
.tip {
display: flex;
margin-top: px2rem(40px);
margin-top: 40px;
.left {
display: flex;
line-height: 1.2;
font-size: px2rem(12px);
font-size: 12px;
.img-wrapper {
width: px2rem(20px);
// margin-right: px2rem(4px);
width: 20px;
// margin-right: 4px;
img {
position: relative;
top: px2rem(1px);
width: px2rem(12px);
height: px2rem(12px);
top: 1px;
width: 12px;
height: 12px;
}
img.android {
top: px2rem(1.5px);
width: px2rem(11.5px);
top: 1.5px;
width: 11.5px;
}
}
span {
display: inline-block;
margin-left: px2rem(4px);
margin-left: 4px;
}
color: #979899;
}
......@@ -176,40 +175,40 @@ export default {
position: relative;
display: flex;
flex-direction: column;
padding: px2rem(20px) 0;
padding: 20px 0;
padding-top: 0;
.cover {
width: px2rem(286px);
width: 286px;
position: absolute;
top: px2rem(21.5px);
top: 21.5px;
z-index: 1000;
border-top: px2rem(4px) solid #fff;
margin-left: px2rem(57px);
margin-right: px2rem(1px);
border-radius: px2rem(4px);
border-top: 4px solid #fff;
margin-left: 57px;
margin-right: 1px;
border-radius: 4px;
}
}
.error {
position: absolute;
top: px2rem(66px);
left: px2rem(56px);
top: 66px;
left: 56px;
display: inline-block;
color: red;
font-size: px2rem(12px);
font-size: 12px;
}
img {
position: absolute;
top: px2rem(33px);
right: px2rem(12px);
width: px2rem(15px);
height: px2rem(15px);
top: 33px;
right: 12px;
width: 15px;
height: 15px;
}
}
.bottom {
display: flex;
margin-bottom: px2rem(40px);
margin-bottom: 40px;
}
}
</style>
......@@ -3,12 +3,12 @@
<div class="common-bottom">
<span>若有问题可联系客服:</span>
<img src="../../images/cme/icon-phone.png" />
<span>400-920-8877</span>
<!-- <span>400-920-8877</span> -->
<a href="tel:4009208877"><span>400-920-8877</span></a>
</div>
</div>
</template>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.common-bottom-info-wrapper {
position: fixed;
width: 100%;
......@@ -29,9 +29,9 @@
height: 14px;
line-height: 14px;
color: #676869;
&:nth-child(3) {
color: #449284;
}
}
a span {
color: #449284;
}
// span:nth-child(1) {
// color: #449284;
......
......@@ -27,20 +27,19 @@ export default {
},
}
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.common-button-wrapper {
font-size: px2rem(14px);
margin: px2rem(20px) px2rem(15px);
font-size: 14px;
margin: 20px 15px;
text-align: center;
&.button-default {
span {
display: block;
height: px2rem(50px);
line-height: px2rem(50px);
height: 50px;
line-height: 50px;
width: 100%;
border-radius: px2rem(25px);
font-size: px2rem(17px);
border-radius: 25px;
font-size: 17px;
font-weight: 700;
color: #FFFFFF;
background: #449284;
......@@ -60,4 +59,4 @@ export default {
}
}
</style>
\ No newline at end of file
</style>
......@@ -56,8 +56,7 @@ export default {
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.common-dialog-wrraper {
position: fixed;
top: 0;
......@@ -79,35 +78,35 @@ export default {
top: 50%;
left: 50%;
overflow: hidden;
width: px2rem(300px);
font-size: px2rem(18px);
width: 300px;
font-size: 18px;
-webkit-transition: 0.3s;
transition: 0.3s;
border-radius: px2rem(4px);
border-radius: 4px;
background-color: #fff;
-webkit-transform: translate3d(-50%, -50%, 0);
transform: translate3d(-50%, -50%, 0);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
.dialog-content {
// margin: px2rem(30px) px2rem(22px);
margin: px2rem(30px);
// margin: 30px 22px;
margin: 30px;
text-align: center;
font-size: px2rem(18px);
font-size: 18px;
font-weight: 400;
color: #373839;
}
.dialog-sub-content {
margin: px2rem(-16px) px2rem(30px) px2rem(30px);
// margin: px2rem(-16px) px2rem(22px) px2rem(30px);
margin: -16px 30px 30px;
// margin: -16px 22px 30px;
text-align: left;
font-size: px2rem(14px);
line-height: px2rem(24px);
font-size: 14px;
line-height: 24px;
font-weight: 400;
color: #676869;
}
.dialog-footer {
height: px2rem(50px);
height: 50px;
display: flex;
align-items: center;
&.v-hairline-top::after {
......@@ -117,9 +116,9 @@ export default {
display: inline-block;
// width: 50%;
flex: 1;
height: px2rem(50px);
line-height: px2rem(50px);
font-size: px2rem(17px);
height: 50px;
line-height: 50px;
font-size: 17px;
text-align: center;
color: #979899;
&.v-hairline-left::after {
......
......@@ -56,8 +56,7 @@ export default {
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.common-dialog-wrraper {
position: fixed;
top: 0;
......@@ -79,35 +78,35 @@ export default {
top: 50%;
left: 50%;
overflow: hidden;
width: px2rem(300px);
font-size: px2rem(18px);
width: 300px;
font-size: 18px;
-webkit-transition: 0.3s;
transition: 0.3s;
border-radius: px2rem(4px);
border-radius: 4px;
background-color: #fff;
-webkit-transform: translate3d(-50%, -50%, 0);
transform: translate3d(-50%, -50%, 0);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
.dialog-content {
// margin: px2rem(30px) px2rem(22px);
margin: px2rem(30px);
// margin: 30px 22px;
margin: 30px;
text-align: center;
font-size: px2rem(18px);
font-size: 18px;
font-weight: 400;
color: #373839;
}
.dialog-sub-content {
margin: px2rem(-16px) px2rem(30px) px2rem(30px);
// margin: px2rem(-16px) px2rem(22px) px2rem(30px);
margin: -16px 30px 30px;
// margin: -16px 22px 30px;
text-align: left;
font-size: px2rem(14px);
line-height: px2rem(24px);
font-size: 14px;
line-height: 24px;
font-weight: 400;
color: #676869;
}
.dialog-footer {
height: px2rem(50px);
height: 50px;
display: flex;
align-items: center;
&.v-hairline-top::after {
......@@ -117,9 +116,9 @@ export default {
display: inline-block;
// width: 50%;
flex: 1;
height: px2rem(50px);
line-height: px2rem(50px);
font-size: px2rem(17px);
height: 50px;
line-height: 50px;
font-size: 17px;
text-align: center;
color: #979899;
&.v-hairline-left::after {
......@@ -154,7 +153,7 @@ export default {
&.shikan {
.dialog-sub-content {
text-align: center;
font-size: px2rem(16px);
font-size: 16px;
}
}
}
......
......@@ -27,26 +27,25 @@ export default {
},
}
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.exjumper-button-wrapper {
position: fixed;
left: 0;
bottom: 0;
right: 0;
z-index: 1000;
font-size: px2rem(14px);
padding: px2rem(20px) px2rem(15px);
font-size: 14px;
padding: 20px 15px;
background: linear-gradient(180deg,rgba(255,255,255,0) 0%,rgba(255,255,255,1) 100%);
text-align: center;
&.button-default {
span {
display: block;
height: px2rem(50px);
line-height: px2rem(50px);
height: 50px;
line-height: 50px;
width: 100%;
border-radius: px2rem(25px);
font-size: px2rem(17px);
border-radius: 25px;
font-size: 17px;
font-weight: 700;
color: #FFFFFF;
background: #449284;
......@@ -66,4 +65,4 @@ export default {
}
}
</style>
\ No newline at end of file
</style>
......@@ -66,8 +66,7 @@ export default {
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.exjumper-dialog-wrraper {
position: fixed;
top: 0;
......@@ -89,54 +88,54 @@ export default {
top: 50%;
left: 50%;
overflow: hidden;
width: px2rem(300px);
font-size: px2rem(18px);
width: 300px;
font-size: 18px;
-webkit-transition: 0.3s;
transition: 0.3s;
border-radius: px2rem(4px);
border-radius: 4px;
background-color: #fff;
-webkit-transform: translate3d(-50%, -50%, 0);
transform: translate3d(-50%, -50%, 0);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
.title {
margin: px2rem(30px) 0 px2rem(20px);
margin: 30px 0 20px;
text-align: center;
font-size: px2rem(18px);
font-size: 18px;
font-weight: 700;
color: #373839;
}
.dialog-content {
// margin: px2rem(30px) px2rem(22px);
margin: px2rem(20px) px2rem(16px) px2rem(30px);
// margin: 30px 22px;
margin: 20px 16px 30px;
text-align: left;
font-size: px2rem(14px);
font-size: 14px;
font-weight: 400;
color: #373839;
}
.sub-wrapper {
margin-right: px2rem(5px);
max-height: px2rem(300px);
margin-right: 5px;
max-height: 300px;
overflow: auto;
.dialog-sub-content {
margin: 0 px2rem(8px) px2rem(20px) px2rem(16px);
margin: 0 8px 20px 16px;
text-align: left;
font-size: px2rem(14px);
line-height: px2rem(24px);
font-size: 14px;
line-height: 24px;
font-weight: 400;
color: #979899;
}
.dialog-img-1 {
width: px2rem(268px);
height: px2rem(165px);
margin-left: px2rem(16px);
margin-bottom: px2rem(20px);
width: 268px;
height: 165px;
margin-left: 16px;
margin-bottom: 20px;
}
.dialog-img-2 {
width: px2rem(268px);
height: px2rem(145px);
margin-left: px2rem(16px);
margin-bottom: px2rem(20px);
width: 268px;
height: 145px;
margin-left: 16px;
margin-bottom: 20px;
}
&::-webkit-scrollbar-track-piece {
......@@ -144,30 +143,30 @@ export default {
border-left: 1px solid rgba(0, 0, 0, 0);
}
&::-webkit-scrollbar {
width: px2rem(5px);
height: px2rem(13px);
-webkit-border-radius: px2rem(3px);
-moz-border-radius: px2rem(3px);
border-radius: px2rem(3px);
width: 5px;
height: 13px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background-color: #C7C8C9;
background-clip: padding-box;
-webkit-border-radius: px2rem(3px);
-moz-border-radius: px2rem(3px);
border-radius: px2rem(3px);
min-height: px2rem(28px);
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
min-height: 28px;
}
&::-webkit-scrollbar-thumb:hover {
background-color: #C7C8C9;
-webkit-border-radius: px2rem(3px);
-moz-border-radius: px2rem(3px);
border-radius: px2rem(3px);
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
}
.dialog-footer {
height: px2rem(50px);
height: 50px;
display: flex;
align-items: center;
&.v-hairline-top::after {
......@@ -177,9 +176,9 @@ export default {
display: inline-block;
// width: 50%;
flex: 1;
height: px2rem(50px);
line-height: px2rem(50px);
font-size: px2rem(17px);
height: 50px;
line-height: 50px;
font-size: 17px;
text-align: center;
color: #979899;
&.v-hairline-left::after {
......
......@@ -40,43 +40,42 @@ export default {
}
}
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.item-intro-container {
padding-bottom: px2rem(20px);
margin: px2rem(30px) px2rem(15px) 0px;
border-bottom: px2rem(1px) solid #E7E8E9;
padding-bottom: 20px;
margin: 30px 15px 0px;
border-bottom: 1px solid #E7E8E9;
.basic-title {
font-size: px2rem(18px);
line-height: px2rem(18px);
font-size: 18px;
line-height: 18px;
color: #373839;
font-weight: 700;
}
.content {
position: relative;
margin-top: px2rem(16px);
margin-top: 16px;
.text {
font-size: px2rem(14px);
line-height: px2rem(21px);
font-size: 14px;
line-height: 21px;
color: #676869;
}
.desc {
// position: absolute;
// right: 0;
// bottom: px2rem(1px);
// bottom: 1px;
text-align: right;
background: #fff;
line-height: px2rem(14px);
line-height: 14px;
z-index: 99;
span {
font-size: px2rem(14px);
line-height: px2rem(14px);
font-size: 14px;
line-height: 14px;
color: #449284;
}
img {
width: px2rem(12px);
width: 12px;
}
}
}
}
</style>
\ No newline at end of file
</style>
......@@ -53,58 +53,60 @@ export default {
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.item-leader-container {
padding-bottom: px2rem(20px);
margin: px2rem(30px) px2rem(15px) 0px;
border-bottom: px2rem(1px) solid #e7e8e9;
padding-bottom: 20px;
margin: 30px 15px 0px;
border-bottom: 1px solid #e7e8e9;
.basic-title {
font-size: px2rem(18px);
line-height: px2rem(18px);
font-size: 18px;
line-height: 18px;
color: #373839;
font-weight: 700;
}
.leader-info {
display: flex;
flex-direction: row;
margin-top: px2rem(16px);
margin-top: 16px;
img {
display: inline-block;
width: px2rem(44px);
height: px2rem(44px);
width: 44px;
height: 44px;
border-radius: 50%;
}
.leader-text {
margin-left: px2rem(16px);
margin-top: px2rem(6px);
flex: 1;
width: 100px;
margin-left: 16px;
margin-top: 6px;
.leader-con {
line-height: px2rem(14px);
line-height: 14px;
display: flex;
flex-direction: row;
white-space: nowrap;
span {
font-size: px2rem(16px);
font-size: 16px;
color: #676869;
}
span:first-child {
font-size: px2rem(16px);
font-size: 16px;
color: #373839;
font-weight: 700;
}
.leader-title {
width: px2rem(220px);
width: 220px;
overflow : hidden;
text-overflow: ellipsis;
white-space:nowrap;
line-height: px2rem(16px);
margin-left: px2rem(10px);
line-height: 16px;
margin-left: 10px;
}
}
.address {
margin-top: px2rem(5px);
font-size: px2rem(13px);
margin-top: 5px;
font-size: 13px;
color: #979899;
width: px2rem(240px);
width: 240px;
overflow : hidden;
text-overflow: ellipsis;
white-space:nowrap;
......@@ -113,28 +115,28 @@ export default {
}
.content {
position: relative;
margin-top: px2rem(16px);
margin-top: 16px;
.text {
font-size: px2rem(14px);
line-height: px2rem(21px);
font-size: 14px;
line-height: 21px;
color: #676869;
}
.desc {
// position: absolute;
// right: 0;
// bottom: px2rem(1px);
// bottom: 1px;
text-align: right;
background: #fff;
line-height: px2rem(14px);
line-height: 14px;
z-index: 99;
span {
font-size: px2rem(14px);
font-size: 14px;
color: #449284;
}
img {
width: px2rem(12px);
width: 12px;
}
}
}
}
</style>
\ No newline at end of file
</style>
......@@ -16,25 +16,24 @@ export default {
}
}
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.learn-know-container {
margin: px2rem(30px) px2rem(15px) px2rem(20px);
margin: 30px 15px 20px;
.basic-title {
font-size: px2rem(18px);
line-height: px2rem(18px);
font-size: 18px;
line-height: 18px;
color: #373839;
font-weight: 700;
}
.content {
margin-top: px2rem(16px);
line-height: px2rem(21px);
margin-top: 16px;
line-height: 21px;
span {
display: inline-block;
text-align: justify;
font-size: px2rem(14px);
font-size: 14px;
color: #676869;
}
}
}
</style>
\ No newline at end of file
</style>
......@@ -23,72 +23,74 @@ export default {
},
data() {
return {
}
},
created() {
},
mounted() {
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.teacter-intro-container {
margin: px2rem(30px) px2rem(15px) 0px;
margin: 30px 15px 0px;
.basic-title {
font-size: px2rem(18px);
line-height: px2rem(18px);
font-size: 18px;
line-height: 18px;
color: #373839;
font-weight: 700;
}
.leader-info {
display: flex;
flex-direction: row;
margin-top: px2rem(16px);
padding-bottom: px2rem(16px);
margin-top: 16px;
padding-bottom: 16px;
img {
display: inline-block;
width: px2rem(44px);
height: px2rem(44px);
width: 44px;
height: 44px;
border-radius: 50%;
}
.leader-text {
margin-left: px2rem(16px);
margin-top: px2rem(6px);
flex: 1;
width: 100px;
margin-left: 16px;
margin-top: 6px;
.leader-con {
line-height: px2rem(14px);
line-height: 14px;
display: flex;
flex-direction: row;
white-space: nowrap;
span {
font-size: px2rem(16px);
font-size: 16px;
color: #676869;
}
span:first-child {
font-size: px2rem(16px);
font-size: 16px;
color: #373839;
font-weight: 700;
line-height: 1.1;
}
.leader-title {
width: px2rem(220px);
width: 220px;
overflow : hidden;
text-overflow: ellipsis;
white-space:nowrap;
line-height: px2rem(16px);
margin-left: px2rem(10px);
line-height: 16px;
margin-left: 10px;
}
}
.address {
margin-top: px2rem(5px);
font-size: px2rem(13px);
margin-top: 5px;
font-size: 13px;
color: #979899;
width: px2rem(240px);
width: 240px;
overflow : hidden;
text-overflow: ellipsis;
white-space:nowrap;
......@@ -96,4 +98,4 @@ export default {
}
}
}
</style>
\ No newline at end of file
</style>
<template>
<div class="common-adert-wrapper">
<img :class="{'margin-top-20': needPadTop}" v-if="showInfo.imageUrl" @click="jumpPage" :src="showInfo.imageUrl" alt="">
<img
:class="{'margin-top-20': needPadTop}"
v-if="showInfo.imageUrl"
@click="jumpPage"
:src="showInfo.imageUrl"
alt
/>
</div>
</template>
<script>
import { EMLINK } from 'constants';
import { EMLINK } from "constants";
export default {
name: 'common-title',
name: "common-title",
data() {
return {
isWeb: window.__isWeb,
showInfo: {
imageUrl: '',
jumpUrl: ''
imageUrl: "",
jumpUrl: ""
}
};
},
......@@ -31,9 +38,9 @@ export default {
},
watch: {
advertInfoList: {
handler (list) {
handler(list) {
list.forEach(element => {
if(element.position == this.position) {
if (element.position == this.position) {
this.showInfo = element;
}
});
......@@ -42,16 +49,15 @@ export default {
}
},
created() {},
mounted() {
},
computed: {
},
mounted() {},
computed: {},
methods: {
// 广告位跳转
jumpPage() {
// if (this.isWeb) {
// window.location.href = this.showInfo.jumpUrl;
// return;
// }
let paramList = [
{
key: "pageUrl",
......@@ -59,25 +65,24 @@ export default {
type: 4,
seqNo: 1
}
]
];
rocNative.dispatchEventByModuleCode({
modeCode: "M300",
jsonString: paramList
});
});
}
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.common-adert-wrapper {
img {
width: 100%;
// padding: px2rem(10px) 0;
// height: px2rem(60px);
// padding: 10px 0;
// height: 60px;
}
.margin-top-20 {
margin-top: px2rem(20px);
margin-top: 20px;
}
}
</style>
......@@ -65,10 +65,9 @@ export default {
methods: {}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.comp-title {
display: flex;
padding-left: px2rem(15px);
padding-left: 15px;
}
</style>
<template>
<CommonTcPlayer style="flex" :options="videoOptions">
</CommonTcPlayer>
</template>
<script>
......@@ -84,10 +84,9 @@ export default {
methods: {}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.comp-title {
display: flex;
padding-left: px2rem(15px);
padding-left: 15px;
}
</style>
......@@ -14,7 +14,7 @@ export default {
name: "common-description",
data() {
return {
};
},
props: {
......@@ -34,7 +34,7 @@ export default {
computed: {
newStudyNum: function() {
if(this.studyNum > 1000 && this.studyNum < 10000) {
return ((Math.round((this.studyNum / 1000) * 10) / 10) + 'K');
return ((Math.round((this.studyNum / 1000) * 10) / 10) + 'K');
}else if(this.studyNum > 10000) {
return ((Math.round((this.studyNum / 10000) * 10) / 10) + 'W');
}else {
......@@ -47,22 +47,21 @@ export default {
},
methods: {
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.desc-container {
padding: px2rem(20px) px2rem(15px);
padding: 20px 15px;
.desc-title {
display: flex;
padding-bottom: 0px;
line-height: px2rem(22px);
line-height: 22px;
font-weight: 700;
span {
font-family: "PingFangSC-Medium", "PingFangSC", "Microsoft Yahei";
font-size: px2rem(18px);
font-size: 18px;
font-weight: 700;
color: #333333;
}
......@@ -71,13 +70,13 @@ export default {
display: flex;
position: relative;
word-break: normal;
// margin-bottom: px2rem(40px);
// height: px2rem(60px);
// margin-bottom: 40px;
// height: 60px;
.desc_text {
padding-top: px2rem(6px);
font-size: px2rem(13px);
padding-top: 6px;
font-size: 13px;
color: #676869;
line-height: px2rem(25px);
line-height: 25px;
letter-spacing: 1px;
word-wrap: break-word;
word-break: break-all;
......@@ -87,7 +86,7 @@ export default {
flex-wrap: wrap;
}
}
}
</style>
......@@ -17,8 +17,7 @@
</template>
<style lang="scss" scoped>
@import '../../style/mixin';
<style lang="less" scoped>
.loader {
&-mask {
position: fixed;
......@@ -31,8 +30,8 @@
}
svg {
position: fixed;
top: px2rem(280px);
left: px2rem(166px);
top: 280px;
left: 166px;
z-index: 9999;
}
}
......
......@@ -124,23 +124,22 @@ export default {
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.back {
position: absolute;
left: px2rem(8px);
top: px2rem(15px);
left: 8px;
top: 15px;
display: inline-block;
width: px2rem(50px);
height: px2rem(50px);
width: 50px;
height: 50px;
img {
padding: px2rem(10px);
width: px2rem(25px);
height: px2rem(25px);
padding: 10px;
width: 25px;
height: 25px;
}
}
.nav-top {
// height: px2rem(65px);
// height: 65px;
background: #fff;
color: #333;
position: relative;
......@@ -148,10 +147,10 @@ export default {
.nav-back {
display: inline-block;
position: absolute;
left: px2rem(16px);
left: 16px;
top: 0;
height: px2rem(25px);
width: px2rem(25px);
height: 25px;
width: 25px;
// -ms-transform: translate(180deg);
// -webkit-transform: (180deg);
// transform: rotate(180deg);
......@@ -172,33 +171,33 @@ export default {
}
.nav-share {
position: absolute;
right: px2rem(16px);
right: 16px;
top: 0;
height: px2rem(25px);
width: px2rem(25px);
height: 25px;
width: 25px;
}
.nav-title {
position: relative;
top: px2rem(10px);
top: 10px;
left: 0;
display: inline-block;
width: 100%;
/* padding:0 px2rem(33px);*/
height: px2rem(36px);
/* padding:0 33px;*/
height: 36px;
&-title {
height: px2rem(18px);
font-size: px2rem(18px);
height: 18px;
font-size: 18px;
font-weight: 500;
color: rgba(51, 51, 51, 1);
line-height: px2rem(26px);
line-height: 26px;
}
}
.nav-part {
width: 100%;
font-size: px2rem(18px);
font-size: 18px;
text-align: center;
padding: 0 0 px2rem(10px) 0;
/* height: px2rem(25px);*/
padding: 0 0 10px 0;
/* height: 25px;*/
}
}
......@@ -207,6 +206,6 @@ export default {
top: 0;
left: 0;
border-bottom: 1px solid #e7e7e7;
/* height: px2rem(25px);*/
/* height: 25px;*/
}
</style>
\ No newline at end of file
</style>
<template>
<section :class="isFixNavbar ? 'nav-top fixed' : 'nav-top'" :style="'height:' + navHeight">
<!-- <section v-if="isWeb" :class="isFixNavbar ? 'nav-top fixed' : 'nav-top'"> -->
<section v-if="!isWeb" :class="isFixNavbar ? 'nav-top fixed' : 'nav-top'" :style="'height:' + navHeight">
<div
class="nav-part"
:style="'background:' + bgColor + ';'
......@@ -10,8 +9,6 @@
<span class="nav-back" @click="goBack">
<img v-show="isBlack" src="../../images/left-array-black.png" alt="">
<img v-show="!isBlack" src="../../images/left-array-whiter.png" alt="">
<!-- <img src="https://pica-pro.oss-cn-shanghai.aliyuncs.com/gpranking/left-icon.png"> -->
<!-- <img class="nav-back" src="../../images//grey-throw.png"/> -->
</span>
<span class="nav-title-title" v-show="bgColor!=='none'">{{title}}</span>
<span v-if="isShowShare" class="nav-share" @click="goShare">
......@@ -25,6 +22,8 @@
</section>
</template>
<script>
import { getWebPageUrl } from "@/utils/index";
import { mapGetters } from 'vuex';
export default {
name: "common-navbar",
data() {
......@@ -35,7 +34,8 @@ export default {
fontSize: 37.5,
content: "",
shareImageUrl:
"https://file.yunqueyi.com/logo.png?version=" + new Date().getTime()
"https://file.yunqueyi.com/logo.png?version=" + new Date().getTime(),
shareUrl: ''
};
},
props: {
......@@ -79,15 +79,18 @@ export default {
shareTitleInfo: {
type: String,
default: ""
},
projectId: {
type: String,
default: ""
},
limitTimes: {
type: String | Number,
default: 0
}
},
computed: {
// bgColor2() {
// return this.bgColor
// },
// borderStyle() {
// return this.bgColor === 'no{ne' ? '0px solid #e7e7e7' : '1px solid #e7e7e7'
// },
...mapGetters(["userInfo"]),
navHeight() {
if (this.isFixNavbar) {
return 0;
......@@ -108,28 +111,51 @@ export default {
methods: {
//返回
goBack() {
// if (this.burialPoint == "activity") {
// this.pageBurialPoin(this.objPoint);
// }
// if (this.backMethod === "inner" || window.__isWeb) {
// this.$router.back(-1);
// } else {
// rocNative.goBack();
// }
rocNative.goBack();
},
//分享
// 生成分享的url
goShare() {
let url = location.href,
_this = this;
let _this = this;
let videoUrl = this.$route.query.videoUrl || '';
let info = "";
if(videoUrl) {
info = JSON.stringify({
projectId: this.projectId,
videoUrl: videoUrl,
limitTimes: this.limitTimes || 0
})
} else {
info = JSON.stringify({
projectId: this.projectId,
})
}
let param = {
channel: 1, // 分享渠道 1:APP
info: info,
type: 3, // 业务类型 1:教培项目 2:继教项目 3:职称考项目
token: _this.userInfo.userToken,
setEntry: true
};
_this.NEW_POST("portal/shareParam/save", param).then(res => {
if (res.code == "000000") {
let url = getWebPageUrl(`profexam/#/sharecoop?uuid=${res.data}`);
_this.shareUrl = url;
_this.goShareAction();
}
}).catch( e => {
console.error(e);;
});
},
//分享
goShareAction() {
// let url = location.href,
let _this = this;
rocNative.shareWechat({
// url: url,
// title: '_this.title',
// content: '_this.content',
// shareImageUrl: '_this.shareImageUrl'
type: 6,
shareId: 0,
shareUrl: url,
shareUrl: _this.shareUrl,
title1: _this.shareTitle,
title2: _this.shareTitleInfo,
shareImageUrl: "https://file.yunqueyi.com/logo.png?version=" + new Date().getTime()
......@@ -138,23 +164,22 @@ export default {
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.back {
position: absolute;
left: px2rem(px);
top: px2rem(15px);
left: px;
top: 15px;
display: inline-block;
width: px2rem(50px);
height: px2rem(50px);
width: 50px;
height: 50px;
img {
padding: px2rem(10px);
width: px2rem(25px);
height: px2rem(25px);
padding: 10px;
width: 25px;
height: 25px;
}
}
.nav-top {
// height: px2rem(65px);
// height: 65px;
background: #fff;
color: #333;
position: relative;
......@@ -162,15 +187,12 @@ export default {
.nav-back {
display: inline-block;
position: absolute;
left: px2rem(0px);
left: 0px;
top: 0;
height: px2rem(25px);
width: px2rem(55px);
padding-left: px2rem(15px);
padding-right: px2rem(15px);
// -ms-transform: translate(180deg);
// -webkit-transform: (180deg);
// transform: rotate(180deg);
height: 25px;
width: 55px;
padding-left: 15px;
padding-right: 15px;
}
img {
display: block;
......@@ -188,33 +210,33 @@ export default {
}
.nav-share {
position: absolute;
right: px2rem(16px);
right: 16px;
top: 0;
height: px2rem(25px);
width: px2rem(25px);
height: 25px;
width: 25px;
}
.nav-title {
position: relative;
top: px2rem(10px);
top: 10px;
left: 0;
display: inline-block;
width: 100%;
/* padding:0 px2rem(33px);*/
height: px2rem(36px);
/* padding:0 33px;*/
height: 36px;
&-title {
height: px2rem(18px);
font-size: px2rem(18px);
height: 18px;
font-size: 18px;
font-weight: 700;
color: rgba(51, 51, 51, 1);
line-height: px2rem(26px);
line-height: 26px;
}
}
.nav-part {
width: 100%;
font-size: px2rem(18px);
font-size: 18px;
text-align: center;
padding: 0 0 px2rem(10px) 0;
/* height: px2rem(25px);*/
padding: 0 0 10px 0;
/* height: 25px;*/
}
}
......@@ -223,6 +245,6 @@ export default {
top: 0;
left: 0;
border-bottom: 1px solid #e7e7e7;
/* height: px2rem(25px);*/
/* height: 25px;*/
}
</style>
\ No newline at end of file
</style>
......@@ -23,8 +23,7 @@ export default {
methods: {}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.split-line {
display: flex;
}
......
......@@ -124,11 +124,10 @@ export default {
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.banner-img {
// display: inherit;
width: px2rem(375px);
height: px2rem(210px);
width: 375px;
height: 210px;
}
</style>
\ No newline at end of file
</style>
......@@ -63,12 +63,11 @@ export default {
...this.options
};
options.width = htmlWidth;
const tcPlayer = new TcPlayer(this.id, options);
tcPlayer.video.on('timeupdate', (event) => {
let ct = tcPlayer.currentTime();
console.log('视频播放时长S => ', ct);
// console.log('视频播放时长S => ', ct);
if (options.trySeeTime && ct >= options.trySeeTime) {
tcPlayer.currentTime(0);
tcPlayer.pause();
......@@ -136,11 +135,10 @@ export default {
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.banner-img {
// display: inherit;
width: px2rem(375px);
height: px2rem(210px);
width: 375px;
height: 210px;
}
</style>
\ No newline at end of file
</style>
......@@ -109,10 +109,9 @@ export default {
}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.comp-title-container {
padding-left: px2rem(15px);
padding-left: 15px;
display: flex;
flex-direction: row;
justify-content: space-between;
......@@ -127,39 +126,39 @@ export default {
display: flex;
flex-direction: row;
align-items: center;
margin-right: px2rem(15px);
margin-right: 15px;
span {
font-size: px2rem(14px);
font-size: 14px;
font-weight: 400;
color: rgba(40, 52, 76, 0.4);
}
img {
width: px2rem(15px);
height: px2rem(16px);
width: 15px;
height: 16px;
}
}
&-explain {
display: flex;
flex-direction: row;
align-items: center;
margin-right: px2rem(15px);
margin-right: 15px;
span {
font-size: px2rem(14px);
font-size: 14px;
font-weight: 400;
color: rgba(40, 52, 76, 0.4);
margin-right: px2rem(3px);
line-height: px2rem(14px);
margin-right: 3px;
line-height: 14px;
}
img {
width: px2rem(8px);
height: px2rem(14px);
width: 8px;
height: 14px;
}
}
}
.banner-img {
width: px2rem(70px);
height: px2rem(20px);
padding-top: px2rem(2px);
width: 70px;
height: 20px;
padding-top: 2px;
}
</style>
......@@ -26,8 +26,7 @@ export default {
},
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.loader {
&-mask {
position: fixed;
......@@ -43,10 +42,10 @@ export default {
width: 100%;
left: 0;
z-index: 301;
bottom: px2rem(30px);
bottom: 30px;
text-align: center;
span {
padding: px2rem(2px) px2rem(10px);
padding: 2px 10px;
background: #eee;
}
}
......
......@@ -67,10 +67,9 @@ export default {
methods: {}
};
</script>
<style lang="scss" scoped>
@import "../../style/mixin";
<style lang="less" scoped>
.comp-title {
display: flex;
padding-left: px2rem(15px);
padding-left: 15px;
}
</style>
<template>
<div class="brief-intro-wrapper">
<TeacherIntro :doctorList="doctorList"></TeacherIntro>
<CourseIntro :intro="intro"></CourseIntro>
<CourseHarvest :harvest="harvest"></CourseHarvest>
</div>
</template>
<script>
import TeacherIntro from "@/components/course/course-teacher";
import CourseIntro from "@/components/course/course-intro";
import CourseHarvest from "@/components/course/course-harvest";
export default {
components: {
TeacherIntro,
CourseIntro,
CourseHarvest,
},
props: {
doctorList: {
type: Array,
default() {
return [];
}
},
intro: {
type: String,
default: "",
},
harvest: {
type: Array,
default() {
return [];
}
}
},
};
</script>
<style lang="less" scoped>
.brief-intro-wrapper {
padding-bottom: 20px;
}
</style>
<template>
<section>
<div class="common-error-tips-wrapper">
<img src="../../images/course/danger.png" alt="">
<span>{{errorMsg}}</span>
</div>
<CommonBottomInfo></CommonBottomInfo>
</section>
</template>
<script>
import CommonBottomInfo from "@/components/cme/common-bottom-info";
export default {
components: {
CommonBottomInfo
},
props: {
errorMsg: {
type: String,
default: '此课程已下架无法查看'
}
}
}
</script>
<style lang="less">
.common-error-tips-wrapper {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 120px;
img {
width: 40px;
height: 40px;
}
span {
display: inline-block;
margin-top: 15px;
font-size: 16px;
line-height: 16px;
font-weight: 700;
color: #111A34;
}
}
</style>
<template>
<span class="common-title-wrapper">{{title}}</span>
</template>
<script>
export default {
props: {
title: {
type: String,
default: "课程简介"
}
}
}
</script>
<style lang="less" scoped>
.common-title-wrapper {
display: inline-block;
height: 18px;
line-height: 18px;
margin: 30px 15px 15px;
font-size: 18px;
font-weight: 700;
color: #373839;
}
</style>
<template>
<span class="course-button-wrapper button-default" :class="type" @click="btnClick">{{btnText}}</span>
</template>
<script>
export default {
props: {
btnText: {
type: String,
default: "去云鹊医App"
},
type: {
type: String,
default: "primary"
}
},
data() {
return {};
},
methods: {
btnClick() {
if (this.type == "disabled") return;
this.$emit("btnClick");
}
}
};
</script>
<style lang="less" scoped>
.course-button-wrapper {
display: inline-block;
text-align: center;
margin: 0 5px;
&.button-default {
display: inline-block;
padding: 0 16px;
text-align: center;
height: 30px;
line-height: 30px;
// width: 100%;
border-radius: 15px;
font-size: 12px;
font-weight: 700;
color: #ffffff;
background: #449284;
}
&.primary {
color: #ffffff;
background: #449284;
}
&.plain {
color: #ffffff;
background: none;
border: 1px solid rgba(255, 255, 255, 1);
}
&.disabled {
color: rgba(255, 255, 255, 0.95);
background: rgba(68, 146, 132, 0.4);
}
}
</style>
<template>
<div class="course-catalog">
<div class="chapter-box" v-for="(chapter, index) in list" :key="index">
<div class="head">
<div class="name ellipsis">{{ chapter.chapterNameText }}</div>
<div class="total" @click="onToggle(index)">
{{ chapter.lectureNum }}
<img class="arrow" :class="{'arrow-active': chapter.showAll}" src="~@/images/course/arrow_down.png" />
</div>
</div>
<div class="lecture-box" v-show="chapter.showAll">
<div class="item"
:class="{'item-active': curtId === lecture.lectureId}"
v-for="lecture in chapter.lectures"
:key="lecture.lectureId"
@click="onSelect(lecture, 1)">
<img class="icon" src="~@/images/course/icon_play.png" />
<div class="info-box line">
<div class="info">
<p class="subname ellipsis">{{ lecture.lectureNameText }}</p>
<p class="time">
时长: {{ lecture.totalTimeText }}
<span>{{ lecture.statusText }}</span>
</p>
</div>
<div class="btn" v-if="lecture.btnText">{{ lecture.btnText }}</div>
<img v-else class="lock" src="~@/images/course/lock.png" alt="" />
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
list: {
type: Array,
default() {
return []
}
},
curtId: {
type: Number,
default: 0,
},
onToggle: {
type: Function
},
onSelect: {
type: Function
}
},
};
</script>
<style lang="less" scoped>
.course-catalog{
.chapter-box{
position: relative;
padding: 0 15px;
&::after{
position: absolute;
content: "";
left: 0;
bottom: 0;
width: 200%;
height: 0;
transform: scale(0.5);
transform-origin: left center;
border-bottom: 1px solid #E7E8E9;
}
.head{
display: flex;
height: 50px;
line-height: 50px;
}
.name{
flex: 1;
width: 100px;
font-size: 15px;
}
.total{
position: relative;
color: #A1A2A3;
font-size: 14px;
padding-right: 15px;
}
.arrow{
position: absolute;
right: 0;
top: 19px;
width: 12px;
height: 12px;
transition: all 0.3s;
}
.arrow-active{
transform: rotate(180deg);
}
}
.lecture-box{
.item{
position: relative;
padding: 15px 0 0 25px;
}
.item-active{
.subname, .time{
color: #449284;
}
}
.icon{
position: absolute;
left: 0;
top: 20px;
width: 12px;
}
.info-box{
position: relative;
display: flex;
align-items: center;
padding-bottom: 15px;
}
.info{
position: relative;
flex: 1;
width: 100px;
padding-right: 5px;
}
.line{
&::after{
position: absolute;
content: "";
left: 0;
bottom: 0;
width: 200%;
height: 0;
transform: scale(0.5);
transform-origin: left center;
border-bottom: 1px solid #E7E8E9;
}
}
.btn{
position: relative;
width: 60px;
height: 26px;
line-height: 26px;
color: #449284;
font-size: 12px;
text-align: center;
&::after{
position: absolute;
content: "";
left: -1px;
top: -1px;
width: 200%;
height: 200%;
border: 1px solid #449284;
transform: scale(0.5);
transform-origin: left top;
border-radius: 26px;
}
}
.lock{
display: block;
width: 16px;
margin: 0 22px;
}
.subname{
color: #676869;
font-size: 15px;
}
.time{
color: #A3A3A3;
font-size: 12px;
margin-top: 8px;
}
}
}
</style>
<template>
<div class="course-comment">
<div class="item" v-for="(item, index) in comments" :key="index">
<img class="img" :src="item.imageUrl || 'https://file.yunqueyi.com/File/doctor_default.png'" alt="头像" @error="onAvatarError" />
<div class="info-box">
<div class="info-user">
<div class="name">{{ item.doctorName }}</div>
<div class="date">{{ item.createTime }}</div>
</div>
<div class="message">{{ item.message }}</div>
<div class="reply-box" v-if="item.len">
<div class="reply-item" v-for="child in item.cList" :key="child.qaId">
<div class="reply-user">
<div class="name">{{ child.doctorName }}</div>
<div class="date">{{ child.createTime }}</div>
</div>
<div class="message">{{ child.message }}</div>
</div>
<div class="show-all" v-if="item.len > 2" @click="spreadAll(index)">
{{ item.showAll ? '收起回复' : `查看全部${item.len}条回复` }}
<img class="show-arrow" :class="{'show-arrow-up': item.showAll}" src="~@/images/course/arrow_down.png" alt="箭头" />
</div>
</div>
</div>
</div>
<div class="go-app" @click="download">
<span>打开App,查看更多讨论内容</span>
</div>
</div>
</template>
<script>
export default {
props: {
list: {
type: Array,
default() {
return []
}
},
download: {
type: Function
}
},
data() {
return {
comments: []
};
},
watch: {
list(val) {
this.dealList(val);
}
},
mounted() {
this.dealList(this.list);
},
methods: {
dealList(list) {
this.comments = list.map(item => {
const aList = item.aList || [];
return {
...item,
aList,
len: aList.length,
cList: aList.slice(0, 2),
showAll: false,
}
})
},
spreadAll(index) {
const { ...item } = this.comments[index];
if (item.showAll) {
item.showAll = false;
item.cList = item.aList.slice(0, 2);
} else {
item.showAll = true;
item.cList = item.aList;
}
this.comments.splice(index, 1, item);
},
}
};
</script>
<style lang="less" scoped>
.course-comment {
padding: 0 15px;
.item{
position: relative;
display: flex;
font-size: 14px;
padding: 20px 0;
&::after{
position: absolute;
content: "";
left: 0;
bottom: 0;
width: 200%;
height: 0;
transform: scale(0.5);
transform-origin: left center;
border-bottom: 1px solid #F0F0F0;
}
}
.img{
display: block;
width: 32px;
height: 32px;
margin-right: 10px;
}
.info-box{
flex: 1;
width: 100px;
}
.info-user, .reply-user{
display: flex;
padding-bottom: 10px;
.name{
color: #676869;
flex: 1;
width: 80px;
}
.date{
color: #979899;
font-size: 12px;
}
}
.message{
line-height: 22px;
text-align: justify;
word-break: break-all;
}
.reply-box{
margin-top: 15px;
padding: 12px 12px 0;
background-color: #F8F9FA;
}
.reply-item{
padding-bottom: 20px;
}
.show-all{
position: relative;
color: #676869;
text-align: right;
font-size: 12px;
padding: 10px 18px 20px 0;
}
.show-arrow{
position: absolute;
right: 0;
top: 12px;
width: 12px;
height: 12px;
transition: all 0.3s;
}
.show-arrow-up{
transform: rotate(180deg);
}
.go-app{
color: #449284;
font-size: 14px;
line-height: 16px;
text-align: center;
padding: 20px 0;
span{
display: inline-block;
padding-right: 20px;
background: url('~@/images/course/array-right.png') no-repeat right center;
background-size: 14px auto;
}
}
}
</style>
<template>
<div class="course-covers-wrapper">
<div class="tips" v-html="coverTips"></div>
<div v-if="isShowBtn" class="course-button-group">
<CourseButton v-if="!isSingle" type="plain" @btnClick="btnClick(1)" :btnText="leftBtnText"></CourseButton>
<CourseButton @btnClick="btnClick(2)" :btnText="rightBtnText"></CourseButton>
</div>
</div>
</template>
<script>
import CourseButton from "@/components/course/course-button";
export default {
components: {
CourseButton
},
props: {
coverTips: {
type: String,
default: "上次观看至7分钟,正在续播"
},
isShowBtn: {
type: Boolean,
default: true
},
isSingle: {
type: Boolean,
default: false
},
leftBtnText: {
type: String,
default: "学习下一节"
},
rightBtnText: {
type: String,
default: "去云鹊医App"
}
},
data() {
return {};
},
methods: {
btnClick(index) {
this.$emit("btnClick", index);
}
}
};
</script>
<style lang="less" scoped>
.course-covers-wrapper {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
// background: rgba(0, 0, 0, 0.8);
justify-content: center;
align-content: center;
.tips {
display: inline-block;
margin-bottom: 15px;
color: #fff;
text-align: center;
font-size: 15px;
}
.course-button-group {
display: flex;
align-items: center;
justify-content:center;
}
}
</style>
<template>
<div v-if="harvest.length > 0" class="course-harvest-wrapper">
<CommonTitle title="学习收获"></CommonTitle>
<ul class="list-wrapper">
<li class="item" v-for="(item, index) in harvest" :key="index">
<span class="name">{{ item.name }}</span>
<span class="btn" @click="onClick(item)">查看</span>
</li>
</ul>
</div>
</template>
<script>
import CommonTitle from "@/components/course/common-title";
import { ImagePreview } from 'vant';
export default {
components: {
CommonTitle
},
props: {
harvest: {
type: Array,
default() {
return [];
}
}
},
methods: {
onClick(item) {
ImagePreview([item.url])
}
},
}
</script>
<style lang="less" scoped>
.course-harvest-wrapper {
.list-wrapper {
.item {
display: flex;
justify-content: space-between;
height: 65px;
line-height: 65px;
margin: 0 15px;
align-items: center;
border-bottom: 1px solid #E7E8E9;
.name {
font-size: 15px;
font-weight: 700;
color: #333333;
}
.btn {
display: inline-block;
height: 25px;
line-height: 25px;
font-size: 12px;
font-weight: 700;
padding: 0 18px;
color: #449284;
border-radius: 15px;
border:1px solid rgba(68, 146, 132, 0.45);
}
}
}
}
</style>
<template>
<div v-if="intro" class="course-intro-wrapper">
<CommonTitle></CommonTitle>
<div class="body">
<p class="content" :class="{'ellipsis': isUp}">{{ intro }}</p>
<div class="toggle-btn" v-show="showArrow" @click="isUp=!isUp">
<span class="action">{{ isUp ? "详情" : "收起"}}</span>
<img v-show="isUp" src="~@/images/down.png" alt="" />
<img v-show="!isUp" src="~@/images/up.png" alt="" />
</div>
<div class="offset">{{ intro }}</div>
</div>
</div>
</template>
<script>
import CommonTitle from "@/components/course/common-title"
export default {
components: {
CommonTitle
},
props: {
intro: {
type: String,
default: ""
}
},
data() {
return {
isUp: true,
showArrow: true,
}
},
watch: {
intro(val) {
this.countH();
}
},
mounted() {
this.countH();
},
methods: {
countH() {
if (this.intro) {
this.$nextTick(() => {
const content = this.$el.querySelector('.content').getBoundingClientRect();
const offset = this.$el.querySelector('.offset').getBoundingClientRect();
if (offset.height < (content.height - 1)) {
this.showArrow = false;
}
})
}
}
},
}
</script>
<style lang="less" scoped>
.course-intro-wrapper {
.body {
position: relative;
color: #676869;
font-size: 14px;
margin: 0 15px;
.content {
display: block;
text-align: justify;
line-height: 21px;
&.ellipsis {
height: 63px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
white-space: normal;
}
}
.toggle-btn {
// background: #fff;
position: absolute;
right: 0;
bottom: -18px;
display: flex;
align-items: center;
// padding-left: 30px;
// background: linear-gradient(90deg, rgba(255, 255, 255, .9), rgba(255, 255, 255, 1));
img {
position: relative;
top: 1px;
margin-left: 6px;
width: 12px;
height: 7px;
}
.action {
color: #449284;
}
}
}
.offset{
position: absolute;
left: 0;
top: 0;
width: 100%;
opacity: 0;
visibility: hidden;
pointer-events: none;
}
}
</style>
<template>
<div v-if="doctorList.length > 0" class="course-teacher-wrapper">
<div class="basic-title">讲师介绍</div>
<div class="leader-info" v-for="(item,index) in doctorList" :key="index">
<img :src="item.app_image_url" alt="头像" @error="onAvatarError" />
<div class="leader-text">
<div class="leader-con">
<span>{{item.name}}</span>
<span class="leader-title">{{item.title}}</span>
</div>
<div class="hospital">{{item.hospital}}</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
doctorList: {
type: Array,
default: () => []
}
},
}
</script>
<style lang="less" scoped>
.course-teacher-wrapper {
padding: 30px 15px 0px;
.basic-title {
font-size: 18px;
line-height: 18px;
color: #373839;
font-weight: 700;
}
.leader-info {
display: flex;
flex-direction: row;
margin-top: 16px;
padding-bottom: 16px;
border-bottom: 1px solid #E7E8E9;
img {
display: inline-block;
width: 44px;
height: 44px;
border-radius: 50%;
}
.leader-text {
margin-left: 16px;
margin-top: 6px;
.leader-con {
line-height: 14px;
display: flex;
flex-direction: row;
white-space: nowrap;
span {
font-size: 16px;
color: #676869;
}
span:first-child {
font-size: 16px;
color: #373839;
font-weight: 700;
line-height: 1.1;
}
.leader-title {
width: 220px;
overflow : hidden;
text-overflow: ellipsis;
white-space:nowrap;
line-height: 16px;
margin-left: 6px;
}
}
.hospital {
margin-top: 5px;
font-size: 13px;
color: #979899;
width: 240px;
overflow : hidden;
text-overflow: ellipsis;
white-space:nowrap;
}
}
}
}
</style>
<template>
<div class="course-ware">
<div v-show="url && loadPdf" class="canvas-box"></div>
<p v-show="!url" class="tip">无相关课件</p>
</div>
</template>
<script>
/**
* 版本:v2.4.456
* 需引用ES5
* GlobalWorkerOptions.workerSrc需要一个加载路径
*/
import pdfJS from 'pdfjs-dist/es5/build/pdf';
pdfJS.GlobalWorkerOptions.workerSrc = '//cdn.bootcdn.net/ajax/libs/pdf.js/2.4.456/pdf.worker.js';
import coverImg from '@/images/course/lock-big.png';
export default {
props: {
url: {
type: String,
default: ""
},
visible: {
type: Boolean,
default: true,
}
},
data() {
return {
loadPdf: false
}
},
watch: {
url(val) {
this.drawPDF();
}
},
mounted() {
this.parentDom = this.$el.querySelector('.canvas-box');
this.drawPDF();
},
methods: {
async drawPDF() {
if (!this.url) {
return;
}
try {
const task = pdfJS.getDocument(this.url);
const pdf = await task.promise.then();
let numPages = 0;
if (pdf && pdf._pdfInfo) {
numPages = pdf._pdfInfo.numPages
}
let pageAll = [];
for (let i = 0; i < numPages; i++) {
pageAll.push(pdf.getPage(i + 1).catch(err => ''))
}
const pages = await Promise.all(pageAll);
this.parentDom.innerHTML = '';
for (let item of pages) {
this.createCanvas(item)
}
this.loadPdf = true;
} catch(err) {
console.log(err)
}
},
createCanvas(pdfPage) {
let viewport = pdfPage.getViewport({ scale: 1.0 });
let box = document.createElement("div");
box.style.position = 'relative';
box.style.marginBottom = '30px';
let canvas = document.createElement("canvas");
canvas.width = viewport.width;
canvas.height = viewport.height;
canvas.style.display = 'block';
canvas.style.width = '100%';
let ctx = canvas.getContext("2d");
let renderTask = pdfPage.render({
canvasContext: ctx,
viewport: viewport,
});
box.appendChild(canvas);
if (!this.visible) {
let cover = document.createElement("div");
cover.style.position = 'absolute';
cover.style.left = '0';
cover.style.top = '0';
cover.style.width = '100%';
cover.style.height = '100%';
cover.style.background = `url(${coverImg}) no-repeat center center`;
cover.style.backgroundSize = '50px auto';
cover.style.backgroundColor = 'rgba(255, 255, 255, .98)';
cover.onclick = () => {
if (!this.$store.getters.logged) {
this.$store.dispatch('goLogin');
return;
}
this.$toast('前往APP购买查看')
}
box.appendChild(cover);
}
this.parentDom.appendChild(box);
}
}
};
</script>
<style lang="less" scoped>
.course-ware{
padding-top: 20px;
overflow: hidden;
.tip{
font-size: 14px;
text-align: center;
margin-top: 50px;
}
}
</style>
<template>
<div class="download-button-wrapper" @click="download">
<img src="../../images/course/pica-icon.png" alt />
<span :class="{'short': needShort}">{{downloadTips}}</span>
</div>
</template>
<script>
export default {
data() {
return {
downloadTips: "打开云鹊医APP",
needShort: false,
}
},
methods: {
download() {
window.location.href =
"https://a.app.qq.com/o/simple.jsp?pkgname=com.picahealth.yunque";
},
},
created() {
setTimeout(() => {
this.downloadTips = '';
this.needShort = true;
}, 5000);
},
};
</script>
<style lang="less" scoped>
.download-button-wrapper {
display: flex;
// width: 100%;
// position: fixed;
position: absolute;
z-index: 1000;
top: 10px;
right: 0;
height: 30px;
align-items: center;
img {
position: relative;
left: 15px;
width: 30px;
height: 30px;
}
span {
display: inline-block;
height: 30px;
line-height: 30px;
padding: 0 8px 0 23px;
font-size: 12px;
font-weight: 700;
color: #5ba99b;
background: #fff;
box-shadow:0px 2px 10px 0px rgba(0,0,0,0.1);
width: 120px;
&.short {
width: 10px;
transition: width 1s;
-moz-transition: width 1s; /* Firefox 4 */
-webkit-transition: width 1s; /* Safari 和 Chrome */
-o-transition: width 1s; /* Opera */
padding: 0 12px;
}
}
}
</style>
\ No newline at end of file
<template>
<div
class="pica-video"
:style="{position: isFullScreen ? 'fixed' : ''}">
<template v-if="isWechat">
<video
:id="vid"
:src="url"
:poster="poster"
preload="metadata"
webkit-playsinline
playsinline
x5-playsinline="true"
x-webkit-airplay="allow"
x5-video-player-type="h5"
x5-video-player-fullscreen="false"
mtt-playsinline="true"
controlsList="nodownload"
@loadedmetadata="loadedMetaData"
@timeupdate="onTimeUpdate"
@ended="onEnded"
@error="onError"
>
</video>
<div class="video-cover" @click="showControl = !showControl"></div>
<!-- 控制栏 -->
<div class="control-box" v-show="showControl">
<div class="control-bar">
<div class="btn-play" :class="{'btn-pause': isPaused}" @click="togglePlay"></div>
<div class="progress-box" @click="setProgress">
<div class="progress-inner">
<div class="progress-bar" :style="progressBar"></div>
</div>
<div
class="progress-ball"
:style="{left: `${progressBall}%`}"
@touchstart.stop="onBallStart"
@touchmove.stop="onBallMove"
@touchend.stop="onBallEnd">
</div>
</div>
<div class="time-box">{{ playTime }}/{{ totalTime }}</div>
<!-- <div class="rate-box" @click="showRate=true">
倍速
<div class="rate-list" v-show="showRate">
<div
class="rate-item"
:class="{'rate-active': rate === curtRate}"
v-for="rate in rates"
:key="rate"
@click.stop="selectRate(rate)">{{ rate }}</div>
</div>
</div> -->
<div class="btn-screen" :class="{'btn-screen-mini': isFullScreen}" @click="onFullscreen"></div>
</div>
</div>
<!-- 播放遮罩 -->
<transition name="fade">
<div v-show="logged && isPaused" class="cover cover-play" @click="togglePlay"></div>
</transition>
<!-- 播放错误 -->
<transition name="fade">
<div v-show="logged && showError" class="cover cover-error">
<p>播放失败,请确认网络正常或重新进入页面</p>
</div>
</transition>
<!-- 接续播放 -->
<transition name="fade">
<div v-show="showResume" class="cover cover-resume">
<p>上次观看至{{ dealTime(history) }},正在续播</p>
</div>
</transition>
<!-- 弹窗放在外部处理 -->
<slot></slot>
<!-- 试看提示 -->
<div class="proved-box" v-show="logged && showProved">
可试看{{ dealTime(proved) }},观看完整版请来 <span @click="download">云鹊医App</span>
</div>
<!-- 重新播放,只有试看有 -->
<div class="replay-box" v-show="showReplay" @click="onReplay">重新播放</div>
</template>
<img v-else class="default-img" src="~@/images/video/course_img.png" alt="" />
</div>
</template>
<script>
/**
* 不使用参数,调用两个方法;
* switchUrl(opt)和switchUrlAndPlay(opt)
* opt: {
* url, // 视频链接
* poster, // 封面
* proved, // 试看时长,单位秒
* history, // 上次观看时长,单位秒
* enable, // 是否可看
* }
* 暴露一个回调onVideoEnd,参数:
* type => 1 播放结束,2 试看结束
*/
import { formatLeftTimeObj } from '@/utils';
export default {
name: 'pica-video',
props: {
coverType: {
type: Number,
default: 0,
},
download: {
type: Function,
default: () => {}
}
},
data() {
return {
url: '', // 视频链接
poster: '', // 封面
proved: 0, // 试看时长,单位秒
history: 0, // 上次观看时长,单位秒
enable: true, // 是否可看
vid: '', // 唯一id
playTime: '00:00', // 播放时长
totalTime: '00:00', // 总时长
isPaused: true, // 是否暂停
isFullScreen: false, // 是否全屏
showControl: true, // 显示控制栏
progressBar: {}, // 进度条
progressBall: 0, // 进度球
rates: [2, 1.5, 1, 0.5],
curtRate: 1,
showRate: false,
showProved: false, // 试看提示文字
showError: false, // 播放错误
showResume: false, // 继续播放
showReplay: false, // 显示重播
isWechat: true, // 微信环境
}
},
computed: {
logged() {
return this.$store.getters.logged;
},
},
created() {
this.vid = `video_${this._uid}`;
this.playTime = 0;
const ua = navigator.userAgent;
this.isWechat = ua.match(/(MicroMessenger)\/([\d.]+)/);
this.isAndroid = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
},
mounted() {
if (this.isWechat) {
const player = document.getElementById(this.vid);
player.addEventListener("timeupdate", this.onTimeUpdate, false);
player.addEventListener("play", this.onPlay, false);
player.addEventListener("pause", this.onPause, false);
this.player = player;
}
},
beforeDestroy() {
this.timer && clearTimeout(this.timer);
if (this.currentTime) {
this.reportLeave();
}
if (!this.isPaused && !this.finish) {
this.reportOnOff(2);
}
},
methods: {
// 被接管时,监听上报
onPlay() {
this.reportOnOff(1);
this.isPaused = false;
this.showProved = false;
},
onPause() {
this.reportOnOff(2);
this.isPaused = true;
},
togglePlay() {
if (!this.logged) {
this.$store.dispatch('goLogin');
return;
}
if (!this.url || !this.enable) {
return;
}
let isPaused = this.isPaused;
// 试看,且超过时间
if (this.proved && this.player.currentTime >= this.proved) {
return;
}
this.player.style.display = 'block';
if (isPaused) {
this.player.play();
this.playTime++;
this.showProved = false;
} else {
this.player.pause();
}
// this.reportOnOff(isPaused ? 1 : 2); // 使用监听发送
this.isPaused = !isPaused;
},
// 切换视频
switchUrl(opts = {}) {
if (!this.isWechat) {
return;
}
this.player.style.display = 'block';
const { url = '', poster = '', proved = 0, history = 0, enable = true } = opts;
this.loaded = false;
this.player.src = url;
this.url = url;
this.poster = poster;
this.proved = proved;
this.history = history;
this.enable = enable;
this.provedOver = false;
this.finish = false;
this.opts = opts;
this.currentTime = null;
this.duration = null;
this.showProved = proved > 0;
this.showReplay = false;
if (this.showError) this.showError = false;
},
// 切换并播放
switchUrlAndPlay(opts = {}) {
if (!this.isWechat) {
return;
}
if (!this.isPaused && !this.finish) {
this.reportOnOff(2);
}
if (!this.finish) {
this.reportLeave();
}
if (this.playTime === 0) {
this.player.play();
}
this.switchUrl(opts);
this.player.autoplay = true;
if (!this.enable) {
return;
}
const loop = () => {
if (this.loaded) {
this.player.play();
if (!this.player.paused) {
this.isPaused = false;
// this.reportOnOff(1);
this.showProved = false;
}
return null;
} else {
return setTimeout(() => {
loop()
}, 100);
}
}
this.timer = loop();
},
// 重播
onReplay() {
this.player.style.display = 'block';
this.player.currentTime = 0;
this.player.play();
this.isPaused = false;
// this.reportOnOff(1);
this.$emit('onReplay');
this.showReplay = false;
this.provedOver = false;
},
// 加载完毕,获取总时长和音量。问题:移动端点击播放才会触发,且不一定会获取时长
loadedMetaData() {
let duration = this.player.duration;
if (duration) {
this.totalTime = this.formatTime(duration);
this.loaded = true;
if (this.history) {
this.player.currentTime = this.history;
this.showResume = true;
setTimeout(() => {
this.showResume = false;
}, 2000);
}
}
},
// 播放中
onTimeUpdate(e) {
const { currentTime, duration } = e.target;
// 试看,且超过时间
if (this.proved && currentTime >= this.proved) {
this.provedEnd();
}
if (this.provedOver) {
return
}
if (currentTime) {
this.playTime = this.formatTime(currentTime);
}
if (currentTime && duration) {
this.setBarPosition(currentTime * 100 / duration, 'progressBar');
this.currentTime = currentTime;
this.duration = duration;
}
if (currentTime < 0.1 && !this.loaded) {
this.loadedMetaData();
}
},
// 设置进度条位置
setBarPosition(percent, target) {
this[target] = {
transform: `translateX(${percent}%)`,
'-webkit-transform': `-webkit-translateX(${percent}%)`,
'-moz-transform': `-moz-translateX(${percent}%)`,
'-ms-transform': `-ms-translateX(${percent}%)`,
}
if (target === 'progressBar' && !this.isMoveingBall) {
this.progressBall = percent
}
},
// 点击设置进度
setProgress(e) {
if (!this.url) {
return;
}
const { offsetX } = e;
const { width } = e.target.getBoundingClientRect();
this.setProgressPosition(offsetX * 100 / width);
},
// 设置进度最终位置
setProgressPosition(percent) {
const duration = this.player.duration;
// 试看,且超过时间
if (this.proved && percent >= this.proved * 100 / duration) {
return;
}
this.setBarPosition(percent, 'progressBar');
this.player.currentTime = percent * duration / 100;
if (this.isPaused) {
this.player.style.display = 'block';
this.player.play();
this.playTime++;
this.isPaused = false;
// this.reportOnOff(1);
}
},
// 拖动进度条
onBallStart(e) {
this.isMoveingBall = true;
const { width } = this.$el.querySelector('.progress-inner').getBoundingClientRect();
const { pageX } = e.changedTouches[0];
this.ballPageX = pageX;
this.progressW = width;
this.oldBallPercent = this.progressBall;
},
onBallMove(e) {
const { pageX } = e.changedTouches[0];
this.progressBall = this.getNewPercent(pageX);
},
onBallEnd(e) {
this.isMoveingBall = false;
const { pageX } = e.changedTouches[0];
const newPercent = this.getNewPercent(pageX);
this.setProgressPosition(newPercent);
},
// 获取拖动百分比
getNewPercent(pageX) {
let newPercent = (pageX - this.ballPageX) * 100 / this.progressW + this.oldBallPercent;
if (newPercent <= 0) {
newPercent = 0
} else if (newPercent >= 100) {
newPercent = 100
}
return newPercent;
},
selectRate(rate) {
if (!this.url) {
return;
}
this.player.playbackRate = rate;
this.curtRate = rate;
this.showRate = false;
},
formatTime(t) {
const time = formatLeftTimeObj(t);
const h = time.h === '00' ? '' : `${time.h}:`;
return `${h}${time.f}:${time.s}`;
},
dealTime(t) {
let text = '';
if (t < 60) {
text = `${t}秒`
} else {
let second = t % 60;
let minute = parseInt(t / 60);
if (second === 0) {
text = `${minute}分钟`
} else {
text = `${minute}${second}秒`
}
}
return text;
},
// 试看结束
provedEnd() {
this.player.pause();
this.player.currentTime = this.proved;
if (this.isAndroid) {
this.player.style.display = 'none';
}
if (!this.provedOver) {
this.$emit('onVideoEnd', { type: 2 });
this.reportOnOff(2);
this.reportLeave();
}
this.finish = true;
this.showReplay = true;
this.provedOver = true;
this.isFullScreen = false;
},
// 播放结束
onEnded() {
this.$emit('onVideoEnd', { type: 1 });
this.finish = true;
if (this.isAndroid) {
this.player.style.display = 'none';
}
this.reportOnOff(2);
this.reportLeave();
this.$nextTick(() => {
if (this.coverType > 0 && this.coverType !== 13) {
this.isFullScreen = false;
}
})
},
onError() {
if (this.url) {
this.showError = true
}
},
// 全屏
onFullscreen() {
this.isFullScreen = !this.isFullScreen;
},
// 上报播放、暂停,status:1开始,2暂停
reportOnOff(status = 1) {
const { chapterId, courseId, lectureId } = this.opts;
if (!chapterId || !courseId || !lectureId) {
return;
}
this.POST('contents/files/resourceRecord', {
fileType: 1,
resourceInfo1: courseId,
resourceInfo2: chapterId,
resourceInfo3: lectureId,
resourceType: 1,
status,
systemType: 3,
timestamp: Date.now(),
})
},
// 上报离开
reportLeave() {
if (!this.currentTime || !this.duration) {
return;
}
const { chapterId, courseId, lectureId } = this.opts;
if (!chapterId || !courseId || !lectureId) {
return;
}
this.POST('contents/joinCourse/', {
requestList: [{
chapterId,
courseId,
lectureId,
nowTime: this.currentTime,
time: this.duration,
timeStamp: Date.now(),
}],
})
},
},
}
</script>
<style lang="less" scoped>
.pica-video{
position: relative;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: #333;
overflow: hidden;
z-index: 1000;
video{
position: absolute;
left: 50%;
top: 50%;
width: 100%;
max-width: 100%;
max-height: 100%;
transform: translate3d(-50%, -50%, 0);
&::-internal-media-controls-download-button {
display: none;
}
&::-webkit-media-controls-enclosure {
overflow: hidden;
}
&::-webkit-media-controls-panel {
width: calc(100% + 30px);
}
}
.video-cover{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.control-box{
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 44px;
}
.control-bar{
position: absolute;
display: flex;
align-items: center;
justify-content: center;
left: 0;
top: 0;
width: 100%;
height: 44px;
// transform: translate3d(0, 60px, 0);
// transition: transform 0.2s;
background: linear-gradient(180deg,rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%);
}
.btn-play{
width: 44px;
height: 44px;
background-image: url('~@/images/video/play.png');
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: 24px auto;
}
.btn-pause{
background-image: url('~@/images/video/pause.png');
}
.progress-box{
position: relative;
display: flex;
align-items: center;
flex: 1;
width: 50px;
height: 44px;
margin-left: 5px;
}
.progress-inner{
position: relative;
width: 50px;
flex: 1;
height: 2px;
background: rgba(255, 255, 255, 0.4);
overflow: hidden;
}
.progress-bar{
position: absolute;
left: -100%;
top: 0;
width: 100%;
height: 100%;
background: #449284;
transform: translateX(0);
pointer-events: none;
}
.progress-ball{
position: absolute;
left: 0;
top: 50%;
width: 7px;
height: 14px;
transform: translate3d(-3px, -7px, 0);
background-color: #fff;
border-radius: 2px;
}
.time-box{
color: #fff;
font-size: 12px;
line-height: 14px;
width: 100px;
text-align: right;
}
.btn-screen{
width: 44px;
height: 44px;
background-image: url('~@/images/video/screen_full.png');
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: 20px auto;
}
.btn-screen-mini{
background-image: url('~@/images/video/screen_mini.png');
}
.rate-box{
position: relative;
color: #fff;
width: 40px;
height: 44px;
line-height: 44px;
font-size: 12px;
text-align: center;
}
.rate-list{
position: absolute;
left: 0;
bottom: 44px;
width: 100%;
background: rgba(0, 0, 0, .7);
border-radius: 2px;
}
.rate-item{
height: 30px;
line-height: 30px;
}
.rate-active{
color: #00a1d6;
}
.proved-box{
position: absolute;
color: #fff;
font-size: 12px;
left: 10px;
bottom: 44px;
height: 24px;
line-height: 24px;
padding: 0 12px;
border-radius: 12px;
background-color: rgba(0, 0, 0, .6);
span{
color: #FFA34B;
}
}
.cover-play{
background: url('~@/images/video/cover_play.png') no-repeat center center;
background-size: 50px auto;
}
.cover-error, .cover-resume{
p{
position: absolute;
left: 0;
top: 50%;
width: 100%;
color: #fff;
font-size: 15px;
text-align: center;
transform: translate3d(0, -50%, 0);
}
}
.replay-box{
position: absolute;
color: #fff;
font-size: 12px;
right: 10px;
bottom: 44px;
height: 24px;
line-height: 24px;
padding: 0 12px 0 22px;
border-radius: 12px;
background: url('~@/images/video/replay.png') no-repeat left center;
background-size: 23px auto;
background-color: rgba(0, 0, 0, .6);
}
.cover{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
}
.default-img{
position: absolute;
left: 50%;
top: 50%;
min-width: 100%;
min-height: 100%;
max-width: 100%;
max-height: 100%;
transform: translate3d(-50%, -50%, 0);
}
}
</style>
......@@ -6,9 +6,9 @@ import store from './store/'
const mixins = require('@/utils/mixins');
import '@/utils/rem' // 引入自适应
import '@/utils/yqy-bridge' // 移动端服务
import '@/utils/wxShare';
// import FastClick from 'fastclick'
import vueFilters from '@/utils/filter'
import VConsole from 'vconsole/dist/vconsole.min.js'
import vueFilters from '@/utils/filter';
import BuriedPoint, { sendBuriedData } from 'web-buried-point';
import Vant from 'vant';
import 'vant/lib/index.css';
......@@ -17,7 +17,7 @@ import clipboard from 'clipboard';
Vue.prototype.clipboard = clipboard;
if (!(process.env.BUILD_ENV === 'uat' || process.env.BUILD_ENV === 'pro')) {
// if(!(process.env.BUILD_ENV === 'pro')) {
const VConsole = require('vconsole');
let vConsole = new VConsole() // 初始化
}
......@@ -53,6 +53,35 @@ const router = new VueRouter({
}
})
// 过滤路由
function fliterRoute(query, path) {
let has = false;
// 登录token保存并替换路径
if (query.token && query.token != 'undefined') {
store.dispatch('setToken', query.token);
delete query.token;
has = true;
}
// 课程详情页去掉projectId
if (path === '/course-detail' && query.projectId) {
sessionStorage.setItem('projectId', query.projectId);
delete query.projectId;
has = true;
}
return [query, has];
}
router.beforeEach((to, from, next) => {
let query = { ...to.query };
// 登录token保存并替换路径
let [newQuery, has] = fliterRoute(query, to.path);
if (has) {
next({ path: to.path, query: newQuery, replace: true });
return;
}
next();
})
// 加入混合
Vue.mixin({
...mixins
......
......@@ -2,31 +2,46 @@ import App from '../App'
const index = r => require.ensure([], () => r(require('../views/index')), 'index')
const merge = r => require.ensure([], () => r(require('../views/merge-detail')), 'merge')
const shareMerge = r => require.ensure([], () => r(require('../views/share-merge-detail')), 'share-merge')
const test = r => require.ensure([], () => r(require('../views/test-components')), 'test-components')
const courseDetail = r => require.ensure([], () => r(require('../views/course-detail')), 'course-detail')
const notFound = r => require.ensure([], () => r(require('../views/not-found')), 'not-found')
export default [{
path: '/',
component: App,
children: [
{
path: '',
redirect: '/index'
},
{
path: '/index',
component: index
},
{
path: '/home',
component: index
},
{
path: '/coop',
component: merge
},
{
path: '/test',
component: test
},
]
path: '/',
component: App,
children: [
{
path: '',
redirect: '/index'
},
{
path: '/index',
component: index
},
{
path: '/home',
component: index
},
{
path: '/coop',
component: merge
},
{
path: '/sharecoop',
component: shareMerge
},
{
path: '/test',
component: test
},
{
path: '/course-detail',
component: courseDetail
},
{
path: '/not-found',
component: notFound
},
]
}]
......@@ -6,5 +6,6 @@ const getters = {
jumpURLForII: state => state.coop.jumpURLForII,
positionInfo: state => state.coop.positionInfo,
organizationInfo: state => state.coop.organizationInfo,
logged: state => !!(state.user.token && state.user.info.id),
}
export default getters
import Vue from 'vue'
import Vuex from 'vuex'
import coop from './modules/coop'
import getters from './getters'
import user from './modules/user'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
coop
coop,
user,
},
getters
})
......
import { Toast } from 'vant';
import fetch from '@/utils/fetch';
import { getBaseUrl } from '@/utils/index'
import { setCookie, delCookie } from '@/utils/index';
import { envConfig } from '@/utils/env-config'
const user = {
state: {
token: localStorage.getItem('token') || '',
info: {}, // 用户信息
},
mutations: {
SET_TOKEN: (state, payload) => {
state.token = payload;
},
SET_USER_INFO: (state, payload) => {
state.info = payload;
},
},
actions: {
// 外部登陆返回设置token
setToken({ commit, dispatch }, params) {
commit('SET_TOKEN', params);
localStorage.setItem('token', params);
setCookie('token', params)
dispatch('getUserInfo');
},
// 获取用户信息
async getUserInfo({ state, commit, dispatch }) {
try {
const errCallBack = () => {
dispatch('logout');
Toast('登录失效,请重新登录~')
}
const res = await fetch({
url: getBaseUrl('account/login/web'),
method: 'get',
headers: { token: state.token }
}).catch(() => {
errCallBack()
});
if (res && res.code === '000000') {
const { certifyDoc, isExist } = res.data;
const picapDoctor = res.data.picapDoctor || {};
if (picapDoctor.id) {
// let avatar = picapDoctor.avatar_image_url || '';
let avatarUrl = '';
// const img1 = await preLoadImg(`https://test-file.yunqueyi.com${avatar}`).catch(err => console.log(err));
// const img2 = await preLoadImg(`https://file.yunqueyi.com${avatar}`).catch(err => console.log(err));
// if (img1) {
// avatarUrl = img1.src;
// }
// if (img2) {
// avatarUrl = img2.src;
// }
picapDoctor.avatar = avatarUrl || 'https://file.yunqueyi.com/File/doctor_default.png';
commit('SET_USER_INFO', { ...picapDoctor, isExist, certifyDoc });
}
} else {
errCallBack()
}
} catch (err) {
console.error(err);
}
},
// 通过登陆
goLogin() {
window.location.href = envConfig[process.env.BUILD_ENV]['webPageUrl'] + "/pica_login?target_url=" + encodeURIComponent(location.href);
},
// 登出
logout({ state, commit }) {
commit('SET_TOKEN', '');
commit('SET_USER_INFO', {});
localStorage.removeItem('token');
delCookie('token')
},
},
}
export default user;
......@@ -12,7 +12,7 @@ body, div, span, header, footer, nav, section, aside, article, ul, dl, dt, dd, l
font-style: normal;
text-decoration: none;
border: none;
// font-size: px2rem(14px);
// font-size: 14px;
// color: #333;
font-weight: normal;
// font-family: "PingFangSC-Medium", "PingFangSC", "Microsoft Yahei";
......@@ -28,6 +28,26 @@ body, div, span, header, footer, nav, section, aside, article, ul, dl, dt, dd, l
}
}
img,
a,
div {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-touch-callout: none;
-webkit-user-select: none;
}
::selection {
background: none;
}
::-moz-selection {
background: none;
}
::-webkit-selection {
background: none;
}
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
::-webkit-scrollbar
{
......@@ -143,3 +163,6 @@ html,body{
// color: #fff !important;
// }
#app{
height: 100%;
}
@import './common.scss';
@import './common.less';
//定位
.relative{
position: relative;
......@@ -25,46 +25,46 @@
text-align: center;
}
.line20{
margin-top: px2rem(10px);
margin-top: 10px;
}
.mb42{
margin-bottom: px2rem(21px);
margin-bottom: 21px;
}
.marginLR40{
margin: 0 px2rem(20px);
margin: 0 20px;
}
.fs10{
font-size: px2rem(10px);
font-size: 10px;
}
.fs11{
font-size: px2rem(11px);
font-size: 11px;
}
.fs13{
font-size: px2rem(13px);
font-size: 13px;
}
.fs14{
font-size: px2rem(14px);
font-size: 14px;
}
.fs22{
font-size: px2rem(11px);
font-size: 11px;
}
.fs24{
font-size: px2rem(12px);
font-size: 12px;
}
.fs26{
font-size: px2rem(13px);
font-size: 13px;
}
.fs28{
font-size: px2rem(14px);
font-size: 14px;
}
.fs32{
font-size: px2rem(16px);
font-size: 16px;
}
.fs30{
font-size: px2rem(15px);
font-size: 15px;
}
.fs50{
font-size: px2rem(25px);
font-size: 25px;
}
.fw{
font-weight: 700;
......@@ -81,12 +81,12 @@
color: #fff;
}
.fs30{
font-size: px2rem(15px);
font-size: 15px;
}
.van-cell {
padding: px2rem(17px) px2rem(15px) !important;
font-size: px2rem(15px) !important;
padding: 17px 15px !important;
font-size: 15px !important;
color: #373839 !important;
}
.van-cell:not(:last-child)::after {
......@@ -96,7 +96,7 @@
text-align: right !important;
}
// .van-hairline--top-bottom::after, .van-hairline-unset--top-bottom::after {
// border-width: px2rem(1px) 0 !important;
// border-width: 1px 0 !important;
// }
// .van-hairline, .van-hairline--surround, .van-hairline--top, .van-hairline--top-bottom {
// position: inherit !important;
......@@ -104,29 +104,29 @@
// .van-hairline--top {
// }
// .van-field__label, .van-field__body {
// height: px2rem(15px) !important;
// line-height: px2rem(15px) !important;
// height: 15px !important;
// line-height: 15px !important;
// }
.van-cell__title span {
font-weight: 700 !important;
}
.bind-cart-wrapper .van-field__control {
border-radius: px2rem(4px);
border-radius: 4px;
border: 1px solid #C7C8C9;
padding: px2rem(7px);
padding: 7px;
text-align: left !important;
}
.bind-cart-wrapper .van-cell__title .van-field__label {
span {
font-size: px2rem(15px) !important;
font-size: 15px !important;
color: #373839 !important;
}
}
.bind-cart-wrapper .van-field__label {
width: px2rem(56px) !important;
padding-top: px2rem(8px);
width: 56px !important;
padding-top: 8px;
}
.bind-cart-wrapper .van-cell {
padding: 0.54rem 0 !important;
......@@ -164,4 +164,19 @@
.bind-cart-wrapper .van-cell:not(:last-child)::after {
border: none !important;
}
\ No newline at end of file
}
// 定义课程中公用弹框样式
.course-detail.van-dialog {
border-radius: 4px;
.van-dialog__message {
padding: 30px;
font-size: 14px;
line-height: 21px;
color: #727374;
}
.van-button__text {
font-size: 17px;
color: #449284;
}
}
@blue: #3190e8;
@bc: #e4e4e4;
@fc:#fff;
$blue: #3190e8;
$bc: #e4e4e4;
$fc:#fff;
// 背景图片地址和大小
@mixin bis($url) {
background-image: url($url);
background-repeat: no-repeat;
background-size: 100% 100%;
}
@mixin borderRadius($radius) {
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
-ms-border-radius: $radius;
-o-border-radius: $radius;
border-radius: $radius;
}
//定位全屏
@mixin allcover{
position:absolute;
top:0;
right:0;
}
//定位上下左右居中
@mixin center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
//定位上下居中
@mixin ct {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
//定位左右居中
@mixin cl {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
//宽高
@mixin wh($width, $height){
width: $width;
height: $height;
}
//字体大小、行高、字体
@mixin font($size, $line-height, $family: 'Microsoft YaHei') {
font: #{$size}/#{$line-height} $family;
}
//字体大小,颜色
@mixin sc($size, $color){
font-size: $size;
color: $color;
}
//flex 布局和 子元素 对其方式
@mixin fj($type: space-between){
display: flex;
justify-content: $type;
}
@function px2rem($px){
$rem: 37.5px;
@return ($px / $rem) + rem;
}
\ No newline at end of file
......@@ -11,18 +11,29 @@ export const envConfig = {
// apiUrl: 'https://dev-api.yunqueyi.com/',
// webPageUrl: 'https://dev-phome.yunqueyi.com/',
// baseUrl: 'https://dev-sc.yunqueyi.com/',
// //hactiveUrl: 'https://dev-hactive.yunqueyi.com',
// http://dev-hactive.yunqueyi.com/message_push/#/study-card
// baseUrl: 'https://test1-sc.yunqueyi.com/',
// apiUrl: 'https://test1-api.yunqueyi.com/',
// webPageUrl: 'https://test1-phome.yunqueyi.com/'
// hactiveUrl: 'https://dev-hactive.yunqueyi.com',
// fileUrl: 'https://dev-www.yunqueyi.com',
// appId: 'wxf4e66242d31c81c2', // 用于微信授权登录
baseUrl: 'https://uat-sc.yunqueyi.com/',
apiUrl: 'https://uat-api.yunqueyi.com/',
webPageUrl: 'https://uat-phome.yunqueyi.com/',
hactiveUrl: 'https://uat-hactive.yunqueyi.com',
baseUrl: 'https://test1-sc.yunqueyi.com/',
apiUrl: 'https://test1-api.yunqueyi.com/',
webPageUrl: 'https://test1-phome.yunqueyi.com/',
hactiveUrl: 'https://dev-hactive.yunqueyi.com',
fileUrl: 'https://test1-www.yunqueyi.com',
appId: 'wxcaad75b7fff5659c', // 用于微信授权登录
// baseUrl: 'https://uat-sc.yunqueyi.com/',
// apiUrl: 'https://uat-api.yunqueyi.com/',
// webPageUrl: 'https://uat-phome.yunqueyi.com/',
// hactiveUrl: 'https://uat-hactive.yunqueyi.com',
// fileUrl: 'https://dev-www.yunqueyi.com',
// appId: 'wxf4e66242d31c81c2', // 用于微信授权登录
// apiUrl: 'https://uat-api.yunqueyi.com/',
// webPageUrl: 'https://uat-phome.yunqueyi.com/',
// hactiveUrl: 'https://uat-hactive.yunqueyi.com',
// phomeDemain: 'https://dev-phome.yunqueyi.com',
// appId: 'wxf4e66242d31c81c2', // 用于微信授权登录
// baseUrl: 'https://sc.yunqueyi.com/',
// apiUrl: 'https://api.yunqueyi.com/',
......@@ -35,23 +46,31 @@ export const envConfig = {
apiUrl: 'https://dev-api.yunqueyi.com/',
webPageUrl: 'https://dev-phome.yunqueyi.com/',
hactiveUrl: 'https://dev-hactive.yunqueyi.com',
fileUrl: 'https://dev-www.yunqueyi.com',
appId: 'wxf4e66242d31c81c2', // 用于微信授权登录
},
test: {
baseUrl: 'https://test1-sc.yunqueyi.com/',
apiUrl: 'https://test1-api.yunqueyi.com/',
webPageUrl: 'https://test1-phome.yunqueyi.com/',
hactiveUrl: 'https://test1-hactive.yunqueyi.com',
fileUrl: 'https://test1-www.yunqueyi.com',
appId: 'wxcaad75b7fff5659c', // 用于微信授权登录
},
uat: {
baseUrl: 'https://uat-sc.yunqueyi.com/',
apiUrl: 'https://uat-api.yunqueyi.com/',
webPageUrl: 'https://uat-phome.yunqueyi.com/',
hactiveUrl: 'https://uat-hactive.yunqueyi.com',
fileUrl: 'https://uat-www.yunqueyi.com',
appId: 'wx342ef0e5afee54a7', // 用于微信授权登录
},
pro: {
baseUrl: 'https://sc.yunqueyi.com/',
apiUrl: 'https://api.yunqueyi.com/',
webPageUrl: 'https://phome.yunqueyi.com/',
hactiveUrl: 'https://hactive.yunqueyi.com',
fileUrl: 'https://www.yunqueyi.com',
appId: 'wx2c577552a2d28550', // 用于微信授权登录
}
}
......@@ -2,6 +2,8 @@
* Created by Anndy Yang on 19/02/28.
*/
import { envConfig } from '@/utils/env-config'
const { BUILD_ENV } = process.env;
// 获取SC服务器域名地址
export function getBaseUrl(url) {
......@@ -23,6 +25,17 @@ export function getHactiveUrl(url) {
return getConfigByEnvType('hactiveUrl') + (url || '')
}
// 获取pdf文件地址
export function getPdfFileUrl(path) {
let base = getConfigByEnvType('webPageUrl');
return `${base}proxyPdf${path}`;
}
// 获取微信APPID
export function getAPPID() {
return getConfigByEnvType('appId')
}
// 根据不同环境,生成URL
function getConfigByEnvType(urlType) {
return envConfig[process.env.BUILD_ENV][urlType]
......@@ -63,47 +76,47 @@ export function parseTime(time, cFormat) {
// 获取APP版本号(数值型)
export function getAppVersion(appVersion) {
if(!appVersion) return 200;
if (!appVersion) return 200;
return appVersion.split('.').join('')
}
export function setEventByModuleCode(itemData){
export function setEventByModuleCode(itemData) {
let modeCode = itemData.appModuleInfo.code || '';
let paramList = itemData.appModuleInfo.paramList ? itemData.appModuleInfo.paramList : ''
if( modeCode === 'M001' || modeCode === 'M002' || modeCode === 'M003') {
paramList = ''
}else if( modeCode === 'M100' || modeCode === 'M300' ) {
if (modeCode === 'M001' || modeCode === 'M002' || modeCode === 'M003') {
paramList = ''
} else if (modeCode === 'M100' || modeCode === 'M300') {
let urlPara = getUrlParmByCode(paramList);
paramList[0] && (paramList[0].value += urlPara);
}else if( modeCode === 'M400') {
} else if (modeCode === 'M400') {
let path = paramList[0]['key'];
let v = paramList[0]['value'];
let query = setRouterParm(paramList);
let path = paramList[0]['key'];
let v = paramList[0]['value'];
let query = setRouterParm(paramList);
}
if(typeof paramList === 'string' && !paramList){
paramList = []
if (typeof paramList === 'string' && !paramList) {
paramList = []
}
return paramList;
}
function getUrlParmByCode(paramList) {
if ( paramList.length <= 1) {
return ''
}
let dataStr = ''
let list = [];
for( let i = 1; i < paramList.length; i ++) {
list.push(paramList[i].key + '=' + paramList[i].value)
}
dataStr = list.join('&')
if (dataStr !== '') {
return '?' + dataStr
}
if (paramList.length <= 1) {
return ''
}
let dataStr = ''
let list = [];
for (let i = 1; i < paramList.length; i++) {
list.push(paramList[i].key + '=' + paramList[i].value)
}
dataStr = list.join('&')
if (dataStr !== '') {
return '?' + dataStr
}
return ''
}
export function deepCopy(obj) {
......@@ -120,13 +133,13 @@ export function deepCopy(obj) {
return result;
}
export function mergeObjs(...ojbs){
export function mergeObjs(...ojbs) {
}
// 跳转:在App中使用原生跳转,在浏览器中使用本地路由跳转
export function gotoPage(context, pageUrl) {
if(__isWeb) {
if (__isWeb) {
context.$router.push(pageUrl)
// context.$router.push({path: pageUrl, query: query});
} else {
......@@ -143,4 +156,85 @@ export function gotoPage(context, pageUrl) {
jsonString: paramList
});
}
}
\ No newline at end of file
}
function formatNum(n) {
return n * 1 < 10 ? `0${n}` : n;
}
// 传入秒,计算出剩余时间的时分秒
export function formatLeftTimeObj(time, hasZero = true) {
if (typeof time !== 'number') {
time = parseInt(time)
}
// time = parseInt(time / 1000)
// const d = parseInt(time / 86400)
// time = time - d * 86400
const h = parseInt(time / 3600)
time = time - h * 3600
const f = parseInt(time / 60)
const s = parseInt(time - f * 60)
return {
// d: hasZero ? formatNum(d) : d,
h: hasZero ? formatNum(h) : h,
f: hasZero ? formatNum(f) : f,
s: hasZero ? formatNum(s) : s,
}
}
export function preLoadImg(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
resolve(img);
}
img.onerror = () => {
reject();
}
img.src = url;
})
}
// 判断是否是微信浏览器
export function isWeiXin() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true;
} else {
return false;
}
}
export const setCookie = (name, value, time) => {
var expires = 30 * 24 * 60 * 60 * 1000; //一天
var date = new Date(+new Date() + expires);
if (time) {
document.cookie =
name +
'=' +
escape(value) +
'; path=/' +
';expires=' +
date.toUTCString();
} else {
document.cookie = name + '=' + escape(value) + '; path=/';
}
};
export const delCookie = key => {
var expires = -1 * 24 * 60 * 60 * 1000; //一天
var date = new Date(+new Date() + expires);
document.cookie =
key + '=' + escape('') + '; path=/' + ';expires=' + date.toUTCString(); //这里只需要把Cookie保质期退回一天便可以删除
};
export const getCookie = key => {
var cookieArr = document.cookie.split('; ');
for (var i = 0; i < cookieArr.length; i++) {
var arr = cookieArr[i].split('=');
if (arr[0] === key) {
return arr[1];
}
}
return '';
};
\ No newline at end of file
......@@ -110,12 +110,14 @@ module.exports = {
// 通用GET请求
GET(api, para, callback, str) {
// debugger
para.token = para.token || this.token || ''
let token = para.token || this.token || this.$store.state.user.token || '';
para.token = token;
let url = api + this.getUrlPara(para)
return fetch({
url: getBaseUrl(url),
method: 'get',
data: para
data: para,
headers: { token }
})
},
......@@ -144,11 +146,13 @@ module.exports = {
// 通用POST请求
POST(api, para, callback) {
para.token = para.token || this.token || '00175A13D70D4234822D90AC3C74202C'
let token = para.token || this.token || this.$store.state.user.token || '';
para.token = token;
return fetch({
url: getBaseUrl(api),
method: 'post',
data: para
data: para,
headers: { token }
})
},
......@@ -207,6 +211,8 @@ module.exports = {
}
return null
},
onAvatarError(e) {
e.target.src = 'https://file.yunqueyi.com/File/doctor_default.png';
},
}
}
/* eslint-disable */
import Vue from 'vue'
import request from '@/utils/fetch';
import wx from 'weixin-js-sdk'
import { getBaseUrl } from "@/utils/index";
/** 注入配置信息 */
export const wxConfig = (link) => {
// const params = { resetURI: true, url: encodeURIComponent(location.href) };
// 上线前是需要把域名改为线上的sc
let baseUrl = getBaseUrl("");
request({ url: `https://sc.yunqueyi.com/wechats/signs?url=${encodeURIComponent(link)}` }).then(res => {
// request({ url: `${baseUrl}/wechats/signs?url=${encodeURIComponent(link)}` }).then(res => {
let configs = res.data.signMap;
wx.config({
debug: false,
appId: configs.appId,
nonceStr: configs.nonceStr,
timestamp: configs.timestamp,
signature: configs.signature,
jsApiList: [
'hideMenuItems',
'previewImage',
'checkJsApi',
'chooseWXPay',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone',
'getLocation',
'openLocation',
'translateVoice'
]
});
});;
};
/**
* wxShare 分享
* @param option
*/
export const wxShare = (option = {}, successCB = () => {}) => {
wx.ready(() => {
WeixinJSBridge.call('showOptionMenu');
wx.showAllNonBaseMenuItem();
// 分享给朋友
wx.onMenuShareAppMessage({
title: option.title,
desc: option.desc,
link: option.link,
imgUrl: option.imgUrl,
success: function(res) {
// 用户确认分享后执行的回调函数
successCB(res);
},
cancel: function() {
// 用户取消分享后执行的回调函数
}
});
// 分享到朋友圈
wx.onMenuShareTimeline({
title: option.friendtitle || option.title, // 标题
desc: option.desc,
link: option.link, // 链接
imgUrl: option.imgUrl, // 分享图标
success: function(res) {
successCB(res);
},
cancel: function() {
// 用户取消分享后执行的回调函数
}
});
});
};
function wxHideMenu() {
wx.ready(() => {
WeixinJSBridge.call('hideOptionMenu');
wx.hideAllNonBaseMenuItem();
});
}
export const wxDisabledShare = () => {
wx.ready(() => {
wx.hideMenuItems({
menuList: [
'menuItem:share:appMessage',
'menuItem:share:timeline',
'menuItem:share:qq',
'menuItem:share:weiboApp',
'menuItem:share:QZone',
'menuItem:copyUrl',
'menuItem:openWithQQBrowser',
'menuItem:openWithSafari',
]
});
});
};
/**
*
* @param source
* @param option
*/
export const wechatShare = (option = {}, successCB = () => {}, hideMenu) => {
const shareOption = {
link: location.href,
title: `云鹊医!`,
friendtitle: `讨论进行中,速来围观!`,
desc: '参与讨论,一起畅谈医学那些事!快来看看吧~',
imgUrl: 'https://file.yunqueyi.com/logo.png',
...option
};
wxConfig(shareOption.link);
if (hideMenu) {
wxHideMenu()
} else {
wxShare(shareOption, successCB);
}
};
Vue.prototype.wechatShare = wechatShare;
Vue.prototype.wxDisabledShare = wxDisabledShare;
<template>
<div class="course-detail">
<!-- 视频 -->
<div class="video-box">
<pica-video ref="picaVideo" :coverType="coverType" :download="download" @onVideoEnd="onVideoEnd" @onReplay="onReplay">
<!-- 试看结束 -->
<div class="cover" v-if="logged && coverType === 1">
<course-covers coverTips="试看结束<br />请来云鹊医App学习完整课程" :isSingle="true" rightBtnText="学习完整课程" @btnClick="btnClick" />
</div>
<!-- 付费课程,下载App -->
<div class="cover" v-if="logged && coverType === 2">
<course-covers coverTips="本课程为付费课程,请来云鹊医App学习" :isSingle="true" rightBtnText="去云鹊医App" @btnClick="btnClick" />
</div>
<!-- 下一个提示 -->
<div class="next-countdown" v-if="coverType === 13">3秒后播放下一节</div>
<!-- 未学完提示 -->
<div class="cover" v-if="logged && coverType === 4">
<course-covers coverTips="您已学习至最后一节<br />但本课程中仍有未学完的内容" :isSingle="true" rightBtnText="继续学完本课程" @btnClick="btnClick" />
</div>
<!-- 已学完,无考试 -->
<div class="cover" v-if="logged && coverType === 5">
<course-covers coverTips="您已完成全部学习<br />来云鹊医App参加考试巩固学习成果" leftBtnText="返回项目" @btnClick="btnClick" />
</div>
<!-- 未登录 -->
<div class="cover" v-if="!logged">
<course-covers coverTips="登录后马上学习课程" :isSingle="true" rightBtnText="去登录" @btnClick="goLogin" />
</div>
</pica-video>
</div>
<!-- 内容滚动 -->
<div class="scroll-box">
<div class="scroll-content">
<div class="course-info">
<div class="course-title">
<span class="level">
{{ course.typeStr }}
</span>{{ course.courseName }}
</div>
<div class="course-num">
<span class="num">{{ course.joinNum }}</span>人已学 /
<span class="num">{{ course.favorNum }}</span>人收藏
<span v-if="course.status === 3 || course.status === 4">/ 总进度<i class="percent">100%</i></span>
<img v-if="course.status === 4" class="img" src="~@/images/has-cert-new.png" alt="" />
</div>
</div>
<!-- tab栏 -->
<div class="tab-box">
<van-sticky :offset-top="videoH">
<div class="tab-inner">
<div
class="tab-item"
:class="{'tab-active': curtTabIdx === index}"
v-for="(tab, index) in tabs"
:key="index"
@click="curtTabIdx=index">
{{ tab.name }}
</div>
<div class="tab-line" :style="{left: `${tabLeft}px`}"></div>
<DownloadButton v-if="showDownloadButton"></DownloadButton>
</div>
</van-sticky>
</div>
<brief-intro v-show="curtTabIdx === 0" :doctor-list="doctors" :intro="course.intro" :harvest="harvest" />
<course-catalog v-show="curtTabIdx === 1" :list="chapters" :curtId="curtLectureId" :onToggle="onToggle" :onSelect="selectLecture" :download="download" />
<course-ware v-show="curtTabIdx === 2" :url="pdfUrl" :visible="pdfVisible" />
<course-comment v-show="curtTabIdx === 3" :list="qsList" :download="download" />
</div>
</div>
<!-- 打开、下载App -->
<!-- <div class="download-box">
<img src="~@/images/icon-pica.png" alt="logo" />
<div class="content">
<p class="title">云鹊医</p>
<p class="sub-title">高效学习 轻松学医</p>
</div>
<div class="btn-download">下载</div>
<div class="btn-open">打开</div>
</div> -->
<Loading v-if="showLoading" />
</div>
</template>
<script>
import PicaVideo from '@/components/course/pica-video';
import CourseCovers from '@/components/course/course-covers';
import BriefIntro from '@/components/course/brief-intro';
import CourseCatalog from '@/components/course/course-catalog';
import CourseWare from '@/components/course/course-ware';
import CourseComment from '@/components/course/course-comment';
import Loading from "@/components/common/common-loading";
import DownloadButton from "@/components/course/download-button";
import { getPdfFileUrl, formatLeftTimeObj, deepCopy } from '@/utils';
export default {
components: {
PicaVideo,
CourseCovers,
BriefIntro,
CourseCatalog,
CourseWare,
CourseComment,
Loading,
DownloadButton
},
data() {
return {
course: {}, // 课程
doctors: [], // 医生
harvest: [], // 学习收获
tabs: [
{ name: '简介' },
{ name: '目录' },
{ name: '课件' },
{ name: '讨论' },
],
curtTabIdx: 0,
tabW: 0, // tab的宽度
videoH: 0, // 视频区高度
chapters: [], // 目录
curtLectureId: 0, // 当前播放课件id
pdfUrl: '', // 当前pdf
qsList: [], // 讨论列表
coverType: 0, // 遮罩,
showLoading: false,
showDownloadButton: false,
};
},
computed: {
logged() {
return this.$store.getters.logged;
},
tabLeft() {
const num = this.curtTabIdx + 0.5;
return this.tabW * num;
},
// 当前pdf是否可看
pdfVisible() {
const { showFlag, hidePpt } = this.course;
let visible = false;
if (showFlag === 0 && !hidePpt && this.logged) {
visible = true;
}
return visible;
}
},
mounted() {
const { token, info } = this.$store.state.user;
if (token && !info.id) {
this.$store.dispatch('getUserInfo');
}
this.projectId = sessionStorage.getItem('projectId');
if (!this.projectId) {
this.$router.replace('/not-found');
return;
}
this.getCourseInfo();
this.getCourseQas();
const { height } = this.$el.querySelector('.video-box').getBoundingClientRect();
const { width } = this.$el.querySelector('.tab-item').getBoundingClientRect();
this.videoH = height;
this.tabW = width;
this.wechatShare(undefined, undefined, true);
},
methods: {
getCourseInfo() {
const { courseId } = this.$route.query;
const projectId = this.projectId;
this.showLoading = true;
this.GET(`contents/courses/${courseId}/pcCourseInfo`, { projectId }).then(res => {
this.showLoading = false;
this.showDownloadButton = true;
if (res.code == "000000") {
const {
showFlag = 0, // 0可看,10该课程为付费课程-请去App查看,20可试看,激活/购买后才可查看
trySeeFlag = 0, // 1为试看
trySeeTime = 0, // 试看时间
courseHeader = {},
introduction = [],
directory: {
chapters = [], // 目录
lectureResourceList = [], // 课件
lastLecture = {}, // 最后观看记录
},
} = res.data;
let intro = '';
for (let item of introduction) {
if (item.type === 1) { // 医生
this.doctors = item.dataList || [];
}
if (item.type === 2) { // 课程简介
if (item.dataList && item.dataList[0]) {
intro = item.dataList[0]['intro'] || '';
}
}
if (item.type === 4) { // 学习收获
this.harvest = item.dataList || [];
}
}
this.course = { ...courseHeader, intro, showFlag, trySeeFlag, trySeeTime };
const [chaptersAll, curtLecture] = this.getAllChapters(chapters, lectureResourceList, lastLecture, showFlag, trySeeFlag, trySeeTime);
this.chapters = chaptersAll;
this.curtLectureId = curtLecture.lectureId;
this.pdfUrl = curtLecture.courseware ? getPdfFileUrl(curtLecture.courseware.filePath) : '';
// 付费课程-请去App查看;或可试看且时长为0
let enable = true;
if (showFlag === 10 || (trySeeFlag && !trySeeTime)) {
this.coverType = 2;
enable = false
}
let history = 0;
if (curtLecture.progress < 1 && !trySeeTime) {
history = curtLecture.lastTime === 1 ? 0 : curtLecture.lastTime
}
this.$refs.picaVideo.switchUrl({
chapterId: curtLecture.chapterId,
courseId: curtLecture.courseId,
lectureId: curtLecture.lectureId,
url: curtLecture.pathUrl,
proved: trySeeTime,
history,
enable, // 付费课程-请去App查看;或可试看且时长为0
});
} else {
this.$toast(res.message);
}
});
},
// 将课件挂在目录上,获取播放id
getAllChapters(chapters, resList, lastLecture, showFlag, trySeeFlag, trySeeTime) {
const lectureObj = {};
for (let item of resList) {
lectureObj[item.lectureId] = { ...item };
}
let curtLecture = {};
let unfinished = false;
for (let i = 0; i < chapters.length; i++) {
let chapter = chapters[i];
chapter.chapterNameText = `${i + 1}.${chapter.chapterName}`;
chapter.showAll = true;
for (let j = 0; j < chapter.lectures.length; j++) {
let lecture = chapter.lectures[j];
let lectureId = lecture.lectureId;
if (lectureObj[lectureId]) {
lecture.courseware = lectureObj[lectureId]
}
lecture.lectureNameText = `${j + 1}.${lecture.lectureName}`;
lecture.statusText = lecture.progress === 0 ? '未开始' : (lecture.progress === 1 ? '已学完' : `已学${parseInt(lecture.progress * 100)}%`);
let btnText = '';
if (showFlag === 10 || (trySeeFlag && !trySeeTime)) {
btnText = ''; // 不可看
}
if (showFlag === 20 && trySeeFlag && trySeeTime) {
btnText = '试看'; // 可试看
}
if (showFlag === 0) {
btnText = lecture.progress === 1 ? '复习课程' : '学习';
}
lecture.btnText = btnText;
const totalTime = formatLeftTimeObj(lecture.totalTime);
const h = totalTime.h === '00' ? '' : `${totalTime.h}:`;
lecture.totalTimeText = `${h}${totalTime.f}:${totalTime.s}`;
if (lastLecture.lectureId) {
if (lastLecture.lectureId === lecture.lectureId) {
curtLecture = { ...lecture, lastTime: lastLecture.lastTime }
}
} else {
// 取第一个未完成的
if (lecture.progress < 1 && !unfinished) {
curtLecture = { ...lecture };
unfinished = true;
}
}
}
}
return [chapters, curtLecture];
},
btnClick(index) {
const coverType = this.coverType;
switch(coverType) {
case 1:
case 2:
this.download();
break;
case 4:
this.selectLecture(this.prev);
break;
case 5:
if (index === 1) {
window.history.back();
} else {
this.download();
}
break;
default:
//
}
},
// 折叠、展开目录
onToggle(index) {
const item = this.chapters[index];
item.showAll = !item.showAll;
this.chapters.splice(index, 1, item);
},
// 选择课程
selectLecture(lecture, isUserSelect) {
if (isUserSelect && !this.logged) {
this.goLogin();
return;
}
const { showFlag, trySeeFlag, trySeeTime, examType } = this.course;
// console.log(lecture);
if (examType === 2) { // 是考试,mustLearnIds必须完成的lectureId
this.$toast('请前往云鹊医APP进行考试');
return;
}
if (lecture.lectureId === this.curtLectureId) {
return;
}
let enable = true;
if (showFlag === 10 || (trySeeFlag && !trySeeTime)) {
this.coverType = 2;
enable = false
} else {
this.coverType = 0;
}
this.curtLectureId = lecture.lectureId;
this.pdfUrl = lecture.courseware ? getPdfFileUrl(lecture.courseware.filePath) : '';
let history = 0;
if (lecture.progress < 1) {
history = lecture.lastTime === 1 ? 0 : lecture.lastTime
}
this.$refs.picaVideo.switchUrlAndPlay({
chapterId: lecture.chapterId,
courseId: lecture.courseId,
lectureId: lecture.lectureId,
url: lecture.pathUrl,
proved: trySeeTime,
history,
enable, // 付费课程-请去App查看;或可试看且时长为0
});
setTimeout(() => {
this.refreshCatalog();
}, 1000);
},
// 刷新目录进度
refreshCatalog() {
const { courseId } = this.$route.query;
const projectId = this.projectId;
this.GET(`contents/courses/${courseId}/pcCourseInfo`, { projectId }).then(res => {
if (res.code == "000000") {
const {
showFlag = 0, // 0可看,10该课程为付费课程-请去App查看,20可试看,激活/购买后才可查看
trySeeFlag = 0, // 1为试看
trySeeTime = 0, // 试看时间
directory: {
chapters = [], // 目录
lectureResourceList = [], // 课件
lastLecture = {}, // 最后观看记录
},
} = res.data;
const [chaptersAll, curtLecture] = this.getAllChapters(chapters, lectureResourceList, lastLecture, showFlag, trySeeFlag, trySeeTime);
this.chapters = chaptersAll;
}
})
},
getCourseQas() {
const { courseId } = this.$route.query;
const projectId = this.projectId;
this.GET(`contents/courses/v2/${courseId}/qas`, { projectId, pageNo: 1, pageSize: 10 }).then(res => {
if (res.code == "000000") {
this.qsList = res.data.model && res.data.model.qaPostModel || [];
} else {
this.$toast(res.message);
}
});
},
// 视频播放结束
onVideoEnd(opt) {
if (opt.type === 1) {
let chapters = deepCopy(this.chapters);
let curtI = 0;
let curtJ = 0;
let curtIndex = 0;
let count = 0;
let prev; // 第一个未完成的
for (let i = 0; i < chapters.length; i++) {
let lectures = chapters[i]['lectures'];
for (let j = 0; j < lectures.length; j++) {
count += 1;
let lecture = lectures[j];
if (this.curtLectureId === lecture.lectureId) {
curtIndex = count;
curtI = i;
curtJ = j;
lecture.progress = 1;
lecture.statusText = '已学完';
lecture.btnText = '复习课程';
}
if (!prev && lecture.progress < 1) {
prev = { ...lecture }
}
}
}
if (curtIndex === count) { // 最后一个
if (prev) {
this.coverType = 4;
this.prev = prev;
} else {
this.coverType = 5;
this.course.status = 3;
}
} else { // 3秒后播放下一个
let next = chapters[curtI]['lectures'][curtJ + 1] || chapters[curtI + 1]['lectures'][0];
this.coverType = 13;
setTimeout(() => {
this.selectLecture(next);
}, 3000)
}
this.chapters = chapters;
} else if (opt.type === 2) { // 试看结束
this.coverType = 1;
}
},
onReplay() {
this.coverType = 0;
},
goLogin() {
this.$store.dispatch('goLogin');
},
// 去下载app
download() {
window.location.href = "https://a.app.qq.com/o/simple.jsp?pkgname=com.picahealth.yunque";
}
}
};
</script>
<style lang="less" scoped>
.course-detail{
position: relative;
height: 100%;
padding-top: 210px;
box-sizing: border-box;
.video-box{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 210px;
}
.scroll-box{
height: 100%;
overflow-x: hidden;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.scroll-content{
// padding-bottom: 60px;
}
.course-info{
padding: 20px 15px;
border-bottom: 6px solid #F8F9FA;
}
.course-title{
line-height: 23px;
font-size: 18px;
font-weight: bold;
.level{
display: inline-block;
color: #fff;
font-weight: normal;
font-size: 12px;
background-color: #6A9FE9;
margin-right: 5px;
transform: translateY(-2px);
padding: 0 3px;
white-space: nowrap;
border-radius: 1px;
}
}
.course-num{
color: #676869;
font-size: 13px;
margin-top: 10px;
.num{
color: #373839;
}
.percent{
color: #4B9D8F;
}
.img{
float: right;
height: 20px;
}
}
.tab-box{
height: 50px;
}
.tab-inner{
display: flex;
position: relative;
background-color: #fff;
&::after{
position: absolute;
content: "";
left: 0;
bottom: 0;
width: 200%;
height: 0;
border-bottom: 1px solid #F0F1F2;
transform: scale(0.5);
transform-origin: left center;
}
}
.tab-item{
color: #979899;
font-size: 15px;
width: 60px;
height: 50px;
line-height: 50px;
text-align: center;
}
.tab-active{
color: #373839;
font-weight: bold;
}
.tab-line{
position: absolute;
left: 30px;
bottom: 3px;
width: 10px;
height: 3px;
background-color: #449284;
border-radius: 1.5px;
transform: translate3d(-5px, 0, 0);
transition: left 0.3s;
}
.download-box{
display: flex;
align-items: center;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 60px;
background-color: #fff;
img{
display: block;
width: 40px;
height: 40px;
margin: 10px 10px 0 15px;
}
.content{
flex: 1;
width: 50px;
padding-top: 10px;
}
.title{
font-size: 16px;
line-height: 22px;
}
.sub-title{
color: #717171;
font-size: 12px;
line-height: 18px;
}
.btn-download{
color: #449284;
display: inline-block;
height: 30px;
line-height: 30px;
font-size: 14px;
padding: 0 15px;
margin-right: 15px;
border: 1px solid #449284;
border-radius: 15px;
}
.btn-open{
color: #fff;
display: inline-block;
height: 30px;
line-height: 30px;
font-size: 14px;
padding: 0 15px;
margin-right: 15px;
background-color: #449284;
border-radius: 15px;
}
}
.next-countdown{
position: absolute;
color: #fff;
right: 10px;
bottom: 44px;
font-size: 12px;
height: 24px;
line-height: 24px;
padding: 0 12px;
border-radius: 12px;
background-color: #373839;
}
}
</style>
<template>
<!-- 专业选择列表 -->
<div class="page-container">
<CommonNavbar
:bgColor="bgColor"
v-show="isShowNavbar"
:title="navTitle"
:isFixNavbar="isFixNavbar"
:burialPoint="pointStyle"
borderStyle="1px solid #fff"
></CommonNavbar>
<section class="page-content">
<section v-show="!existBind" class="cb-wrapper padding-top-111">
<CardBanner :hasLogin="hasLogin"></CardBanner>
</section>
<section class="body" :class="{'body-pt': !existBind}">
<ul class="left fixed" :class="{'top': !existBind}">
<li
v-for="(model, mIndex) in titleTestModelList"
:key="mIndex"
:class="{active: currentModelIndex == mIndex}"
@click="selectModel(model, mIndex)"
>
<span>{{model.title}}</span>
</li>
</ul>
<ul class="left">
<!-- <li
v-for="(model, mIndex) in titleTestModelList"
:key="mIndex"
:class="{active: currentModelIndex == mIndex}"
@click="selectModel(model, mIndex)"
>
<span>{{model.title}}</span>
</li> -->
</ul>
<article class="right">
<ul class="list-wrapper">
<li class="list" v-for="(item, index) in listData" :key="index">
<span class="title">{{item.name}}</span>
<ul class="item">
<li
:id="'subject_' + index + '_' + sIndex"
:class="{'no-active' : subject.openFlag == 0, 'has-bind' : subject.bindCardStatus == 1}"
v-for="(subject, sIndex) in item.secondSubjectModelList"
:key="sIndex"
@click="coopDetails(subject)"
>
<span>{{subject.name}}</span>
<span>({{subject.code}})</span>
<span v-show="subject.bindCardStatus == 1" class="buy">己购</span>
<span
v-show="subject.openFlag == 0"
class="time"
>{{formatTime(subject.predictTime, '{y}年{m}月')}}上线</span>
</li>
</ul>
</li>
<li class="no-list" v-show="!listData.length">
<img src="../images/subject/no-subject.png" alt />
<span>正在更新中,敬请期待</span>
</li>
</ul>
</article>
</section>
<!-- <section class="body">
<ul class="left-fixed">
<li
v-for="(model, mIndex) in titleTestModelList"
:key="mIndex"
:class="{active: currentModelIndex == mIndex}"
@click="selectModel(model, mIndex)"
>
<span>{{model.title}}</span>
</li>
</ul>
</section> -->
</section>
<transition name="fade">
<article v-show="needShowBackup" @click="scrollTop" class="back-up-icon">
<img src="../images/cme/phrase2/back-top.png" alt />
</article>
</transition>
<Loading v-if="showLoading" />
</div>
</template>
<script>
import CommonNavbar from "@/components/common/common-navbar";
import CardBanner from "@/components/cme/card-banner";
import Loading from "@/components/common/common-loading";
import CommonTitle from "@/components/common/common-title";
import { mapGetters, mapActions } from "vuex";
import { getWebPageUrl, parseTime } from "@/utils/index";
export default {
data() {
return {
existBind: 0,
currentModelIndex: 0,
titleTestModelList: [],
showLoading: false,
isWeb: window.__isWeb,
isAndroid: window.__isAndroid,
isIOS: window.__isIOS,
bgColor: "#fff",
isShow: false,
navTitle: "选择专业",
isShowNavbar: true,
isFixNavbar: true,
pointStyle: "activity",
tabIndex: 1,
joinProjectList: [], // 我的项目
otherProjectList: [], // 全部项目
token: "",
userMobile: "",
needShowBackup: false,
listData: [
{
name: "中医",
list: [
{ name: "全科中医", code: 201, bindStatus: 0 },
{ name: "中医内科学中医内科学", code: 201, bindStatus: 0 },
{ name: "全科中医", code: 201, bindStatus: 0 }
]
},
{
name: "妇科",
list: [
{ name: "妇产科学", code: 201, bindStatus: 0 },
{ name: "中医内科学中医内科学", code: 201, bindStatus: 0 },
{ name: "全科中医", code: 201, bindStatus: 0 }
]
},
{
name: "内科",
list: [
{ name: "肾内科学", code: 201, bindStatus: 0 },
{
name: "肾内科学肾内科学肾内科学肾内科学",
code: 201,
bindStatus: 0
},
{ name: "全科中医", code: 201, bindStatus: 0 }
]
}
],
isInfresh: false,
hasLogin: false,
hasResetPosition: false,
};
},
computed: {
...mapGetters(["userInfo"])
},
components: {
CardBanner,
CommonNavbar,
Loading,
CommonTitle
},
created() {
var _this = this;
_this.currentModelIndex = 0;
window.__getUserInfo = function(param) {
_this.setUserInfo(param);
_this.token = param.userToken;
_this.checkToken();
_this.userMobile = param.userMobile;
_this.getListData();
console.log("__getUserInfo", param);
};
_this.getUserInfo();
if (__isWeb) {
_this.getListData();
}
window.__refresh = function() {
_this.isInfresh = true;
// _this.currentModelIndex = 0;
console.log(_this.currentModelIndex);
_this.getUserInfo();
};
// 打开页面埋点
// this.$sendBuriedData({
// component_tag: "210#0#0#0"
// });
window.addEventListener("scroll", this.scrollFun);
},
mounted() {
this.listData = [];
// this.currentModelIndex = 0;
},
methods: {
...mapActions(["setUserInfo"]),
// 选择职称
selectModel(model, index) {
this.currentModelIndex = index;
this.listData =
this.titleTestModelList[index].firstSubjectModelList || [];
},
// 跳转到项目页面
coopDetails(item) {
if (item.openFlag == 0) return;
// this.$sendBuriedData({
// component_tag: `880#8803#${item.id}#${item.name}` //'210#210002#0#'+item.projectName
// });
// 临时添加
if (window.__isWeb) {
this.$router.push({
path: "/coop",
query: {
id: item.projectId
}
});
return;
}
let appVersion = this.userInfo.appVersion;
let appVersionNum = appVersion.split(".").join("");
console.log("appVersionNum", appVersionNum);
if (appVersionNum < 341) {
Toast("请您下载新版本App");
return;
}
let paramList = [
{
key: "pageUrl",
value: getWebPageUrl(`profexam/#/coop?id=${item.projectId}`),
type: 4,
seqNo: 1
}
];
rocNative.dispatchEventByModuleCode({
modeCode: "M300",
jsonString: paramList
});
},
//获取版本号
getUserInfo() {
rocNative.getUserInfo({
__funcName: "__getUserInfo"
});
},
// 查询列表
getListData() {
let _this = this;
let param = {
token: _this.token,
setEntry: true
};
this.showLoading = true;
this.GET(`portal/titleTestApp/list`, param).then(res => {
this.showLoading = false;
if (res.code == "000000") {
this.existBind = res.data.existBind || 0;
this.titleTestModelList = res.data.titleTestModelList;
// 如果有绑定的卡,并且之前没有做定位,则进行定位
if (this.existBind && !this.hasResetPosition) {
this.hasResetPosition = true;
this.resetPosition(this.titleTestModelList);
// 否则直接使用当前的位置信息
} else {
this.listData = res.data.titleTestModelList[this.currentModelIndex].firstSubjectModelList;
}
} else {
this.message.error(res.message);
}
});
},
// 查找对应的职称与专业
resetPosition(list) {
if (!list.length) return;
let parentIndex = 0,
fIndex = 0,
subIndex = 0,
firstSub = [],
secondSub = [];
outloop: for (let i = 0; i < list.length; i++) {
firstSub = list[i].firstSubjectModelList;
for (let j = 0; j < firstSub.length; j++) {
secondSub = firstSub[j].secondSubjectModelList;
for (let k = 0; k < secondSub.length; k++) {
if (secondSub[k].bindCardStatus) {
parentIndex = i;
fIndex = j;
subIndex = k;
break outloop;
}
}
}
}
this.currentModelIndex = parentIndex;
this.listData = this.titleTestModelList[parentIndex].firstSubjectModelList || [];
this.$forceUpdate();
this.resetProjectPosition(fIndex, subIndex);
},
// 将定位到的元素,滚动到最上面
resetProjectPosition(fIndex, subIndex) {
this.$nextTick(() => {
setTimeout(() => {
let scrollTop = document.getElementById(`subject_${fIndex}_${subIndex}`).offsetTop;
window.scrollTo(0, scrollTop - 120);
}, 100);
});
},
// 监听滚动事件
scrollFun() {
let scrollTop = window.scrollY;
if (scrollTop >= 500) {
this.needShowBackup = true;
} else {
this.needShowBackup = false;
}
},
// 滚动到顶部
scrollTop() {
window.scrollTo(0, 0);
},
// 格式化时间
formatTime(time, cFormat) {
return parseTime(time, cFormat);
},
// token是否失效校验
checkToken() {
let _this = this;
let param = {
token: _this.userInfo.userToken || _this.token,
setEntry: true
};
this.GET("campaign/admin/task/checkToken", param).then(res => {
if (res.code !== "000000") {
//未登录 跳转登录页
console.log("跳登录", _this.isInfresh);
if (_this.isInfresh) {
rocNative.goBack();
} else {
rocNative.gotoLogin();
}
_this.isInfresh = false;
} else {
_this.hasLogin = true;
}
});
}
}
};
</script>
<style lang="scss" scoped>
@import "../style/mixin";
.page-content {
padding-top: px2rem(74px);
min-height: 100vh;
.body {
// min-height: 90vh;
display: flex;
flex-direction: row;
font-size: px2rem(14px);
color: #676869;
&.body-pt {
padding-top: px2rem(40px);
}
.left {
width: px2rem(130px);
background: #fff;
li {
position: relative;
display: block;
height: px2rem(60px);
line-height: px2rem(60px);
padding-left: px2rem(15px);
&.active {
color: #449284;
background: #fff;
&.active::before {
position: absolute;
left: 0;
top: px2rem(20px);
z-index: 1;
content: "";
height: px2rem(20px);
width: px2rem(3px);
border-radius: px2rem(2px);
background: #449284;
}
}
}
&.fixed {
position: fixed;
top: px2rem(74px);
left: 0;
bottom: 0;
right: px2rem(130px);
z-index: 1;
background: #f8f9fa;
&.top {
top: px2rem(114px);
}
}
}
.right {
flex: 1;
padding: 0 px2rem(15px) px2rem(30px);
.list-wrapper {
.list {
.title {
display: inline-block;
// height: px2rem(35px);
padding: px2rem(6px) 0 px2rem(10px);
line-height: px2rem(1.2);
margin-top: px2rem(14px);
font-size: px2rem(15px);
font-weight: 700;
}
.item {
li {
position: relative;
top: 0;
left: 0;
z-index: 1;
display: flex;
flex-direction: column;
// height: px2rem(55px);
padding: px2rem(12px) 0;
margin-bottom: px2rem(6px);
justify-content: center;
text-align: center;
border-radius: px2rem(4px);
background: #f8f9fa;
align-items: center;
span {
display: inline-block;
// height: px2rem(20px);
line-height: px2rem(20px);
padding: 0 px2rem(20px);
}
&.has-bind {
color: #449284;
background: rgba(68, 146, 132, 0.1);
.buy {
position: absolute;
top: 0;
right: 0;
z-index: 1;
height: px2rem(15px);
line-height: px2rem(15px);
padding: 0 px2rem(4px);
border-radius: 0px px2rem(4px) 0px px2rem(4px);
font-size: px2rem(11px);
color: #fff;
background: #449284;
}
}
&.no-active {
color: #c7c8c9;
.time {
position: absolute;
top: 0;
right: 0;
z-index: 1;
height: px2rem(15px);
line-height: px2rem(15px);
padding: 0 px2rem(4px);
border-radius: 0px px2rem(4px) 0px px2rem(4px);
opacity: 0.4;
font-size: px2rem(11px);
background: rgba(0, 0, 0, 1);
}
}
}
}
}
.no-list {
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
align-items: center;
margin-top: px2rem(30px);
// width: px2rem(50px);
// height: px2rem(50px);
img {
width: px2rem(100px);
height: px2rem(100px);
}
span {
font-size: px2rem(12px);
color: #c7c8c9;
}
}
}
}
}
.cb-wrapper {
position: fixed;
z-index: 2;
width: 100%;
}
}
.back-up-icon {
position: fixed;
z-index: 10;
bottom: px2rem(50px);
right: px2rem(15px);
img {
width: px2rem(35px);
height: px2rem(35px);
}
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
</style>
......@@ -248,7 +248,8 @@ export default {
this.showLoading = false;
if (res.code == "000000") {
this.existBind = res.data.existBind || 0;
this.titleTestModelList = res.data.titleTestModelList;
this.titleTestModelList = res.data.titleTestModelList || [];
let len = this.titleTestModelList.length > 0 ? (this.titleTestModelList.length - 1) : 0;
// 如果有绑定的卡,并且之前没有做定位,则进行定位
if (this.existBind && !this.hasResetPosition) {
this.hasResetPosition = true;
......@@ -257,11 +258,12 @@ export default {
} else {
this.listData =
res.data.titleTestModelList[
this.currentModelIndex
len
].firstSubjectModelList;
this.currentModelIndex = len;
}
} else {
this.message.error(res.message);
this.$toast(res.message);
}
});
},
......@@ -362,96 +364,94 @@ export default {
}
};
</script>
<style lang="scss" scoped>
@import "../style/mixin";
<style lang="less" scoped>
.page-content {
padding-top: px2rem(74px);
padding-top: 74px;
min-height: 100vh;
.body {
// min-height: 90vh;
display: flex;
flex-direction: row;
font-size: px2rem(14px);
font-size: 14px;
color: #676869;
&.body-pt {
padding-top: px2rem(40px);
padding-top: 40px;
}
.left {
width: px2rem(130px);
width: 130px;
background: #fff;
li {
position: relative;
display: block;
height: px2rem(60px);
line-height: px2rem(60px);
padding-left: px2rem(15px);
height: 60px;
line-height: 60px;
padding-left: 15px;
&.active {
color: #449284;
background: #fff;
&.active::before {
position: absolute;
left: 0;
top: px2rem(20px);
top: 20px;
z-index: 1;
content: "";
height: px2rem(20px);
width: px2rem(3px);
border-radius: px2rem(2px);
height: 20px;
width: 3px;
border-radius: 2px;
background: #449284;
}
}
}
&.fixed {
position: fixed;
top: px2rem(74px);
top: 74px;
left: 0;
bottom: 0;
right: px2rem(130px);
right: 130px;
z-index: 1;
background: #f8f9fa;
&.top {
top: px2rem(114px);
top: 114px;
}
}
}
.right {
flex: 1;
padding: 0 px2rem(15px) px2rem(30px);
padding: 0 15px 30px;
.list-wrapper {
.list {
.title {
display: inline-block;
// height: px2rem(35px);
padding: px2rem(6px) 0 px2rem(10px);
// line-height: px2rem(1.2);
margin-top: px2rem(14px);
font-size: px2rem(15px);
// height: 35px;
padding: 6px 0 10px;
// line-height: 1.2;
margin-top: 14px;
font-size: 15px;
font-weight: 700;
color: #373839;
}
.item {
li {
min-height: px2rem(60px);
min-height: 60px;
position: relative;
top: 0;
left: 0;
z-index: 1;
display: flex;
flex-direction: column;
// height: px2rem(55px);
padding: px2rem(12px) 0;
margin-bottom: px2rem(6px);
// height: 55px;
padding: 12px 0;
margin-bottom: 6px;
justify-content: center;
text-align: center;
border-radius: px2rem(4px);
border-radius: 4px;
background: #f8f9fa;
align-items: center;
span {
display: inline-block;
// height: px2rem(20px);
line-height: px2rem(20px);
padding: 0 px2rem(20px);
// height: 20px;
line-height: 20px;
padding: 0 20px;
}
&.has-bind {
color: #449284;
......@@ -461,11 +461,11 @@ export default {
top: 0;
right: 0;
z-index: 1;
height: px2rem(15px);
line-height: px2rem(15px);
padding: 0 px2rem(4px);
border-radius: 0px px2rem(4px) 0px px2rem(4px);
font-size: px2rem(11px);
height: 15px;
line-height: 15px;
padding: 0 4px;
border-radius: 0px 4px 0px 4px;
font-size: 11px;
color: #fff;
background: #449284;
}
......@@ -477,12 +477,12 @@ export default {
top: 0;
right: 0;
z-index: 1;
height: px2rem(15px);
line-height: px2rem(15px);
padding: 0 px2rem(4px);
border-radius: 0px px2rem(4px) 0px px2rem(4px);
height: 15px;
line-height: 15px;
padding: 0 4px;
border-radius: 0px 4px 0px 4px;
opacity: 0.4;
font-size: px2rem(11px);
font-size: 11px;
background: rgba(0, 0, 0, 1);
}
}
......@@ -496,15 +496,15 @@ export default {
justify-content: center;
align-content: center;
align-items: center;
margin-top: px2rem(60px);
// width: px2rem(50px);
// height: px2rem(50px);
margin-top: 60px;
// width: 50px;
// height: 50px;
img {
width: px2rem(100px);
height: px2rem(100px);
width: 100px;
height: 100px;
}
span {
font-size: px2rem(12px);
font-size: 12px;
color: #c7c8c9;
}
}
......@@ -520,11 +520,11 @@ export default {
.back-up-icon {
position: fixed;
z-index: 10;
bottom: px2rem(50px);
right: px2rem(15px);
bottom: 50px;
right: 15px;
img {
width: px2rem(35px);
height: px2rem(35px);
width: 35px;
height: 35px;
}
}
.fade-enter-active,
......
......@@ -11,7 +11,10 @@
:shareTitle="project.projectName"
:shareTitleInfo="project.projectIntro"
:isFixNavbar="isFixNavbar"
:shareUrl="shareUrl"
:burialPoint="pointStyle"
:projectId="projectId"
:limitTimes="limitTimes"
borderStyle="0px solid #fff"
:backMethod="from"
></CommonNavbar>
......@@ -27,7 +30,7 @@
<div class="sk-btn-cover-new" @click="continueStudy()" v-if="bannerType == 2 && hasBindCard">
<!-- <div class="sk-btn-cover-new" @click="continueStudy()" > -->
<span :class="{'android': isAndroid}">继续学习</span>
</div>
</div>
<!-- 项目标题 -->
<CommonDescription
:projectName="project.projectName"
......@@ -141,7 +144,7 @@
cancleBtnText="我知道了"
:isShowDialog="isShowIOSDownloadDialog"
@handlerAction="goBack"
/>
/>
</div>
</template>
<script>
......@@ -184,7 +187,7 @@ export default {
textContent: "",
leaderText: "",
pageTitle: "",
isShowShare: false,
isShowShare: true,
tabFlag: true, // 显示目录还是简介
fixedFlag: false, // 目录和简介是否固定
project: {
......@@ -265,6 +268,7 @@ export default {
skCourseId: 0,
isShowSkDialog: false,
isShowIOSDownloadDialog: false,
shareUrl: location.href,
};
},
components: {
......@@ -308,7 +312,7 @@ export default {
// 如果是iOS系统并且版本小于344,则提示升级
if(__isIOS && appVersionNum < 344) {
_this.isShowIOSDownloadDialog = true;
}
}
_this.setUserInfo(param);
_this.checkToken();
_this.getProjectInfoById();
......@@ -552,7 +556,7 @@ export default {
seqNo: 1
}
];
this.$refs.tcPlayerRef && this.$refs.tcPlayerRef.pause();
this.$refs.tcPlayerRef && this.$refs.tcPlayerRef.pause();
rocNative.dispatchEventByModuleCode({
modeCode: "M200",
jsonString: paramList
......@@ -739,7 +743,7 @@ export default {
param.trySeeFlag = 0;
} else {
param.trySeeFlag = 1;
}
}
console.log('getProjectInfoById', param);
_this.showLoading = true;
this.NEW_GET(`cme/project/${_this.projectId}/info`, param).then(res => {
......@@ -974,8 +978,8 @@ export default {
if(this.continueStudyType == 1) {
this.gotoExamNew();
} else {
this.gotoCourseNew();
}
this.gotoCourseNew();
}
},
// 跳转到考试
......@@ -1015,8 +1019,8 @@ export default {
// message: '激活/购买后可学习完整课程',
message: '升级最新版本可试看课程',
confirmButtonText: '我知道了',
}).then(res => {
}).then(res => {
})
return;
}
......@@ -1074,88 +1078,87 @@ export default {
goBack() {
this.isShowIOSDownloadDialog = false;
rocNative.goBack();
}
}
}
};
</script>
<style lang="scss" scoped>
@import "../style/mixin";
<style lang="less" scoped>
.page-container-merge {
.nav-top .nav-title {
height: px2rem(0px);
// padding: px2rem(18px);
height: 0px;
// padding: 18px;
}
.banner-img {
display: inherit;
width: px2rem(375px);
height: px2rem(210px);
width: 375px;
height: 210px;
&-1 {
position: absolute;
left: 0;
top: px2rem(180px);
width: px2rem(76px);
height: px2rem(30px);
top: 180px;
width: 76px;
height: 30px;
}
&-5 {
position: absolute;
left: 0;
top: px2rem(180px);
width: px2rem(76px);
height: px2rem(30px);
top: 180px;
width: 76px;
height: 30px;
}
&-10 {
position: absolute;
left: 0;
top: px2rem(180px);
width: px2rem(76px);
height: px2rem(30px);
top: 180px;
width: 76px;
height: 30px;
}
}
.list-container {
// margin-bottom: px2rem(40px);
// margin-bottom: 40px;
.sk-btn-cover-new {
position: absolute;
top: 0;
left: 0;
right: 0;
height: px2rem(210px);
height: 210px;
z-index: 100;
text-align: center;
// background: #fff;
font-size: px2rem(13px);
font-size: 13px;
// border-radius: 50%;
background: rgba(51, 51, 51, 0.8);
span {
display: inline-block;
margin-top: px2rem(82px);
width: px2rem(100px);
height: px2rem(36px);
line-height: px2rem(36px);
font-size: px2rem(15px);
margin-top: 82px;
width: 100px;
height: 36px;
line-height: 36px;
font-size: 15px;
font-weight: 700;
border-radius: px2rem(20px);
border-radius: 20px;
color: #fff;
background: #449284;
&.android {
padding-top: px2rem(2px);
padding-top: 2px;
}
}
}
}
}
.intro-catalogue-container {
.title {
height: px2rem(50px);
line-height: px2rem(30px);
padding: 0 px2rem(15px);
height: 50px;
line-height: 30px;
padding: 0 15px;
border-bottom: 1px solid #f0f1f2;
span {
display: inline-block;
line-height: px2rem(15px);
font-size: px2rem(15px);
line-height: 15px;
font-size: 15px;
color: #979899;
padding-right: px2rem(35px);
padding-right: 35px;
}
span.focus {
position: relative;
......@@ -1164,19 +1167,19 @@ export default {
span.focus:after {
content: "";
position: absolute;
left: px2rem(9px);
bottom: px2rem(-14px);
left: 9px;
bottom: -14px;
background: #449284;
// border-bottom: px2rem(1px) solid #449284;
width: px2rem(10px);
height: px2rem(3px);
border-radius: px2rem(3px);
// border-bottom: 1px solid #449284;
width: 10px;
height: 3px;
border-radius: 3px;
}
}
.title.fixed-title-1 {
position: fixed;
left: 0;
top: px2rem(60px);
top: 60px;
background: #fff;
width: 100%;
z-index: 999;
......@@ -1184,40 +1187,40 @@ export default {
.title.fixed-title-2 {
position: fixed;
left: 0;
top: px2rem(0px);
top: 0px;
background: #fff;
width: 100%;
z-index: 999;
}
.catalogue-content {
padding: 0 px2rem(15px);
padding: 0 15px;
.catalogue-title {
// display: flex;
// flex-direction: row;
// align-items: center;
// align-content: center;
margin-top: px2rem(5px);
// margin-bottom: px2rem(16px);
margin-top: 5px;
// margin-bottom: 16px;
.c-title {
font-size: px2rem(18px);
font-size: 18px;
color: #373839;
font-weight: 700;
}
.c-sub {
margin-left: px2rem(-6px);
font-size: px2rem(12px);
margin-left: -6px;
font-size: 12px;
color: #979899;
}
}
}
.fixed-flag-height {
height: px2rem(50px);
height: 50px;
}
}
}
.no-more-bottom {
position: relative;
width: 100%;
height: px2rem(40px);
height: 40px;
}
</style>
<template>
<div class="not-found">
<img class="img" src="~@/images/no-content.png" alt="" />
<p class="tip">此课程已下架,无法查看</p>
</div>
</template>
<script>
export default {
data() {
return {};
},
mounted() {
},
methods: {
}
};
</script>
<style lang="less" scoped>
.not-found {
.img{
display: block;
width: 120px;
margin: 100px auto 0;
}
.tip{
font-size: 15px;
text-align: center;
}
}
</style>
<template>
<!-- 组件详情页面:模块列表及其下面的元件列表 -->
<div class="page-container-merge">
<div class="page-container-merge" >
<CommonNavbar
id="header"
:bgColor="bgColor"
......@@ -23,11 +23,26 @@
<img v-show="project.status == 10" class="banner-img-10" src="../images/status-end-cme.png" />
</div>
<!-- banner视频 -->
<CommonTcPlayer ref="tcPlayerRef" v-if="bannerType == 2" style="flex" :options="videoOptions" @sk-tip="isShowSkDialog=true"></CommonTcPlayer>
<div class="sk-btn-cover-new" @click="continueStudy()" v-if="bannerType == 2 && hasBindCard">
<!-- <div class="sk-btn-cover-new" @click="continueStudy()" > -->
<div class="video-box" v-if="bannerType == 2">
<pica-video ref="picaVideo" :coverType="coverType" :download="download" @onVideoEnd="onVideoEnd" @onReplay="onReplay">
<!-- 试看结束 -->
<div class="cover" v-if="logged && coverType === 1">
<course-covers coverTips="试看结束<br />请来云鹊医App学习完整课程" :isSingle="true" rightBtnText="学习完整课程" @btnClick="btnClick" />
</div>
<!-- 播放结束,下载App -->
<div class="cover" v-if="logged && coverType === 2">
<course-covers coverTips="播放结束<br />更多其他课程,请前往鹊医App学习" :isSingle="true" rightBtnText="去云鹊医App" @btnClick="btnClick" />
</div>
<!-- 未登录 -->
<div class="cover" v-if="!logged">
<course-covers coverTips="登录后马上学习课程" :isSingle="true" rightBtnText="去登录" @btnClick="goLogin" />
</div>
</pica-video>
</div>
<!-- <div class="sk-btn-cover-new" @click="continueStudy()" v-if="bannerType == 2 && hasBindCard">
<span :class="{'android': isAndroid}">继续学习</span>
</div>
</div> -->
<!-- 项目标题 -->
<CommonDescription
:projectName="project.projectName"
......@@ -44,6 +59,7 @@
>
<span :class="{'focus': tabFlag}" @click="jumpIntro">简介</span>
<span :class="{'focus': !tabFlag}" @click="jumpCatalogue">目录</span>
<DownloadButton v-if="showDownloadButton"></DownloadButton>
</div>
<div v-show="fixedFlag" class="fixed-flag-height"></div>
<div id="intro-content" class="intro-content">
......@@ -76,13 +92,15 @@
<span class="c-title">目录</span>
<span v-if="needShowUpdate" class="c-sub">每周更新课程</span>
</div>
<CellListDetail
<CellListDetailShare
:projectComponent="projectComponentDTOS"
:actionList="actionList"
:detailNum="detailNum"
:courseRequire="courseRequire"
:hasBindCard="hasBindCard"
:limitTimes="limitTimes"
:logged="logged"
:projectId="projectId"
/>
</div>
</div>
......@@ -92,31 +110,34 @@
<div v-if="detailNum <= 9" class="no-more-bottom"></div>
</div>
<!-- <ExjumperButton
@btnClick="beforeJumpToExam"
v-if="hasBindCard"
:btnText="project.currentProgress > 1 ? '参加考试' : '学完全部课程,可参加考试'"
:type="project.currentProgress > 1 ? 'primary' : 'disabled'"
></ExjumperButton> -->
<div v-if="!hasBindCard && !isWeb" style="padding-top: 30px"></div>
<div v-if="!hasBindCard" style="padding-top: 60px"></div>
<!-- <div v-if="!hasBindCard && !isWeb" style="padding-top: 30px"></div> -->
<BindCardButton
<!-- <BindCardButton
v-if="!hasBindCard && !isWeb"
:cardInfo="cardInfo"
@changeClick="changeClick"
@gotoBuy="confirm"
></BindCardButton>
></BindCardButton>-->
<BindCardButtonShare
v-if="!hasBindCard"
:cardInfo="cardInfo"
@changeClick="changeClick"
@gotoBuy="confirm"
></BindCardButtonShare>
<!--去激活-->
<ChangeCard
:changeErrorMsg="changeCardErrorMsg"
:isShow="showChangeCard"
@cancle="cancleChangeCard"
@confirm="changeCardAction">
</ChangeCard>
@confirm="changeCardAction"
></ChangeCard>
<Loading v-show="showLoading" />
<div>
<span ref="copyLinkBtn"
<span
ref="copyLinkBtn"
data-clipboard-action="copy"
class="cobyOrderSn"
:data-clipboard-text="this.project.cardKey"
......@@ -124,24 +145,41 @@
></span>
</div>
<ShiKanCommonDialog
class="shikan"
needSubContent
content="试看结束"
subContent="购买后可看完整课程"
confirmBtnText="去购买"
:isShowDialog="isShowSkDialog"
@handlerAction="goBuyKc"
/>
<IOSDownloadDialog
class="shikan"
isSingle
content="请您下载新版本App"
cancleBtnText="我知道了"
:isShowDialog="isShowIOSDownloadDialog"
@handlerAction="goBack"
/>
<!-- 未登录提示 -->
<div class="course-tips" v-if="!logged">
<CourseCovers isSingle coverTips="登录后马上学习课程" rightBtnText="去登录" @btnClick="btnClick"></CourseCovers>
</div>
<!-- 试看结束 -->
<div class="course-tips" v-if="isShowSkDialog">
<CourseCovers
isSingle
coverTips="试看结束<br>学习完整版课程,请来云鹊医App购买"
rightBtnText="APP购买更优惠"
@btnClick="download(1)"
></CourseCovers>
</div>
<!-- 播放结束 -->
<div class="course-tips" v-if="isShowEndDialog">
<CourseCovers
isSingle
coverTips="播放结束<br>更多其他课程,请前往云鹊医APP学习"
rightBtnText="APP购买更优惠"
@btnClick="download(1)"
></CourseCovers>
</div>
<!-- 本课程为付费课程 -->
<div class="course-tips" v-if="isShowFFDialog">
<CourseCovers
isSingle
coverTips="本课程为付费课程<br>学习完整版课程,请来云鹊医App购买"
rightBtnText="APP购买更优惠"
@btnClick="download(1)"
></CourseCovers>
</div>
</div>
</template>
<script>
......@@ -149,8 +187,7 @@ import CommonNavbar from "@/components/common/common-navbar";
import CommonDescription from "@/components/common/common-description";
import CommonSpliteLine from "@/components/common/common-splite-line";
import CellListDetail from "@/components/business/cell-list-detail";
import CommonTcPlayer from "@/components/common/common-tcplayer";
import CellListDetailShare from "@/components/business/cell-list-detail-share";
import Loading from "@/components/common/common-loading";
import BasicInfo from "@/components/cme/basic-info";
......@@ -162,15 +199,18 @@ import CommonDialog from "@/components/cme/common-dialog";
import ExjumperButton from "@/components/cme/exjumper-button";
import NoMoreContent from "@/components/business/no-more-content";
import CommonAdertImg from "@/components/common/common-advert-img";
import ShiKanCommonDialog from "@/components/cme/common-dialog";
import IOSDownloadDialog from "@/components/cme/common-dialog";
import { getWebPageUrl, gotoPage, getAppVersion } from "@/utils/index";
import { mapGetters, mapActions } from "vuex";
import vueFilters from "@/utils/filter";
import { Toast } from "vant";
import BindCardButton from "@/components/cme/bind-card-button";
import BindCardButtonShare from "@/components/cme/bind-card-button-share";
import ChangeCard from "@/components/cme/change-card";
import CourseCovers from "@/components/course/course-covers";
import DownloadButton from "@/components/course/download-button";
import PicaVideo from '@/components/course/pica-video';
import { getCookie } from '@/utils/index';
let cataOffsetTop = 0;
let intorOffsetTop = 0;
let titleOffsetHeight = 50;
......@@ -178,13 +218,14 @@ let titleOffsetHeight = 50;
export default {
data() {
return {
// token: "9B62E5874DA94979A54DB3E9DFC1443F",
coverType: 0,
downloadTips: "打开云鹊医APP",
isWeb: window.__isWeb,
isAndroid: __isAndroid,
textContent: "",
leaderText: "",
pageTitle: "",
isShowShare: false,
isShowShare: true,
tabFlag: true, // 显示目录还是简介
fixedFlag: false, // 目录和简介是否固定
project: {
......@@ -213,7 +254,7 @@ export default {
firstIntoExam: false, // true弹框,是否首次进入考试,用于首次跳转弹框提示,只跟项目和人员有关
jumpToContents: false, // 是否跳转到目录
cardStatus: 0,
cardKey: '',
cardKey: ""
},
hasBindCard: false, // 是否绑定过学习卡或激活过 没有绑定,则显示绑定按钮
limitTimes: 60,
......@@ -225,16 +266,19 @@ export default {
projectId: "1",
contentList: [],
//moduleName: "",
bannerType: 1, // 1 图片 2视频
bannerType: 2, // 1 图片 2视频
videoOptions: {
mp4: "",
autoplay: true, //iOS下safari浏览器,以及大部分移动端浏览器是不开放视频自动播放这个能力的
autoplay: false, //iOS下safari浏览器,以及大部分移动端浏览器是不开放视频自动播放这个能力的
coverpic: require("../images/video-cover.png"),
width: "415", //视频的显示宽度,请尽量使用视频分辨率宽度
height: "210" //视频的显示高度,请尽量使用视频分辨率高度
height: "210", //视频的显示高度,请尽量使用视频分辨率高度
trySeeTime: "",
x5_fullscreen: false
},
//projectStatus: 1, //1没有获得证书 2是获得全部证书
attachmentUrl: require("../images/banner-default.png"),
// attachmentUrl: require("../images/banner-default.png"),
attachmentUrl: require("../images/video-cover.png"),
bgColor: "none",
navTitle: "项目详情",
// compTitle: "组件名称",
......@@ -261,16 +305,20 @@ export default {
needShowUpdate: false,
skCourseId: 0,
isShowSkDialog: false,
isShowIOSDownloadDialog: false,
isShowEndDialog: false,
isShowFFDialog: false,
needShort: false,
showDownloadButton: false,
uuid: '',
token: ''
};
},
components: {
CommonNavbar,
CommonDescription,
CommonSpliteLine,
CellListDetail,
CellListDetailShare,
Loading,
CommonTcPlayer,
BasicInfo,
LearnKnow,
ItemIntro,
......@@ -280,70 +328,88 @@ export default {
ExjumperButton,
CommonAdertImg,
NoMoreContent,
BindCardButton,
BindCardButtonShare,
ChangeCard,
ShiKanCommonDialog,
IOSDownloadDialog
CourseCovers,
DownloadButton,
PicaVideo
},
computed: {
...mapGetters(["userInfo"])
...mapGetters(["userInfo", "logged"])
},
created() {
let _this = this;
this.from = this.$route.query.from || this.from || "native";
this.projectId = this.$route.query.id || 1;
console.log('#######location', location);
window.__getUserInfo64Comp = function(param) {
// appVersion 安卓 3.2.2 iOS
console.log("__getUserInfo64Comp", param);
_this.token = param.userToken;
let appVersion = param.appVersion || '300';
let appVersionNum = appVersion.split(".").join("");
// 如果是iOS系统并且版本小于344,则提示升级
if(__isIOS && appVersionNum < 344) {
_this.isShowIOSDownloadDialog = true;
}
_this.setUserInfo(param);
_this.checkToken();
_this.getProjectInfoById();
};
_this.getUserInfo();
// if (__isWeb && process.env.BUILD_ENV == "development") {
// let param = {};
// __getUserInfo64Comp(param);
// }
if (__isWeb) {
_this.getProjectInfoById();
let href = location.href;
let uuidIndex = href.indexOf('uuid') || 0;
if(uuidIndex > 0) {
this.uuid = href.substr(uuidIndex + 5, 32);
} else {
this.uuid = '07F9625472D6444EBAE4BF7D2EF83BC4'
}
if(href.indexOf('singlemessage') >= 0 || href.indexOf('wx_code') >= 0) {
let shareUrl = getWebPageUrl(`profexam/#/sharecoop?uuid=${this.uuid}`);
location.replace(shareUrl);
}
window.__refresh = function() {
_this.isInfresh = true;
_this.getUserInfo();
};
window.__getPositionData = function(param) {
console.log(param);
// _this.showLoading = false;
param.setEntry = true;
_this.getProvinceIdByPosition(param);
};
const { token, info } = this.$store.state.user;
this.token = getCookie('token') || token;
// 如果有token,但没有用户信息,则获取用户信息
if (this.token && !info.id) {
this.$store.dispatch('setToken', this.token);
// this.$store.dispatch('getUserInfo');
}
this.queryByUuid(this.uuid);
// 调用广告位接口
this.getAdvertInfoList();
},
mounted() {
window.addEventListener("scroll", this.scrollFun);
const _this = this;
},
beforeDestroyed() {
window.removeEventListener("scroll", this.scrollFun);
},
methods: {
...mapActions(["setUserInfo"]),
...mapActions(["setUserInfo", "goLogin"]),
// 解析uuid
queryByUuid(uuid) {
let param = {
uuid: uuid
};
this.GET(`portal/shareParam/queryByUuid`, param).then(res => {
if (res.code == "000000") {
this.shareParam = JSON.parse(res.data || "{}");
this.projectId = this.shareParam.projectId || 0; // 797
this.getProjectInfoById();
console.log('queryByUuid', res);
}
});
},
// 视频播放结束
onVideoEnd(opt) {
if (opt.type === 1) {
this.coverType = 2;
} else if (opt.type === 2) { // 试看结束
this.coverType = 1;
}
},
onReplay() {
this.coverType = 0;
},
btnClick() {
this.download();
},
download() {
window.location.href =
"https://a.app.qq.com/o/simple.jsp?pkgname=com.picahealth.yunque";
},
// 关闭激活弹框
cancleChangeCard() {
this.showChangeCard = false;
},
......@@ -358,21 +424,22 @@ export default {
setEntry: true
};
_this.changeCardErrorMsg = "";
this.POST("cme/projectCard/bind", param).then(res => {
if (res.code == "000000") {
if(res.data == 0) {
_this.changeCardErrorMsg = "请输入正确的激活码";
this.POST("cme/projectCard/bind", param)
.then(res => {
if (res.code == "000000") {
if (res.data == 0) {
_this.changeCardErrorMsg = "请输入正确的激活码";
} else {
_this.showChangeCard = false;
Toast("激活成功,开始学习");
_this.getProjectInfoById();
}
} else {
_this.$refs.tcPlayerRef && _this.$refs.tcPlayerRef.pause();
_this.showChangeCard = false;
Toast("激活成功,开始学习");
_this.getProjectInfoById();
}
} else {
}
}).catch( e => {
_this.changeCardErrorMsg = "请输入正确的激活码";
});
})
.catch(e => {
_this.changeCardErrorMsg = "请输入正确的激活码";
});
},
// 复制卡密
......@@ -402,84 +469,9 @@ export default {
});
},
// 点击“参与考试”
beforeJumpToExam() {
// this.$sendBuriedData({
// component_tag: `882#8824`
// });
// 如果是首次,则弹出弹框
this.jumpToCardList();
},
// 跳转II类学习详情页面(跳转的页面由后面配置)
jumpToCardList() {
// this.$sendBuriedData({
// component_tag: `885#8851`
// });
this.showLoading = false;
// 判断版本号,如果小于3.4.0,则只做提示
let appVersion = this.userInfo.appVersion;
let appVersionNum = appVersion.split(".").join("");
if (appVersionNum < 341) {
Toast("请您下载新版本App");
return;
}
// 复制卡密
this.$refs.copyLinkBtn.click();
setTimeout(() => {
if (window.__isWeb) {
return;
} else {
let pageUrl = this.project.examBtnUrl;
let paramList = [
{
key: "pageUrl",
value: pageUrl,
type: 4,
seqNo: 1
},
// 此字段不配置,则用原来的逻辑
{
key: "needCache",
value: "1", // 0不缓存,其它值都做缓存
type: 4,
seqNo: 1
}
];
rocNative.dispatchEventByModuleCode({
modeCode: "M300",
jsonString: paramList
});
}
}, 1000);
},
// 跳转前判断是否有机构,否则使用定位信息
preJumper() {
// TODO 测试代码
if (window.__isWeb) {
this.getCardInfoByProvinceId(310);
} else {
if (this.organizationId != 0 && this.provinceId != 0) {
this.getCardInfoByProvinceId(this.provinceId);
} else {
this.getPositionData();
}
}
},
// 根据位置信息获取省ID
getProvinceIdByPosition(param) {
param.setEntry = true;
this.POST("aggregate/cme/convertLocationToProvinceId", param).then(
res => {
if (res.code == "000000") {
this.getCardInfoByProvinceId(res.data);
}
}
);
this.getCardInfoByProvinceId(this.provinceId || "");
},
// 根据省ID,获取学习卡信息
......@@ -499,102 +491,19 @@ export default {
});
},
// 获取地理位置信息
getPositionData() {
// this.showLoading = true;
console.log("getPositionData");
rocNative.getPositionData({
__funcName: "__getPositionData"
});
},
// 跳转到原生的购买页面
confirm() {
this.$sendBuriedData({
component_tag: `882#88203`
});
let appVersion = this.userInfo.appVersion || "";
let appVersionNum = appVersion.split(".").join("");
if (appVersionNum < 344) {
Toast("请您下载新版本App");
return;
}
// let pageUrl = this.project.examBtnUrl;
// 直接传入项目ID(projectId)
let projectId = this.project.projectId;
let pageUrl = getWebPageUrl(
`/profexam/#/index?id=${projectId}&projectName=${this.project.projectName}&profexamProjectId=${projectId}`
);
let paramList = [
{
key: "className",
value:
"com.picahealth.yunque.activitys.studycard.StudyCardDetailActivity###PicaDo.LearningCardVC",
type: 4,
seqNo: 1
},
{
key: "goodId",
value: this.cardInfo.id,
type: 4,
seqNo: 1
},
{
key: "courseUrl",
value: encodeURIComponent(pageUrl),
// value: projectId,
type: 4,
seqNo: 1
}
];
this.$refs.tcPlayerRef && this.$refs.tcPlayerRef.pause();
rocNative.dispatchEventByModuleCode({
modeCode: "M200",
jsonString: paramList
});
},
// 跳转到原生的购买页面
confirmOld() {
// this.$sendBuriedData({
// component_tag: `885#8852`
// component_tag: `882#88203`
// });
let pageUrl = this.project.examBtnUrl;
let paramList = [
{
key: "className",
value:
"com.picahealth.yunque.activitys.studycard.StudyCardDetailActivity###PicaDo.LearningCardVC",
type: 4,
seqNo: 1
},
{
key: "goodId",
value: this.cardInfo.id,
type: 4,
seqNo: 1
},
{
key: "courseUrl",
value: encodeURIComponent(pageUrl),
type: 4,
seqNo: 1
}
];
rocNative.dispatchEventByModuleCode({
modeCode: "M200",
jsonString: paramList
});
window.location.href =
"https://a.app.qq.com/o/simple.jsp?pkgname=com.picahealth.yunque";
},
// 首次进入考试时记录(点击‘我知道了’时调用)
firstIntoExamAction() {
let _this = this;
let param = {
token: _this.userInfo.userToken || this.token,
token: _this.token,
setEntry: true
};
this.NEW_POST(`cme/project/${_this.projectId}/firstIntoExam`, param).then(
......@@ -606,43 +515,14 @@ export default {
);
},
//获取用户信息
getUserInfo() {
rocNative.getUserInfo({
__funcName: "__getUserInfo64Comp"
});
},
// token是否失效校验
checkToken() {
let _this = this;
let param = {
token: _this.userInfo.userToken || _this.token,
setEntry: true
};
this.GET("campaign/admin/task/checkToken", param).then(res => {
if (res.code !== "000000") {
//未登录 跳转登录页
console.log("跳登录", _this.isInfresh);
if(_this.isInfresh) {
rocNative.goBack();
} else {
_this.$refs.tcPlayerRef && _this.$refs.tcPlayerRef.pause();
rocNative.gotoLogin();
}
_this.isInfresh = false;
}
});
},
//去激活
changeClick(msg) {
console.log("in changeClick");
this.showChangeCard = true;
this.$sendBuriedData({
component_tag: `882#88202`
});
// this.$sendBuriedData({
// component_tag: `882#88202`
// });
},
scrollFun() {
......@@ -660,7 +540,7 @@ export default {
}
if (window.__isWeb) {
h = intorOffsetTop - 75;
h = intorOffsetTop - 88;
} else if (window.__isIOS) {
h = intorOffsetTop - 140;
}
......@@ -728,50 +608,66 @@ export default {
getProjectInfoById() {
let _this = this;
let param = {
token: _this.userInfo.userToken || this.token || '47993ED00ECB46CE8D31ECF3AE34B4AA',
token: _this.token,
setEntry: true
};
let videoUrl = this.$route.query.videoUrl || '';
if(videoUrl) {
// let videoUrl = this.$route.query.videoUrl || "";
let videoUrl = this.shareParam.videoUrl;
if (videoUrl) {
param.trySeeFlag = 0;
} else {
param.trySeeFlag = 1;
}
console.log('getProjectInfoById', param);
}
console.log("getProjectInfoById", param);
_this.showLoading = true;
this.NEW_GET(`cme/project/${_this.projectId}/info`, param).then(res => {
if (res.code == "000000") {
if(videoUrl) {
_this.limitTimes = this.$route.query.trySeeTime || 300000;
this.showDownloadButton = true;
if (videoUrl) {
_this.limitTimes = this.shareParam.limitTimes || 0;
_this.videoOptions.mp4 = videoUrl;
_this.videoOptions.trySeeTime = this.$route.query.trySeeTime || 300000;
_this.videoOptions.trySeeTime =
this.shareParam.limitTimes || 0;
} else {
_this.limitTimes = res.data.trySeeTime;
_this.videoOptions.mp4 = res.data.attachmentUrl;
_this.videoOptions.trySeeTime = res.data.trySeeTime || 300000;
_this.videoOptions.trySeeTime = res.data.trySeeTime || 0;
}
_this.hasBindCard = res.data.cardStatus == 0 ? false : true;
if(_this.hasBindCard) {
_this.videoOptions.trySeeTime = 300000;
if (_this.hasBindCard) {
_this.videoOptions.trySeeTime = 0;
_this.videoOptions.autoplay = false;
}
_this.bannerType = 2; // 这里写死是2
console.log('_this.videoOptions.mp4, trySeeTime, autoplay', _this.videoOptions.mp4, _this.videoOptions.trySeeTime, _this.videoOptions.autoplay);
// 先设置视频URL再显示视频组件 ------------ BEGIN
// if (res.data.attachmentType == 2) {
// _this.videoOptions.mp4 = res.data.attachmentUrl;
// } else {
// _this.attachmentUrl = res.data.attachmentUrl;
// }
// _this.bannerType = res.data.attachmentType;
// if (_this.bannerType == 2) {
// _this.clientType = __isWeb ? 1 : __isAndroid ? 2 : 3;
// }
let mp4Url = _this.videoOptions.mp4;
// 判断是否是mp4
if (mp4Url.lastIndexOf(".mp4") > 0) {
_this.bannerType = 2;
this.$nextTick( () => {
console.log('_this.$refs.picaVideo', _this.$refs.picaVideo);
_this.$refs.picaVideo.switchUrl({
url: mp4Url,
proved: _this.videoOptions.trySeeTime,
enable: true,
});
})
// // TODO test
// _this.videoOptions.mp4 += 2;
} else {
if (res.data.attachmentType == 2) {
_this.videoOptions.mp4 = res.data.attachmentUrl;
} else {
_this.attachmentUrl = res.data.attachmentUrl;
}
_this.bannerType = res.data.attachmentType;
}
// 先设置视频URL再显示视频组件 ------------ END
console.log("location", location);
console.log(
"_this.videoOptions.mp4, trySeeTime, autoplay",
_this.videoOptions.mp4,
_this.videoOptions.trySeeTime,
_this.videoOptions.autoplay
);
_this.project = res.data;
if (_this.project.projectIntro) {
......@@ -814,19 +710,13 @@ export default {
cataOffsetTop = document.getElementById("catalogue-content")
.offsetTop;
intorOffsetTop = document.getElementById("intro-content").offsetTop;
console.log(
"getProjectInfoById",
cataOffsetTop,
intorOffsetTop
);
console.log("getProjectInfoById", cataOffsetTop, intorOffsetTop);
// 直接跳转
// if (_this.project.jumpToContents) {
if (_this.hasBindCard) {
setTimeout(() => {
this.jumpCatalogue();
}, 200);
}
// _this.copyLink();
// if (_this.hasBindCard) {
// setTimeout(() => {
// this.jumpCatalogue();
// }, 200);
// }
}, 200);
setTimeout(() => {
_this.showLoading = false;
......@@ -838,9 +728,26 @@ export default {
}
// 请求成功后统计,获取项目名
this.$sendBuriedData({
component_tag: `882#88201#${_this.projectId}#${_this.project.projectName}`
});
// this.$sendBuriedData({
// component_tag: `882#88201#${_this.projectId}#${_this.project.projectName}`
// });
// 二次分享
// let shareUrl = encodeURIComponent(location.href);
// let shareUrl = location.href;
let shareUrl = getWebPageUrl(`profexam/#/sharecoop?uuid=${this.uuid}`);
this.wechatShare(
{
link: shareUrl,
title: this.project.projectName,
friendtitle: this.project.projectName,
desc: this.project.projectIntro,
imgUrl: "https://file.yunqueyi.com/logo.png"
},
() => {
console.log("share success...");
}
);
}
});
},
......@@ -885,16 +792,6 @@ export default {
detailNum++;
list[i].portalModuleDTOS[j].value =
"共" + list[i].portalModuleDTOS[j].nodeCount + "节";
// if (list[i].portalModuleDTOS[j].status === 2) {
// list[i].portalModuleDTOS[j].value =
// "共" + list[i].portalModuleDTOS[j].nodeCount + "节";
// } else {
// list[i].portalModuleDTOS[j].value = "尚未开始";
// }
// list[i].portalModuleDTOS[j].disabled =
// list[i].portalModuleDTOS[j].status === 2 ? false : true;
//展开项记录
if (list[i].portalModuleDTOS[j].expandStatus == 1) {
actionList.push(list[i].portalModuleDTOS[j].expandKey);
......@@ -904,8 +801,8 @@ export default {
z < list[i].portalModuleDTOS[j].contentList.length;
z++
) {
if(!needShowUpdate) {
if(!list[i].portalModuleDTOS[j].contentList[z].id) {
if (!needShowUpdate) {
if (!list[i].portalModuleDTOS[j].contentList[z].id) {
this.needShowUpdate = true;
}
}
......@@ -936,243 +833,110 @@ export default {
return 1;
}
},
// 查找没有学习完成的课程或考试
continueStudy() {
let courseIdOrExamId = '';
let portalModuleDTOS = [];
let contentList = [];
let item = {};
let firstItem = null;
outloop: for(let i = 0; i < this.projectComponentDTOS.length; i ++) {
portalModuleDTOS = this.projectComponentDTOS[i].portalModuleDTOS;
for(let j = 0; j < portalModuleDTOS.length; j ++) {
contentList = portalModuleDTOS[j].contentList;
for(let k = 0; k < contentList.length; k ++) {
item = contentList[k];
if(!firstItem && item.id) {
firstItem = item;
}
if( (item.type == 1 && item.id && (item.useFlag != 2) && (item.status == 11 || item.status == 12))
|| (item.type == 2 && item.id && (item.useFlag != 2) && (item.status == 21 || item.status == 22)) ) {
this.continueStudyType = item.type;
this.skCourseId = item.id;
break outloop;
}
}
}
}
if(!this.skCourseId) {
this.continueStudyType = firstItem.type;
this.skCourseId = firstItem.id;
}
console.log('continueStudyType', this.continueStudyType, 'skCourseId', this.skCourseId);
if(this.continueStudyType == 1) {
this.gotoExamNew();
} else {
this.gotoCourseNew();
}
},
// 跳转到考试
gotoExamNew: function(examId) {
let paramList = [
{
key: "className",
value:
"com.picahealth.yunque.activitys.exammodule.ExamPreActivity###PicaDo.ExamModuleManager",
type: 4,
seqNo: 1
},
{
key: "examId",
value: this.skCourseId,
type: 4,
seqNo: 1
}
];
rocNative.dispatchEventByModuleCode({
modeCode: "M200",
jsonString: paramList
});
},
// 跳转到课程
gotoCourseNew: function() {
// if(this.hasBindCard || this.project.cmeType != 2) return;
// let courseId = '';
let appVersion = getAppVersion(this.userInfo.appVersion);
// 弹框提示下载新版本可以试看
if(appVersion < 343 && !this.hasBindCard) {
this.$dialog.confirm({
className: 'con-dialog',
showCancelButton: false,
// message: '激活/购买后可学习完整课程',
message: '升级最新版本可试看课程',
confirmButtonText: '我知道了',
}).then(res => {
})
return;
}
let paramList = []
// let limitTimes = this.limitTimes - 0;
// if(this.hasBindCard) {
// limitTimes = -1;
// }
paramList = [
{
key: "className",
value: "com.picahealth.yunque.activitys.courseplaynew.MyTcPlayVideoActivity###CourseMultiMediaPlayController",
type: 4,
seqNo: 1
},
{
key: "isCHC",
value: 0,
type: 4,
seqNo: 1
},
{
key: "courseId",
value: this.skCourseId,
type: 4,
seqNo: 1
},
{
key: "courseRequire",
value: this.courseRequire - 0,
type: 4,
seqNo: 1
},
// {
// key: "limitTimes",
// value: limitTimes,
// type: 4,
// seqNo: 1
// },
];
console.log('gotoCourse', paramList);
rocNative.dispatchEventByModuleCode({
modeCode: "M200",
jsonString: paramList
});
},
goBuyKc(type) {
this.$refs.tcPlayerRef && this.$refs.tcPlayerRef.pause();
this.isShowSkDialog = false;
type == 2 && this.confirm();
},
// 直接返回到上层
goBack() {
this.isShowIOSDownloadDialog = false;
rocNative.goBack();
}
}
};
</script>
<style lang="scss" scoped>
@import "../style/mixin";
<style lang="less" scoped>
.page-container-merge {
.nav-top .nav-title {
height: px2rem(0px);
// padding: px2rem(18px);
height: 0px;
// padding: 18px;
}
.banner-img {
display: inherit;
width: px2rem(375px);
height: px2rem(210px);
width: 375px;
height: 210px;
&-1 {
position: absolute;
left: 0;
top: px2rem(180px);
width: px2rem(76px);
height: px2rem(30px);
top: 180px;
width: 76px;
height: 30px;
}
&-5 {
position: absolute;
left: 0;
top: px2rem(180px);
width: px2rem(76px);
height: px2rem(30px);
top: 180px;
width: 76px;
height: 30px;
}
&-10 {
position: absolute;
left: 0;
top: px2rem(180px);
width: px2rem(76px);
height: px2rem(30px);
top: 180px;
width: 76px;
height: 30px;
}
}
.video-box{
position: relative;
height: 210px;
}
.list-container {
// margin-bottom: px2rem(40px);
// margin-bottom: 40px;
.sk-btn-cover-new {
position: absolute;
top: 0;
left: 0;
right: 0;
height: px2rem(210px);
height: 210px;
z-index: 100;
text-align: center;
// background: #fff;
font-size: px2rem(13px);
font-size: 13px;
// border-radius: 50%;
background: rgba(51, 51, 51, 0.8);
span {
display: inline-block;
margin-top: px2rem(82px);
width: px2rem(100px);
height: px2rem(36px);
line-height: px2rem(36px);
font-size: px2rem(15px);
margin-top: 82px;
width: 100px;
height: 36px;
line-height: 36px;
font-size: 15px;
font-weight: 700;
border-radius: px2rem(20px);
border-radius: 20px;
color: #fff;
background: #449284;
&.android {
padding-top: px2rem(2px);
padding-top: 2px;
}
}
}
}
}
.intro-catalogue-container {
.title {
height: px2rem(50px);
line-height: px2rem(30px);
padding: 0 px2rem(15px);
position: relative;
height: 50px;
line-height: 30px;
padding: 0 15px;
border-bottom: 1px solid #f0f1f2;
span {
& > span {
display: inline-block;
line-height: px2rem(15px);
font-size: px2rem(15px);
line-height: 15px;
font-size: 15px;
color: #979899;
padding-right: px2rem(35px);
padding-right: 35px;
}
span.focus {
& > span.focus {
position: relative;
color: #373839;
}
span.focus:after {
content: "";
position: absolute;
left: px2rem(9px);
bottom: px2rem(-14px);
left: 9px;
bottom: -14px;
background: #449284;
// border-bottom: px2rem(1px) solid #449284;
width: px2rem(10px);
height: px2rem(3px);
border-radius: px2rem(3px);
// border-bottom: 1px solid #449284;
width: 10px;
height: 3px;
border-radius: 3px;
}
}
.title.fixed-title-1 {
position: fixed;
left: 0;
top: px2rem(60px);
top: 60px;
background: #fff;
width: 100%;
z-index: 999;
......@@ -1180,40 +944,47 @@ export default {
.title.fixed-title-2 {
position: fixed;
left: 0;
top: px2rem(0px);
top: 0;
background: #fff;
width: 100%;
z-index: 999;
}
.catalogue-content {
padding: 0 px2rem(15px);
padding: 0 15px;
.catalogue-title {
// display: flex;
// flex-direction: row;
// align-items: center;
// align-content: center;
margin-top: px2rem(5px);
// margin-bottom: px2rem(16px);
margin-top: 5px;
// margin-bottom: 16px;
.c-title {
font-size: px2rem(18px);
font-size: 18px;
color: #373839;
font-weight: 700;
}
.c-sub {
margin-left: px2rem(-6px);
font-size: px2rem(12px);
margin-left: -6px;
font-size: 12px;
color: #979899;
}
}
}
.fixed-flag-height {
height: px2rem(50px);
height: 50px;
}
}
.course-tips {
width: 100%;
position: absolute;
z-index: 100;
top: 0;
left: 0;
}
}
.no-more-bottom {
position: relative;
width: 100%;
height: px2rem(40px);
height: 0;
}
</style>
<template>
<div class="test-container">
<CommonButton btnText="去学习"></CommonButton>
<!-- <CommonButton btnText="去学习"></CommonButton> -->
<!-- <CommonDialog content="该项目仅对河北省石家庄市的用户开放" :isShowDialog="isShowDialog" @handlerAction="handlerDialogAction"></CommonDialog> -->
<!-- <CommonDialog content="您暂未认证身份,完成认证身份后可申请学分" confirmBtnText="去认证" :isShowDialog="isShowDialog" @handlerAction="handlerDialogAction"></CommonDialog> -->
<!-- <CommonDialog content="您暂未加入机构,加入机构后且认证身份后可申请学分" confirmBtnText="加入机构" :isShowDialog="isShowDialog" @handlerAction="handlerDialogAction"></CommonDialog> -->
<!-- <CommonDialog content="您的所属机构不在可申请范围(河北省石家庄市)内" cancleBtnText="我知道了" isSingle :isShowDialog="isShowDialog" @handlerAction="handlerDialogAction"></CommonDialog> -->
<CommonDialog content="提交成功" subContent="您可在“个人中心-证书与学分”中查看审核结果" cancleBtnText="我知道了" isSingle needSubContent :isShowDialog="isShowDialog" @handlerAction="handlerDialogAction"></CommonDialog>
<!-- <CommonDialog content="提交成功" subContent="您可在“个人中心-证书与学分”中查看审核结果" cancleBtnText="我知道了" isSingle needSubContent :isShowDialog="isShowDialog" @handlerAction="handlerDialogAction"></CommonDialog> -->
<!-- <CommonDialog content="兑换" subContent="确定要花200云鹊豆兑换课程吗?<br>我的云鹊豆:<span style='color:#FF9A4B;'>1500</span>" cancleBtnText="我再想想" confirmBtnText="确认兑换" needSubContent :isShowDialog="isShowDialog" @handlerAction="handlerDialogAction"></CommonDialog> -->
<CommonBottomInfo></CommonBottomInfo>
<!-- <CommonBottomInfo></CommonBottomInfo> -->
<!-- 新组件测试 -->
<!-- <CommonErrorTips></CommonErrorTips> -->
<!-- <div class="course-button-group">
<CourseButton type="plain"></CourseButton>
<CourseButton></CourseButton>
</div> -->
<!-- <CourseCovers></CourseCovers> -->
<!-- <div @click="testDialog">testDialog</div> -->
<CourseIntro :intro="intro"></CourseIntro>
<BriefIntro></BriefIntro>
</div>
</template>
<script>
import CommonButton from "@/components/cme/common-button";
import CommonDialog from "@/components/cme/common-dialog";
import CommonBottomInfo from "@/components/cme/common-bottom-info";
import CommonErrorTips from "@/components/course/common-error-tips";
import CourseButton from "@/components/course/course-button";
import CourseCovers from "@/components/course/course-covers";
import BriefIntro from "@/components/course/brief-intro";
import CourseIntro from "@/components/course/course-intro";
export default {
data() {
return {
isShowDialog: true,
intro: "更多其他课程,请前往鹊医App学习更多其他课程,请前往鹊医App学习更多其他课程,请前往鹊医App学习更多其他课程,请前往鹊医App学习更多其他课程,请前往鹊医App学习更多其他课程,请前往鹊医App学习更多其他课程,请前往鹊医App学习"
};
},
components: {
CommonButton,
CommonDialog,
CommonBottomInfo
// CommonButton,
// CommonDialog,
// CommonBottomInfo,
// CommonErrorTips,
// CourseButton,
// CourseCovers,
BriefIntro,
CourseIntro
},
mounted() {
// Toast
this.$toast({message: '展示图片', duration: 3000 });
// this.$toast({message: '展示图片', duration: 3000 });
},
beforeDestroyed() {},
methods: {
handlerDialogAction(type) {
this.isShowDialog = false;
},
testDialog() {
this.$dialog
.confirm({
className: "course-detail",
showCancelButton: false,
// message: '激活/购买后可学习完整课程',
message: "恭喜您,已完成全部课程学习",
confirmButtonText: "我知道了"
})
.then(res => {});
}
}
};
</script>
<style lang="scss" scoped>
@import "../style/mixin";
<style lang="less" scoped>
.test-container {
// background: rgba($color: #000000, $alpha: 0.8);
}
</style>
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册