|
@@ -20,12 +20,16 @@
|
|
</el-row>
|
|
</el-row>
|
|
<el-row>
|
|
<el-row>
|
|
<el-form-item label="批次编码" prop="code">
|
|
<el-form-item label="批次编码" prop="code">
|
|
- <el-input :disabled="isEdit" v-model.trim="form.code"></el-input>
|
|
|
|
|
|
+ <el-input
|
|
|
|
+ :disabled="isEdit"
|
|
|
|
+ v-model.trim="form.code"
|
|
|
|
+ maxlength="30"
|
|
|
|
+ ></el-input>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-row>
|
|
</el-row>
|
|
<el-row>
|
|
<el-row>
|
|
<el-form-item label="批次名称" prop="name">
|
|
<el-form-item label="批次名称" prop="name">
|
|
- <el-input v-model.trim="form.name"></el-input>
|
|
|
|
|
|
+ <el-input v-model.trim="form.name" maxlength="30"></el-input>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-row>
|
|
</el-row>
|
|
<el-row>
|
|
<el-row>
|
|
@@ -43,32 +47,37 @@
|
|
</el-row>
|
|
</el-row>
|
|
<el-row v-if="!isModeAnytime">
|
|
<el-row v-if="!isModeAnytime">
|
|
<el-form-item label="候考时长(分钟)">
|
|
<el-form-item label="候考时长(分钟)">
|
|
- <MinuteInput v-model.trim="form.prepareSeconds"> </MinuteInput>
|
|
|
|
|
|
+ <MinuteInput
|
|
|
|
+ v-model.trim="form.prepareSeconds"
|
|
|
|
+ :min="0"
|
|
|
|
+ :max="10000"
|
|
|
|
+ >
|
|
|
|
+ </MinuteInput>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-row>
|
|
</el-row>
|
|
<el-row>
|
|
<el-row>
|
|
- <el-form-item label="考试次数限制">
|
|
|
|
|
|
+ <el-form-item label="考试次数限制" prop="examCount">
|
|
<el-input-number
|
|
<el-input-number
|
|
v-model.number.trim="form.examCount"
|
|
v-model.number.trim="form.examCount"
|
|
- :min="0"
|
|
|
|
|
|
+ :min="1"
|
|
|
|
+ :max="10000"
|
|
></el-input-number>
|
|
></el-input-number>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-row>
|
|
</el-row>
|
|
<el-row>
|
|
<el-row>
|
|
- <el-form-item label="考试时长(分钟)">
|
|
|
|
|
|
+ <el-form-item label="考试时长(分钟)" prop="maxDurationSeconds">
|
|
<MinuteInput v-model.trim="form.maxDurationSeconds">
|
|
<MinuteInput v-model.trim="form.maxDurationSeconds">
|
|
</MinuteInput>
|
|
</MinuteInput>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-row>
|
|
</el-row>
|
|
<el-row v-if="!isModeAnytime">
|
|
<el-row v-if="!isModeAnytime">
|
|
- <el-form-item label="迟到时长(分钟)">
|
|
|
|
|
|
+ <el-form-item label="迟到时长(分钟)" prop="openingSeconds">
|
|
<MinuteInput v-model.trim="form.openingSeconds"> </MinuteInput>
|
|
<MinuteInput v-model.trim="form.openingSeconds"> </MinuteInput>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-row>
|
|
</el-row>
|
|
<el-row>
|
|
<el-row>
|
|
- <el-form-item label="冻结时间(分钟)">
|
|
|
|
- <MinuteInput v-model.trim="form.minDurationSeconds">
|
|
|
|
- </MinuteInput>
|
|
|
|
|
|
+ <el-form-item label="冻结时间(分钟)" prop="minDurationSeconds">
|
|
|
|
+ <MinuteInput v-model.trim="form.minDurationSeconds" />
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-row>
|
|
</el-row>
|
|
<el-row v-if="!isModeAnytime">
|
|
<el-row v-if="!isModeAnytime">
|
|
@@ -101,12 +110,17 @@
|
|
<el-form-item v-if="enableBreakProxy" label="断点次数">
|
|
<el-form-item v-if="enableBreakProxy" label="断点次数">
|
|
<el-input-number
|
|
<el-input-number
|
|
v-model.trim="form.breakResumeCount"
|
|
v-model.trim="form.breakResumeCount"
|
|
- :min="0"
|
|
|
|
|
|
+ :min="1"
|
|
|
|
+ :max="10000"
|
|
></el-input-number>
|
|
></el-input-number>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-row>
|
|
</el-row>
|
|
<el-row>
|
|
<el-row>
|
|
- <el-form-item v-if="enableBreakProxy" label="断点时长(分钟)">
|
|
|
|
|
|
+ <el-form-item
|
|
|
|
+ v-if="enableBreakProxy"
|
|
|
|
+ prop="breakExpireSeconds"
|
|
|
|
+ label="断点时长(分钟)"
|
|
|
|
+ >
|
|
<MinuteInput v-model.trim="form.breakExpireSeconds">
|
|
<MinuteInput v-model.trim="form.breakExpireSeconds">
|
|
</MinuteInput>
|
|
</MinuteInput>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
@@ -191,12 +205,11 @@
|
|
:model="form"
|
|
:model="form"
|
|
:rules="rules"
|
|
:rules="rules"
|
|
label-width="180px"
|
|
label-width="180px"
|
|
- inline
|
|
|
|
:disabled="disableEdit"
|
|
:disabled="disableEdit"
|
|
>
|
|
>
|
|
<el-row class="tab-invililation">
|
|
<el-row class="tab-invililation">
|
|
<h2>开考检测</h2>
|
|
<h2>开考检测</h2>
|
|
- <el-form-item label="">
|
|
|
|
|
|
+ <el-form-item label="" label-width="0px">
|
|
<div class="d-flex flex-column tab-invililation-radio">
|
|
<div class="d-flex flex-column tab-invililation-radio">
|
|
<el-radio v-model="form.entryAuthenticationPolicy" label="OFF">
|
|
<el-radio v-model="form.entryAuthenticationPolicy" label="OFF">
|
|
安全级别:<span style="color: #202b4b; font-size: 20px;">
|
|
安全级别:<span style="color: #202b4b; font-size: 20px;">
|
|
@@ -375,162 +388,136 @@
|
|
</el-radio>
|
|
</el-radio>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-row>
|
|
</el-row>
|
|
- <!-- <el-row>
|
|
|
|
- <el-form-item v-if="form.monitorProxy" label="是否需要视频回放">
|
|
|
|
- <el-radio v-model="form.monitorRecord" :label="1">是 </el-radio>
|
|
|
|
- <el-radio v-model="form.monitorRecord" :label="0">否 </el-radio>
|
|
|
|
- </el-form-item>
|
|
|
|
- </el-row> -->
|
|
|
|
- <el-row>
|
|
|
|
- <el-form-item v-if="form.monitorProxy" label="电脑&手机监控方案">
|
|
|
|
- <el-checkbox-group v-model="form.monitorVideoSource">
|
|
|
|
- <div class="d-flex">
|
|
|
|
- <div class="d-flex flex-column justify-content-between">
|
|
|
|
- <el-checkbox label="CLIENT_CAMERA"
|
|
|
|
- >电脑摄像头主机位</el-checkbox
|
|
|
|
- >
|
|
|
|
- <el-checkbox
|
|
|
|
- label="CLIENT_SCREEN"
|
|
|
|
- :disabled="
|
|
|
|
- !form.monitorVideoSource.includes('CLIENT_CAMERA')
|
|
|
|
- "
|
|
|
|
- :title="
|
|
|
|
- !form.monitorVideoSource.includes('CLIENT_CAMERA') &&
|
|
|
|
- '原因:先选择电脑摄像头主机位'
|
|
|
|
- "
|
|
|
|
- >电脑开启录屏</el-checkbox
|
|
|
|
- >
|
|
|
|
- <el-checkbox label="MOBILE_FIRST">手机主机位</el-checkbox>
|
|
|
|
- <el-checkbox
|
|
|
|
- :disabled="
|
|
|
|
- !form.monitorVideoSource.includes('MOBILE_FIRST')
|
|
|
|
- "
|
|
|
|
- :title="
|
|
|
|
- !form.monitorVideoSource.includes('MOBILE_FIRST') &&
|
|
|
|
- '原因:先选择手机主机位'
|
|
|
|
- "
|
|
|
|
- label="MOBILE_SECOND"
|
|
|
|
- >手机辅机位</el-checkbox
|
|
|
|
- >
|
|
|
|
- <span style="color: red; font-size: 12px;"
|
|
|
|
- >*主机位设备负责收音及播放监考提示</span
|
|
|
|
- >
|
|
|
|
- </div>
|
|
|
|
- <div
|
|
|
|
- style="
|
|
|
|
- margin-left: 20px;
|
|
|
|
- padding: 10px;
|
|
|
|
- font-size: 10px;
|
|
|
|
- background: #f0f4f9;
|
|
|
|
- position: relative;
|
|
|
|
- "
|
|
|
|
- >
|
|
|
|
- <div
|
|
|
|
- style="
|
|
|
|
- position: absolute;
|
|
|
|
- width: 108px;
|
|
|
|
- height: 40px;
|
|
|
|
- border-left: 1px dotted grey;
|
|
|
|
- border-bottom: 1px dotted grey;
|
|
|
|
- left: 35px;
|
|
|
|
- top: 115px;
|
|
|
|
- border-radius: 5px;
|
|
|
|
- "
|
|
|
|
- :class="
|
|
|
|
- form.monitorVideoSource.includes('MOBILE_SECOND') &&
|
|
|
|
- 'enhance-left-bottom-line'
|
|
|
|
- "
|
|
|
|
- ></div>
|
|
|
|
- <div
|
|
|
|
- style="
|
|
|
|
- position: absolute;
|
|
|
|
- width: 108px;
|
|
|
|
- height: 40px;
|
|
|
|
- border-right: 1px dotted grey;
|
|
|
|
- border-top: 1px dotted grey;
|
|
|
|
- right: 35px;
|
|
|
|
- bottom: 122px;
|
|
|
|
- border-radius: 5px;
|
|
|
|
- "
|
|
|
|
- :class="
|
|
|
|
- form.monitorVideoSource.includes('MOBILE_FIRST') &&
|
|
|
|
- 'enhance-right-bottom-line'
|
|
|
|
- "
|
|
|
|
- ></div>
|
|
|
|
- <div
|
|
|
|
- style="
|
|
|
|
- position: absolute;
|
|
|
|
- width: 2px;
|
|
|
|
- height: 10px;
|
|
|
|
- border-right: 1px dotted grey;
|
|
|
|
- left: 236px;
|
|
|
|
- top: 92px;
|
|
|
|
- "
|
|
|
|
- :class="
|
|
|
|
- form.monitorVideoSource.includes('CLIENT_CAMERA') &&
|
|
|
|
- 'enhance-right-line'
|
|
|
|
- "
|
|
|
|
- ></div>
|
|
|
|
- <div class="d-flex">
|
|
|
|
- <div
|
|
|
|
- class="d-flex flex-column justify-content-center align-items-center"
|
|
|
|
- style="width: 52px !important;"
|
|
|
|
- >
|
|
|
|
- <div :class="monitorImgSrc('MOBILE_SECOND')" />
|
|
|
|
- <span style="font-size: 10px;">手机辅机位</span>
|
|
|
|
- </div>
|
|
|
|
- <div
|
|
|
|
- class="d-flex flex-column justify-content-center align-items-center"
|
|
|
|
- style="width: 350px !important;"
|
|
|
|
- >
|
|
|
|
- <div :class="monitorImgSrc('CLIENT_CAMERA')" />
|
|
|
|
- <span style="font-size: 10px;">电脑摄像头主机位</span>
|
|
|
|
- </div>
|
|
|
|
- <div style="width: 52px !important;"></div>
|
|
|
|
- </div>
|
|
|
|
- <div
|
|
|
|
- class="d-flex"
|
|
|
|
- style="margin-bottom: -60px; margin-top: -30px;"
|
|
|
|
- >
|
|
|
|
- <div style="width: 52px !important;"></div>
|
|
|
|
- <div
|
|
|
|
- class="d-flex flex-column justify-content-center align-items-center"
|
|
|
|
- style="width: 350px !important;"
|
|
|
|
- >
|
|
|
|
- <div :class="monitorImgSrc('CLIENT_SCREEN')" />
|
|
|
|
- <span style="font-size: 10px;">电脑开启录屏</span>
|
|
|
|
- </div>
|
|
|
|
- <div style="width: 52px !important;"></div>
|
|
|
|
- </div>
|
|
|
|
- <div class="d-flex">
|
|
|
|
- <div style="width: 52px !important;"></div>
|
|
|
|
- <div style="width: 350px !important;"></div>
|
|
|
|
- <div
|
|
|
|
- class="d-flex flex-column justify-content-center align-items-center"
|
|
|
|
- style="width: 52px !important;"
|
|
|
|
- >
|
|
|
|
- <div :class="monitorImgSrc('MOBILE_FIRST')" />
|
|
|
|
- <span style="font-size: 10px;">手机主机位</span>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </el-checkbox-group>
|
|
|
|
- </el-form-item>
|
|
|
|
- </el-row>
|
|
|
|
|
|
+ <div
|
|
|
|
+ class="monitor-config"
|
|
|
|
+ v-if="form.monitorProxy && enablePrevilleges"
|
|
|
|
+ >
|
|
|
|
+ <div class="monitor-config-options">
|
|
|
|
+ <h3 class="monitor-title">监考直播方案配置:</h3>
|
|
|
|
+ <el-form-item label="电脑摄像头主机位">
|
|
|
|
+ <el-radio-group
|
|
|
|
+ v-model="monitorVideoSource.CLIENT_CAMERA"
|
|
|
|
+ @change="monitorClientCameraChange"
|
|
|
|
+ >
|
|
|
|
+ <el-radio
|
|
|
|
+ v-for="(val, key) in monitorTypes"
|
|
|
|
+ :key="key"
|
|
|
|
+ :label="key"
|
|
|
|
+ >{{ val }}
|
|
|
|
+ </el-radio>
|
|
|
|
+ </el-radio-group>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="电脑操作录屏">
|
|
|
|
+ <el-radio-group
|
|
|
|
+ v-model="monitorVideoSource.CLIENT_SCREEN"
|
|
|
|
+ :disabled="monitorVideoSource.CLIENT_CAMERA !== '1'"
|
|
|
|
+ :title="
|
|
|
|
+ monitorVideoSource.CLIENT_CAMERA === '0' &&
|
|
|
|
+ '原因:先选择电脑摄像头主机位'
|
|
|
|
+ "
|
|
|
|
+ @change="monitorClientScreenChange"
|
|
|
|
+ >
|
|
|
|
+ <el-radio
|
|
|
|
+ v-for="(val, key) in monitorTinyTypes"
|
|
|
|
+ :key="key"
|
|
|
|
+ :label="key"
|
|
|
|
+ >{{ val }}
|
|
|
|
+ </el-radio>
|
|
|
|
+ </el-radio-group>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="手机监考主机位">
|
|
|
|
+ <el-radio-group
|
|
|
|
+ v-model="monitorVideoSource.MOBILE_FIRST"
|
|
|
|
+ @change="monitorMobileFirstChange"
|
|
|
|
+ >
|
|
|
|
+ <el-radio
|
|
|
|
+ v-for="(val, key) in monitorTypes"
|
|
|
|
+ :key="key"
|
|
|
|
+ :label="key"
|
|
|
|
+ >{{ val }}
|
|
|
|
+ </el-radio>
|
|
|
|
+ </el-radio-group>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="手机监考辅机位">
|
|
|
|
+ <el-radio-group
|
|
|
|
+ v-model="monitorVideoSource.MOBILE_SECOND"
|
|
|
|
+ :disabled="monitorVideoSource.MOBILE_FIRST === '0'"
|
|
|
|
+ :title="
|
|
|
|
+ monitorVideoSource.MOBILE_FIRST === '0' &&
|
|
|
|
+ '原因:先选择手机监考主机位'
|
|
|
|
+ "
|
|
|
|
+ @change="monitorVideoSourceChange"
|
|
|
|
+ >
|
|
|
|
+ <el-radio
|
|
|
|
+ v-for="(val, key) in monitorTypes"
|
|
|
|
+ :key="key"
|
|
|
|
+ :label="key"
|
|
|
|
+ >{{ val }}
|
|
|
|
+ </el-radio>
|
|
|
|
+ </el-radio-group>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <p class="tips-info tips-error">
|
|
|
|
+ *主机位设备负责收音及播放监考提示
|
|
|
|
+ </p>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="monitor-config-view">
|
|
|
|
+ <div class="monitor-item monitor-client-camera">
|
|
|
|
+ <div
|
|
|
|
+ :class="['monitor-item-img', monitorImgSrc('CLIENT_CAMERA')]"
|
|
|
|
+ />
|
|
|
|
+ <p class="monitor-item-desc">电脑摄像头主机位</p>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="monitor-item monitor-client-screen">
|
|
|
|
+ <div
|
|
|
|
+ :class="['monitor-item-img', monitorImgSrc('CLIENT_SCREEN')]"
|
|
|
|
+ />
|
|
|
|
+ <p class="monitor-item-desc">电脑开启录屏</p>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="monitor-item monitor-mobile-first">
|
|
|
|
+ <div
|
|
|
|
+ :class="['monitor-item-img', monitorImgSrc('MOBILE_FIRST')]"
|
|
|
|
+ />
|
|
|
|
+ <p class="monitor-item-desc">手机监考主机位</p>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="monitor-item monitor-mobile-second">
|
|
|
|
+ <div
|
|
|
|
+ :class="['monitor-item-img', monitorImgSrc('MOBILE_SECOND')]"
|
|
|
|
+ />
|
|
|
|
+ <p class="monitor-item-desc">手机监考辅机位</p>
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ v-if="monitorVideoSource.MOBILE_SECOND !== '0'"
|
|
|
|
+ class="monitor-line-mobile-second"
|
|
|
|
+ >
|
|
|
|
+ <span></span>
|
|
|
|
+ <span></span>
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ v-if="monitorVideoSource.MOBILE_FIRST !== '0'"
|
|
|
|
+ class="monitor-line-mobile-first"
|
|
|
|
+ ></div>
|
|
|
|
+ <div
|
|
|
|
+ v-if="monitorVideoSource.CLIENT_CAMERA !== '0'"
|
|
|
|
+ class="monitor-line-client-camera"
|
|
|
|
+ ></div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
</el-form>
|
|
</el-form>
|
|
</el-tab-pane>
|
|
</el-tab-pane>
|
|
|
|
|
|
<el-tab-pane label="其他设置" name="third">
|
|
<el-tab-pane label="其他设置" name="third">
|
|
<el-form
|
|
<el-form
|
|
|
|
+ ref="form3"
|
|
:model="form"
|
|
:model="form"
|
|
label-width="170px"
|
|
label-width="170px"
|
|
|
|
+ :rules="rules"
|
|
inline
|
|
inline
|
|
:disabled="disableEdit"
|
|
:disabled="disableEdit"
|
|
>
|
|
>
|
|
<el-row>
|
|
<el-row>
|
|
- <el-form-item label="考试须知">
|
|
|
|
|
|
+ <el-form-item prop="preNotice" label="考试须知">
|
|
<VEditor
|
|
<VEditor
|
|
|
|
+ ref="preNoticeEditor"
|
|
:value="form.preNoticeClone"
|
|
:value="form.preNoticeClone"
|
|
style="width: 300px;"
|
|
style="width: 300px;"
|
|
@result="(v) => (form.preNotice = v)"
|
|
@result="(v) => (form.preNotice = v)"
|
|
@@ -539,14 +526,19 @@
|
|
</el-row>
|
|
</el-row>
|
|
<el-row>
|
|
<el-row>
|
|
<el-form-item label="须知强制阅读时长">
|
|
<el-form-item label="须知强制阅读时长">
|
|
- <el-input v-model.trim="form.preNoticeStaySeconds">
|
|
|
|
- <template slot="append">秒</template>
|
|
|
|
- </el-input>
|
|
|
|
|
|
+ <el-input-number
|
|
|
|
+ :min="1"
|
|
|
|
+ :max="24 * 60"
|
|
|
|
+ step-strictly
|
|
|
|
+ :controls="false"
|
|
|
|
+ v-model.trim="form.preNoticeStaySeconds"
|
|
|
|
+ />(秒)
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-row>
|
|
</el-row>
|
|
<el-row>
|
|
<el-row>
|
|
- <el-form-item label="考后说明">
|
|
|
|
|
|
+ <el-form-item prop="postNotice" label="考后说明">
|
|
<VEditor
|
|
<VEditor
|
|
|
|
+ ref="postNoticeEditor"
|
|
:value="form.postNoticeClone"
|
|
:value="form.postNoticeClone"
|
|
style="width: 300px;"
|
|
style="width: 300px;"
|
|
@result="(v) => (form.postNotice = v)"
|
|
@result="(v) => (form.postNotice = v)"
|
|
@@ -559,9 +551,12 @@
|
|
<el-radio v-model="form.enableIpLimit" :label="0">否</el-radio>
|
|
<el-radio v-model="form.enableIpLimit" :label="0">否</el-radio>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-row>
|
|
</el-row>
|
|
- <el-row>
|
|
|
|
- <el-form-item label="IP段(*表示任意):">
|
|
|
|
- <el-input v-model.trim="form.ipAllow"></el-input>
|
|
|
|
|
|
+ <el-row v-if="form.enableIpLimit">
|
|
|
|
+ <el-form-item label="IP段(*表示任意):" prop="ipAllow">
|
|
|
|
+ <el-input
|
|
|
|
+ v-model.trim="form.ipAllow"
|
|
|
|
+ placeholder="192.168.10.1, 192.168.11.*, 172.10.*.*"
|
|
|
|
+ ></el-input>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-row>
|
|
</el-row>
|
|
</el-form>
|
|
</el-form>
|
|
@@ -620,7 +615,7 @@ export default {
|
|
set(v) {
|
|
set(v) {
|
|
if (v) {
|
|
if (v) {
|
|
this.form.breakResumeCount = 1;
|
|
this.form.breakResumeCount = 1;
|
|
- this.form.breakExpireSeconds = 0;
|
|
|
|
|
|
+ this.form.breakExpireSeconds = 60;
|
|
} else {
|
|
} else {
|
|
this.form.breakResumeCount = null;
|
|
this.form.breakResumeCount = null;
|
|
this.form.breakExpireSeconds = null;
|
|
this.form.breakExpireSeconds = null;
|
|
@@ -633,6 +628,9 @@ export default {
|
|
disableEdit() {
|
|
disableEdit() {
|
|
return this.form.monitorStatus === "FINISHED";
|
|
return this.form.monitorStatus === "FINISHED";
|
|
},
|
|
},
|
|
|
|
+ enablePrevilleges() {
|
|
|
|
+ return !!this.$store.state.user.orgInfo.enableMonitorRecord;
|
|
|
|
+ },
|
|
},
|
|
},
|
|
watch: {
|
|
watch: {
|
|
"form.mode": {
|
|
"form.mode": {
|
|
@@ -657,38 +655,11 @@ export default {
|
|
handler(v) {
|
|
handler(v) {
|
|
if (!v) {
|
|
if (!v) {
|
|
this.form.monitorVideoSource = [];
|
|
this.form.monitorVideoSource = [];
|
|
- this.form.monitorRecord = 0;
|
|
|
|
|
|
+ this.form.monitorRecord = [];
|
|
}
|
|
}
|
|
if (this.form.monitorVideoSource === null) {
|
|
if (this.form.monitorVideoSource === null) {
|
|
this.form.monitorVideoSource = [];
|
|
this.form.monitorVideoSource = [];
|
|
- }
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- "form.monitorVideoSource": {
|
|
|
|
- immediate: true,
|
|
|
|
- handler(v, ov) {
|
|
|
|
- if (!v) {
|
|
|
|
- this.form.monitorVideoSource = [];
|
|
|
|
- }
|
|
|
|
- if (
|
|
|
|
- // 没动静,不修改,避免死循环
|
|
|
|
- (v || []).includes("MOBILE_FIRST") !==
|
|
|
|
- (ov || []).includes("MOBILE_FIRST") &&
|
|
|
|
- !this.form.monitorVideoSource.includes("MOBILE_FIRST")
|
|
|
|
- ) {
|
|
|
|
- this.form.monitorVideoSource = this.form.monitorVideoSource.filter(
|
|
|
|
- (v) => v !== "MOBILE_SECOND"
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- if (
|
|
|
|
- // 没动静,不修改,避免死循环
|
|
|
|
- (v || []).includes("CLIENT_CAMERA") !==
|
|
|
|
- (ov || []).includes("CLIENT_CAMERA") &&
|
|
|
|
- !this.form.monitorVideoSource.includes("CLIENT_CAMERA")
|
|
|
|
- ) {
|
|
|
|
- this.form.monitorVideoSource = this.form.monitorVideoSource.filter(
|
|
|
|
- (v) => v !== "CLIENT_SCREEN"
|
|
|
|
- );
|
|
|
|
|
|
+ this.form.monitorRecord = [];
|
|
}
|
|
}
|
|
},
|
|
},
|
|
},
|
|
},
|
|
@@ -721,9 +692,12 @@ export default {
|
|
this.form.inProcessLivenessFixedRange = [0, 0];
|
|
this.form.inProcessLivenessFixedRange = [0, 0];
|
|
}
|
|
}
|
|
this.form.startEndTimeProxy = [this.form.startTime, this.form.endTime];
|
|
this.form.startEndTimeProxy = [this.form.startTime, this.form.endTime];
|
|
- this.form.monitorProxy = !!this.form.monitorVideoSource;
|
|
|
|
|
|
+ this.form.monitorRecord = this.form.monitorRecord || [];
|
|
|
|
+ this.form.monitorVideoSource = this.form.monitorVideoSource || [];
|
|
|
|
+ this.form.monitorProxy = !!this.form.monitorVideoSource.length;
|
|
this.form.preNoticeClone = this.form.preNotice;
|
|
this.form.preNoticeClone = this.form.preNotice;
|
|
this.form.postNoticeClone = this.form.postNotice;
|
|
this.form.postNoticeClone = this.form.postNotice;
|
|
|
|
+ this.parseMonitorVideoSource();
|
|
}
|
|
}
|
|
|
|
|
|
// sleep
|
|
// sleep
|
|
@@ -773,15 +747,76 @@ export default {
|
|
inProcessLivenessFixedRange: [0, 0],
|
|
inProcessLivenessFixedRange: [0, 0],
|
|
inProcessLivenessJudgePolicy: "ALL",
|
|
inProcessLivenessJudgePolicy: "ALL",
|
|
monitorProxy: false,
|
|
monitorProxy: false,
|
|
- monitorRecord: 0,
|
|
|
|
|
|
+ monitorRecord: [],
|
|
monitorVideoSource: [],
|
|
monitorVideoSource: [],
|
|
ipAllow: "",
|
|
ipAllow: "",
|
|
},
|
|
},
|
|
rules: {
|
|
rules: {
|
|
mode: { required: true, message: "必填" },
|
|
mode: { required: true, message: "必填" },
|
|
- name: { required: true, message: "必填" },
|
|
|
|
- code: { required: true, message: "必填" },
|
|
|
|
|
|
+ name: [
|
|
|
|
+ { required: true, message: "必填" },
|
|
|
|
+ { type: "string", min: 1, max: 30, message: "长度必须在1到30之间" },
|
|
|
|
+ ],
|
|
|
|
+ code: [
|
|
|
|
+ { required: true, message: "必填" },
|
|
|
|
+ { type: "string", min: 1, max: 30, message: "长度必须在1到30之间" },
|
|
|
|
+ ],
|
|
startEndTimeProxy: { required: true, message: "必填" },
|
|
startEndTimeProxy: { required: true, message: "必填" },
|
|
|
|
+ examCount: [
|
|
|
|
+ { required: true, message: "必填" },
|
|
|
|
+ { type: "number", min: 1, message: "必须大于0" },
|
|
|
|
+ ],
|
|
|
|
+ maxDurationSeconds: [
|
|
|
|
+ { required: true, message: "必填" },
|
|
|
|
+ { type: "number", min: 1, message: "必须大于0" },
|
|
|
|
+ ],
|
|
|
|
+ openingSeconds: {
|
|
|
|
+ validator: (rule, value) => {
|
|
|
|
+ // console.log(value);
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
+ if (
|
|
|
|
+ !this.form.isModeAnytime &&
|
|
|
|
+ this.form.maxDurationSeconds < value
|
|
|
|
+ ) {
|
|
|
|
+ reject("迟到时长必须小于考试时长");
|
|
|
|
+ } else {
|
|
|
|
+ resolve();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ minDurationSeconds: {
|
|
|
|
+ trigger: "change",
|
|
|
|
+ validator: (rule, value) => {
|
|
|
|
+ // console.log(value);
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
+ if (this.form.maxDurationSeconds < value) {
|
|
|
|
+ reject("冻结时长必须小于考试时长");
|
|
|
|
+ } else {
|
|
|
|
+ resolve();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ breakExpireSeconds: {
|
|
|
|
+ trigger: "change",
|
|
|
|
+ validator: (rule, value) => {
|
|
|
|
+ // console.log(value);
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
+ if (this.enableBreakProxy) {
|
|
|
|
+ if (this.form.monitorRecord.length && value > 25 * 60) {
|
|
|
|
+ reject("开启回放情况下,断点时长不得超过25分钟");
|
|
|
|
+ } else if (!value) {
|
|
|
|
+ reject("请设置断点时长");
|
|
|
|
+ } else {
|
|
|
|
+ resolve();
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ resolve();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
inProcessLivenessFixedRange: {
|
|
inProcessLivenessFixedRange: {
|
|
validator: (rule, value) => {
|
|
validator: (rule, value) => {
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
@@ -812,6 +847,94 @@ export default {
|
|
},
|
|
},
|
|
// message: "格式错误",
|
|
// message: "格式错误",
|
|
},
|
|
},
|
|
|
|
+ ipAllow: {
|
|
|
|
+ validator: (rule, value) => {
|
|
|
|
+ // console.log(value);
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
+ if (!this.form.enableIpLimit) {
|
|
|
|
+ resolve();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ const ips = value.split(",").map((v) => v.trim());
|
|
|
|
+ // console.log(ips);
|
|
|
|
+ const checkIpSeg = (seg, idx) => {
|
|
|
|
+ if (idx < 2) {
|
|
|
|
+ if (!/^\d+$/.test(seg)) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ } else if (idx >= 2 && idx < 4) {
|
|
|
|
+ if (!(/^\d+$/.test(seg) || /^\*$/.test(seg))) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+ };
|
|
|
|
+ if (
|
|
|
|
+ ips.every(
|
|
|
|
+ (v) =>
|
|
|
|
+ v.split(".").length === 4 && v.split(".").every(checkIpSeg)
|
|
|
|
+ )
|
|
|
|
+ ) {
|
|
|
|
+ resolve();
|
|
|
|
+ } else {
|
|
|
|
+ reject("格式不匹配");
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ postNotice: {
|
|
|
|
+ trigger: "change",
|
|
|
|
+ validator: (rule, value) => {
|
|
|
|
+ // console.log(value);
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
+ if (
|
|
|
|
+ value &&
|
|
|
|
+ this.$refs.postNoticeEditor.getTextContent().length > 1000
|
|
|
|
+ ) {
|
|
|
|
+ reject("考后说明最多允许输入1000个字符");
|
|
|
|
+ } else {
|
|
|
|
+ resolve();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ preNotice: {
|
|
|
|
+ trigger: "change",
|
|
|
|
+ validator: (rule, value) => {
|
|
|
|
+ // console.log(value);
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
+ if (
|
|
|
|
+ value &&
|
|
|
|
+ this.$refs.preNoticeEditor.getTextContent().length > 1000
|
|
|
|
+ ) {
|
|
|
|
+ reject("考试须知最多允许输入1000个字符");
|
|
|
|
+ } else {
|
|
|
|
+ resolve();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ sources: [
|
|
|
|
+ "MOBILE_FIRST",
|
|
|
|
+ "MOBILE_SECOND",
|
|
|
|
+ "CLIENT_CAMERA",
|
|
|
|
+ "CLIENT_SCREEN",
|
|
|
|
+ ],
|
|
|
|
+ monitorTypes: {
|
|
|
|
+ 0: "关闭",
|
|
|
|
+ 1: "直播",
|
|
|
|
+ 2: "直播+回放",
|
|
|
|
+ },
|
|
|
|
+ monitorTinyTypes: {
|
|
|
|
+ 0: "关闭",
|
|
|
|
+ 1: "直播",
|
|
|
|
+ },
|
|
|
|
+ monitorVideoSource: {
|
|
|
|
+ CLIENT_CAMERA: "0",
|
|
|
|
+ CLIENT_SCREEN: "0",
|
|
|
|
+ MOBILE_FIRST: "0",
|
|
|
|
+ MOBILE_SECOND: "0",
|
|
},
|
|
},
|
|
orgSetting: null,
|
|
orgSetting: null,
|
|
loading: false,
|
|
loading: false,
|
|
@@ -819,7 +942,7 @@ export default {
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
monitorImgSrc(monitorSource) {
|
|
monitorImgSrc(monitorSource) {
|
|
- const selected = this.form.monitorVideoSource.includes(monitorSource);
|
|
|
|
|
|
+ const selected = this.monitorVideoSource[monitorSource] !== "0";
|
|
const selectedStr = selected ? "-selected" : "";
|
|
const selectedStr = selected ? "-selected" : "";
|
|
if (monitorSource === "MOBILE_FIRST") {
|
|
if (monitorSource === "MOBILE_FIRST") {
|
|
return `mobile-first-img${selectedStr}`;
|
|
return `mobile-first-img${selectedStr}`;
|
|
@@ -836,11 +959,52 @@ export default {
|
|
|
|
|
|
return "";
|
|
return "";
|
|
},
|
|
},
|
|
|
|
+ monitorClientCameraChange(val) {
|
|
|
|
+ if (val === "0" || val === "2") {
|
|
|
|
+ this.monitorVideoSource.CLIENT_SCREEN = "0";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.monitorVideoSourceChange();
|
|
|
|
+ },
|
|
|
|
+ monitorClientScreenChange() {
|
|
|
|
+ this.monitorVideoSourceChange();
|
|
|
|
+ },
|
|
|
|
+ monitorMobileFirstChange(val) {
|
|
|
|
+ if (val === "0") this.monitorVideoSource.MOBILE_SECOND = "0";
|
|
|
|
+ this.monitorVideoSourceChange();
|
|
|
|
+ },
|
|
|
|
+ monitorVideoSourceChange() {
|
|
|
|
+ let monitorVideoSource = [],
|
|
|
|
+ monitorRecord = [];
|
|
|
|
+ this.sources.forEach((source) => {
|
|
|
|
+ if (this.monitorVideoSource[source] === "0") return;
|
|
|
|
+ if (this.monitorVideoSource[source] === "2") {
|
|
|
|
+ monitorRecord.push(source);
|
|
|
|
+ }
|
|
|
|
+ monitorVideoSource.push(source);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.form.monitorVideoSource = monitorVideoSource;
|
|
|
|
+ this.form.monitorRecord = monitorRecord;
|
|
|
|
+ },
|
|
|
|
+ parseMonitorVideoSource() {
|
|
|
|
+ this.sources.forEach((source) => {
|
|
|
|
+ const hasRecord = this.form.monitorRecord.includes(source);
|
|
|
|
+ const hasSource = this.form.monitorVideoSource.includes(source);
|
|
|
|
+ if (hasRecord) {
|
|
|
|
+ this.monitorVideoSource[source] = "2";
|
|
|
|
+ } else if (hasSource) {
|
|
|
|
+ this.monitorVideoSource[source] = "1";
|
|
|
|
+ } else {
|
|
|
|
+ this.monitorVideoSource[source] = "0";
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
async save() {
|
|
async save() {
|
|
try {
|
|
try {
|
|
await this.$refs.form1.validate();
|
|
await this.$refs.form1.validate();
|
|
await this.$refs.form2.validate();
|
|
await this.$refs.form2.validate();
|
|
- // await this.$refs.form3.validate();
|
|
|
|
|
|
+ await this.$refs.form3.validate();
|
|
} catch (error) {
|
|
} catch (error) {
|
|
console.log("校验失败", error);
|
|
console.log("校验失败", error);
|
|
this.$notify({
|
|
this.$notify({
|
|
@@ -909,6 +1073,79 @@ export default {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+.monitor-config {
|
|
|
|
+ &-options {
|
|
|
|
+ display: inline-block;
|
|
|
|
+ vertical-align: top;
|
|
|
|
+ width: 470px;
|
|
|
|
+
|
|
|
|
+ .el-form-item {
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ &-view {
|
|
|
|
+ position: relative;
|
|
|
|
+ display: inline-block;
|
|
|
|
+ vertical-align: top;
|
|
|
|
+ width: 498px;
|
|
|
|
+ height: 257px;
|
|
|
|
+ background: #f0f4f9;
|
|
|
|
+ border-radius: 6px;
|
|
|
|
+ border: 1px solid #e8edf3;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.monitor-title {
|
|
|
|
+ height: 20px;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ font-weight: 600;
|
|
|
|
+ color: #202b4b;
|
|
|
|
+ line-height: 20px;
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
+ padding-left: 20px;
|
|
|
|
+
|
|
|
|
+ &::before {
|
|
|
|
+ content: "";
|
|
|
|
+ display: inline-block;
|
|
|
|
+ vertical-align: middle;
|
|
|
|
+ width: 4px;
|
|
|
|
+ height: 10px;
|
|
|
|
+ background: #1886fe;
|
|
|
|
+ border-radius: 2px;
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.monitor-item {
|
|
|
|
+ position: absolute;
|
|
|
|
+ text-align: center;
|
|
|
|
+
|
|
|
|
+ &-img {
|
|
|
|
+ margin: 0 auto;
|
|
|
|
+ }
|
|
|
|
+ &-desc {
|
|
|
|
+ font-size: 12px;
|
|
|
|
+ line-height: 1;
|
|
|
|
+ margin: 5px 0 0;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.monitor-client-camera {
|
|
|
|
+ left: 171px;
|
|
|
|
+ top: 21px;
|
|
|
|
+}
|
|
|
|
+.monitor-client-screen {
|
|
|
|
+ left: 124px;
|
|
|
|
+ bottom: 20px;
|
|
|
|
+}
|
|
|
|
+.monitor-mobile-first {
|
|
|
|
+ left: 20px;
|
|
|
|
+ top: 20px;
|
|
|
|
+}
|
|
|
|
+.monitor-mobile-second {
|
|
|
|
+ bottom: 20px;
|
|
|
|
+ right: 20px;
|
|
|
|
+}
|
|
|
|
+
|
|
.mobile-first-img {
|
|
.mobile-first-img {
|
|
background-image: url(./imgs/手机监考主机位.png);
|
|
background-image: url(./imgs/手机监考主机位.png);
|
|
background-repeat: no-repeat;
|
|
background-repeat: no-repeat;
|
|
@@ -956,18 +1193,87 @@ export default {
|
|
background-image: url(./imgs/电脑操作录屏-选中.png);
|
|
background-image: url(./imgs/电脑操作录屏-选中.png);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+.monitor-line-point {
|
|
|
|
+ content: "";
|
|
|
|
+ display: block;
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 5px;
|
|
|
|
+ height: 5px;
|
|
|
|
+ border: 1px solid #c1cbdb;
|
|
|
|
+ border-radius: 50%;
|
|
|
|
+ background: #f0f4f9;
|
|
|
|
+}
|
|
|
|
+.monitor-line-client-camera {
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 0;
|
|
|
|
+ height: 23px;
|
|
|
|
+ border-left: 1px solid #c1cbdb;
|
|
|
|
+ top: 89px;
|
|
|
|
+ left: 219px;
|
|
|
|
|
|
-.enhance-left-bottom-line {
|
|
|
|
- border-left-style: solid !important;
|
|
|
|
- border-bottom-style: solid !important;
|
|
|
|
|
|
+ &::before {
|
|
|
|
+ @extend .monitor-line-point;
|
|
|
|
+ left: -3px;
|
|
|
|
+ top: 0;
|
|
|
|
+ }
|
|
|
|
+ &::after {
|
|
|
|
+ @extend .monitor-line-point;
|
|
|
|
+ left: -3px;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+.monitor-line-mobile-first {
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 56px;
|
|
|
|
+ height: 28px;
|
|
|
|
+ bottom: 96px;
|
|
|
|
+ left: 63px;
|
|
|
|
+ border-left: 1px solid #c1cbdb;
|
|
|
|
+ border-bottom: 1px solid #c1cbdb;
|
|
|
|
|
|
-.enhance-right-bottom-line {
|
|
|
|
- border-right-style: solid !important;
|
|
|
|
- border-top-style: solid !important;
|
|
|
|
|
|
+ &::before {
|
|
|
|
+ @extend .monitor-line-point;
|
|
|
|
+ left: -3px;
|
|
|
|
+ top: 0;
|
|
|
|
+ }
|
|
|
|
+ &::after {
|
|
|
|
+ @extend .monitor-line-point;
|
|
|
|
+ right: 0;
|
|
|
|
+ bottom: -3px;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+.monitor-line-mobile-second {
|
|
|
|
+ span:nth-of-type(1) {
|
|
|
|
+ display: block;
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 35px;
|
|
|
|
+ height: 63px;
|
|
|
|
+ bottom: 92px;
|
|
|
|
+ right: 139px;
|
|
|
|
+ border-right: 1px solid #c1cbdb;
|
|
|
|
+ border-bottom: 1px solid #c1cbdb;
|
|
|
|
|
|
-.enhance-right-line {
|
|
|
|
- border-right-style: solid !important;
|
|
|
|
|
|
+ &::before {
|
|
|
|
+ @extend .monitor-line-point;
|
|
|
|
+ left: 0;
|
|
|
|
+ bottom: -3px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ span:nth-of-type(2) {
|
|
|
|
+ display: block;
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 78px;
|
|
|
|
+ height: 23px;
|
|
|
|
+ top: 100px;
|
|
|
|
+ right: 61px;
|
|
|
|
+ border-right: 1px solid #c1cbdb;
|
|
|
|
+ border-top: 1px solid #c1cbdb;
|
|
|
|
+
|
|
|
|
+ &::after {
|
|
|
|
+ @extend .monitor-line-point;
|
|
|
|
+ right: -3px;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
</style>
|
|
</style>
|