我都笔记组件提取

This commit is contained in:
zhaofang
2022-09-07 19:32:21 +08:00
parent 8d7e9d98d7
commit ae4dc87f21
7 changed files with 287 additions and 175 deletions

BIN
public/images/no-note.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1,4 +1,5 @@
import ajax from '@/utils/xajax.js' // import ajax from '@/utils/xajax.js'
import ajax from '../cesource/index.js';
/** /**

View File

@@ -0,0 +1,234 @@
<template>
<div class="my-note">
<div class="mynote">
<div class="mynote-tab">
<div @click="notetabType(1)" :class="notetab == 1 ? 'noteactive' : ' ' "> <a href="#">新增笔记</a> </div>
<div @click="notetabType(2)" :class="notetab == 2 ? 'noteactive' : ' '"> <a href="#">我的笔记</a> </div>
</div>
<!-- 新增笔记 -->
<div class="newcote-content" v-if="notetab == 1">
<div class="newcote-time" v-if="mynoteData.playTime != 0">
<img src="../../../public/images/coteplay.png" alt="">
8:40
<img src="../../../public/images/cotedetel.png" alt="">
</div>
<div class="newcote-text">
<el-input
type="textarea"
placeholder="好记性不如烂笔头,记录些什么吧~"
v-model="mynoteData.content"
maxlength="200"
:autosize="{ minRows: 4, maxRows: 8}"
show-word-limit>
</el-input>
</div>
</div>
<!-- 我的笔记 -->
<div class="mycote-content" v-if="notetab == 2">
<div v-if="noteList.length > 0">
<div style="border-bottom:1px solid #4444;padding-bottom:25px;" >
<span class="mycote-time">2022-06-21 21:35:12 <span class="sm">私密</span> <span class="more" icon="el-icon-more"></span> </span>
<div style="margin-top:20px" class="newcote-time">
<img src="../../../public/images/coteplay.png" alt="">
8:40
<img src="../../../public/images/cotedetel.png" alt="">
</div>
<div class="newcote-text">
在做策略写方案的时候都经常错套都要照着这个理论的要求来实施营销传播写PPT时也要照着这个理论的框架来写
我见划公司的在做策略写方案的时候都经常不管是什么行业企业处在什么来实施营销传播写PPT时也要照着这个理论的框架来写
</div>
</div>
<h6 class="mycote-dibu">已经到底啦</h6>
</div>
<div class="my-nonote" v-else>
<img src="../../../public/images/no-note.png" alt=""/>
<h6 style="color: #666666;font-size: 14px;">你还没有记录此课程的笔记哦</h6>
</div>
</div>
<div class="newcote-bottom" v-if="notetab == 1">
<span style="cursor: pointer;" @click="videoLocation"> <img src="../../../public/images/playtime.png" alt=""> 视频位置</span>
<el-radio v-model="mynoteData.openType" :label="1">公开</el-radio>
<el-radio v-model="mynoteData.openType" :label="2">私密</el-radio>
<el-button type="primary" size="small" :disabled="mynoteData.content == ''" @click="saveNote()">保存</el-button>
</div>
</div>
</div>
</template>
<script>
import apiNote from '@/api/modules/note.js';
import { mapGetters } from 'vuex';
import {formatDate,formatSeconds} from '@/utils/datetime.js';
import {testType,correctJudgment,numberToLetter} from '@/utils/tools.js';
export default {
props:{
data: {
type: Object,
default:()=>{}
},
},
name:'MyNote',
data() {
return {
radio:'1',
notetab:1,
mynoteData:{
type:1, //我发布的是1 我导入的是2
content:'',
playTime:'',
courseId:'',// 课程id
contentId:'',//课程内容id
courseName:'',// 课程名称
openType:1,// 1表不公开 9表完全公开
},
noteList:[],
};
},
computed: {
...mapGetters(['intTimeNote','userInfo']),
},
mounted() {
this.mynoteData.courseId = this.data.courseId;
this.mynoteData.contentId = this.data.id;
this.getMyNote();
},
watch:{
intTimeNote(val) {
this.mynoteData.playTime = val;
}
},
methods: {
getMyNote() {
apiNote.myCourse(this.mynoteData.courseId).then(res=>{
if(res.status == 200) {
}
})
},
videoLocation() {
this.$emit('videoLocation');
},
notetabType(num) {
this.notetab = num;
},
saveNote() {
apiNote.save(this.mynoteData).then(res=>{
})
}
}
}
</script>
<style scoped lang="scss">
.mynote{
// width: 100%;
margin: 35px 30px;
.newcote-time{
width: 120px;
height: 30px;
border-radius: 4px;
border: 1px solid #3379FB;
font-size: 14px;
font-weight: 400;
color: #387DF7;;
text-align: center;
line-height: 28px;
margin-bottom: 24px;
img{
vertical-align: middle;
margin: 0 5px;
}
}
.newcote-bottom{
span{
font-size: 14px;
color: #333333;
margin-right: 30px;
img{
width: 20px;
height: 24px;
vertical-align: middle;
}
}
}
.newcote-text{
// margin-top: 24px;
font-size: 14px;
color: #333333;
height: 100%;
::v-deep .el-textarea__inner{
background: #f5f5f5;
border: none;
padding: 0;
}
}
.newcote-content{
margin: 30px 0px;
box-sizing: border-box;
padding: 35px 30px;
height: 474px;
background-color: #F5F5F5 ;
}
.mycote-content{
margin: 30px 0px;
box-sizing: border-box;
padding: 35px 30px;
height: 474px;
background-color: #fff;
.my-nonote{
text-align: center;
margin-top: 100px;
img{
width: 198px;
height: 163px;
}
}
.mycote-time{
color: #666;
font-size: 14px;
padding-bottom: 20px;
.sm{
width: 50px;
height: 22px;
border-radius: 10px;
border: 1px solid #3379FB;
color: #3379FB;
font-size: 12px;
line-height: 50px;
margin-left: 20px;
padding: 3px 10px;
}
}
.mycote-dibu{
margin: 50px 38%;
color: #999999;
font-size: 14px;
}
}
.mynote-tab{
width: 180px;
margin-top: 17px;
display: flex;
div{
font-size: 16px;
color: #666666;
flex: 1;
}
.noteactive a{
font-weight: 600;
color: #333333;
padding-bottom: 7px;
border-bottom: 4px solid #387DF7;
}
}
}
</style>

View File

@@ -11,10 +11,12 @@ const getters = {
orgId: state => state.user.orgId, orgId: state => state.user.orgId,
permissions: state => state.user.permissions, permissions: state => state.user.permissions,
identity: state => state.user.identity, identity: state => state.user.identity,
intTimeNote: state => state.user.intTimeNote,
curIdentity: state => state.user.curIdentity, curIdentity: state => state.user.curIdentity,
permission_routes: state => state.permission.routes, permission_routes: state => state.permission.routes,
sidebarRouters: state => state.permission.sidebarRouters, sidebarRouters: state => state.permission.sidebarRouters,
portalCase: state => state.portal.case, portalCase: state => state.portal.case,
// intTimeNote: state => state.portal.intTimeNote,
portalLoginRememberMe: state => state.portal.loginRememberMe, portalLoginRememberMe: state => state.portal.loginRememberMe,
portalBackUrl: state => state.portal.backUrl, portalBackUrl: state => state.portal.backUrl,
resOwnerMap:state => state.resOwner.resOwnerMap, resOwnerMap:state => state.resOwner.resOwnerMap,

View File

@@ -3,7 +3,7 @@ const state = {
readProtocol: sessionStorage.getItem("readProtocol") == null ? false : JSON.parse(sessionStorage.getItem("readProtocol")) readProtocol: sessionStorage.getItem("readProtocol") == null ? false : JSON.parse(sessionStorage.getItem("readProtocol"))
}, },
loginRememberMe: sessionStorage.getItem("loginRememberMe") == null ? {} : JSON.parse(sessionStorage.getItem("loginRememberMe")), loginRememberMe: sessionStorage.getItem("loginRememberMe") == null ? {} : JSON.parse(sessionStorage.getItem("loginRememberMe")),
backUrl:'' backUrl:'',
} }
const mutations = { const mutations = {
@@ -18,6 +18,7 @@ const mutations = {
SET_BackUrl: (state, u) => { SET_BackUrl: (state, u) => {
state.backUrl = u; state.backUrl = u;
}, },
} }
const actions = { const actions = {

View File

@@ -15,8 +15,12 @@ const user = {
studyTaskCount:0,//学习任务数 studyTaskCount:0,//学习任务数
curIdentity: sessionStorage.getItem("curIdentity") == null ? 1 : sessionStorage.getItem("curIdentity"), // 用户当前选择的身份 1学员 2教师 3管理员 curIdentity: sessionStorage.getItem("curIdentity") == null ? 1 : sessionStorage.getItem("curIdentity"), // 用户当前选择的身份 1学员 2教师 3管理员
permissions: [], permissions: [],
intTimeNote:0,
}, },
mutations: { mutations: {
SET_IntTimeNote: (state, u) => {
state.intTimeNote = u;
},
SET_Identity: (state, iden) => { SET_Identity: (state, iden) => {
state.identity = iden state.identity = iden
}, },
@@ -41,6 +45,14 @@ const user = {
}, },
}, },
actions: { actions: {
SetIntTimeNote({
commit
}, iden) {
return new Promise((resolve) => {
commit('SET_IntTimeNote', iden);
resolve();
})
},
refrashMsg({ commit }) { refrashMsg({ commit }) {
apiMessage.isRead().then(res=>{ apiMessage.isRead().then(res=>{
if(res.status==200){ if(res.status==200){

View File

@@ -104,7 +104,7 @@
</div> </div>
</div> </div>
</div> </div>
<div style="padding-left:5px;margin: 14px 0px;background-color: #FFFFFF;" class="info"> <div style="padding-left:5px;margin: 24px 0px;background-color: #FFFFFF;" class="info">
<div class="coure-tab"> <div class="coure-tab">
<div @click="coutab" :class="courestab == true? 'coureactive' : ''">课程评论<span class=""></span> </div> <div @click="coutab" :class="courestab == true? 'coureactive' : ''">课程评论<span class=""></span> </div>
<div @click="coutab" :class="courestab == false? 'coureactive' : ''">课程笔记<span class=""></span> </div> <div @click="coutab" :class="courestab == false? 'coureactive' : ''">课程笔记<span class=""></span> </div>
@@ -128,81 +128,22 @@
<div @click="heartabtwo" :class="tab == 2 ? 'tab-active' : ' '"><i class="el-icon-edit" style="margin-right:9px;margin-left:9px"></i>我的笔记</div> <div @click="heartabtwo" :class="tab == 2 ? 'tab-active' : ' '"><i class="el-icon-edit" style="margin-right:9px;margin-left:9px"></i>我的笔记</div>
</div> </div>
<!-- 课程单元 -->
<div class="course-units" v-if="tab == 1"> <div class="course-units" v-if="tab == 1">
<div class="units-info"> <div style="min-height: 500px;">
1. 任务工程师角色认知 <div class="catalog">
</div> <div v-for="(item, index) in catalogTree" :key="index" :name="index">
<div class="units-info units-active"> <div class="units-info" :class="{'units-active':contentData.id == ele.id}" @click="showRes(ele,i,index)" v-for="(ele, i) in item.children" :key="i">
<img src="../../../public/images/playicon.png" alt=""> 1. 任务工程师角色认知 <img v-if="contentData.id == ele.id" src="../../../public/images/playicon.png" alt=""> 1. {{ ele.contentName }}
</div> </div>
<div class="units-info">
1. 任务工程师角色认知
</div>
<div class="units-info">
1. 任务工程师角色认知
</div>
<div class="units-info">
1. 任务工程师角色认知
</div>
<div class="units-info">
1. 任务工程师角色认知
</div>
<div class="units-info">
1. 任务工程师角色认知
</div>
<div class="units-info">
1. 任务工程师角色认知
</div>
<div class="units-info">
1. 任务工程师角色认知
</div>
<div class="units-info">
1. 任务工程师角色认知
</div> </div>
</div>
</div>
</div> </div>
<!-- 我的笔记 -->
<div class="mynote" v-if="tab == 2"> <div class="mynote" v-if="tab == 2">
<div class="mynote-tab"> <my-note :data="contentData" @videoLocation="videoLocation"></my-note>
<div @click="notetab1" :class="notetab == 1 ? 'noteactive' : ' ' "> <a href="#">新增笔记</a> </div>
<div @click="notetab2" :class="notetab == 2 ? 'noteactive' : ' '"> <a href="#">我的笔记</a> </div>
</div>
<div class="newcote-content" v-if="notetab == 1">
<div class="newcote-time">
<img src="../../../public/images/coteplay.png" alt="">
8:40
<img src="../../../public/images/cotedetel.png" alt="">
</div>
<div class="newcote-text">
我见过的策划们不管是甲方企业的还是广告代理公司的还营销策划公司的在做策略写方案的时候都经常错误找一个营销理论做策略时直接向上套不管是什么行业企业处在什么发展阶段都要照着这个理论的要求来实施营销传播写PPT时也要照着这个理论的框架来写
我见过的策划们不管是甲方企业的还是广告代理公司的还营销策划公司的在做策略写方案的时候都经常错误找一个营销理论做策略时直接向上套不管是什么行业企业处在什么发展阶段都要照着这个理论的要求来实施营销传播写PPT时也要照着这个理论的框架来写
</div>
</div>
<div class="mycote-content" v-if="notetab == 2">
<div style="border-bottom:1px solid #4444;padding-bottom:25px;">
<span class="mycote-time">2022-06-21 21:35:12 <span class="sm">私密</span> <span class="more" icon="el-icon-more"></span> </span>
<div style="margin-top:20px" class="newcote-time">
<img src="../../../public/images/coteplay.png" alt="">
8:40
<img src="../../../public/images/cotedetel.png" alt="">
</div>
<div class="newcote-text">
在做策略写方案的时候都经常错套都要照着这个理论的要求来实施营销传播写PPT时也要照着这个理论的框架来写
我见划公司的在做策略写方案的时候都经常不管是什么行业企业处在什么来实施营销传播写PPT时也要照着这个理论的框架来写
</div>
</div>
<h6 class="mycote-dibu">已经到底啦</h6>
</div>
<div class="newcote-bottom" v-if="notetab == 1">
<span> <img src="../../../public/images/playtime.png" alt=""> 视频位置</span>
<el-radio v-model="radio" label="1">公开</el-radio>
<el-radio v-model="radio" label="2">私密</el-radio>
<el-button type="primary" size="small">保存</el-button>
</div>
</div> </div>
</div> </div>
<div class="coures-tearch"> <div class="coures-tearch">
<div class="tearch-top"><img src="../../../public/images/tearch-top.png" alt=""></div> <div class="tearch-top"><img src="../../../public/images/tearch-top.png" alt=""></div>
@@ -239,7 +180,6 @@
<script> <script>
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import portalHeader from "@/components/PortalHeader.vue"; import portalHeader from "@/components/PortalHeader.vue";
import portalFooter from "@/components/PortalFooter.vue";
import comments from "@/components/Portal/comments.vue"; import comments from "@/components/Portal/comments.vue";
import interactBar from "@/components/Portal/interactBar.vue"; import interactBar from "@/components/Portal/interactBar.vue";
import audioPlayer from '@/components/AudioPlayer/index.vue'; import audioPlayer from '@/components/AudioPlayer/index.vue';
@@ -252,6 +192,7 @@ import apiStudy from '@/api/modules/courseStudy.js';
import apiVideoStudy from "@/api/modules/videoStudy.js"; import apiVideoStudy from "@/api/modules/videoStudy.js";
import apiCourseGrade from '@/api/modules/courseGrade.js'; import apiCourseGrade from '@/api/modules/courseGrade.js';
import apiPraises from '@/api/modules/praises.js'; import apiPraises from '@/api/modules/praises.js';
import apiNote from '@/api/modules/note.js';
import apiTrample from '@/api/modules/trample.js'; import apiTrample from '@/api/modules/trample.js';
import apiCoursePortal from '@/api/modules/coursePortal.js'; import apiCoursePortal from '@/api/modules/coursePortal.js';
import apiCourse from '@/api/modules/course.js'; import apiCourse from '@/api/modules/course.js';
@@ -263,15 +204,18 @@ import courseImage from '@/components/Course/courseImage.vue';
import exam from '@/components/Course/exam'; import exam from '@/components/Course/exam';
import homework from '@/components/Course/homework'; import homework from '@/components/Course/homework';
import assess from '@/components/Course/assess'; import assess from '@/components/Course/assess';
import myNote from '../../components/Course/myNote.vue';
export default { export default {
name: "atticle", name: "atticle",
components: {courseImage, portalHeader, portalFooter, hyperLink, comments, homework, exam, interactBar, assess, pdfPreview, audioPlayer, videoPlayer }, components: {courseImage, portalHeader, hyperLink, comments, homework, exam, interactBar, assess, pdfPreview, audioPlayer, videoPlayer,myNote },
data(){ data(){
return{ return{
intTimeNote:'',
courestab:true, courestab:true,
curCFile:{ curCFile:{
converStatus:4, converStatus:4,
}, },
radio:'',
interactRuning:false, interactRuning:false,
playerBoxShow:false, playerBoxShow:false,
userAvatarText, userAvatarText,
@@ -357,6 +301,11 @@ export default {
} }
}, },
methods: { methods: {
// 笔记功能
videoLocation() {// 记录笔记视频位置
this.$store.dispatch("SetIntTimeNote", 1);
},
coutab(){ coutab(){
this.courestab = !this.courestab; this.courestab = !this.courestab;
}, },
@@ -490,9 +439,9 @@ export default {
} }
}, },
handleChange(val) { // handleChange(val) {
console.log(val); // console.log(val);
}, // },
loadScorePraiseAndTrample() { loadScorePraiseAndTrample() {
//加载是否请过分 //加载是否请过分
apiCourseGrade.has(this.courseId).then(rs => { apiCourseGrade.has(this.courseId).then(rs => {
@@ -675,6 +624,7 @@ export default {
onPlayerPlaying(itme) { onPlayerPlaying(itme) {
this.isAppendTime=false; this.isAppendTime=false;
this.appendStartTime=null; this.appendStartTime=null;
this.intTimeNote = parseInt(itme);
//console.log("当前播放"+itme); //console.log("当前播放"+itme);
//console.log("当前播放11"+itme); //console.log("当前播放11"+itme);
if (this.contentData.contentType && this.contentData.contentType == 10){ if (this.contentData.contentType && this.contentData.contentType == 10){
@@ -1081,12 +1031,9 @@ export default {
heartabtwo(){ heartabtwo(){
this.tab = 2 this.tab = 2
}, },
notetab1(){ notetab1(num){
this.notetab = 1 this.notetab = num
}, },
notetab2(){
this.notetab = 2
}
}, },
} }
</script> </script>
@@ -1114,6 +1061,10 @@ export default {
} }
} }
.coures-tearch{
margin-top: 24px;
margin-left: 20px;
}
.coure-tab{ .coure-tab{
display: flex; display: flex;
width: 300px; width: 300px;
@@ -1577,99 +1528,10 @@ export default {
.more{ .more{
float: right; float: right;
} }
.newcote-bottom{
span{
font-size: 14px;
color: #333333;
margin-right: 30px;
img{
width: 20px;
height: 24px;
vertical-align: middle;
}
}
}
.newcote-time{
width: 120px;
height: 30px;
border-radius: 4px;
border: 1px solid #3379FB;
font-size: 14px;
font-weight: 400;
color: #387DF7;;
text-align: center;
line-height: 30px;
img{
vertical-align: middle;
margin: 0 5px;
}
}
.newcote-text{
margin-top: 24px;
font-size: 14px;
color: #333333;
}
.mycote-content{
margin: 30px 0px;
box-sizing: border-box;
padding: 35px 30px;
height: 474px;
background-color: #fff;
.mycote-time{
color: #666;
font-size: 14px;
padding-bottom: 20px;
.sm{
width: 50px;
height: 22px;
border-radius: 10px;
border: 1px solid #3379FB;
color: #3379FB;
font-size: 12px;
line-height: 50px;
margin-left: 20px;
padding: 3px 10px;
}
}
.mycote-dibu{
margin: 50px 38%;
color: #999999;
font-size: 14px;
}
}
.newcote-content{
margin: 30px 0px;
box-sizing: border-box;
padding: 35px 30px;
height: 474px;
background-color: #F5F5F5 ;
}
.mynote{
// width: 100%;
margin: 35px 30px;
.mynote-tab{
width: 180px;
margin-top: 17px;
display: flex;
div{
font-size: 16px;
color: #666666;
flex: 1;
}
.noteactive a{
font-weight: 600;
color: #333333;
padding-bottom: 7px;
border-bottom: 4px solid #387DF7;
}
}
}
.coures-content{ .coures-content{
height: 745px; height: 745px;
margin: 20px 80px; margin: 20px 80px;
@@ -1678,12 +1540,12 @@ export default {
.coures-infobox{ .coures-infobox{
width: 500px; width: 500px;
.coures-info{ .coures-info{
height: 745px; height: 710px;
background-color: #fff; background-color: #fff;
box-sizing: border-box; box-sizing: border-box;
.hear-tab{ .hear-tab{
margin: 35px 30px; margin: 35px 30px 10px 30px;
width: 300px; width: 300px;
border-bottom: 1px solid #D8D8D8 ; border-bottom: 1px solid #D8D8D8 ;
display: flex; display: flex;