完善 预览功能
This commit is contained in:
parent
24502a526d
commit
bcd6f63bb3
|
|
@ -13,7 +13,7 @@
|
|||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "",
|
||||
"launchUrl": "/swagger/index.html",
|
||||
"applicationUrl": "http://*:5238",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
|
|
|
|||
|
|
@ -9,21 +9,21 @@ export class hTableAPI {
|
|||
this.url = url;
|
||||
}
|
||||
PageList(data = {}) {
|
||||
return http.request<Res<any>>("post", `api/${this.url}/PageList`, { data });
|
||||
return http.request<any>("post", `api/${this.url}/PageList`, { data });
|
||||
}
|
||||
Info(tag) {
|
||||
const pUrl = `api/${this.url}/${tag}`;
|
||||
let getUrl = pUrl;
|
||||
return http.request<Res<any>>("get", getUrl);
|
||||
return http.request<any>("get", getUrl);
|
||||
}
|
||||
edit(data) {
|
||||
return http.request<Res<any>>("post", `api/${this.url}/Edit`, { data });
|
||||
return http.request<any>("post", `api/${this.url}/Edit`, { data });
|
||||
}
|
||||
delete(data) {
|
||||
return http.request<Res<any>>("post", `api/${this.url}/Del`, { data });
|
||||
return http.request<any>("post", `api/${this.url}/Del`, { data });
|
||||
}
|
||||
querycombo(data = {}) {
|
||||
return http.request<Res<ComboModel[]>>(
|
||||
return http.request<ComboModel[]>(
|
||||
"post",
|
||||
`api/${this.url}/QueryCombo`,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ export interface Question {
|
|||
}
|
||||
|
||||
export interface VideoKnowRes {
|
||||
Theme: string;
|
||||
Content: string;
|
||||
KnowPoint: string;
|
||||
KnowPointId: number;
|
||||
QuestionArr: Question[];
|
||||
theme: string;
|
||||
content: string;
|
||||
knowPoint: string;
|
||||
knowPointId: number;
|
||||
questionArr: Question[];
|
||||
startTime: number;
|
||||
}
|
||||
|
||||
|
|
@ -25,8 +25,8 @@ export interface SenseVoiceRes {
|
|||
export interface ShowTaskInfoRes {
|
||||
captions: SenseVoiceRes[];
|
||||
captions1: SenseVoiceRes[];
|
||||
VideoKnows: VideoKnowRes[];
|
||||
MediaUrl: string;
|
||||
videoKnows: VideoKnowRes[];
|
||||
mediaUrl: string;
|
||||
}
|
||||
export interface RowRloadResult {
|
||||
progress: string;
|
||||
|
|
|
|||
|
|
@ -303,13 +303,13 @@ export class SearchConditions {
|
|||
this.defaultConditions = [];
|
||||
this.Conditions = [];
|
||||
}
|
||||
/** 是否显示搜索 */
|
||||
/** 是否显示搜索 [true]*/
|
||||
show?: boolean;
|
||||
/** 显示分页器 */
|
||||
/** 显示分页器 [true]*/
|
||||
showPage?:boolean;
|
||||
/** 当前页码 */
|
||||
/** 当前页码 [0]*/
|
||||
PageIndex?: number;
|
||||
/** 每页大小 */
|
||||
/** 每页大小 [20]*/
|
||||
PageSize?: number;
|
||||
/** 排序字段 */
|
||||
OrderBy?: string;
|
||||
|
|
|
|||
|
|
@ -248,12 +248,9 @@ function handleResetForm() {
|
|||
function tableClose() {
|
||||
handleAddCallback();
|
||||
}
|
||||
function pageSizeChange(o) {
|
||||
table.value.search.PageSize = o;
|
||||
fetchPagedData();
|
||||
}
|
||||
function pageIndexChange(o) {
|
||||
table.value.search.PageIndex = o - 1;
|
||||
function paginationChange(currentPage: number, pageSize: number) {
|
||||
table.value.search.PageIndex = currentPage - 1;
|
||||
table.value.search.PageSize = pageSize;
|
||||
fetchPagedData();
|
||||
}
|
||||
|
||||
|
|
@ -375,7 +372,7 @@ function fetchPagedData() {
|
|||
table.value.data = res.data.map((s, i) => {
|
||||
return { ...s, customId: i };
|
||||
});
|
||||
table.value.pageData = res.data;
|
||||
table.value.pageData = res;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -556,13 +553,10 @@ function fetchPagedData() {
|
|||
"
|
||||
>
|
||||
<el-pagination
|
||||
:current-page="table.search.PageIndex + 1"
|
||||
:page-sizes="[20, 40, 80, 100]"
|
||||
:page-size="table.search.PageSize"
|
||||
layout="prev, pager, next,sizes, total"
|
||||
:total="table.pageData.total"
|
||||
@size-change="pageSizeChange"
|
||||
@current-change="pageIndexChange"
|
||||
@change="paginationChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,20 @@ export default {
|
|||
},
|
||||
{
|
||||
path: "/welcome/showTask",
|
||||
name: "ShowTask",
|
||||
name: "showTask",
|
||||
component: () => import("@/views/welcome/showTask.vue"),
|
||||
meta: {
|
||||
title: "预览任务",
|
||||
showLink: false
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/welcome/runningTask",
|
||||
name: "runningTask",
|
||||
component: () => import("@/views/welcome/runningTask.vue"),
|
||||
meta: {
|
||||
title: "进行中任务",
|
||||
showLink: VITE_HIDE_HOME === "true" ? false : true
|
||||
showLink: true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -17,16 +17,16 @@ import { ReStart, RowRload } from "@/api/videoTask";
|
|||
import { Refresh } from "@element-plus/icons-vue";
|
||||
import { message } from "@/utils/message";
|
||||
import { json } from "stream/consumers";
|
||||
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const ControllerName = "VideoTask";
|
||||
|
||||
defineOptions({
|
||||
name: ControllerName,
|
||||
});
|
||||
|
||||
const props = defineProps<{
|
||||
data: any;
|
||||
}>();
|
||||
|
||||
const route = useRouter();
|
||||
function searchCallback(data) {}
|
||||
const table = ref<{ initTable: (config: TableConfig) => void }>();
|
||||
const tableData: TableConfig = intTableData({
|
||||
|
|
@ -40,6 +40,7 @@ const tableData: TableConfig = intTableData({
|
|||
// 查询条件
|
||||
show: true,
|
||||
PageSize: 10,
|
||||
showPage: true,
|
||||
},
|
||||
operationColumn: true, // 显示操作按钮
|
||||
operationColumnData: [],
|
||||
|
|
@ -100,6 +101,7 @@ let redisChannelEnum = ref<ComboModel[]>([]);
|
|||
const showTable = ref(false);
|
||||
onMounted(async () => {
|
||||
//初始化数据
|
||||
|
||||
tableData.column.videoType.setting.datasource = await getenum("AttachmentsInfoType");
|
||||
tableData.column.lastEnum.setting.datasource = await getenum("RedisChannelEnum");
|
||||
tableData.column.subject.setting.datasource = await getenum("SubjectEnum");
|
||||
|
|
@ -132,11 +134,12 @@ async function RloadTaskInfo(row: any) {
|
|||
element.time = formatDateToChinese(
|
||||
row.TaskInfo.startTime[element.title.toLowerCase()]
|
||||
);
|
||||
if (element.value < row.TaskInfo.lastEnum) {
|
||||
let i = row.TaskInfo.stepData.indexOf(element);
|
||||
if (i < row.TaskInfo.active) {
|
||||
element.status = "finish";
|
||||
} else if (element.value == 60) {
|
||||
element.status = "success";
|
||||
} else if (element.value == row.TaskInfo.lastEnum) {
|
||||
} else if (i == row.TaskInfo.active) {
|
||||
element.status = "process";
|
||||
} else {
|
||||
element.status = "wait";
|
||||
|
|
@ -198,7 +201,16 @@ const stepData = ref<StepData[]>([
|
|||
<el-button type="danger" @click="showDialog(props.row.id)"
|
||||
>重试</el-button
|
||||
>
|
||||
<el-button type="primary">预览</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="
|
||||
route.push({
|
||||
path: '/welcome/showTask',
|
||||
query: { id: props.row.id.toString() },
|
||||
})
|
||||
"
|
||||
>预览</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,233 @@
|
|||
<template>
|
||||
<div id="video-container">
|
||||
<div v-if="videoKnows.length > 0">
|
||||
<div id="segmentsContainer" class="sc" :class="{ locked: isLocked }">
|
||||
<h2>
|
||||
<button class="gudingBtn" @click="toggleLock">
|
||||
{{ isLocked ? "🔓" : "🔒" }}
|
||||
</button>
|
||||
</h2>
|
||||
<div v-for="(item, index) in videoKnows" :key="index" class="knowDiv">
|
||||
<div class="knowTtile">
|
||||
<div style="cursor: pointer" @click="spClick(index, $event)">
|
||||
<div class="knowTtileTheme">{{ getTimeRange(item) }} {{ item.Theme }}</div>
|
||||
<span class="kSpan">#{{ item.KnowPointId }} {{ item.KnowPoint }}</span>
|
||||
</div>
|
||||
<div>概览: {{ item.Content }}</div>
|
||||
<br />
|
||||
<div v-if="item.QuestionArr && item.QuestionArr.length > 0">
|
||||
<div
|
||||
v-for="(q, qIndex) in item.QuestionArr"
|
||||
:key="qIndex"
|
||||
class="knowQuestion"
|
||||
@click="spClickTime(q.startTime)"
|
||||
>
|
||||
<h3>
|
||||
问题: <span class="kSpan">{{ q.startTime }} 秒</span>
|
||||
</h3>
|
||||
<div class="kSpan">{{ q.topicStem }}</div>
|
||||
<div>{{ q.question }}</div>
|
||||
<img
|
||||
style="text-align: center"
|
||||
:src="q.pPTImageUrl"
|
||||
width="320"
|
||||
height="180"
|
||||
:alt="'问题图片' + qIndex"
|
||||
/>
|
||||
</div>
|
||||
<br />
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
</div>
|
||||
<button class="kBtn" @click="spClick(index, $event)">
|
||||
<span>{{ getFirstChar(item.Theme) }} {{ item.Theme }}</span>
|
||||
<br />
|
||||
<span class="kSpan textEllipsis"
|
||||
>#{{ item.KnowPointId }} {{ item.KnowPoint }}</span
|
||||
>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<video ref="videoPlayerEL" controls autoplay>
|
||||
<source :src="videoSrc" type="video/mp4" />
|
||||
</video>
|
||||
<div ref="subtitleAreaEL" class="subtitles">{{ currentSubtitle }}</div>
|
||||
<div ref="subtitleArea1EL" class="subtitles" :style="subtitleStyle">
|
||||
{{ currentSubtitle1 }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SenseVoiceRes, ShowTaskInfo, VideoKnowRes } from "@/api/videoTask";
|
||||
import { message } from "@/utils/message";
|
||||
import { isEmpty } from "@pureadmin/utils";
|
||||
import { ref, onMounted, nextTick } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
defineOptions({
|
||||
name: "runningTask",
|
||||
});
|
||||
|
||||
const subtitleAreaEL = ref<HTMLElement | null>(null);
|
||||
const subtitleArea1EL = ref<HTMLElement | null>(null);
|
||||
const videoPlayerEL = ref<HTMLVideoElement | null>(null);
|
||||
|
||||
// 响应式数据
|
||||
const videoKnows = ref<VideoKnowRes[]>([]);
|
||||
const currentSubtitle = ref("");
|
||||
const currentSubtitle1 = ref("");
|
||||
const isLocked = ref(false);
|
||||
const displayButton = ref<any[]>([]);
|
||||
const lastSegments = ref<any>(null);
|
||||
const videoSrc = ref("");
|
||||
const subtitles = ref<SenseVoiceRes[]>([]);
|
||||
const b1 = ref([]);
|
||||
const subtitles1 = ref<SenseVoiceRes[]>([]);
|
||||
|
||||
// 计算样式
|
||||
const subtitleStyle = {
|
||||
bottom: "101px",
|
||||
backgroundColor: "rgb(99 129 103 / 50%)",
|
||||
};
|
||||
|
||||
// 获取首字符
|
||||
const getFirstChar = (str: string): string => {
|
||||
return str ? str.charAt(0) : "";
|
||||
};
|
||||
|
||||
// 切换锁定状态
|
||||
const toggleLock = () => {
|
||||
isLocked.value = !isLocked.value;
|
||||
};
|
||||
|
||||
// 点击知识点
|
||||
const spClick = (index: number, event: Event) => {
|
||||
if (videoPlayerEL && displayButton.value[index]) {
|
||||
videoPlayerEL.value.currentTime = displayButton.value[index].startTime;
|
||||
}
|
||||
};
|
||||
|
||||
// 点击时间跳转
|
||||
const spClickTime = (startTime: number) => {
|
||||
if (videoPlayerEL) {
|
||||
videoPlayerEL.value.currentTime = startTime;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化知识点按钮
|
||||
const initKD = () => {
|
||||
const btns = document.getElementsByClassName("kBtn");
|
||||
if (btns.length === 0) return;
|
||||
|
||||
displayButton.value = b1.value.map((s: any, i: number) => {
|
||||
return { ...s, button: btns[i] };
|
||||
});
|
||||
};
|
||||
|
||||
// 设置数据(模拟从后端获取)
|
||||
const setDB = (
|
||||
a: SenseVoiceRes[],
|
||||
a1: SenseVoiceRes[],
|
||||
videoKnows: VideoKnowRes[],
|
||||
c: string
|
||||
) => {
|
||||
subtitles.value = a;
|
||||
subtitles1.value = a1;
|
||||
b1.value = videoKnows;
|
||||
videoSrc.value = c;
|
||||
|
||||
// 初始化视频数据
|
||||
init();
|
||||
};
|
||||
|
||||
// 初始化
|
||||
const init = () => {
|
||||
if (!videoPlayerEL) return;
|
||||
|
||||
// 视频时间变化监听
|
||||
videoPlayerEL.value.addEventListener("timeupdate", function () {
|
||||
if (displayButton.value.length === 0) initKD();
|
||||
|
||||
const currentTime = videoPlayerEL.value.currentTime;
|
||||
if (subtitleAreaEL) subtitleAreaEL.value.textContent = "";
|
||||
if (subtitleArea1EL) subtitleArea1EL.value.textContent = "";
|
||||
|
||||
// 更新字幕
|
||||
subtitles.value.forEach((subtitle, index) => {
|
||||
if (
|
||||
currentTime >= subtitle.start &&
|
||||
currentTime <= subtitle.end &&
|
||||
subtitleAreaEL &&
|
||||
subtitleAreaEL.value.textContent !== subtitle.text
|
||||
) {
|
||||
currentSubtitle.value = subtitle.text;
|
||||
currentSubtitle1.value = subtitles1.value[index]?.text || "";
|
||||
}
|
||||
});
|
||||
|
||||
// 更新当前时间段
|
||||
const segment = displayButton.value.findLast((s: any) => currentTime >= s.startTime);
|
||||
if (segment) {
|
||||
segment.button.style.backgroundColor = "rgb(238, 200, 118)";
|
||||
if (lastSegments.value && lastSegments.value !== segment) {
|
||||
lastSegments.value.button.style.backgroundColor = "rgb(240, 249, 235)";
|
||||
}
|
||||
lastSegments.value = segment;
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 扩展功能:格式化开始和结束时间范围
|
||||
* @param segment 包含 StartTime 和 EndTime 的对象
|
||||
* @returns 格式化的时间范围字符串 (MM:SS - MM:SS)
|
||||
*/
|
||||
function getTimeRange(segment: VideoKnowRes): string {
|
||||
const startTime = segment.startTime ?? 0;
|
||||
|
||||
const startMinutes = Math.floor(startTime / 60);
|
||||
const startSeconds = Math.floor(startTime % 60);
|
||||
|
||||
const sf = startMinutes.toString().padStart(2, "0");
|
||||
const sm = startSeconds.toString().padStart(2, "0");
|
||||
|
||||
return `${sf}:${sm}`;
|
||||
}
|
||||
// 组件挂载后
|
||||
onMounted(async () => {
|
||||
// 初始化MathJax
|
||||
if (window.MathJax) {
|
||||
window.MathJax = {
|
||||
tex: {
|
||||
inlineMath: [
|
||||
["$", "$"],
|
||||
["\\(", "\\)"],
|
||||
],
|
||||
displayMath: [
|
||||
["$$", "$$"],
|
||||
["\\[", "\\]"],
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
// 获取当前路由对象
|
||||
const route = useRoute();
|
||||
const data = isEmpty(route.params) ? route.query : route.params;
|
||||
if (isEmpty(data.id) || data.id == null) {
|
||||
message("无效的任务", { type: "warning" });
|
||||
return;
|
||||
}
|
||||
let info = await ShowTaskInfo(data.id);
|
||||
debugger;
|
||||
setDB(info.captions, info.captions1, info.VideoKnows, info.MediaUrl);
|
||||
});
|
||||
|
||||
// 扩展Window接口以包含全局变量
|
||||
declare global {
|
||||
interface Window {
|
||||
MathJax: any;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -10,14 +10,14 @@
|
|||
<div v-for="(item, index) in videoKnows" :key="index" class="knowDiv">
|
||||
<div class="knowTtile">
|
||||
<div style="cursor: pointer" @click="spClick(index, $event)">
|
||||
<div class="knowTtileTheme">{{ getTimeRange(item) }} {{ item.Theme }}</div>
|
||||
<span class="kSpan">#{{ item.KnowPointId }} {{ item.KnowPoint }}</span>
|
||||
<div class="knowTtileTheme">{{ getTimeRange(item) }} {{ item.theme }}</div>
|
||||
<span class="kSpan">#{{ item.knowPointId }} {{ item.knowPoint }}</span>
|
||||
</div>
|
||||
<div>概览: {{ item.Content }}</div>
|
||||
<div>概览: {{ item.content }}</div>
|
||||
<br />
|
||||
<div v-if="item.QuestionArr && item.QuestionArr.length > 0">
|
||||
<div v-if="item.questionArr && item.questionArr.length > 0">
|
||||
<div
|
||||
v-for="(q, qIndex) in item.QuestionArr"
|
||||
v-for="(q, qIndex) in item.questionArr"
|
||||
:key="qIndex"
|
||||
class="knowQuestion"
|
||||
@click="spClickTime(q.startTime)"
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
:src="q.pPTImageUrl"
|
||||
width="320"
|
||||
height="180"
|
||||
:alt="'问题图片' + qIndex"
|
||||
:alt="'试题' + qIndex"
|
||||
/>
|
||||
</div>
|
||||
<br />
|
||||
|
|
@ -41,16 +41,16 @@
|
|||
<br />
|
||||
</div>
|
||||
<button class="kBtn" @click="spClick(index, $event)">
|
||||
<span>{{ getFirstChar(item.Theme) }} {{ item.Theme }}</span>
|
||||
<span>{{ getTimeRange(item) }} {{ item.theme }}</span>
|
||||
<br />
|
||||
<span class="kSpan textEllipsis"
|
||||
>#{{ item.KnowPointId }} {{ item.KnowPoint }}</span
|
||||
>#{{ item.knowPointId }} {{ item.knowPoint }}</span
|
||||
>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<video ref="videoPlayerEL" controls autoplay>
|
||||
<video ref="videoPlayerEL" @timeupdate="timeupdateVideo" controls autoplay>
|
||||
<source :src="videoSrc" type="video/mp4" />
|
||||
</video>
|
||||
<div ref="subtitleAreaEL" class="subtitles">{{ currentSubtitle }}</div>
|
||||
|
|
@ -62,11 +62,14 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { SenseVoiceRes, ShowTaskInfo, VideoKnowRes } from "@/api/videoTask";
|
||||
import { message } from "@/utils/message";
|
||||
import { isEmpty } from "@pureadmin/utils";
|
||||
import { ref, onMounted, nextTick } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const subtitleAreaEL = ref<HTMLElement | null>(null);
|
||||
const subtitleArea1EL = ref<HTMLElement | null>(null);
|
||||
defineOptions({
|
||||
name: "showTask",
|
||||
});
|
||||
const videoPlayerEL = ref<HTMLVideoElement | null>(null);
|
||||
|
||||
// 响应式数据
|
||||
|
|
@ -125,54 +128,43 @@ const initKD = () => {
|
|||
const setDB = (
|
||||
a: SenseVoiceRes[],
|
||||
a1: SenseVoiceRes[],
|
||||
videoKnows: VideoKnowRes[],
|
||||
vKnows: VideoKnowRes[],
|
||||
c: string
|
||||
) => {
|
||||
subtitles.value = a;
|
||||
subtitles1.value = a1;
|
||||
b1.value = videoKnows;
|
||||
b1.value = vKnows;
|
||||
videoKnows.value = vKnows;
|
||||
videoSrc.value = c;
|
||||
|
||||
// 初始化视频数据
|
||||
init();
|
||||
videoPlayerEL.value?.load();
|
||||
videoPlayerEL.value?.play();
|
||||
};
|
||||
function timeupdateVideo() {
|
||||
if (displayButton.value.length === 0) initKD();
|
||||
|
||||
// 初始化
|
||||
const init = () => {
|
||||
if (!videoPlayerEL) return;
|
||||
const currentTime = videoPlayerEL.value.currentTime;
|
||||
// 更新字幕
|
||||
let subtitleI = subtitles.value.findIndex(
|
||||
(subtitle) => currentTime >= subtitle.start && currentTime <= subtitle.end
|
||||
);
|
||||
if (subtitleI > -1 && currentSubtitle.value !== subtitles.value[subtitleI].text) {
|
||||
currentSubtitle.value = subtitles.value[subtitleI].text;
|
||||
currentSubtitle1.value = subtitles1.value[subtitleI]?.text || "";
|
||||
} else if (subtitleI == -1) {
|
||||
currentSubtitle.value = "";
|
||||
currentSubtitle1.value = "";
|
||||
}
|
||||
|
||||
// 视频时间变化监听
|
||||
videoPlayerEL.value.addEventListener("timeupdate", function () {
|
||||
if (displayButton.value.length === 0) initKD();
|
||||
|
||||
const currentTime = videoPlayerEL.value.currentTime;
|
||||
if (subtitleAreaEL) subtitleAreaEL.value.textContent = "";
|
||||
if (subtitleArea1EL) subtitleArea1EL.value.textContent = "";
|
||||
|
||||
// 更新字幕
|
||||
subtitles.value.forEach((subtitle, index) => {
|
||||
if (
|
||||
currentTime >= subtitle.start &&
|
||||
currentTime <= subtitle.end &&
|
||||
subtitleAreaEL &&
|
||||
subtitleAreaEL.value.textContent !== subtitle.text
|
||||
) {
|
||||
currentSubtitle.value = subtitle.text;
|
||||
currentSubtitle1.value = subtitles1.value[index]?.text || "";
|
||||
}
|
||||
});
|
||||
|
||||
// 更新当前时间段
|
||||
const segment = displayButton.value.findLast((s: any) => currentTime >= s.startTime);
|
||||
if (segment) {
|
||||
segment.button.style.backgroundColor = "rgb(238, 200, 118)";
|
||||
if (lastSegments.value && lastSegments.value !== segment) {
|
||||
lastSegments.value.button.style.backgroundColor = "rgb(240, 249, 235)";
|
||||
}
|
||||
lastSegments.value = segment;
|
||||
// 更新当前时间段
|
||||
const segment = displayButton.value.findLast((s: any) => currentTime >= s.startTime);
|
||||
if (segment) {
|
||||
segment.button.style.backgroundColor = "rgb(238, 200, 118)";
|
||||
if (lastSegments.value && lastSegments.value !== segment) {
|
||||
lastSegments.value.button.style.backgroundColor = "rgb(240, 249, 235)";
|
||||
}
|
||||
});
|
||||
};
|
||||
lastSegments.value = segment;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 扩展功能:格式化开始和结束时间范围
|
||||
* @param segment 包含 StartTime 和 EndTime 的对象
|
||||
|
|
@ -206,12 +198,15 @@ onMounted(async () => {
|
|||
},
|
||||
};
|
||||
}
|
||||
|
||||
// 获取当前路由对象
|
||||
const route = useRoute();
|
||||
const id = route.params.id;
|
||||
let info = await ShowTaskInfo(id);
|
||||
setDB(info.captions, info.captions1, info.VideoKnows, info.MediaUrl);
|
||||
const data = isEmpty(route.params) ? route.query : route.params;
|
||||
if (isEmpty(data.id) || data.id == null) {
|
||||
message("无效的任务", { type: "warning" });
|
||||
return;
|
||||
}
|
||||
let info = await ShowTaskInfo(data.id);
|
||||
setDB(info.captions, info.captions1, info.videoKnows, info.mediaUrl);
|
||||
});
|
||||
|
||||
// 扩展Window接口以包含全局变量
|
||||
|
|
@ -221,3 +216,124 @@ declare global {
|
|||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.locked {
|
||||
right: 0px !important;
|
||||
}
|
||||
#video-container {
|
||||
position: relative;
|
||||
width: 1660px;
|
||||
height: 850px;
|
||||
float: left;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.kSpan {
|
||||
color: rgba(120, 120, 120, 0.66);
|
||||
font-size: 0.8rem;
|
||||
width: 330px;
|
||||
}
|
||||
|
||||
.textEllipsis {
|
||||
white-space: nowrap; /* 禁止换行 */
|
||||
overflow: hidden; /* 隐藏溢出内容 */
|
||||
text-overflow: ellipsis; /* 显示省略号 */
|
||||
}
|
||||
|
||||
video {
|
||||
width: 94%;
|
||||
height: 85%;
|
||||
}
|
||||
|
||||
.gudingBtn {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
/* border-radius: 16px; */
|
||||
line-height: 27px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.subtitles {
|
||||
position: absolute;
|
||||
bottom: 200px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
color: white;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
#segmentsContainer:is(:hover) {
|
||||
right: 0px !important;
|
||||
}
|
||||
|
||||
#segmentsContainer {
|
||||
transition: right 0.7s;
|
||||
z-index: 999;
|
||||
overflow-x: hidden;
|
||||
background-color: #e3e3e3c2;
|
||||
position: absolute;
|
||||
right: -300px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 400px;
|
||||
height: 750px;
|
||||
gap: 10px;
|
||||
overflow-y: scroll;
|
||||
float: left;
|
||||
flex-wrap: nowrap;
|
||||
padding: 10px;
|
||||
align-content: flex-start;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.kBtn {
|
||||
width: 340px;
|
||||
height: 60px;
|
||||
font-size: 1.3rem;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
color: rgb(103, 194, 58);
|
||||
background-color: rgb(240, 249, 235);
|
||||
border: 1px solid rgb(179, 225, 157);
|
||||
}
|
||||
|
||||
.knowTtileTheme {
|
||||
font-size: 1.3rem;
|
||||
cursor: pointer;
|
||||
color: rgb(103, 194, 58);
|
||||
}
|
||||
|
||||
.kBtn:hover {
|
||||
background-color: rgb(248, 230, 191) !important;
|
||||
border: 1px solid rgb(206, 187, 81);
|
||||
}
|
||||
|
||||
.knowDiv {
|
||||
}
|
||||
|
||||
.knowQuestion {
|
||||
cursor: pointer;
|
||||
border: 2px solid #ff000059;
|
||||
border-radius: 10px;
|
||||
background-color: #cddc393d;
|
||||
}
|
||||
|
||||
.knowDiv:hover .knowTtile {
|
||||
width: 340px;
|
||||
display: block;
|
||||
background-color: rgb(240, 249, 235);
|
||||
border: 1px solid rgb(179, 225, 157);
|
||||
}
|
||||
|
||||
.knowTtile {
|
||||
position: absolute;
|
||||
text-align: left;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue