Explorar el Código

feat(pptEasyClass): add course share function

1. 新增分享图标按钮到课堂页面,支持老师打开分享弹窗
2. 新增多语言分享相关文案
3. 新增分享弹窗组件,支持生成分享链接、复制链接功能
4. 添加分享图标资源文件
lsc hace 1 semana
padre
commit
f4992f9a83

+ 6 - 0
src/assets/share.svg

@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32" width="24" height="24" style="" filter="none">
+    
+    <g>
+    <path d="M13.333 4v2.667h-6.667v18.667h18.667v-6.667h2.667v8c0 0.736-0.597 1.333-1.333 1.333v0h-21.333c-0.736 0-1.333-0.597-1.333-1.333v0-21.333c0-0.736 0.597-1.333 1.333-1.333v0h8zM23.448 6.667h-6.115v-2.667h10.667v10.667h-2.667v-6.115l-9.333 9.333-1.885-1.885 9.333-9.333z" fill="rgba(79,79,79,1)"></path>
+    </g>
+  </svg>

+ 27 - 1
src/components/pptEasyClass/index.vue

@@ -29,6 +29,9 @@
             <span class="class-label" v-if="inviteCode">{{ lang.ssInviteCode }}</span>
             <span class="class-label" v-if="inviteCode">{{ lang.ssInviteCode }}</span>
             <span class="class-value" v-if="inviteCode">{{ inviteCode }}</span>
             <span class="class-value" v-if="inviteCode">{{ inviteCode }}</span>
           </div>
           </div>
+          <div @click.stop="openShareDialog" class="shareBtn" v-if="tcid && tType == 1">
+            <img src="../../assets/share.svg" alt="" />
+          </div>
         </div>
         </div>
         <div class="pec_h_center">
         <div class="pec_h_center">
           <el-tooltip effect="dark" :content="lang.ssRefresh" placement="bottom">
           <el-tooltip effect="dark" :content="lang.ssRefresh" placement="bottom">
@@ -110,6 +113,8 @@
     <messageInstruction ref="messageInstructionRef"></messageInstruction>
     <messageInstruction ref="messageInstructionRef"></messageInstruction>
     <!-- 确认提示组件 -->
     <!-- 确认提示组件 -->
     <confirmInstruction ref="confirmInstructionRef"></confirmInstruction>
     <confirmInstruction ref="confirmInstructionRef"></confirmInstruction>
+    <!-- 分享弹窗 -->
+    <shareDialog ref="shareDialogRef"></shareDialog>
   </div>
   </div>
 </template>
 </template>
 
 
@@ -119,12 +124,14 @@ import selectTeachingClassDialog from "../dialog/selectTeachingClassDialog2.vue"
 
 
 import messageInstruction from '../components/messageInstruction.vue';
 import messageInstruction from '../components/messageInstruction.vue';
 import confirmInstruction from '../components/confirmInstruction.vue';
 import confirmInstruction from '../components/confirmInstruction.vue';
+import shareDialog from './shareDialog.vue';
 export default {
 export default {
   mixins: [myMixin],
   mixins: [myMixin],
   components: {
   components: {
     messageInstruction,
     messageInstruction,
     confirmInstruction,
     confirmInstruction,
-    selectTeachingClassDialog
+    selectTeachingClassDialog,
+    shareDialog
   },
   },
   data() {
   data() {
     return {
     return {
@@ -922,7 +929,12 @@ export default {
         //   };
         //   };
         // }
         // }
       }
       }
+    },
+    // 打开分享弹窗
+    openShareDialog() {
+      this.$refs.shareDialogRef.open(this.id, this.tcid2)
     }
     }
+    
   },
   },
   destroyed() {
   destroyed() {
     clearInterval(this.opertimer);
     clearInterval(this.opertimer);
@@ -1129,6 +1141,20 @@ export default {
   height: 100%;
   height: 100%;
 }
 }
 
 
+.shareBtn {
+  width: 25px;
+  height: 25px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  cursor: pointer;
+}
+
+.shareBtn img {
+  width: 100%;
+  height: 100%;
+}
+
 .class-info-group {
 .class-info-group {
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;

+ 27 - 1
src/components/pptEasyClass/indexPS.vue

@@ -29,6 +29,9 @@
             <span class="class-label" v-if="inviteCode">{{ lang.ssInviteCode }}</span>
             <span class="class-label" v-if="inviteCode">{{ lang.ssInviteCode }}</span>
             <span class="class-value" v-if="inviteCode">{{ inviteCode }}</span>
             <span class="class-value" v-if="inviteCode">{{ inviteCode }}</span>
           </div>
           </div>
+          <div @click.stop="openShareDialog" class="shareBtn" v-if="tcid && tType == 1">
+            <img src="../../assets/share.svg" alt="" />
+          </div>
         </div>
         </div>
         <div class="pec_h_center">
         <div class="pec_h_center">
           <el-tooltip effect="dark" :content="lang.ssRefresh" placement="bottom">
           <el-tooltip effect="dark" :content="lang.ssRefresh" placement="bottom">
@@ -110,6 +113,8 @@
     <messageInstruction ref="messageInstructionRef"></messageInstruction>
     <messageInstruction ref="messageInstructionRef"></messageInstruction>
     <!-- 确认提示组件 -->
     <!-- 确认提示组件 -->
     <confirmInstruction ref="confirmInstructionRef"></confirmInstruction>
     <confirmInstruction ref="confirmInstructionRef"></confirmInstruction>
+    <!-- 分享弹窗 -->
+    <shareDialog ref="shareDialogRef"></shareDialog>
   </div>
   </div>
 </template>
 </template>
 
 
@@ -119,12 +124,15 @@ import selectTeachingClassDialog from "../dialog/selectTeachingClassDialog2.vue"
 
 
 import messageInstruction from '../components/messageInstruction.vue';
 import messageInstruction from '../components/messageInstruction.vue';
 import confirmInstruction from '../components/confirmInstruction.vue';
 import confirmInstruction from '../components/confirmInstruction.vue';
+import shareDialog from './shareDialog.vue';
+
 export default {
 export default {
   mixins: [myMixin],
   mixins: [myMixin],
   components: {
   components: {
     messageInstruction,
     messageInstruction,
     confirmInstruction,
     confirmInstruction,
-    selectTeachingClassDialog
+    selectTeachingClassDialog,
+    shareDialog
   },
   },
   data() {
   data() {
     return {
     return {
@@ -922,6 +930,9 @@ export default {
         //   };
         //   };
         // }
         // }
       }
       }
+    },
+    openShareDialog() {
+      this.$refs.shareDialogRef.open(this.id, this.tcid2)
     }
     }
   },
   },
   destroyed() {
   destroyed() {
@@ -1129,6 +1140,21 @@ export default {
   height: 100%;
   height: 100%;
 }
 }
 
 
+.shareBtn {
+  width: 25px;
+  height: 25px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  cursor: pointer;
+}
+
+.shareBtn img {
+  width: 100%;
+  height: 100%;
+}
+
+
 .class-info-group {
 .class-info-group {
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;

+ 359 - 0
src/components/pptEasyClass/shareDialog.vue

@@ -0,0 +1,359 @@
+<template>
+  <div>
+    <el-dialog
+      :title="lang.ssShareSetting"
+      :visible.sync="dialogVisible"
+      width="600px"
+      v-loading="loading"
+    >
+      <div class="sc_formUrl" v-show="form.url">
+        <el-input
+          class="sc_fu_input"
+          style="color: black"
+          disabled
+          v-model="form.url"
+        >
+          <template slot="append"
+            ><div class="sc_fu_copyBtn" @click.stop="copyUrl()">
+              {{ lang.ssCopyLink }}
+            </div></template
+          >
+        </el-input>
+        <!-- <div class="qrcode" ref="qrCodeRef"></div>
+				<el-link class="qrcodeBtn" type="primary" @click="downloadQrCode()">下载二维码</el-link> -->
+      </div>
+      <!-- <span slot="footer" class="shareFooter">
+        <el-button @click="close()">{{ lang.ssCancelBtn }}</el-button>
+      </span> -->
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import QRCode from "qrcodejs2";
+export default {
+  data() {
+    return {
+      dialogVisible: false,
+      loading: false,
+      date: "0",
+      courseId: "",
+      form: {
+        setPassword: false,
+        password: "",
+        setStudentLook: false,
+        studentLook: "1",
+        setComment: false,
+        comment: "1",
+        setDownload: false,
+        download: "1",
+        setHomeWorkUpload: false,
+        url: ""
+      }
+    };
+  },
+  watch: {
+    "form.url"(newValue) {
+      console.log(newValue)
+      // this.$nextTick(() => {
+      //   this.$refs.qrCodeRef.innerHTML = "";
+      //   if (!newValue) return;
+      //   new QRCode(this.$refs.qrCodeRef, {
+      //     text: `https://beta.cloud.cocorobo.cn/#/?shareCourseId=${this.courseId}`, // 需要转换为二维码的内容
+      //     width: 100,
+      //     height: 100,
+      //     colorDark: "#000000",
+      //     colorLight: "#ffffff",
+      //     correctLevel: QRCode.CorrectLevel.H
+      //   });
+      // });
+    }
+  },
+  methods: {
+    open(courseId, classid) {
+      this.courseId = courseId;
+      this.classId = classid;
+      this.dialogVisible = true;
+      this.form.id = "default";
+      let url = 'https://beta.cloud.cocorobo.cn'
+      if (window.location.href.includes('beta')) {
+        url = url
+      }
+      else if (this.lang.lang === 'cn') {
+        url = 'https://cloud.cocorobo.cn'
+      }
+      else if (this.lang.lang === 'hk') {
+        url = 'https://cloud.cocorobo.hk'
+      }
+      else if (this.lang.lang === 'en') {
+        url = 'https://cloud.cocorobo.com'
+      }
+      this.form.url = `${url}/admin.htm?ccid=${this.courseId}&classid=${this.classId}`;
+      // this.getData();
+    },
+    close() {
+      this.dialogVisible = false;
+      this.form = {
+        setPassword: false,
+        password: "",
+        setStudentLook: false,
+        studentLook: "1",
+        setComment: false,
+        comment: "1",
+        setDownload: false,
+        download: "1",
+        setHomeWorkUpload: false,
+        url: ""
+      };
+      this.date = "0";
+      this.courseId = "";
+    },
+    generate() {
+      if (!this.courseId) return this.$message.error("错误:无课程ID");
+      if (this.loading) return;
+      this.loading = true;
+      if (this.form.setPassword) {
+        // 判断密码是否没输入
+        if (!this.form.password) {
+          this.loading = false;
+          return this.$message.error("请输入密码");
+        }
+        // 判断密码是否符合规则
+        const reg = /^[A-Za-z0-9]+$/;
+        if (!reg.test(this.form.password)) {
+          this.loading = false;
+          return this.$message.error("密码仅支持数字及英文字母");
+        }
+      }
+      this.form.url = `https://beta.cloud.cocorobo.cn/#/?shareCourseId=${this.courseId}`;
+      let pram = [
+        {
+          cid: this.courseId,
+          jsonData: JSON.stringify(this.form),
+          date: this.date,
+          type: 1
+        }
+      ];
+      this.ajax
+        .post(this.$store.state.api + "addShareCourse", pram)
+        .then(res => {
+          if (res.data == 1) {
+            this.$message.success("生成成功");
+          } else {
+            this.$message.error("生成失败");
+          }
+          this.getData();
+        })
+        .catch(err => {
+          console.log(err);
+          this.$message.error("生成失败");
+          this.getData();
+          this.loading = false;
+        });
+
+      // this.$message.success("生成成功");
+      this.loading = false;
+    },
+    resetGenerate() {
+      this.$confirm("此操作将重置分享链接, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        this.loading = true;
+        let pram = [
+          {
+            cid: this.courseId,
+            type: 1
+          }
+        ];
+        this.ajax
+          .post(this.$store.state.api + "delShareCourse", pram)
+          .then(res => {
+            if (res.data == 1) {
+              this.$message.success("重置成功");
+            } else {
+              this.$message.error("重置失败");
+            }
+            this.getData();
+          })
+          .catch(err => {
+            console.log(err);
+            this.$message.error("重置失败");
+            this.getData();
+            this.loading = false;
+          });
+        // this.form = {
+        // 	setPassword: false,
+        // 	password: "",
+        // 	setStudentLook: false,
+        // 	studentLook: "1",
+        // 	setComment: false,
+        // 	comment: "1",
+        // 	setDownload: false,
+        // 	download: "1",
+        // 	setHomeWorkUpload: false,
+        // 	url: "",
+        // };
+        // this.date = "0";
+        // this.$message.success('重置成功')
+      });
+    },
+    copyUrl() {
+      if (!this.form.url) {
+        return this.$message.info(this.lang.ssPleaseGenerateLink);
+      }
+      const input = document.createElement("input");
+      // 设置 display为none会导致无法复制
+      // input.style.display = "none";
+      // 所以只能用其他方法隐藏
+      input.style.opacity = 0;
+      // 为了不影响布局
+      input.style.position = "fixed";
+      input.style.left = "-100%";
+      input.style.top = "-100%";
+      input.value = this.form.url;
+      document.body.appendChild(input);
+      input.select();
+      const success = document.execCommand("copy");
+      document.body.removeChild(input);
+      if (!success) {
+        return this.$message.error(this.lang.ssCopyFailed);
+      } else {
+        return this.$message.success(this.lang.ssCopySuccess);
+      }
+    },
+    getData() {
+      this.form = {
+        setPassword: false,
+        password: "",
+        setStudentLook: false,
+        studentLook: "1",
+        setComment: false,
+        comment: "1",
+        setDownload: false,
+        download: "1",
+        setHomeWorkUpload: false,
+        url: ""
+      };
+      this.date = "0";
+      this.loading = true;
+      // 这里查询数据库是否有数据
+      this.ajax
+        .get(this.$store.state.api + "getShareCourse", {
+          cid: this.courseId,
+          type: 1
+        })
+        .then(res => {
+          let _data = res.data[0];
+          if (_data.length == 0) return (this.loading = false);
+          let jsonData = _data[0].json ? JSON.parse(_data[0].json) : {};
+          this.form = { ...jsonData, id: _data[0].id };
+          this.date = _data[0].time;
+          this.loading = false;
+        })
+        .catch(err => {
+          this.loading = false;
+          console.error(err);
+        });
+    },
+		downloadQrCode(){
+			let canvas = this.$refs.qrCodeRef.getElementsByTagName('canvas')[0];
+			let ctx = canvas.getContext('2d');
+
+			// 创建一个新的canvas,大小为原来的两倍
+			var newCanvas = document.createElement("canvas");
+			newCanvas.width = canvas.width * 2;
+			newCanvas.height = canvas.height * 2;
+
+			// 获取新canvas的context,并绘制原来的canvas到新canvas上
+			var newCtx = newCanvas.getContext("2d");
+			newCtx.drawImage(canvas, 0, 0, newCanvas.width, newCanvas.height);
+
+			// 创建一个链接来下载图片
+			var link = document.createElement("a");
+			link.download = "课程分享二维码.png";
+			link.href = newCanvas.toDataURL();
+			link.click();
+		}
+  }
+};
+</script>
+
+<style scoped>
+.shareContent {
+  width: 600px;
+  max-width: 600px;
+  height: auto;
+}
+
+.shareFooter {
+  display: flex;
+  justify-content: flex-end;
+}
+
+.sc_formItemDate {
+  width: 100%;
+  height: auto;
+  display: flex;
+  align-items: center;
+  margin: 10px 0;
+}
+
+.sc_fd_radio {
+  margin-left: 55px;
+}
+
+.sc_formAuthorityItem {
+  margin-top: 30px;
+  margin-bottom: 20px;
+}
+
+.sc_formAuthorityItem > span {
+  font-size: 14px;
+  color: #7f7f7f;
+  margin-left: 20px;
+}
+
+.sc_fai_switch {
+  width: 190px;
+}
+
+.sc_fai_input {
+  width: 120px;
+  text-align: center;
+  margin-left: 20px;
+}
+
+.sc_fai_radio {
+  width: 120px;
+  margin-left: 20px;
+}
+.sc_fu_copyBtn {
+  color: black;
+  cursor: pointer;
+}
+
+.qrcode {
+  width: 100px;
+  height: 100px;
+  margin-top: 20px;
+}
+
+.sc_fu_input /deep/.el-input__inner {
+  color: black !important;
+  cursor: text !important;
+}
+
+.sc_fu_input >>> .el-input__inner {
+  color: black !important;
+  cursor: text !important;
+}
+
+.qrcodeBtn{
+	width: 100px;
+	display: flex;
+	justify-content: center;
+	margin-top: 10px;
+}
+</style>

+ 5 - 1
src/lang/cn.json

@@ -900,5 +900,9 @@
   "ssBeginClassRecording": "开始课堂录制",
   "ssBeginClassRecording": "开始课堂录制",
   "ssFinishClassRecording": "结束课堂录制",
   "ssFinishClassRecording": "结束课堂录制",
   "ssNoPermStop":"未开启录音权限,已停止录音",
   "ssNoPermStop":"未开启录音权限,已停止录音",
-  "ssStudentLoggedOut": "当前登录学生已退出账户"
+  "ssStudentLoggedOut": "当前登录学生已退出账户",
+  "ssShareSetting": "分享链接",
+  "ssCopyLink": "复制链接",
+  "ssPleaseGenerateLink": "请先生成链接",
+  "ssCopyFailed": "复制失败"
 }
 }

+ 5 - 1
src/lang/en.json

@@ -900,5 +900,9 @@
   "ssBeginClassRecording": "Begin Class Recording",
   "ssBeginClassRecording": "Begin Class Recording",
   "ssFinishClassRecording": "End Class Recording",
   "ssFinishClassRecording": "End Class Recording",
   "ssNoPermStop":"Recording permission not enabled, recording has been stopped",
   "ssNoPermStop":"Recording permission not enabled, recording has been stopped",
-  "ssStudentLoggedOut": "The currently logged-in student has logged out"
+  "ssStudentLoggedOut": "The currently logged-in student has logged out",
+  "ssShareSetting": "Share Link",
+  "ssCopyLink": "Copy Link",
+  "ssPleaseGenerateLink": "Please generate link first",
+  "ssCopyFailed": "Copy failed"
 }
 }

+ 5 - 1
src/lang/hk.json

@@ -900,5 +900,9 @@
   "ssBeginClassRecording": "開始課堂錄製",
   "ssBeginClassRecording": "開始課堂錄製",
   "ssFinishClassRecording": "結束課堂錄製",
   "ssFinishClassRecording": "結束課堂錄製",
   "ssNoPermStop":"未開啟錄音權限,已停止錄音",
   "ssNoPermStop":"未開啟錄音權限,已停止錄音",
-  "ssStudentLoggedOut": "當前登入學生已退出賬戶"
+  "ssStudentLoggedOut": "當前登入學生已退出賬戶",
+  "ssShareSetting": "分享鏈接",
+  "ssCopyLink": "複製鏈接",
+  "ssPleaseGenerateLink": "請先生成鏈接",
+  "ssCopyFailed": "複製失敗"
 }
 }