SanHQin 2 ヶ月 前
コミット
80dfbfde34

+ 1 - 1
dist/index.html

@@ -32,7 +32,7 @@
       width: 100%;
       background: #e6eaf0;
       font-family: '黑体';
-    }</style><link href=./static/css/app.2b7b0631413e33d5eca5efdf3f899e46.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.161e82026ac2ae03ab6f.js></script><script type=text/javascript src=./static/js/vendor.bb486323f0fa002ba2e7.js></script><script type=text/javascript src=./static/js/app.231ec9c82bf757dc57d2.js></script></body></html><script>function stopSafari() {
+    }</style><link href=./static/css/app.3eb815cf8219036b2f594c61b5a36c3b.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.161e82026ac2ae03ab6f.js></script><script type=text/javascript src=./static/js/vendor.bb486323f0fa002ba2e7.js></script><script type=text/javascript src=./static/js/app.afde9fc35ba410f7dd95.js></script></body></html><script>function stopSafari() {
     //阻止safari浏览器双击放大功能
     let lastTouchEnd = 0  //更新手指弹起的时间
     document.documentElement.addEventListener("touchstart", function (event) {

ファイルの差分が大きいため隠しています
+ 0 - 0
dist/static/css/app.3eb815cf8219036b2f594c61b5a36c3b.css


ファイルの差分が大きいため隠しています
+ 0 - 0
dist/static/css/app.3eb815cf8219036b2f594c61b5a36c3b.css.map


ファイルの差分が大きいため隠しています
+ 0 - 0
dist/static/js/app.afde9fc35ba410f7dd95.js


ファイルの差分が大きいため隠しています
+ 0 - 0
dist/static/js/app.afde9fc35ba410f7dd95.js.map


ファイルの差分が大きいため隠しています
+ 0 - 0
dist/static/js/manifest.161e82026ac2ae03ab6f.js.map


+ 5 - 0
src/assets/icon/classroomObservation/audio_file.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M5.5 6.4C5.5 5.56 5.5 5.14 5.663 4.819C5.80685 4.53651 6.03651 4.30685 6.319 4.163C6.639 4 7.059 4 7.9 4H12.506C12.873 4 13.056 4 13.229 4.041C13.3837 4.07833 13.528 4.13833 13.662 4.221C13.814 4.314 13.943 4.444 14.202 4.703L17.797 8.297C18.057 8.557 18.187 8.687 18.279 8.837C18.3617 8.973 18.4217 9.11767 18.459 9.271C18.5 9.444 18.5 9.627 18.5 9.994V18.6C18.5 19.44 18.5 19.86 18.337 20.181C18.1931 20.4635 17.9635 20.6931 17.681 20.837C17.361 21 16.941 21 16.1 21H7.9C7.06 21 6.64 21 6.319 20.837C6.03651 20.6931 5.80685 20.4635 5.663 20.181C5.5 19.861 5.5 19.441 5.5 18.6V6.4Z" stroke="black"/>
+<path d="M12.5 4V7.6C12.5 8.44 12.5 8.86 12.664 9.181C12.8076 9.46334 13.0369 9.69298 13.319 9.837C13.639 10 14.059 10 14.9 10H18.5" stroke="black"/>
+<path d="M11.7619 15.1825L11.3175 11.5H15V12.8334H12.2381L12.6825 16.7225C12.6824 17.1139 12.5486 17.4943 12.3018 17.8047C12.055 18.1151 11.709 18.3383 11.3175 18.4395C10.926 18.5407 10.5108 18.5144 10.1364 18.3646C9.76197 18.2148 9.44919 17.9498 9.24658 17.6109C9.04397 17.272 8.96284 16.8779 9.01577 16.4899C9.06871 16.1019 9.25276 15.7416 9.53937 15.4649C9.82597 15.1882 10.1991 15.0105 10.601 14.9595C11.0028 14.9084 11.4109 14.9868 11.7619 15.1825Z" fill="black"/>
+</svg>

+ 7 - 0
src/assets/icon/classroomObservation/textFile_icon.svg

@@ -0,0 +1,7 @@
+<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M5.5 6.4C5.5 5.56 5.5 5.14 5.663 4.819C5.80685 4.53651 6.03651 4.30685 6.319 4.163C6.639 4 7.059 4 7.9 4H12.506C12.873 4 13.056 4 13.229 4.041C13.3837 4.07833 13.528 4.13833 13.662 4.221C13.814 4.314 13.943 4.444 14.202 4.703L17.797 8.297C18.057 8.557 18.187 8.687 18.279 8.837C18.3617 8.973 18.4217 9.11767 18.459 9.271C18.5 9.444 18.5 9.627 18.5 9.994V18.6C18.5 19.44 18.5 19.86 18.337 20.181C18.1931 20.4635 17.9635 20.6931 17.681 20.837C17.361 21 16.941 21 16.1 21H7.9C7.06 21 6.64 21 6.319 20.837C6.03651 20.6931 5.80685 20.4635 5.663 20.181C5.5 19.861 5.5 19.441 5.5 18.6V6.4Z" stroke="black"/>
+<path d="M12.5 4V7.6C12.5 8.44 12.5 8.86 12.664 9.181C12.8076 9.46334 13.0369 9.69298 13.319 9.837C13.639 10 14.059 10 14.9 10H18.5" stroke="black"/>
+<rect x="8" y="11.5" width="8" height="1" rx="0.5" fill="black"/>
+<rect x="8" y="14.5" width="8" height="1" rx="0.5" fill="black"/>
+<rect x="8" y="17.5" width="8" height="1" rx="0.5" fill="black"/>
+</svg>

+ 5 - 0
src/assets/icon/classroomObservation/videoFile_icon.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M5.5 6.4C5.5 5.56 5.5 5.14 5.663 4.819C5.80685 4.53651 6.03651 4.30685 6.319 4.163C6.639 4 7.059 4 7.9 4H12.506C12.873 4 13.056 4 13.229 4.041C13.3837 4.07833 13.528 4.13833 13.662 4.221C13.814 4.314 13.943 4.444 14.202 4.703L17.797 8.297C18.057 8.557 18.187 8.687 18.279 8.837C18.3617 8.973 18.4217 9.11767 18.459 9.271C18.5 9.444 18.5 9.627 18.5 9.994V18.6C18.5 19.44 18.5 19.86 18.337 20.181C18.1931 20.4635 17.9635 20.6931 17.681 20.837C17.361 21 16.941 21 16.1 21H7.9C7.06 21 6.64 21 6.319 20.837C6.03651 20.6931 5.80685 20.4635 5.663 20.181C5.5 19.861 5.5 19.441 5.5 18.6V6.4Z" stroke="black"/>
+<path d="M12.5 4V7.6C12.5 8.44 12.5 8.86 12.664 9.181C12.8076 9.46334 13.0369 9.69298 13.319 9.837C13.639 10 14.059 10 14.9 10H18.5" stroke="black"/>
+<path d="M14.2222 14.375V12.9167C14.2222 12.8062 14.1754 12.7002 14.092 12.622C14.0087 12.5439 13.8957 12.5 13.7778 12.5H8.44444C8.32657 12.5 8.21352 12.5439 8.13017 12.622C8.04683 12.7002 8 12.8062 8 12.9167V17.0833C8 17.1938 8.04683 17.2998 8.13017 17.378C8.21352 17.4561 8.32657 17.5 8.44444 17.5H13.7778C13.8957 17.5 14.0087 17.4561 14.092 17.378C14.1754 17.2998 14.2222 17.1938 14.2222 17.0833V15.625L16 17.2917V12.7083L14.2222 14.375Z" fill="black"/>
+</svg>

+ 2 - 2
src/components/pages/classroomObservation/components/chatArea.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="chatArea" v-loading="loading">
+  <div class="chatArea">
     <div class="m-operation">
       <div>实时转录</div>
       <div>{{ createTime }}</div>
@@ -795,7 +795,7 @@ export default {
       showTeacherVoiceprintBox: false,
       teacherVoiceprintList: [],
       chosenVoiceprint: [],
-      recorderProvider: "shengyang",
+      recorderProvider: "microsoft",
       shengyangContext: {
         recorder: null,
         ws: null

+ 243 - 33
src/components/pages/classroomObservation/dialog/batchCreationClassDialog.vue

@@ -16,7 +16,9 @@
             <span>返回</span>
           </div>
           <div class="b_b_right">
-            <el-button type="primary" size="small" @click="uploadFile">上传文件</el-button>
+            <el-button type="primary" size="small" @click="uploadFile"
+              >上传文件</el-button
+            >
           </div>
         </div>
         <div class="b_head">
@@ -55,7 +57,10 @@
           </div>
         </div>
       </div>
-      <uploadFileToCreateClassDialog ref="uploadFileToCreateClassDialogRef"/>
+      <uploadFileToCreateClassDialog
+        ref="uploadFileToCreateClassDialogRef"
+        @success="uploadFileSuccess"
+      />
     </el-dialog>
   </div>
 </template>
@@ -63,6 +68,7 @@
 <script>
 import batchClassCard from "../newComponents/batchClassCard.vue";
 import uploadFileToCreateClassDialog from "./uploadFileToCreateClassDialog.vue";
+import { v4 as uuidv4 } from "uuid";
 export default {
   components: {
     batchClassCard,
@@ -76,6 +82,7 @@ export default {
         { label: "处理中", value: "2" },
         { label: "等待处理", value: "3" }
       ],
+      userId: this.$route.query["userid"],
       selectStatus: "0",
       show: false,
       selectAll: false,
@@ -85,24 +92,183 @@ export default {
           name: "文件名称文件名称文件名称",
           create_at: "2025-05-07 16.05.03",
           remarks: "备注1",
-          type:"txt",
-          baseMessage:{
-            courseName: "",
-				    teacherName: "",
-            time:"",
-				    grade: "",
-				    subject: "",
-            textbook:"",
-				    studentNum: 0,
-            imageList:[],
-          },
-          stepsList: [
+          jsonData: {
+            baseMessage: {
+              courseName: "",
+              teacherName: "",
+              time: "",
+              grade: "",
+              subject: "",
+              textbook: "",
+              studentNum: 0,
+              imageList: {
+                fileList1: [],
+                fileList2: [],
+                fileList3: [],
+                NephogramList: [],
+                videoList: []
+              }
+            },
+            tagList: [
+              { value: 0, name: "通用课堂分析", loading: false },
+              { value: 1, name: "学科课堂分析", loading: false },
+              { value: 2, name: "扩展分析", loading: false }
+            ],
+            steps: [
+              {
+                type: "uploadFile",
+                text: "上传文件",
+                status: "0",
+                progress: "0"
+              },
+              {
+                type: "transcription",
+                text: "文本转录",
+                status: "0",
+                progress: "0"
+              },
+              {
+                type: "automaticCoding",
+                text: "自动编码",
+                status: "0",
+                progress: "0"
+              },
+              {
+                type: "generateReport",
+                text: "生成报告",
+                status: "0",
+
+                progress: "0"
+              }
+            ],
+            analysisList:[],
+            fileData:{
+              name: "文件名称",
+              url: "",
+              type: "text/plain",
+              size: "10kb"
+            },
+            automaticCoding:false,
+          }
+        }
+      ]
+    };
+  },
+  methods: {
+    open() {
+      this.show = true;
+    },
+    close() {
+      this.show = false;
+    },
+    init() {},
+    changeStatus(newValue) {
+      this.selectStatus = newValue;
+    },
+    uploadFile() {
+      this.$refs.uploadFileToCreateClassDialogRef.open();
+    },
+    async uploadFileSuccess(data) {
+      this.$refs.uploadFileToCreateClassDialogRef.close();
+      console.log("上传文件成功", data);
+      let { fileList, automaticCoding, analysisTemplate } = data;
+      this.loading = true;
+
+      let fileDataList =  fileList.map(i => i.successData);
+
+      let _tempData = await this.getTemplateData(analysisTemplate[1]);
+
+      let _analysisList = JSON.parse(_tempData.tips);
+      let tagList = _analysisList.find(i => i.isOtherData);
+
+
+      if (!tagList) {
+        tagList = [
+          { value: 0, name: "通用课堂分析", loading: false },
+          { value: 1, name: "学科课堂分析", loading: false },
+          { value: 2, name: "扩展分析", loading: false }
+        ];
+      }
+
+      let batch = uuidv4();
+
+      _analysisList = _analysisList.fileList(i=>(!i.isOtherData && i.jsonData.name!="词频词汇分析"));
+
+      fileDataList.forEach(i=>{
+
+
+
+        let data = {
+          id: "1",
+          name: i.name,
+          create_at: "2025-05-07 16.05.03",
+          remarks: "备注",
+          batch:batch,
+          jsonData: {
+            file_ids:"",
+            baseMessage: {
+              courseName: i.name,
+              teacherName: "",
+              time: "",
+              grade: "",
+              subject: "",
+              textbook: "",
+              studentNum: 0,
+              imageList: {
+                fileList:[],
+                fileList1: [],
+                fileList2: [],
+                fileList3: [],
+                NephogramList: [],
+                videoList: []
+              }
+            },
+            tagList: tagList,
+            steps: [],
+            analysisList:_analysisList,
+            fileData:i,
+            automaticCoding:automaticCoding,
+          }
+        }
+
+        if(i.type == "text/plain"){
+          data.jsonData.steps= [
             {
               type: "uploadFile",
               text: "上传文件",
+              status: "1",
+            },
+            {
+              type: "transcription",
+              text: "文本转录",
               status: "0",
               progress: "0"
             },
+            {
+              type: "getFileIds",
+              text: "获取文件fileid",
+              status: "0",
+            },
+            {
+              type: "generateReport",
+              text: "生成报告",
+              status: "0",
+              progress: "0"
+            }
+          ]
+        }else if(i.type == "audio/wav"){
+          data.jsonData.baseMessage.imageList.fileList = [{
+            name: i.name,
+            status: "success",
+					  url: i.url,
+            uid:"1"
+          }]
+          data.jsonData.steps= [
+          {
+              type: "uploadFile",
+              text: "上传文件",
+              status: "1",
+            },
             {
               type: "transcription",
               text: "文本转录",
@@ -115,6 +281,11 @@ export default {
               status: "0",
               progress: "0"
             },
+            {
+              type: "getFileIds",
+              text: "获取文件fileid",
+              status: "0",
+            },
             {
               type: "generateReport",
               text: "生成报告",
@@ -122,27 +293,66 @@ export default {
               progress: "0"
             }
           ]
-        },
-      ]
-    };
-  },
-
-  computed: {},
-  methods: {
-    open() {
-      this.show = true;
-    },
+        }else if(i.type == "video/mp4"){
+          data.jsonData.baseMessage.imageList.videoList = [{
+            name: i.name,
+            status: "success",
+					  url: i.url,
+            uid:"1"
+          }]
+          data.jsonData.steps= [{
+              type: "uploadFile",
+              text: "上传文件",
+              status: "1",
+            },
+            {
+              type:"getVideoVoice",
+              text:"视频提取音频",
+              status:"0",
+              progress: "0"
+            },
+            {
+              type: "transcription",
+              text: "文本转录",
+              status: "0",
+              progress: "0"
+            },
+            {
+              type: "automaticCoding",
+              text: "自动编码",
+              status: "0",
+              progress: "0"
+            },
+            {
+              type: "getFileIds",
+              text: "获取文件fileid",
+              status: "0",
+            },
+            {
+              type: "generateReport",
+              text: "生成报告",
+              status: "0",
+              progress: "0"
+            }]
+        }
+      })
 
-    close() {
-      this.show = false;
-    },
-    init() {},
-    changeStatus(newValue) {
-      this.selectStatus = newValue;
-    },
-    uploadFile(){
-      this.$refs.uploadFileToCreateClassDialogRef.open();
     },
+    getTemplateData(tid) {
+      return new Promise(resolve => {
+        let params = {
+          uid: this.userId,
+          cid: tid,
+          st: 0
+        };
+        this.ajax
+          .get(this.$store.state.api + "selectClassroomTemplateDetail", params)
+          .then(res => {
+            let _data = res.data[0][0];
+            resolve(_data);
+          });
+      });
+    }
   },
   mounted() {}
 };

+ 345 - 278
src/components/pages/classroomObservation/dialog/uploadFileToCreateClassDialog.vue

@@ -19,10 +19,68 @@
         </div>
         <div class="b_main">
           <div class="b_m_left">
-            <img
-              src="../../../../assets/icon/classroomObservation/file_processing.svg"
-            />
-            <span>文件格式支持:mp4、wav、txt 文件</span>
+            <div class="b_m_l_fileList" v-if="fileList.length > 0">
+              <div class="fl_item" v-for="item in fileList" :key="item.index">
+                <div class="fl_i_left">
+                  <img
+                   v-if="item.type =='text/plain'"
+                    src="../../../../assets/icon/classroomObservation/textFile_icon.svg"
+                  />
+
+                  <img
+                   v-if="item.type =='audio/wav'"
+                    src="../../../../assets/icon/classroomObservation/audio_file.svg"
+                  />
+
+                  <img
+                   v-if="item.type =='video/mp4'"
+                    src="../../../../assets/icon/classroomObservation/videoFile_icon.svg"
+                  />
+                </div>
+                <div class="fl_i_center">
+                  <div class="fl_i_c_top">
+                    <span>{{ item.name }}</span>
+                    <div>
+                      <span v-if="item.status === 'wait'">等待上传</span>
+                      <span
+                        class="uploadingText"
+                        v-else-if="item.status === 'uploading'"
+                        >{{ item.progress.percent }}%</span
+                      >
+                      <span
+                        class="successText"
+                        v-else-if="item.status === 'success'"
+                        >上传成功
+                      </span>
+                    </div>
+                  </div>
+                  <div class="fl_i_c_bottom">
+                    <div class="f_i_c_progress">
+                      <div
+                        class="f_i_c_p_value"
+                        :class="{
+                          successProgress: item.status === 'success',
+                          uploadingProgress: item.status === 'uploading'
+                        }"
+                        :style="`width:${item.progress.percent}%`"
+                      ></div>
+                    </div>
+                  </div>
+                </div>
+                <div class="fl_i_right">
+                  <img
+                    @click="delUploadFile(item)"
+                    src="../../../../assets/icon/classroomObservation/del.svg"
+                  />
+                </div>
+              </div>
+            </div>
+            <div class="b_m_l_noFile" v-else @click="addFile()">
+              <img
+                src="../../../../assets/icon/classroomObservation/file_processing.svg"
+              />
+              <span>文件格式支持:mp4、wav、txt 文件</span>
+            </div>
           </div>
           <div class="b_m_right">
             <span>配置</span>
@@ -51,293 +109,46 @@
             >确定修改</el-button
           >
         </div>
+        <uploadFile
+          v-for="(item, index) in fileList"
+          v-if="item.status == 'uploading'"
+          :ref="`uploadFileRef_${item.index}`"
+          :key="item.index"
+          :index="item.index"
+          @progressUpdate="progressUpdate"
+          @success="uploadSuccess"
+        />
       </div>
     </el-dialog>
   </div>
 </template>
 
 <script>
+import uploadFile from "../newComponents/uploadFile.vue";
+import { v4 as uuidv4 } from "uuid";
 export default {
+  components: {
+    uploadFile
+  },
   data() {
     return {
       loading: false,
       show: false,
-      loading: false,
       automaticCoding: false,
-      analysisTemplate: "",
+      analysisTemplate: [],
+      userId: this.$route.query["userid"],
+      fileList: [],
       options: [
-        {
-          value: "zhinan",
-          label: "指南",
-          children: [
-            {
-              value: "shejiyuanze",
-              label: "设计原则",
-              children: [
-                {
-                  value: "yizhi",
-                  label: "一致"
-                },
-                {
-                  value: "fankui",
-                  label: "反馈"
-                },
-                {
-                  value: "xiaolv",
-                  label: "效率"
-                },
-                {
-                  value: "kekong",
-                  label: "可控"
-                }
-              ]
-            },
-            {
-              value: "daohang",
-              label: "导航",
-              children: [
-                {
-                  value: "cexiangdaohang",
-                  label: "侧向导航"
-                },
-                {
-                  value: "dingbudaohang",
-                  label: "顶部导航"
-                }
-              ]
-            }
-          ]
-        },
-        {
-          value: "zujian",
-          label: "组件",
-          children: [
-            {
-              value: "basic",
-              label: "Basic",
-              children: [
-                {
-                  value: "layout",
-                  label: "Layout 布局"
-                },
-                {
-                  value: "color",
-                  label: "Color 色彩"
-                },
-                {
-                  value: "typography",
-                  label: "Typography 字体"
-                },
-                {
-                  value: "icon",
-                  label: "Icon 图标"
-                },
-                {
-                  value: "button",
-                  label: "Button 按钮"
-                }
-              ]
-            },
-            {
-              value: "form",
-              label: "Form",
-              children: [
-                {
-                  value: "radio",
-                  label: "Radio 单选框"
-                },
-                {
-                  value: "checkbox",
-                  label: "Checkbox 多选框"
-                },
-                {
-                  value: "input",
-                  label: "Input 输入框"
-                },
-                {
-                  value: "input-number",
-                  label: "InputNumber 计数器"
-                },
-                {
-                  value: "select",
-                  label: "Select 选择器"
-                },
-                {
-                  value: "cascader",
-                  label: "Cascader 级联选择器"
-                },
-                {
-                  value: "switch",
-                  label: "Switch 开关"
-                },
-                {
-                  value: "slider",
-                  label: "Slider 滑块"
-                },
-                {
-                  value: "time-picker",
-                  label: "TimePicker 时间选择器"
-                },
-                {
-                  value: "date-picker",
-                  label: "DatePicker 日期选择器"
-                },
-                {
-                  value: "datetime-picker",
-                  label: "DateTimePicker 日期时间选择器"
-                },
-                {
-                  value: "upload",
-                  label: "Upload 上传"
-                },
-                {
-                  value: "rate",
-                  label: "Rate 评分"
-                },
-                {
-                  value: "form",
-                  label: "Form 表单"
-                }
-              ]
-            },
-            {
-              value: "data",
-              label: "Data",
-              children: [
-                {
-                  value: "table",
-                  label: "Table 表格"
-                },
-                {
-                  value: "tag",
-                  label: "Tag 标签"
-                },
-                {
-                  value: "progress",
-                  label: "Progress 进度条"
-                },
-                {
-                  value: "tree",
-                  label: "Tree 树形控件"
-                },
-                {
-                  value: "pagination",
-                  label: "Pagination 分页"
-                },
-                {
-                  value: "badge",
-                  label: "Badge 标记"
-                }
-              ]
-            },
-            {
-              value: "notice",
-              label: "Notice",
-              children: [
-                {
-                  value: "alert",
-                  label: "Alert 警告"
-                },
-                {
-                  value: "loading",
-                  label: "Loading 加载"
-                },
-                {
-                  value: "message",
-                  label: "Message 消息提示"
-                },
-                {
-                  value: "message-box",
-                  label: "MessageBox 弹框"
-                },
-                {
-                  value: "notification",
-                  label: "Notification 通知"
-                }
-              ]
-            },
-            {
-              value: "navigation",
-              label: "Navigation",
-              children: [
-                {
-                  value: "menu",
-                  label: "NavMenu 导航菜单"
-                },
-                {
-                  value: "tabs",
-                  label: "Tabs 标签页"
-                },
-                {
-                  value: "breadcrumb",
-                  label: "Breadcrumb 面包屑"
-                },
-                {
-                  value: "dropdown",
-                  label: "Dropdown 下拉菜单"
-                },
-                {
-                  value: "steps",
-                  label: "Steps 步骤条"
-                }
-              ]
-            },
-            {
-              value: "others",
-              label: "Others",
-              children: [
-                {
-                  value: "dialog",
-                  label: "Dialog 对话框"
-                },
-                {
-                  value: "tooltip",
-                  label: "Tooltip 文字提示"
-                },
-                {
-                  value: "popover",
-                  label: "Popover 弹出框"
-                },
-                {
-                  value: "card",
-                  label: "Card 卡片"
-                },
-                {
-                  value: "carousel",
-                  label: "Carousel 走马灯"
-                },
-                {
-                  value: "collapse",
-                  label: "Collapse 折叠面板"
-                }
-              ]
-            }
-          ]
-        },
-        {
-          value: "ziyuan",
-          label: "资源",
-          children: [
-            {
-              value: "axure",
-              label: "Axure Components"
-            },
-            {
-              value: "sketch",
-              label: "Sketch Templates"
-            },
-            {
-              value: "jiaohu",
-              label: "组件交互文档"
-            }
-          ]
-        }
+        { value: "0", label: "社区", children: [] },
+        { value: "1", label: "我的", children: [] },
+        { value: "2", label: "收藏", children: [] }
       ]
     };
   },
-  computed: {},
   methods: {
     open(data) {
+      this.init();
+      this.getTemplateData();
       this.loading = false;
       this.show = true;
     },
@@ -346,11 +157,154 @@ export default {
       this.init();
     },
     init() {
+      this.fileList = [];
+      this.analysisTemplate = [];
+      this.automaticCoding = false
       this.loading = false;
     },
     submit() {
-      this.$message.info("确认上传");
-      this.close();
+      if(this.fileList.length<=0)return this.$message.error("请上传文件");
+      if(this.analysisTemplate.length<=1)return this.$message.error("请选择分析模板");
+      if(this.fileList.some(i=>i.status==='wait' || i.status==='uploading'))return this.$message.error("请等待文件上传完毕");
+      this.$emit('success',{fileList:this.fileList,automaticCoding:this.automaticCoding,analysisTemplate:this.analysisTemplate});
+    },
+    delUploadFile(item) {
+      this.$confirm("确定要删除吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      })
+        .then(() => {
+          // 确定删除
+
+          if (item.status === "uploading") {
+            this.$refs[`uploadFileRef_${item.index}`][0].stopUpload();
+            this.$refs[`uploadFileRef_${item.index}`][0].abortMultipartUpload(
+              item.progress.key,
+              item.progress.uploadid
+            );
+          }
+          this.fileList = this.fileList.filter(i => i.index != item.index);
+          this.$forceUpdate();
+        })
+        .catch(() => {
+          // 取消删除
+        });
+    },
+    progressUpdate(res) {
+      console.log(res);
+      this.fileList.find(i => i.index == res.index).progress.status =
+        res.status;
+      this.fileList.find(i => i.index == res.index).progress.percent =
+        res.percent;
+      this.fileList.find(i => i.index == res.index).progress.key = res.key;
+      this.fileList.find(i => i.index == res.index).progress.uploadid =
+        res.uploadid;
+    },
+    uploadSuccess(res) {
+      let data = res.data;
+      let _name = this.fileList.find(i => i.index == res.index).file.name;
+      let size = this.fileList.find(i => i.index == res.index).file.size;
+      let _type = this.fileList.find(i => i.index == res.index).type;
+      console.log(data);
+      this.fileList.find(i => i.index == res.index).successData = {
+        name: _name,
+        url: data.Location,
+        type: _type,
+        size: size
+      };
+      this.fileList.find(i => i.index == res.index).status = "success";
+      let uploadingFile = this.fileList.find(file => file.status === "wait");
+      if (uploadingFile) {
+        this.fileList.find(file => file.status === "wait").status = "uploading";
+        this.$nextTick(() => {
+          this.$refs[`uploadFileRef_${uploadingFile.index}`][0].awsupload({
+            file: uploadingFile.file
+          });
+        });
+      } else {
+        console.log("上传完成");
+      }
+    },
+    addFile() {
+      let input = document.createElement("input");
+      input.type = "file";
+      input.accept = "video/mp4, audio/wav, text/plain";
+      input.multiple = true; // 支持多文件上传
+      input.style.display = "none";
+
+      input.click();
+
+      input.addEventListener("change", e => {
+        let files = e.target.files;
+        for (let i = 0; i < files.length; i++) {
+          if (
+            ["video/mp4", "audio/wav", "text/plain"].includes(files[i].type)
+          ) {
+            this.fileList.push({
+              file: files[i],
+              index: uuidv4(),
+              successData: null,
+              name: files[i].name,
+              type: files[i].type,
+              progress: { status: "", percent: 0, key: "", uploadid: "" },
+              status: "wait"
+            });
+          } else {
+            this.$message.info("文件格式不支持,仅支持mp4、wav、txt文件。");
+          }
+        }
+        if (!this.fileList.some(i => i.status === "uploading")) {
+          let uploadingFile = this.fileList.find(
+            file => file.status === "wait"
+          );
+          if (uploadingFile) {
+            this.fileList.find(file => file.status === "wait").status =
+              "uploading";
+            this.$nextTick(() => {
+              this.$refs[`uploadFileRef_${uploadingFile.index}`][0].awsupload({
+                file: uploadingFile.file
+              });
+            });
+          }
+        }
+      });
+    },
+    async getTemplateData() {
+      const promises = this.options.map(option => {
+        return new Promise((resolve, reject) => {
+          const params = {
+            uid: this.userId,
+            txt: "",
+            sub: "0",
+            type1: option.value
+          };
+
+          this.ajax
+            .get(this.$store.state.api + "selectClassroomTemplate", params)
+            .then(res => {
+              const _data = res.data[0].map(item => ({
+                value: item.id,
+                label: item.name
+              }));
+              this.options.find(
+                option2 => option2.value === option.value
+              ).children = _data;
+              resolve();
+            })
+            .catch(err => {
+              console.log(err);
+              reject(err);
+            });
+        });
+      });
+
+      try {
+        await Promise.all(promises);
+        console.log("获取模板成功");
+      } catch (error) {
+        console.log("获取模板失败");
+      }
     }
   }
 };
@@ -440,18 +394,24 @@ export default {
 
 .b_m_left {
   background-color: #fff;
+}
+
+.b_m_l_noFile {
+  width: 100%;
+  height: 100%;
   display: flex;
   flex-direction: column;
   align-items: center;
   justify-content: center;
+  cursor: pointer;
 }
 
-.b_m_left > img {
+.b_m_l_noFile > img {
   width: 140px;
   height: 140px;
 }
 
-.b_m_left > span {
+.b_m_l_noFile > span {
   font-size: 16px;
   color: #000;
 }
@@ -467,11 +427,118 @@ export default {
   color: #000;
 }
 
-.b_m_right>div{
+.b_m_right > div {
   margin-top: 20px;
   font-size: 16px;
   color: #000;
 }
 
+.b_m_l_fileList {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  overflow: auto;
+  box-sizing: border-box;
+  padding: 5px 10px;
+}
+
+.fl_item {
+  width: 100%;
+  height: 60px;
+  margin: 5px 0;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.fl_i_left {
+  width: 50px;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.fl_i_left > img {
+  width: 80%;
+  height: 80%;
+}
+
+.fl_i_center {
+  width: calc(100% - 90px);
+  height: 100%;
+}
+
+.fl_i_right {
+  width: 40px;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.fl_i_right > img {
+  width: 25px;
+  height: 25px;
+  cursor: pointer;
+}
+
+.fl_i_c_top {
+  width: 100%;
+  display: flex;
+  align-items: center;
+  height: 50%;
+  justify-content: space-between;
+}
+
+.fl_i_c_top > span {
+  max-width: calc(100% - 100px);
+  display: block;
+  align-items: center;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
 
+.fl_i_c_top > div {
+  width: 100px;
+  display: flex;
+  justify-content: flex-end;
+  font-size: 14px;
+}
+.fl_i_c_bottom {
+  width: 100%;
+  height: 50%;
+  display: flex;
+  align-items: center;
+}
+
+.f_i_c_progress {
+  width: 100%;
+  height: 6px;
+  background-color: rgba(217, 217, 217, 1);
+  border-radius: 5px;
+  overflow: hidden;
+}
+
+.f_i_c_p_value {
+  height: 100%;
+}
+
+.successText {
+  color: rgba(188, 230, 133, 1);
+}
+
+.successProgress {
+  background-color: rgba(188, 230, 133, 1);
+}
+
+.uploadingText {
+  color: rgba(54, 129, 252, 1);
+}
+
+.uploadingProgress {
+  background-color: rgba(54, 129, 252, 1);
+}
 </style>

+ 327 - 0
src/components/pages/classroomObservation/newComponents/uploadFile.vue

@@ -0,0 +1,327 @@
+<template>
+	<div class="uploadBox"></div>
+</template>
+
+<script>
+import "../../../../common/aws-sdk-2.235.1.min.js";
+export default {
+	props:{
+		index:{
+			type:String,
+			default:"0"
+		},
+	},
+	data() {
+		return {
+			bucket: "", //aws上传接口
+			bucketname: "ccrb", //桶
+			uploadid: "",
+			partsize: 10 * 1024 * 1024, //10MB  分片
+			filestate: {
+				status: "", //有 error(直接报错) 和 fail(上传的时候报错) 和 success(上传成功) 和 processing(上传中)
+				percent: 0, //(0-100的进度)
+			},
+			file: null,
+			flag:true,
+		};
+	},
+	watch: {
+		filestate: {
+			handler(newValue) {
+				this.$emit("progressUpdate", {index:this.index,...newValue});
+			},
+			immediate: true,
+			deep: true,
+		},
+	},
+	methods: {
+		//--------------------------分断上传保证稳定性
+		//初始化上传
+		// async init(){
+		// 	const credentials = {
+		// 	    accessKeyId: "AKIATLPEDU37QV5CHLMH",
+		// 	    secretAccessKey: "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",
+		// 	}; //秘钥形式的登录上传
+		// 	window.AWS.config.update(credentials);
+		// 	window.AWS.config.region = "cn-northwest-1"; //设置区域
+		// 	//桶的设置
+		// 	bucket = new window.AWS.S3({
+		// 	    params: {
+		// 	        Bucket: this.bucketname
+		// 	    }
+		// 	});
+		// 	return bucket;
+		// },
+		// 初始化上传入口
+		async initMultipartUpload(key, file) {
+			const params = {
+				Bucket: this.bucketname,
+				Key: key,
+				ContentType: file.type,
+				ACL: "public-read",
+			};
+			//创建一个续传通道
+			const data = await this.bucket.createMultipartUpload(params).promise();
+			return data.UploadId;
+		},
+		// 上传文件的某一部分
+		async uploadPart(file, keyname, uploadid, pn, start, end) {
+			//key可以设置为桶的相对路径,Body为文件, ACL最好要设置
+			if(!this.flag)return;
+			var params = {
+				Bucket: this.bucketname,
+				Key: keyname,
+				// ContentType: file.type,
+				PartNumber: pn,
+				UploadId: uploadid,
+				Body: file.slice(start, end),
+				// "Access-Control-Allow-Credentials": "*",
+				// ACL: "public-read",
+			};
+			const result = await this.bucket.uploadPart(params).promise();
+			return { ETag: result.ETag, PartNumber: pn };
+		},
+		//完成分块上传
+		async completeMultipartUpload(parts, keyname, uploadid) {
+			if(!this.flag)return;
+			const params = {
+				Bucket: this.bucketname,
+				Key: keyname,
+				MultipartUpload: { Parts: parts },
+				UploadId: uploadid,
+			};
+			return await this.bucket.completeMultipartUpload(params).promise();
+		},
+		async abortMultipartUpload(key, uploadid) {
+			const params = {
+				Bucket: this.bucketname,
+				Key: key,
+				UploadId: uploadid,
+			};
+			let data = await this.bucket.abortMultipartUpload(params).promise();
+			this.$emit("delUpload",{index:this.index})
+
+		},
+		//--------------------------------下面支持断点续传
+
+		//初始化亚马逊参数
+		async init() {
+			//秘钥形式的登录上传
+			const credentials = {
+				accessKeyId: "AKIATLPEDU37QV5CHLMH",
+				secretAccessKey: "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",
+				region: "cn-northwest-1",
+			};
+			window.AWS.config.update(credentials);
+			// window.AWS.config.region = "cn-northwest-1"; //设置区域
+			//桶的设置
+			this.bucket = new window.AWS.S3({
+				params: {
+					Bucket: this.bucketname,
+				},
+			});
+			return this.bucket;
+		},
+
+		//获取当前文件是否有已上传断点信息
+		async getawscheckpoint(key) {
+			let partsinfo;
+			try {
+				const result = await this.bucket
+					.listMultipartUploads({ Bucket: this.bucketname, Prefix: key })
+					.promise();
+				//获取具体分片信息
+				if (result.Uploads.length) {
+					this.uploadid = result.Uploads[result.Uploads.length - 1].UploadId;
+					partsinfo = await this.bucket
+						.listParts({
+							Bucket: this.bucketname,
+							Key: key,
+							UploadId: this.uploadid,
+						})
+						.promise();
+				}
+			} catch (err) {
+				console.log(err);
+			}
+			return { uploadid: this.uploadid, partsinfo };
+		},
+
+		//分段上传
+		async awsuploadpart(filestate, file, uploadid, parts, key) {
+			var partarr = []; //已完成的数组
+			//已完成的分片,转化成提交格式
+			const completeparts = parts.map((_) => {
+				partarr.push(_.PartNumber);
+				return { PartNumber: _.PartNumber, ETag: _.ETag };
+			});
+			// 分块上传文件
+			// parts = [];
+			let uploadpart;
+			let start = 0;
+			let end = 0;
+			let len = Math.ceil(file.size / this.partsize); //循环的长度
+			if (partarr.length) {
+				this.filestate.status = "processing";
+				this.filestate.percent = parseInt((completeparts.length * 100) / len);
+			}
+			//循环上传
+			for (let i = 0; i < len; i++) {
+				if(!this.flag)break;
+				start = i * this.partsize;
+				end = (i + 1) * this.partsize;
+				if (!partarr.includes(i+1)) {
+
+					uploadpart = await this.uploadPart(
+						file,
+						key,
+						uploadid,
+						i + 1,
+						start,
+						end
+					);
+					if (uploadpart.ETag != null) {
+						completeparts.push(uploadpart);
+						partarr.push(uploadpart.PartNumber);
+						this.filestate.status = "processing";
+						this.filestate.percent = parseInt(
+							(completeparts.length * 100) / len
+						);
+					} else {
+						this.filestate.status = "fail";
+						this.stopUpload();
+						return;
+					}
+				}
+			}
+			//提交上传成功信息
+			if(this.flag){
+					let data = await this.completeMultipartUpload(
+					completeparts,
+					key,
+					uploadid
+				);
+				this.filestate.status = "success";
+				return data;
+			}
+		},
+
+		//上传的接口
+		async awsupload({ file = this.file, keyName, folderName }) {
+			if (!file) return this.$message.error("请上传文件");
+			this.init(); //初始化桶
+			// const key = (folderid || uuidv4()) + "/" + file.name; //需要上传的文件名
+			let key = "";
+			if (keyName) {
+				key = keyName;
+			} else {
+				if (folderName) {
+					key = `${folderName}/${file.name}`;
+				} else {
+					key = `default/${file.name.split(".")[0] +
+							new Date().getTime() +
+							"." +
+							file.name.split(".")[file.name.split(".").length - 1]}`;
+				}
+			}
+			this.filestate = {
+				percent: 0,
+				status: "start",
+			};
+			this.filestate.percent = 0;
+			this.filestate.status = "start";
+			this.file = file;
+			//上传的参数
+			var params = {
+				Bucket: this.bucketname,
+				Key: key,
+			};
+			this.flag = true;
+			//设置桶上传文件
+			try {
+				//检查文件是否已上传
+				this.bucket.headObject(params, async (err, data) => {
+					// 没有上传成功,head方法会返回失败
+					if (err) {
+						//检查是否部分上传
+						const { uploadid, partsinfo } = await this.getawscheckpoint(
+							key,
+							this.bucket
+						);
+						//如果已经部分存在,那么直接在节点续传
+						if (uploadid) {
+							//断点续传
+							this.$emit("startUpload", { index:this.index,key, uploadid });
+							this.filestate.key = key;
+							this.filestate.uploadid = uploadid;
+							this.flag = true;
+							let data = await this.awsuploadpart(
+								this.filestate,
+								file,
+								uploadid,
+								partsinfo.Parts,
+								key
+							);
+							if(this.flag || this.filestate.percent==100)return this.$emit("success", {index:this.index, data, key, uploadid });
+							// return {data,key,uploadid}
+						}
+						//不存在,上传新的
+						else {
+							const uploadid = await this.initMultipartUpload(key, file); //初始化文件上传
+							this.$emit("startUpload", { index:this.index,key, uploadid });
+							this.filestate.key = key;
+							this.filestate.uploadid = uploadid;
+							this.flag = true;
+							let data = await this.awsuploadpart(
+								this.filestate,
+								file,
+								uploadid,
+								[],
+								key
+							);
+							if(this.flag || this.filestate.percent==100)return this.$emit("success", {index:this.index, data, key, uploadid });
+							// return {data,key,uploadid}
+						}
+					}
+					//如果已经上传成功了,那么直接返回状态百分百
+					else if (data) {
+						//data存在,上传成功
+						this.filestate.percent = 100;
+						this.filestate.status = "success";
+						let url = `https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/${key}`
+						this.file = null;
+						if(this.flag)return this.$emit("success", { index:this.index,data:{
+							Key:key,
+							Location:url,
+							ETag:data.ETag,
+							size:data.ContentLength,
+							ServerSideEncryption:data.ServerSideEncryption,
+							Bucket:this.bucketname
+							} });
+						// return {data,key,uploadid}
+					}
+				});
+			} catch (err) {
+				this.filestate.status = "error";
+				this.stopUpload();
+				console.log(err);
+			}
+		},
+		// 停止上传
+		stopUpload(){
+			this.filestate.status = "stop";
+			this.flag = false;
+		}
+	},
+	mounted() {
+		this.bucket = "";
+		this.file = null;
+	},
+};
+</script>
+
+<style scoped>
+.uploadBox {
+	display: none;
+}
+</style>

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません