فهرست منبع

feat:语音播报接口调试

zhangjie 2 سال پیش
والد
کامیت
167ada3f3d

+ 9 - 5
src/api/examwork-activity.js

@@ -57,15 +57,19 @@ export function toggleEnableActivity({ examId, id, enable }) {
   return httpApp.post("/api/admin/activity/save", [{ examId, id, enable }]);
 }
 
-export function searchActivityAudios(ary) {
-  return httpApp.post("/api/admin/activity/audio/query", ary);
+export function searchActivityAudios(datas) {
+  return httpApp.post(
+    "/api/admin/activity/audio/query?" + object2QueryString(datas)
+  );
 }
 
 export function saveActivityAudio(datas) {
   return httpApp.post("/api/admin/activity/audio/save", datas);
 }
 export function toggleEnableActivityAudio({ audioId, enable }) {
-  return httpApp.post("/api/admin/activity/audio/enable", [
-    { audioId, enable },
-  ]);
+  return httpApp.post(
+    "/api/admin/activity/audio/enable",
+    {},
+    { params: { audioId, enable } }
+  );
 }

+ 11 - 6
src/api/invigilation.js

@@ -128,12 +128,17 @@ export function examMonitorBatchList(datas) {
   return httpApp.post("/api/admin/exam/query?" + object2QueryString(data), {});
 }
 // 监考老师::考试批次列表
-export function examBatchList(userId) {
-  const type = "monitor";
-  const paramQuery = userId
-    ? `?userId=${userId}&type=${type}`
-    : `?type=${type}`;
-  return httpApp.post("/api/admin/sys/exam/query" + paramQuery);
+export function examBatchList({
+  userId = "",
+  name = "",
+  type = "monitor",
+  warnCount = false,
+}) {
+  const data = pickBy({ userId, name, type, warnCount }, (v) => v !== "");
+  return httpApp.post(
+    "/api/admin/sys/exam/query?" + object2QueryString(data),
+    {}
+  );
 }
 // 批次下考场列表
 export function examRoomList(batchCode) {

+ 10 - 1
src/components/UploadFileView.vue

@@ -19,6 +19,7 @@
       :on-progress="handleProgress"
       :http-request="upload"
       :show-file-list="false"
+      :multiple="false"
       :disabled="disabled"
       style="display: inline-block; margin: 0 10px;"
       ref="UploadComp"
@@ -144,6 +145,13 @@ export default {
 
       return httpApp.post(options.action, formData, {
         headers: options.headers,
+        onUploadProgress: (progressEvent) => {
+          if (progressEvent.total > 0 && progressEvent.loaded) {
+            this.percent = Math.round(
+              (progressEvent.loaded / progressEvent.total) * 100
+            );
+          }
+        },
       });
     },
     handleError(error) {
@@ -165,11 +173,12 @@ export default {
         message: "导入成功!",
       };
       this.$emit("upload-success", {
-        ...responseData,
+        ...responseData.data.data,
         filename: this.uploadDataDict[this.addFilenameParam],
       });
     },
     handleProgress(progressEvent) {
+      console.log(progressEvent);
       this.loading = true;
       if (progressEvent.total > 0 && progressEvent.loaded) {
         this.percent = (

+ 6 - 2
src/constant/constants.js

@@ -150,8 +150,12 @@ export const IMPORT_EXPORT_TASKS = [
 ];
 
 export const ACTIVITY_AUDIO_TYPE = {
-  BEFORE: "开考前语音",
-  AFTER: "考试结束前语音",
+  BEFORE: "开考前",
+  AFTER: "考试结束前",
+};
+export const ACTIVITY_AUDIO_DEFAULT = {
+  SYS: "系统",
+  CUSTOM: "自定义",
 };
 
 let domain;

+ 17 - 13
src/features/examwork/ActivityManagement/ActivityAudioDialog.vue

@@ -2,7 +2,7 @@
   <el-dialog
     ref="dialog"
     :title="(isEdit ? '编辑' : '新增') + '语音'"
-    width="540px"
+    width="580px"
     :visible.sync="visible"
     :close-on-click-modal="false"
     :close-on-press-escape="false"
@@ -71,14 +71,14 @@
 <script>
 import { saveActivityAudio } from "@/api/examwork-activity";
 import { ACTIVITY_AUDIO_TYPE } from "@/constant/constants";
+import { objAssign } from "@/utils/utils";
 
 const initForm = {
   id: null,
   audioDefault: "CUSTOM",
   attachmentId: null,
-  orgId: null,
   type: "BEFORE",
-  playTime: 1,
+  playTime: 60,
   activityId: null,
   content: "",
 };
@@ -87,11 +87,11 @@ export default {
   name: "ActivityAudioDialog",
   components: {},
   props: {
-    activity: Object,
+    instance: Object,
   },
   computed: {
     isEdit() {
-      return this.activity.id;
+      return this.instance.id;
     },
   },
   data() {
@@ -102,9 +102,7 @@ export default {
         ...initForm,
       },
       rules: {
-        attachmentId: [
-          { required: true, message: "请上传语音文件", trigger: "change" },
-        ],
+        attachmentId: [{ required: true, message: "请上传语音文件" }],
         content: [
           { required: true, message: "请输入内容描述", trigger: "blur" },
         ],
@@ -135,11 +133,14 @@ export default {
   },
   methods: {
     visibleChange() {
-      if (this.activity.id) {
-        this.modalForm = Object.assign({}, initForm, this.activity);
+      if (this.instance.id) {
+        objAssign;
+        this.form = objAssign(initForm, this.instance);
       } else {
-        this.modalForm = { ...initForm };
+        this.form = { ...initForm };
+        this.form.activityId = this.instance.activityId;
       }
+      this.form.playTime = this.form.playTime / 60;
 
       this.$nextTick(() => {
         this.$refs.modalFormComp.clearValidate();
@@ -157,7 +158,6 @@ export default {
     },
     uploadSuccess(data) {
       this.$message.success("上传成功!");
-
       this.form.attachmentId = data.id;
       this.$refs.modalFormComp.validateField("attachmentId");
     },
@@ -167,7 +167,11 @@ export default {
 
       if (this.loading) return;
       this.loading = true;
-      const res = await saveActivityAudio({ ...this.form }).catch(() => {});
+      const datas = {
+        ...this.form,
+      };
+      datas.playTime = datas.playTime * 60;
+      const res = await saveActivityAudio(datas).catch(() => {});
       this.loading = false;
       if (!res) return;
       this.$emit("reload");

+ 26 - 11
src/features/examwork/ActivityManagement/ActivityAudioManagement.vue

@@ -24,23 +24,26 @@
     </div>
 
     <el-table :data="tableData">
-      <el-table-column width="100" prop="id" label="ID"> </el-table-column>
+      <el-table-column width="200" prop="id" label="ID"> </el-table-column>
       <el-table-column label="语音内容">
         <span slot-scope="scope">{{ scope.row.content }}</span>
       </el-table-column>
       <el-table-column label="播报时间">
-        <span slot-scope="scope">{{ scope.row.type }}</span>
+        <span slot-scope="scope"
+          >{{ scope.row.type | activityAudioTypeFilter
+          }}{{ scope.row.playTime | playTimFilter }}</span
+        >
       </el-table-column>
       <el-table-column width="80" label="状态">
         <span slot-scope="scope">{{
-          scope.row.enable | zeroOneEnableDisableFilter
+          scope.row.enable | booleanEnableDisableFilter
         }}</span>
       </el-table-column>
-      <el-table-column width="100" label="语音">
+      <!-- <el-table-column width="100" label="语音">
         <template slot-scope="scope">
           <audio :src="scope.row.attachmentPath"></audio>
         </template>
-      </el-table-column>
+      </el-table-column> -->
       <el-table-column width="120" label="操作人">
         <span slot-scope="scope">{{ scope.row.updateName }}</span>
       </el-table-column>
@@ -49,14 +52,20 @@
           scope.row.updateTime | datetimeFilter
         }}</span>
       </el-table-column>
-      <el-table-column :context="_self" label="操作" width="210" fixed="right">
+      <el-table-column :context="_self" label="操作" width="160" fixed="right">
         <div slot-scope="scope">
-          <el-button size="mini" type="primary" plain @click="edit(scope.row)">
+          <el-button
+            v-if="scope.row.audioDefault === 'CUSTOM'"
+            size="mini"
+            type="primary"
+            plain
+            @click="edit(scope.row)"
+          >
             编辑
           </el-button>
           <el-button
             size="mini"
-            type="primary"
+            :type="!scope.row.enable ? 'primary' : 'danger'"
             plain
             @click="enableAudio(scope.row)"
           >
@@ -80,7 +89,7 @@
 
     <ActivityAudioDialog
       ref="ActivityAudioDialog"
-      :activity="selectedAudio"
+      :instance="selectedAudio"
       @reload="searchForm"
     />
   </div>
@@ -92,12 +101,18 @@ import {
   toggleEnableActivityAudio,
 } from "@/api/examwork-activity";
 import ActivityAudioDialog from "./ActivityAudioDialog";
+import { timeNumberToText } from "@/utils/utils";
 
 export default {
   name: "ActivityAudioManagement",
   components: {
     ActivityAudioDialog,
   },
+  filters: {
+    playTimFilter(val) {
+      return val ? timeNumberToText(val * 1000) : "";
+    },
+  },
   computed: {
     activityId() {
       return this.$route.params.activityId;
@@ -153,9 +168,9 @@ export default {
     async enableAudio(row) {
       await toggleEnableActivityAudio({
         audioId: row.id,
-        enable: row.enable === 0 ? 1 : 0,
+        enable: !row.enable,
       });
-      this.searchForm();
+      row.enable = !row.enable;
     },
   },
 };

+ 7 - 7
src/features/examwork/ActivityManagement/ActivityManagement.vue

@@ -36,31 +36,31 @@
 
     <el-table :data="tableData">
       <el-table-column type="selection" width="42" />
-      <el-table-column width="100" label="ID">
+      <el-table-column width="200" label="ID">
         <span slot-scope="scope">{{ scope.row.id }}</span>
       </el-table-column>
-      <el-table-column width="200" label="场次代码">
+      <el-table-column min-width="120" label="场次代码">
         <span slot-scope="scope">{{ scope.row.code }}</span>
       </el-table-column>
-      <el-table-column label="候考时间">
+      <el-table-column width="120" label="候考时间">
         <span slot-scope="scope">{{ scope.row.prepareSeconds / 60 }}</span>
       </el-table-column>
-      <el-table-column width="120" label="状态">
+      <el-table-column width="80" label="状态">
         <span slot-scope="scope">{{
           scope.row.enable | zeroOneEnableDisableFilter
         }}</span>
       </el-table-column>
-      <el-table-column width="100" label="开始时间">
+      <el-table-column width="170" label="开始时间">
         <span slot-scope="scope">{{
           scope.row.startTime | datetimeFilter
         }}</span>
       </el-table-column>
-      <el-table-column width="100" label="结束时间">
+      <el-table-column width="170" label="结束时间">
         <span slot-scope="scope">{{
           scope.row.finishTime | datetimeFilter
         }}</span>
       </el-table-column>
-      <el-table-column width="120" label="更新人">
+      <el-table-column min-width="120" label="更新人">
         <span slot-scope="scope">{{ scope.row.updateName }}</span>
       </el-table-column>
       <el-table-column sortable width="170" label="更新时间">

+ 1 - 1
src/features/invigilation/InvigilationDetail/InvigilationDetail.vue

@@ -367,7 +367,7 @@ export default {
     },
     async getExamBatchList() {
       const userId = this.IS_INVIGILATE ? this.user.id : null;
-      const res = await examBatchList(userId);
+      const res = await examBatchList({ userId });
       this.examBatchs = res.data.data;
     },
     async getExamActivityRoomList() {

+ 1 - 1
src/features/invigilation/ProgressDetail/ProgressDetail.vue

@@ -215,7 +215,7 @@ export default {
     async getExamBatchList() {
       const user = this.$store.state.user;
       const userId = user.roleCodes.includes("INVIGILATE") ? user.id : null;
-      const res = await examBatchList(userId);
+      const res = await examBatchList({ userId });
       this.examBatchs = res.data.data;
     },
     async getExamActivityRoomList() {

+ 1 - 1
src/features/invigilation/ReexamApply/ReexamApply.vue

@@ -203,7 +203,7 @@ export default {
     async getExamBatchList() {
       const user = this.$store.state.user;
       const userId = user.roleCodes.includes("INVIGILATE") ? user.id : null;
-      const res = await examBatchList(userId);
+      const res = await examBatchList({ userId });
       this.examBatchs = res.data.data;
     },
     async getExamActivityRoomList() {

+ 13 - 2
src/features/invigilation/WarningManage/WarningManage.vue

@@ -20,7 +20,18 @@
                 :key="item.id"
                 :value="item.id"
                 :label="item.name"
-              ></el-option>
+              >
+                <span style="float: left;">{{ item.name }}</span>
+                <span
+                  style="
+                    float: right;
+                    color: #1886fe;
+                    font-size: 13px;
+                    font-weight: bold;
+                  "
+                  >{{ item.warnCount }}</span
+                >
+              </el-option>
             </el-select>
           </el-form-item>
           <el-form-item>
@@ -315,7 +326,7 @@ export default {
     },
     async getExamBatchList() {
       const userId = this.IS_INVIGILATE ? this.user.id : null;
-      const res = await examBatchList(userId);
+      const res = await examBatchList({ userId, warnCount: true });
       this.examBatchs = res.data.data;
     },
     async getExamActivityRoomList() {

+ 9 - 1
src/filters/index.js

@@ -1,6 +1,10 @@
 import Vue from "vue";
 import { dateFormatForAPI, timeFormatForAPI } from "@/utils/utils";
-import { APPROVE_STATUS, EXAM_RECORD_STATUS } from "@/constant/constants";
+import {
+  APPROVE_STATUS,
+  EXAM_RECORD_STATUS,
+  ACTIVITY_AUDIO_TYPE,
+} from "@/constant/constants";
 
 Vue.filter("booleanYesNoFilter", function (val) {
   if (val === null) return "无";
@@ -68,6 +72,10 @@ Vue.filter("examRecordStatusFilter", function (val) {
   if (val === null) return "";
   return EXAM_RECORD_STATUS[val];
 });
+Vue.filter("activityAudioTypeFilter", function (val) {
+  if (val === null) return "";
+  return ACTIVITY_AUDIO_TYPE[val];
+});
 Vue.filter("minuteFilter", function (val) {
   return Math.floor(val / 60);
 });

+ 4 - 0
src/styles/element-ui-custom.scss

@@ -31,6 +31,10 @@
   .el-textarea__inner {
     border-color: #e8edf3;
     background-color: #f0f4f9;
+
+    & + .el-input__count {
+      background-color: transparent;
+    }
   }
 }