Просмотр исходного кода

feat(组件): 新增消息提示和确认弹窗组件并替换原有实现

新增 messageInstruction 和 confirmInstruction 组件,用于统一管理消息提示和确认弹窗
替换原有 $message 和 $confirm 调用,使用新组件实现相同功能
优化代码结构,提升可维护性和一致性
SanHQin 5 дней назад
Родитель
Сommit
242da44a13

+ 154 - 0
src/components/components/confirmInstruction.vue

@@ -0,0 +1,154 @@
+<template>
+  <div class="confirmInstruction" :style="{display:show?'flex':'none'}">
+    <div class="mask" v-if="show" @click="close()"></div>
+    <div class="dialog" v-if="show">
+      <div class="title">{{ title }}</div>
+      <div class="message" v-html="message"></div>
+      <div class="footer">
+        <div class="cancel" @click="cancelFn()">{{ cancelText }}</div>
+        <div class="submit" @click="submitFn()">{{ submitText }}</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: 'confirmInstruction',
+    data() {
+      return {
+        show: false,
+        cancel:null,
+        submit:null,
+        title:'',
+        message:'',
+        cancelText:'取消',
+        submitText:'确认',
+        cancelCallback:null,
+        submitCallback:null,
+        type:'',
+      }
+    },
+    methods: {
+      open({title='',message='',cancelText='取消',submitText='确认',cancelCallback=null,submitCallback=null,type=''}) {
+        this.show = true;
+        this.type = type;
+        this.title = title;
+        this.message = message;
+        this.cancelText = cancelText;
+        this.submitText = submitText;
+        this.cancelCallback = cancelCallback;
+        this.submitCallback = submitCallback;
+      },
+      init(){
+        this.title = ''
+        this.message = ''
+        this.cancelText = '取消'
+        this.submitText = '确认'
+        this.cancelCallback = null
+        this.submitCallback = null
+      },
+      cancelFn(){
+        this.cancelCallback ? this.cancelCallback() : null
+        this.close()
+      },
+      submitFn(){
+        this.submitCallback ? this.submitCallback() : null
+        this.close()
+      },
+      close() {
+        this.show = false;
+        this.init()
+      },
+    }
+  }
+</script>
+
+<style scoped>
+.confirmInstruction{
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 9998;
+  overflow: hidden;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.mask{
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0, 0, 0, 0.5);
+}
+
+.dialog{
+  width: 30rem;
+  padding: 1.5rem;
+  max-width: 80vw;
+  height: auto;
+  background: #FFFFFF;
+  z-index: 9999;
+  border-radius: .5rem;
+  animation: slideDownFadeIn 0.3s ease-out;
+}
+
+.dialog>.title{
+  font-size: 1.1rem;
+  font-weight: bold;
+  margin-bottom: 2rem;
+}
+
+.dialog>.message{
+  font-size: 1rem;
+  margin-bottom: 2rem;
+  color: #737373;
+}
+
+.dialog>.footer{
+  display: flex;
+  justify-content: flex-end;
+  gap: .5rem;
+}
+
+.dialog>.footer>div{
+  padding: .5rem 1rem;
+  border-radius: .5rem;
+  font-size: .9rem;
+  cursor: pointer;
+  border: 1px solid #EAEAEA;
+  transition: .2s;
+}
+
+.dialog>.footer>div:hover{
+  background: #EAEAEA;
+}
+
+.dialog>.footer>.submit{
+  background: #F1C600;
+  border-color: #F1C600;
+}
+
+.dialog>.footer>.submit:hover{
+  background: #e4ba00;
+}
+
+
+@keyframes slideDownFadeIn {
+  from {
+    opacity: 0;
+    transform: translateY(-2rem);
+  }
+  to {
+    opacity: 1;
+    transform: translateY(0);
+  }
+}
+
+
+</style>

+ 181 - 0
src/components/components/messageInstruction.vue

@@ -0,0 +1,181 @@
+<template>
+  <div class="messageInstruction">
+    <div class="messageItem" :class="item.type" v-for="item in messageList" :key="item.id">
+      <div class="icon">
+        <svg v-if="['success'].includes(item.type)" viewBox="0 0 1024 1024"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m-74.965333 550.4L346.453333 545.152a42.666667 42.666667 0 1 0-60.330666 60.330667l120.704 120.704a42.666667 42.666667 0 0 0 60.330666 0l301.653334-301.696a42.666667 42.666667 0 1 0-60.288-60.330667l-271.530667 271.488z" fill="#67C239"></path></svg>
+        <svg v-if="['pptMessage'].includes(item.type)" viewBox="0 0 1024 1024" ><path d="M512 85.333c-234.667 0-426.667 192-426.667 426.667s192 426.667 426.667 426.667 426.667-192 426.667-426.667S746.667 85.333 512 85.333z m21.333 640h-42.666c-12.8 0-21.334-8.533-21.334-21.333v-42.667c0-12.8 8.534-21.333 21.334-21.333h42.666c12.8 0 21.334 8.533 21.334 21.333V704c0 12.8-8.534 21.333-21.334 21.333zM512 554.667c-25.6 0-42.667-17.067-42.667-42.667V341.333c0-25.6 17.067-42.666 42.667-42.666s42.667 17.066 42.667 42.666V512c0 25.6-17.067 42.667-42.667 42.667z" fill="#FCCF00"></path></svg>
+        <!-- <svg v-if="['pptMessage'].includes(item.type)" viewBox="0 0 1024 1024"><path d="M512 28.444444C244.906667 28.444444 28.444444 244.906667 28.444444 512s216.462222 483.555556 483.555556 483.555556 483.555556-216.462222 483.555556-483.555556S779.093333 28.444444 512 28.444444z m30.225067 755.5584A30.190933 30.190933 0 0 1 512 814.222222a30.190933 30.190933 0 0 1-30.225067-30.225066A30.190933 30.190933 0 0 1 512 753.777778a30.190933 30.190933 0 0 1 30.225067 30.225066z m0-120.888888A30.190933 30.190933 0 0 1 512 693.327644a30.190933 30.190933 0 0 1-30.225067-30.225066V240.008533A30.190933 30.190933 0 0 1 512 209.772089a30.190933 30.190933 0 0 1 30.225067 30.225067v423.105422z" fill="#FCCF00"></path></svg> -->
+      </div>
+      <div class="message" v-html="item.message"></div>
+      <div class="close" @click="close(item.id)" v-if="item.showClose">
+        <svg viewBox="0 0 1025 1024"><path d="M997.553471 154.252491 639.804427 512.001535 997.553471 869.751602l0 0c16.34988 16.374439 26.450623 38.948897 26.450623 63.898376 0 49.899981-40.450041 90.350022-90.351045 90.350022-24.949479 0-47.549519-10.100743-63.897353-26.475181l0 0L512.003581 639.775775 154.255561 997.525842l0 0c-16.34988 16.374439-38.948897 26.475181-63.899399 26.475181-49.901004 0-90.350022-40.450041-90.350022-90.350022 0-24.950502 10.099719-47.523938 26.449599-63.898376l0 0 357.750067-357.750067L26.454716 154.252491l0 0c-16.34988-16.350903-26.449599-38.949921-26.449599-63.900423 0-49.899981 40.449018-90.348999 90.350022-90.348999 24.950502 0 47.550543 10.099719 63.899399 26.474158l0 0 357.748021 357.749044L869.754672 26.477228l0 0c16.348857-16.374439 38.948897-26.474158 63.897353-26.474158 49.901004 0 90.351045 40.449018 90.351045 90.348999C1024.00307 115.301547 1013.902327 137.901588 997.553471 154.252491L997.553471 154.252491z" fill="#1A1A1A"></path></svg>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'messageInstruction',
+  data() {
+    return {
+      messageList: []
+    }
+  },
+  methods: {
+    success(data) {
+      if (typeof data === 'string') {
+        let _id = Date.now();
+        this.messageList.push({
+          id: _id,
+          type: 'success',
+          message: data
+        })
+        setTimeout(() => {
+          this.messageList = this.messageList.filter(item => item.id !== _id);
+        }, 3000);
+      } else if (typeof data === 'object' && data.message && data.duration) {
+        let _id = Date.now();
+        this.messageList.push({
+          id: _id,
+          type: 'success',
+          message: data.message
+        })
+        setTimeout(() => {
+          this.messageList = this.messageList.filter(item => item.id !== _id);
+        }, data.duration);
+      }
+    },
+    // error(data){
+    //   if(typeof data === 'string'){
+    //     let _id = Date.now();
+    //     this.messageList.push({
+    //       id: _id,
+    //       type: 'error',
+    //       message: data
+    //     })
+    //     setTimeout(() => {
+    //       this.messageList = this.messageList.filter(item => item.id !== _id);
+    //     }, 3000);
+    //   }else if(typeof data === 'object' && data.message && data.duration){
+    //     let _id = Date.now();
+    //     this.messageList.push({
+    //       id: _id,
+    //       type: 'error',
+    //       message: data.message
+    //     })
+    //     setTimeout(() => {
+    //       this.messageList = this.messageList.filter(item => item.id !== _id);
+    //     }, data.duration);
+    //   }
+    // },
+    pptMessage(data){
+      if(typeof data === 'string'){
+        let _id = Date.now();
+        this.messageList.push({
+          id: _id,
+          type: 'pptMessage',
+          message: data,
+          showClose:data.showClose || true
+        })
+        setTimeout(() => {
+          this.messageList = this.messageList.filter(item => item.id !== _id);
+        }, 3000);
+      }else if(typeof data === 'object' && data.message && data.duration){
+        let _id = Date.now();
+        this.messageList.push({
+          id: _id,
+          type: 'pptMessage',
+          message: data.message,
+          showClose:data.showClose || true
+        })
+        setTimeout(() => {
+          this.messageList = this.messageList.filter(item => item.id !== _id);
+        }, data.duration);
+      }
+    },
+    close(id){
+      this.messageList = this.messageList.filter(item => item.id !== id);
+    }
+  },
+}
+</script>
+
+<style scoped>
+.messageInstruction {
+  position: fixed;
+  top: 80px;
+  left: 50%;
+  transform: translate(-50%, 0%);
+  width: auto;
+  height: auto;
+  z-index: 9999;
+  display: flex;
+  flex-direction: column;
+  gap: .5rem;
+}
+
+.messageItem{
+  padding: 15px 20px;
+  border-radius: .2rem;
+  font-size: 1rem;
+  display: flex;
+  /* align-items: center; */
+  justify-content: space-between;
+  background: #FFFFFF;
+  box-shadow: 0 0 .2rem rgba(0, 0, 0, 0.1);
+  transition: .3s;
+}
+
+.messageItem>.icon{
+  width: 1.3rem;
+  height: 1.3rem;
+  margin-right: .8rem;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-top: -.1rem;
+}
+
+.messageItem>.icon>svg{
+  width: 100%;
+  height: 100%;
+}
+
+.messageItem>.close{
+  width: .6rem;
+  height: .6rem;
+  margin-left: 1.5rem;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-top: .3rem;
+}
+
+.messageItem>.close>svg{
+  width: 100%;
+  height: 100%;
+  cursor: pointer;
+}
+
+.messageItem>.message{
+  flex: 1;
+  max-width: 50vh;
+}
+
+.messageItem {
+  animation: slideDownFadeIn 0.3s ease-out;
+}
+
+@keyframes slideDownFadeIn {
+  from {
+    opacity: 0;
+    transform: translateY(-20px);
+  }
+  to {
+    opacity: 1;
+    transform: translateY(0);
+  }
+}
+
+</style>

+ 110 - 48
src/components/pptEasyClass/index.vue

@@ -91,14 +91,24 @@
       <iframe v-if="showObserveDialog" :src="observeDialogUrl" frameborder="0"
         style="width: 100%; height: 85vh; border: none;"></iframe>
     </el-dialog>
+
+    <!-- 消息提示组件 -->
+    <messageInstruction ref="messageInstructionRef"></messageInstruction>
+    <!-- 确认提示组件 -->
+    <confirmInstruction ref="confirmInstructionRef"></confirmInstruction>
   </div>
 </template>
 
 <script>
 import { myMixin } from '../../mixins/mixin';
-
+import messageInstruction from '../components/messageInstruction.vue';
+import confirmInstruction from '../components/confirmInstruction.vue';
 export default {
   mixins: [myMixin],
+  components: {
+    messageInstruction,
+    confirmInstruction
+  },
   data() {
     return {
       id: this.$route.query.courseId,
@@ -183,25 +193,43 @@ export default {
             this.$message.warning(this.lang.ssRecordingTimeAtLeast5Seconds);
             return;
           }
-          this.$confirm(this.lang.ssStopRecordingNotice, this.lang.ssStopRecordingConfirm, {
-            confirmButtonText: this.lang.ssConfirm,
-            cancelButtonText: this.lang.ssCancel,
-            confirmButtonClass: "pptEasyClassConfirmButtonText",
-            cancelButtonClass: "pptEasyClassCancelButtonText"
-          }).then(() => {
-            console.log("确定")
-            // this.$message({
-            //   dangerouslyUseHTMLString: true,
-            //   customClass:"pptEasyClassMessage",
-            //   message: '已停止录制 <p style="color:#3AB855;text-decoration: underline;cursor: pointer;float:right;margin-left:10px" target="_blank">查看结果</p>'
-            // });
-            this.onFinishRecordWithMicrosoft().then(() => {
-              resolve(true)
-            });
-          }).catch(() => {
-            console.log("取消")
-            resolve(false)
-          });
+
+          this.$refs.confirmInstructionRef.open({
+            title: this.lang.ssStopRecordingConfirm,
+            message: this.lang.ssStopRecordingNotice,
+            cancelText: this.lang.ssCancel,
+            submitText: this.lang.ssConfirm,
+            submitCallback: () => {
+              console.log("确定")
+              this.onFinishRecordWithMicrosoft().then(() => {
+                resolve(true)
+              });
+            },
+            cancelCallback: () => {
+              console.log("取消")
+              resolve(false)
+            },
+          })
+
+          // this.$confirm(this.lang.ssStopRecordingNotice, this.lang.ssStopRecordingConfirm, {
+          //   confirmButtonText: this.lang.ssConfirm,
+          //   cancelButtonText: this.lang.ssCancel,
+          //   confirmButtonClass: "pptEasyClassConfirmButtonText",
+          //   cancelButtonClass: "pptEasyClassCancelButtonText"
+          // }).then(() => {
+          //   console.log("确定")
+          //   // this.$message({
+          //   //   dangerouslyUseHTMLString: true,
+          //   //   customClass:"pptEasyClassMessage",
+          //   //   message: '已停止录制 <p style="color:#3AB855;text-decoration: underline;cursor: pointer;float:right;margin-left:10px" target="_blank">查看结果</p>'
+          //   // });
+          //   this.onFinishRecordWithMicrosoft().then(() => {
+          //     resolve(true)
+          //   });
+          // }).catch(() => {
+          //   console.log("取消")
+          //   resolve(false)
+          // });
 
         } else {
           const now = new Date();
@@ -489,12 +517,7 @@ export default {
         _pageWindow.focus()
       }
 
-      this.$message({
-        dangerouslyUseHTMLString: true,
-        customClass: "pptEasyClassMessage",
-        duration: 3000,
-        message: `${this.lang.ssStoppedRecording} <p style="color:#3AB855;text-decoration: underline;cursor: pointer;float:right;margin-left:10px" target="_blank" onclick="(${openPageWindow.toString()})()">${this.lang.ssViewRecordingResult}</p>`
-      });
+      this.$refs.messageInstructionRef.pptMessage(`${this.lang.ssStoppedRecording} <p style="color:#3AB855;text-decoration: underline;cursor: pointer;float:right;margin-left:10px" target="_blank" onClick="(${openPageWindow.toString()})()">${this.lang.ssViewRecordingResult}</p>`)
 
     },
     addPPTClass(file) {
@@ -651,32 +674,71 @@ export default {
       if (this.recordedForm.status == 1) {
         this.toggleRecording().then((flag) => {
           if (flag) {
-            this.$confirm(this.lang.ssEndClassConfirm, this.lang.ssPrompt, {
-              confirmButtonText: this.lang.ssConfirm,
-              cancelButtonText: this.lang.ssCancel,
-              type: 'warning'
-            }).then(() => {
-              this.$refs.ppt.contentWindow.PPTistStudent.forceLogout();
-              this.$message.success(this.lang.ssStudentLoggedOut)
-              setTimeout(() => {
-                this.back()
-              }, 1000)
-            }).catch(() => { });
+
+            this.$refs.confirmInstructionRef.open({
+              title: this.lang.ssPrompt,
+              message: this.lang.ssEndClassConfirm,
+              cancelText: this.lang.ssCancel,
+              submitText: this.lang.ssConfirm,
+              submitCallback: () => {
+                this.$refs.ppt.contentWindow.PPTistStudent.forceLogout();
+                this.$refs.messageInstructionRef.pptMessage(this.lang.ssStudentLoggedOut)
+                setTimeout(() => {
+                  this.tcid2 = ""
+                  this.refreshCourse()
+                }, 1000)
+              },
+              cancelCallback: () => {
+                console.log("取消")
+              }
+            })
+
+
+            //   this.$confirm(this.lang.ssEndClassConfirm, this.lang.ssPrompt, {
+            //     confirmButtonText: this.lang.ssConfirm,
+            //     cancelButtonText: this.lang.ssCancel,
+            //     type: 'warning'
+            //   }).then(() => {
+            //     this.$refs.ppt.contentWindow.PPTistStudent.forceLogout();
+            //     this.$refs.messageInstructionRef.pptMessage(this.lang.ssStudentLoggedOut)
+            //     setTimeout(() => {
+            //       this.tcid2 = ""
+            //       this.refreshCourse()
+            //     }, 1000)
+            //   }).catch(() => { });
 
           }
         })
       } else {
-        this.$confirm(this.lang.ssEndClassConfirm, this.lang.ssPrompt, {
-          confirmButtonText: this.lang.ssConfirm,
-          cancelButtonText: this.lang.ssCancel,
-          type: 'warning'
-        }).then(() => {
-          this.$refs.ppt.contentWindow.PPTistStudent.forceLogout();
-          this.$message.success(this.lang.ssStudentLoggedOut)
-          setTimeout(() => {
-            this.back()
-          }, 1000)
-        }).catch(() => { });
+        // this.$confirm(this.lang.ssEndClassConfirm, this.lang.ssPrompt, {
+        //   confirmButtonText: this.lang.ssConfirm,
+        //   cancelButtonText: this.lang.ssCancel,
+        //   type: 'warning'
+        // }).then(() => {
+        //   this.$refs.ppt.contentWindow.PPTistStudent.forceLogout();
+        //   this.$refs.messageInstructionRef.pptMessage(this.lang.ssStudentLoggedOut)
+        //   setTimeout(() => {
+        //     this.tcid2 = ""
+        //     this.refreshCourse()
+        //   }, 1000)
+        // }).catch(() => { });
+        this.$refs.confirmInstructionRef.open({
+          title: this.lang.ssPrompt,
+          message: this.lang.ssEndClassConfirm,
+          cancelText: this.lang.ssCancel,
+          submitText: this.lang.ssConfirm,
+          submitCallback: () => {
+            this.$refs.ppt.contentWindow.PPTistStudent.forceLogout();
+            this.$refs.messageInstructionRef.pptMessage(this.lang.ssStudentLoggedOut)
+            setTimeout(() => {
+              this.tcid2 = ""
+              this.refreshCourse()
+            }, 1000)
+          },
+          cancelCallback: () => {
+            console.log("取消")
+          }
+        })
       }
 
     },