forked from integrated_whb/integrated_whb_vue
教育培训
parent
f570e9dcc6
commit
566eee266e
|
@ -6,8 +6,11 @@ import {
|
|||
getDepartmentTree,
|
||||
getLevelsCorp,
|
||||
getElectronicFenceTree,
|
||||
getListSelectTree,
|
||||
getDepartmentzTree,
|
||||
getTrainingType,
|
||||
getIndustryType,
|
||||
getPostType,
|
||||
getTrainingLevel,
|
||||
} from "@/request/data_dictionary.js";
|
||||
import { ref } from "vue";
|
||||
|
||||
|
@ -37,34 +40,6 @@ export const layoutFnGetEnterpriseScale = async () => {
|
|||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 培训行业类型
|
||||
export const layoutFnGetTrainingIndustryType = async () => {
|
||||
const resData = await getLevelsByParentId({
|
||||
parentId: "052369aa22d242118236cde52d0c67ea",
|
||||
});
|
||||
return ref(JSON.parse(resData.zTreeNodes));
|
||||
};
|
||||
// 培训岗位类型
|
||||
export const layoutFnGetTrainingPostType = async () => {
|
||||
const resData = await getLevelsByParentId({
|
||||
parentId: "f6a7c4f5602f46e291d06b1390a3f820",
|
||||
});
|
||||
return ref(JSON.parse(resData.zTreeNodes));
|
||||
};
|
||||
// 培训板块类型
|
||||
export const layoutFnGetTrainingPlateType = async () => {
|
||||
const resData = await getLevelsByParentId({
|
||||
parentId: "d538d11e4eec409ab428f5d2f3c67c24",
|
||||
});
|
||||
return ref(JSON.parse(resData.zTreeNodes));
|
||||
};
|
||||
// 大纲类型
|
||||
export const layoutFnGetOutlineType = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "3c0d9b5e74834adfacb76139e5d731e5",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 管控措施分类1
|
||||
export const layoutFnGetControlMeasures1 = async () => {
|
||||
const resData = await getLevelsByParentId({
|
||||
|
@ -79,27 +54,6 @@ export const layoutFnGetControlMeasures2 = async () => {
|
|||
});
|
||||
return ref(JSON.parse(resData.zTreeNodes));
|
||||
};
|
||||
// 受限空间类型
|
||||
export const layoutFnGetTypeOfConfinedSpace = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "dad23a464729485ba364994942db83cc",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 风险等级
|
||||
export const layoutFnGetRiskLevel = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "a178357ce6ce4d6a9ac95def6aca3a14",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 风险成因
|
||||
export const layoutFnGetRiskCauses = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "1bacbc4c1f6544718519c0d470dfeb62",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 民族
|
||||
export const layoutFnGetNation = async () => {
|
||||
const resData = await getLevels({
|
||||
|
@ -220,13 +174,6 @@ export const layoutFnGetAccidentType = async () => {
|
|||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 事故级别
|
||||
export const layoutFnGetAccidentLevel = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "9a77f67eff4c49b19454bf3e40e2ae57",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 风险分级
|
||||
export const layoutFnGetRiskClassification = async () => {
|
||||
const resData = await getLevels({
|
||||
|
@ -234,146 +181,6 @@ export const layoutFnGetRiskClassification = async () => {
|
|||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 承诺书级别
|
||||
export const layoutFnGetCommitmentLevel = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "8c5064693fba4dbca1cbfea631cd097a",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 申报等级
|
||||
export const layoutFnGetDeclarationGrade = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "246a2fe3af964eb18f0e005339e334dd",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 重大危险源类型
|
||||
export const layoutFnGetMajorHazardSourceType = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "6f7469fadb75401e9928edb0ab19b17e",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 监测数据类型
|
||||
export const layoutFnGetEquipmentType = async () => {
|
||||
const resData = await getLevelsCorp({
|
||||
DICTIONARIES_ID: "6a724d36c3ad416fad22049d932c1987",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 学习园地类型
|
||||
export const layoutFnGetLearningGardenType = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "5aa989ad8fd54bef862c1b096a3b07d8",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 学习园地学习类型
|
||||
export const layoutFnGetLearningGardenLearningType = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "c4f00e7ed9334789ba2fb4795f54bae2",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 培训类型
|
||||
export const layoutFnGetTrainingType = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "10ffcf646d354ff0a94630c7435e73fe",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 适用领域
|
||||
export const layoutFnGetApplicableFields = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "ab52643da4714042be2ebfb880097330",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 预案类别
|
||||
export const layoutFnGetPlanCategory = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "b2759070db524cc4ae2d60ee4b263dc3",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 预案备案状态
|
||||
export const layoutFnGetPlanFilingStatus = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "8d07af03be10473ca17e1516a8e860d2",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 预案级别
|
||||
export const layoutFnGetPlanLevel = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "ab54d50f12ef4f578bc29c3b980b83e5",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 装备类别
|
||||
export const layoutFnGetEquipmentCategory = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "716f792cfc354fcf81bf3c0e904fb4f8",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 救援专业
|
||||
export const layoutFnGetRescueSpecialty = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "6a724d36c3ad416fad22049d932c329e",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 队伍属性
|
||||
export const layoutFnGetTeamAttribute = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "afde28dd39c841d984fb331116781ff3",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 队伍类别
|
||||
export const layoutFnGetTeamCategory = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "ef2f9a53723b4531968279fe4816be3d",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 队伍等级
|
||||
export const layoutFnGetTeamGrade = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "4dca6d39490d4845ba7b02df2ab68aa4",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 队伍级别
|
||||
export const layoutFnGetTeamLevel = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "bfd057e59c124b42ac93e13c6a30b85e",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 特种设备类型
|
||||
export const layoutFnGetSpecialEquipmentType = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "cffb3d28d48548328ddd78976610b05d",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 特种设备状态
|
||||
export const layoutFnGetSpecialEquipmentState = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "0feb448f975e422fafbf5db20c0b85c9",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 巡检周期
|
||||
export const layoutFnGetInspectionCycle = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "3017f7f6f6794f23bf15d026a1e55426",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
// 部门树
|
||||
export const layoutFnGetDepartmentTree = async (params) => {
|
||||
const resData = await getDepartmentTree(params);
|
||||
|
@ -389,13 +196,6 @@ export const layoutFnGetElectronicFenceTree = async (params) => {
|
|||
const resData = await getElectronicFenceTree(params);
|
||||
return ref(JSON.parse(resData.zTreeNodes));
|
||||
};
|
||||
// 检查类型树
|
||||
export const layoutFnGetInspectionTypeTree = async () => {
|
||||
const resData = await getListSelectTree({
|
||||
DICTIONARIES_ID: "60e6481d96e44a5390ff5c347c4d1ffe",
|
||||
});
|
||||
return ref(JSON.parse(resData.zTreeNodes));
|
||||
};
|
||||
// 无法确定DICTIONARIES_ID的数据字典
|
||||
export const layoutFnGetLevels = async (DICTIONARIES_ID) => {
|
||||
const resData = await getLevels({ DICTIONARIES_ID });
|
||||
|
@ -406,15 +206,6 @@ export const layoutFnGetLevelsAndChildrenNumber = async (DICTIONARIES_ID) => {
|
|||
const resData = await getLevelsAndChildrenNumber({ DICTIONARIES_ID });
|
||||
return ref(resData.list);
|
||||
};
|
||||
|
||||
// 相关方作业类别
|
||||
export const layoutFnGetPersonnelManagementJobType = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "a8bfd4554af54ee2b816f3007d8baea6",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
|
||||
// 年检周期
|
||||
export const layoutFnGetAnnualInspectionCycle = async () => {
|
||||
const resData = await getLevels({
|
||||
|
@ -422,7 +213,6 @@ export const layoutFnGetAnnualInspectionCycle = async () => {
|
|||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
|
||||
// 保险公司
|
||||
export const layoutFnGetInsuranceCompany = async () => {
|
||||
const resData = await getLevels({
|
||||
|
@ -430,3 +220,24 @@ export const layoutFnGetInsuranceCompany = async () => {
|
|||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
|
||||
// 培训类型
|
||||
export const layoutFnGetTrainingType = async (params) => {
|
||||
const resData = await getTrainingType(params);
|
||||
return ref(resData.trainingtypelist);
|
||||
};
|
||||
// 行业类型
|
||||
export const layoutFnGetIndustryType = async (params) => {
|
||||
const resData = await getIndustryType(params);
|
||||
return ref(JSON.parse(resData.zTreeNodes));
|
||||
};
|
||||
// 岗位类型
|
||||
export const layoutFnGetPostType = async (params) => {
|
||||
const resData = await getPostType(params);
|
||||
return ref(resData.varList);
|
||||
};
|
||||
// 培训级别
|
||||
export const layoutFnGetTrainingLevel = async (params) => {
|
||||
const resData = await getTrainingLevel(params);
|
||||
return ref(resData.varList);
|
||||
};
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
<template>
|
||||
<el-tree-select
|
||||
ref="treeSelectRef"
|
||||
v-model="modelValue"
|
||||
:data="data"
|
||||
:props="{
|
||||
value: 'id',
|
||||
children: 'nodes',
|
||||
label: 'name',
|
||||
}"
|
||||
node-key="id"
|
||||
:render-after-expand="false"
|
||||
accordion
|
||||
check-strictly
|
||||
:clearable="true"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { layoutFnGetInspectionTypeTree } from "@/assets/js/data_dictionary";
|
||||
import { ref } from "vue";
|
||||
import { useVModel } from "@vueuse/core";
|
||||
|
||||
defineOptions({
|
||||
name: "LayoutInspectionType",
|
||||
});
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:modelValue"]);
|
||||
const modelValue = useVModel(props, "modelValue", emits);
|
||||
const treeSelectRef = ref(null);
|
||||
const getCurrentNode = () => {
|
||||
return treeSelectRef.value.getCurrentNode();
|
||||
};
|
||||
defineExpose({
|
||||
getCurrentNode,
|
||||
});
|
||||
const data = await layoutFnGetInspectionTypeTree();
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
File diff suppressed because it is too large
Load Diff
|
@ -1,84 +0,0 @@
|
|||
<template>
|
||||
<div id="bi_container">
|
||||
<div id="map" class="map_bg"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onBeforeUnmount, onMounted } from "vue";
|
||||
import { initMap, handleViewAlarm, handleMouseClick } from "./map";
|
||||
import { useUserStore } from "@/pinia/user.js";
|
||||
import { getEnterpriseInfo } from "@/request/enterprise_management.js";
|
||||
|
||||
const props = defineProps({
|
||||
alarm: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: null,
|
||||
},
|
||||
userList: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
const userStore = useUserStore();
|
||||
const CORPINFO_ID = userStore.getUserInfo.CORPINFO_ID;
|
||||
|
||||
onMounted(async () => {
|
||||
const corp = await getEnterpriseInfo({ CORPINFO_ID });
|
||||
initMap(corp.pd);
|
||||
handleMouseClick();
|
||||
handleViewAlarm(props.alarm, props.userList);
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
window.$scene = null;
|
||||
window.$icy = null;
|
||||
window.$carmer = null;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
#bi_container {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
color: #ffffff;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
|
||||
.map_bg {
|
||||
width: 100%;
|
||||
height: 540px;
|
||||
}
|
||||
|
||||
.options {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
|
||||
.option {
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
}
|
||||
|
||||
.label {
|
||||
margin-top: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.id {
|
||||
background-color: #1b284a;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
height: 37px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,152 +0,0 @@
|
|||
<template>
|
||||
<div id="bi_container">
|
||||
<div id="map" class="map_bg"></div>
|
||||
<div class="options">
|
||||
<template v-if="type === 1">
|
||||
<div class="option" @click="confrim">
|
||||
<div>
|
||||
<img src="/src/assets/images/map_tools/icon1.png" alt="" />
|
||||
</div>
|
||||
<div class="label">完成绘制</div>
|
||||
</div>
|
||||
<div class="option" @click="clear">
|
||||
<div>
|
||||
<img src="/src/assets/images/map_tools/icon2.png" alt="" />
|
||||
</div>
|
||||
<div class="label">清除绘制</div>
|
||||
</div>
|
||||
<div class="option" @click="reduction">
|
||||
<div>
|
||||
<img src="/src/assets/images/map_tools/icon3.png" alt="" />
|
||||
</div>
|
||||
<div class="label">还原建筑</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="id">当前选中楼层id:{{ model_id }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useVModels } from "@vueuse/core";
|
||||
import { onBeforeUnmount, onMounted, ref } from "vue";
|
||||
import {
|
||||
clearEnclosure,
|
||||
handleEnclosure,
|
||||
handleMouseClick,
|
||||
handlePut,
|
||||
initMap,
|
||||
reduction,
|
||||
showEnclosure,
|
||||
} from "./map";
|
||||
import { useUserStore } from "@/pinia/user.js";
|
||||
import { getEnterpriseInfo } from "@/request/enterprise_management.js";
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
positions: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
position: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
modUuid: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
const userStore = useUserStore();
|
||||
const CORPINFO_ID = userStore.getUserInfo.CORPINFO_ID;
|
||||
const data = [];
|
||||
const model_id = ref(0);
|
||||
const emits = defineEmits([
|
||||
"update:positions",
|
||||
"update:position",
|
||||
"update:modUuid",
|
||||
]);
|
||||
const { positions, position, modUuid } = useVModels(props, emits);
|
||||
|
||||
const confrim = () => {
|
||||
showEnclosure(data);
|
||||
positions.value = [...data];
|
||||
modUuid.value = model_id.value;
|
||||
};
|
||||
const clear = () => {
|
||||
clearEnclosure(data);
|
||||
data.length = 0;
|
||||
positions.value = [];
|
||||
};
|
||||
onMounted(async () => {
|
||||
const corp = await getEnterpriseInfo({ CORPINFO_ID });
|
||||
initMap(corp.pd);
|
||||
handleMouseClick(model_id);
|
||||
if (props.type === 1) {
|
||||
handleEnclosure(data);
|
||||
} else {
|
||||
handlePut(position);
|
||||
}
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
window.$scene = null;
|
||||
window.$icy = null;
|
||||
window.$carmer = null;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
#bi_container {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
color: #ffffff;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
|
||||
.map_bg {
|
||||
width: 100%;
|
||||
height: 540px;
|
||||
}
|
||||
|
||||
.options {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
|
||||
.option {
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
}
|
||||
|
||||
.label {
|
||||
margin-top: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.id {
|
||||
background-color: #1b284a;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
height: 37px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep {
|
||||
div#menu {
|
||||
button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,167 +0,0 @@
|
|||
import axios from "axios";
|
||||
import { useUserStore } from "@/pinia/user";
|
||||
import pinia from "@/pinia";
|
||||
|
||||
const userStore = useUserStore(pinia);
|
||||
const pls_ip = userStore.getUserInfo.POST_URL;
|
||||
const url = pls_ip.replace("8084", "9000") + "/buildr/public/models/glb/";
|
||||
export class Loadglb {
|
||||
static modelMap = {};
|
||||
constructor(icy) {
|
||||
this.icy = icy;
|
||||
this.model_def_group = null;
|
||||
this.scene = null;
|
||||
this.idList = [];
|
||||
this.entityList = [];
|
||||
this.number = 0;
|
||||
this.building_group = null;
|
||||
this.groundHeight = 0.2; // 设置地面的高度
|
||||
}
|
||||
|
||||
async fetchData() {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
pls_ip.replace("8084", "9000") +
|
||||
"/buildr/public/models/scene_000001.json"
|
||||
);
|
||||
// 将获取的数据保存到实例的属性中
|
||||
this.scene = response.data.scene;
|
||||
this.model_def_group = response.data.scene.model_def_group;
|
||||
|
||||
const map = new Map();
|
||||
this.model_def_group.forEach((i) => {
|
||||
map.set(i.guid.split("-")[3], { name: i.name, id: i.guid });
|
||||
});
|
||||
this.scene.building_group.forEach((i) => {
|
||||
i.layer_group.forEach((a) => {
|
||||
a.modelName = map.get(a.guid[0].split("-")[3]);
|
||||
});
|
||||
});
|
||||
this.building_group = this.scene.building_group;
|
||||
// console.log(this.building_group);
|
||||
} catch (error) {
|
||||
// 处理可能错误
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
async model(Model) {
|
||||
try {
|
||||
// 执行 axios 请求并等待 fetchData 函数的异步操作完成
|
||||
await this.fetchData();
|
||||
const modelList = {};
|
||||
this.scene.model_def_group.forEach((item) => {
|
||||
modelList[item.guid] = item.name;
|
||||
});
|
||||
const modelTotal = this.scene.building_group.length;
|
||||
this.createModel(Model, modelList, modelTotal);
|
||||
this.scene.ground_group.forEach((ground) => {
|
||||
const lon = ground.transform.translate.x;
|
||||
const lat = ground.transform.translate.y;
|
||||
const scale = ground.transform.scale;
|
||||
ground.model_ref_group.forEach((layer) => {
|
||||
// console.log(layer,'111');
|
||||
const height = this.groundHeight;
|
||||
const unit = {
|
||||
lon,
|
||||
lat,
|
||||
scale,
|
||||
id: layer.model_def_guid,
|
||||
};
|
||||
this.logNum([layer], height, unit, modelList, Model);
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
// 处理可能的错误
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
createModel(Model, modelList, modelTotal) {
|
||||
this.scene.building_group.forEach((building, index) => {
|
||||
if (
|
||||
Number(this.number * 2) <= index &&
|
||||
index < Number((this.number + 1) * 2)
|
||||
) {
|
||||
const lon = building.transform.translate.x;
|
||||
const lat = building.transform.translate.y;
|
||||
const scale = building.transform.scale;
|
||||
building.layer_group.forEach((layer) => {
|
||||
// console.log(layer,'111');
|
||||
const height = Number(layer.height[0] + this.groundHeight);
|
||||
const unit = {
|
||||
lon,
|
||||
lat,
|
||||
scale,
|
||||
id: layer.guid[0],
|
||||
};
|
||||
this.logNum(layer.model_ref_group, height, unit, modelList, Model);
|
||||
});
|
||||
}
|
||||
});
|
||||
if (this.number * 2 < modelTotal) {
|
||||
const throttle = setTimeout(() => {
|
||||
this.number++;
|
||||
this.createModel(Model, modelList, modelTotal);
|
||||
sessionStorage.setItem("loading", (this.number * 2) / modelTotal);
|
||||
clearTimeout(throttle);
|
||||
}, 20);
|
||||
if (
|
||||
(this.number * 2) / modelTotal >= 0.5 &&
|
||||
(this.number * 2) / modelTotal < 0.8
|
||||
) {
|
||||
sessionStorage.setItem("loadModel", "过半");
|
||||
} else if ((this.number * 2) / modelTotal >= 0.8) {
|
||||
sessionStorage.setItem("loadModel", "临底");
|
||||
}
|
||||
} else {
|
||||
console.log(
|
||||
"加载完成 ,此次加载:" +
|
||||
modelTotal +
|
||||
"栋建筑,共:" +
|
||||
this.model_def_group.length +
|
||||
"个模型"
|
||||
);
|
||||
sessionStorage.setItem("loadModel", "完成");
|
||||
}
|
||||
}
|
||||
|
||||
logNum(red, height, unit, modelList, Model) {
|
||||
red.forEach((item) => {
|
||||
if (this.idList.indexOf(item.model_def_guid) !== -1) {
|
||||
return;
|
||||
}
|
||||
this.idList.push(item.model_def_guid);
|
||||
if (
|
||||
Object.prototype.hasOwnProperty.call(
|
||||
Loadglb.modelMap,
|
||||
`${unit.id.split("-")[3].slice(0, unit.id.split("-")[3].length - 2)}`
|
||||
)
|
||||
) {
|
||||
Loadglb.modelMap[
|
||||
`${unit.id.split("-")[3].slice(0, unit.id.split("-")[3].length - 2)}`
|
||||
].push(item.model_def_guid);
|
||||
} else {
|
||||
Loadglb.modelMap[
|
||||
`${unit.id.split("-")[3].slice(0, unit.id.split("-")[3].length - 2)}`
|
||||
] = [item.model_def_guid];
|
||||
}
|
||||
const m = new Model(this.icy, {
|
||||
id: item.model_def_guid,
|
||||
name: "建筑",
|
||||
url: `${url}${modelList[item.model_def_guid]}.gltf`,
|
||||
height,
|
||||
lon: unit.lon,
|
||||
lat: unit.lat,
|
||||
scale: unit.scale,
|
||||
angle: [90, 0, 0],
|
||||
// angle: [97.4843053, 0, 0]
|
||||
});
|
||||
this.entityList.push(m);
|
||||
});
|
||||
}
|
||||
|
||||
getArr() {
|
||||
return this.building_group;
|
||||
}
|
||||
}
|
|
@ -1,404 +0,0 @@
|
|||
import { Loadglb } from "./loadglb.js";
|
||||
|
||||
const loadMap = 3;
|
||||
let $entityTransparent = [];
|
||||
const clickModel = new Map();
|
||||
|
||||
let enclosure = null;
|
||||
let entities = null;
|
||||
export const initMap = (corp) => {
|
||||
window.$scene = new window.CustomCesium.Scene(
|
||||
"map",
|
||||
corp.CORP_NAME,
|
||||
Number(loadMap)
|
||||
);
|
||||
window.$icy = window.$scene.getIcy();
|
||||
window.$carmer = new window.CustomCesium.Carmer(window.$icy);
|
||||
window.$icy.viewer.targetFrameRate = "30";
|
||||
window.$icy.viewer.scene.light = new window.Cesium.DirectionalLight({
|
||||
// 去除时间原因影响模型颜色
|
||||
direction: new window.Cesium.Cartesian3(
|
||||
0.35492591601301104,
|
||||
-0.8909182691839401,
|
||||
-0.2833588392420772
|
||||
),
|
||||
});
|
||||
const [wgsLat, wgsLon] = bd09ToWgs84(corp.LATITUDE, corp.LONGITUDE);
|
||||
flyTo(wgsLon, wgsLat);
|
||||
// 亮度设置
|
||||
const stages = window.$icy.viewer.scene.postProcessStages;
|
||||
window.$icy.viewer.scene.brightness =
|
||||
window.$icy.viewer.scene.brightness ||
|
||||
stages.add(window.Cesium.PostProcessStageLibrary.createBrightnessStage());
|
||||
window.$icy.viewer.scene.brightness.enabled = true;
|
||||
window.$icy.viewer.scene.brightness.uniforms.brightness = Number(1.05); // 此处亮度值为倍数
|
||||
createGlb(); // 加载glb
|
||||
};
|
||||
|
||||
const bd09ToWgs84 = (bdLat, bdLon) => {
|
||||
const x_pi = (Math.PI * 3000.0) / 180.0;
|
||||
const x = bdLon - 0.0065;
|
||||
const y = bdLat - 0.006;
|
||||
const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
|
||||
const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
|
||||
const gcjLon = z * Math.cos(theta);
|
||||
const gcjLat = z * Math.sin(theta);
|
||||
|
||||
let dlat = transformlat(gcjLon - 105.0, gcjLat - 35.0);
|
||||
let dlng = transformlng(gcjLon - 105.0, gcjLat - 35.0);
|
||||
const radlat = (gcjLat / 180.0) * Math.PI;
|
||||
let magic = Math.sin(radlat);
|
||||
magic = 1 - 0.006693421622965943 * magic * magic;
|
||||
const sqrtmagic = Math.sqrt(magic);
|
||||
dlat =
|
||||
(dlat * 180.0) /
|
||||
(((6378245.0 * (1 - 0.006693421622965943)) / (magic * sqrtmagic)) *
|
||||
Math.PI);
|
||||
dlng =
|
||||
(dlng * 180.0) / ((6378245.0 / sqrtmagic) * Math.cos(radlat) * Math.PI);
|
||||
const mglat = gcjLat + dlat;
|
||||
const mglng = gcjLon + dlng;
|
||||
const wgsLon = gcjLon * 2 - mglng;
|
||||
const wgsLat = gcjLat * 2 - mglat;
|
||||
|
||||
return [wgsLat, wgsLon];
|
||||
};
|
||||
|
||||
const transformlat = (lng, lat) => {
|
||||
let ret =
|
||||
-100.0 +
|
||||
2.0 * lng +
|
||||
3.0 * lat +
|
||||
0.2 * lat * lat +
|
||||
0.1 * lng * lat +
|
||||
0.2 * Math.sqrt(Math.abs(lng));
|
||||
ret +=
|
||||
((20.0 * Math.sin(6.0 * lng * Math.PI) +
|
||||
20.0 * Math.sin(2.0 * lng * Math.PI)) *
|
||||
2.0) /
|
||||
3.0;
|
||||
ret +=
|
||||
((20.0 * Math.sin(lat * Math.PI) + 40.0 * Math.sin((lat / 3.0) * Math.PI)) *
|
||||
2.0) /
|
||||
3.0;
|
||||
ret +=
|
||||
((160.0 * Math.sin((lat / 12.0) * Math.PI) +
|
||||
320 * Math.sin((lat * Math.PI) / 30.0)) *
|
||||
2.0) /
|
||||
3.0;
|
||||
return ret;
|
||||
};
|
||||
// 纬度转换
|
||||
const transformlng = (lng, lat) => {
|
||||
let ret =
|
||||
300.0 +
|
||||
lng +
|
||||
2.0 * lat +
|
||||
0.1 * lng * lng +
|
||||
0.1 * lng * lat +
|
||||
0.1 * Math.sqrt(Math.abs(lng));
|
||||
ret +=
|
||||
((20.0 * Math.sin(6.0 * lng * Math.PI) +
|
||||
20.0 * Math.sin(2.0 * lng * Math.PI)) *
|
||||
2.0) /
|
||||
3.0;
|
||||
ret +=
|
||||
((20.0 * Math.sin(lng * Math.PI) + 40.0 * Math.sin((lng / 3.0) * Math.PI)) *
|
||||
2.0) /
|
||||
3.0;
|
||||
ret +=
|
||||
((150.0 * Math.sin((lng / 12.0) * Math.PI) +
|
||||
300.0 * Math.sin((lng / 30.0) * Math.PI)) *
|
||||
2.0) /
|
||||
3.0;
|
||||
return ret;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const flyTo = (lng, lat) => {
|
||||
window.$carmer.flyTo({
|
||||
// 视角飞入
|
||||
maxHeight: 1500,
|
||||
time: 1,
|
||||
position: [lng, lat - 0.001, 200],
|
||||
angle: [0, -60, 0],
|
||||
});
|
||||
};
|
||||
|
||||
const createGlb = () => {
|
||||
// 加载glb(建筑模型)
|
||||
const loadGlb = new Loadglb(window.$icy);
|
||||
loadGlb.model(window.CustomCesium.Model);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export const handleMouseClick = (model_id) => {
|
||||
// 加载鼠标拾取
|
||||
const $mouse = new window.CustomCesium.Mouse(window.$icy);
|
||||
// 隐藏逻辑
|
||||
$mouse.mouseLeft((model) => {
|
||||
if (model._name === "建筑") {
|
||||
if (model_id) model_id.value = model._id;
|
||||
clickBuilding(model);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const clickBuilding = (model) => {
|
||||
if (
|
||||
Loadglb.modelMap[
|
||||
`${model._id.split("-")[3].slice(0, model._id.split("-")[3].length - 2)}`
|
||||
]
|
||||
) {
|
||||
if (
|
||||
clickModel.get(
|
||||
`${model._id
|
||||
.split("-")[3]
|
||||
.slice(0, model._id.split("-")[3].length - 2)}`
|
||||
) === undefined
|
||||
) {
|
||||
// 如果这个模型是第一次点击
|
||||
const m =
|
||||
Loadglb.modelMap[
|
||||
`${model._id
|
||||
.split("-")[3]
|
||||
.slice(0, model._id.split("-")[3].length - 2)}`
|
||||
]; // 整栋楼的id集合
|
||||
// console.log(m, '整栋楼id');
|
||||
if (m.length > 1) {
|
||||
// 当前点击这建筑是否有多层
|
||||
m.forEach((id) => {
|
||||
const entity = window.$icy.viewer.entities.getById(id);
|
||||
if (model.id !== id) {
|
||||
// 排除当前点击楼层
|
||||
if (entity._icy.height > model._icy.height) {
|
||||
if (
|
||||
$entityTransparent.map((a) => a._id).indexOf(entity._id) === -1
|
||||
) {
|
||||
$entityTransparent.push(entity);
|
||||
}
|
||||
// console.log(this.$entityTransparent, '被隐藏的模型楼层集合');
|
||||
entity.model.show = false;
|
||||
}
|
||||
} else {
|
||||
clickModel.set(
|
||||
`${model._id
|
||||
.split("-")[3]
|
||||
.slice(0, model._id.split("-")[3].length - 2)}`,
|
||||
model._icy.height
|
||||
); // 存储这个模型数据
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// 如果点击过这个模型
|
||||
const m =
|
||||
Loadglb.modelMap[
|
||||
`${model._id
|
||||
.split("-")[3]
|
||||
.slice(0, model._id.split("-")[3].length - 2)}`
|
||||
]; // 整栋楼的id集合
|
||||
// console.log(m, '整栋楼id');
|
||||
if (m.length > 1) {
|
||||
// 当前点击这建筑是否有多层
|
||||
if (
|
||||
model._icy.height ===
|
||||
clickModel.get(
|
||||
`${model._id
|
||||
.split("-")[3]
|
||||
.slice(0, model._id.split("-")[3].length - 2)}`
|
||||
)
|
||||
) {
|
||||
m.forEach((id) => {
|
||||
const entity = window.$icy.viewer.entities.getById(id);
|
||||
entity.model.show = true;
|
||||
clickModel.delete(
|
||||
`${model._id
|
||||
.split("-")[3]
|
||||
.slice(0, model._id.split("-")[3].length - 2)}`
|
||||
);
|
||||
});
|
||||
} else {
|
||||
m.forEach((id) => {
|
||||
const entity = window.$icy.viewer.entities.getById(id);
|
||||
if (model.id !== id) {
|
||||
// 排除当前点击楼层
|
||||
if (entity._icy.height > model._icy.height) {
|
||||
if (
|
||||
$entityTransparent.map((a) => a._id).indexOf(entity._id) ===
|
||||
-1
|
||||
) {
|
||||
$entityTransparent.push(entity);
|
||||
}
|
||||
// console.log(this.$entityTransparent, '被隐藏的模型楼层集合');
|
||||
entity.model.show = false;
|
||||
}
|
||||
} else {
|
||||
clickModel.set(
|
||||
`${model._id
|
||||
.split("-")[3]
|
||||
.slice(0, model._id.split("-")[3].length - 2)}`,
|
||||
model._icy.height
|
||||
); // 存储这个模型数据
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// model.model.color = new Cesium.Color(1, 1, 1, 0.6);
|
||||
}
|
||||
};
|
||||
|
||||
// 还原建筑物
|
||||
export const reduction = () => {
|
||||
// 揭盖一键还原
|
||||
if ($entityTransparent.length !== 0) {
|
||||
$entityTransparent = $entityTransparent.forEach((item) => {
|
||||
item.model.color = new window.Cesium.Color(1, 1, 1, 1);
|
||||
item.model.show = true;
|
||||
});
|
||||
$entityTransparent = [];
|
||||
}
|
||||
};
|
||||
|
||||
export const handleEnclosure = (positions) => {
|
||||
const $mouse = new window.CustomCesium.Mouse(window.$icy);
|
||||
enclosure = new window.CustomCesium.Enclosure(window.$icy);
|
||||
// 编辑围栏使用鼠标控件参照demo.html
|
||||
enclosure.start();
|
||||
$mouse.mouseRight((e) => {
|
||||
enclosure.add(e.lng, e.lat, e.alt);
|
||||
positions.push([e.lng, e.lat, e.alt]);
|
||||
});
|
||||
};
|
||||
|
||||
export const clearEnclosure = () => {
|
||||
if (enclosure) {
|
||||
try {
|
||||
enclosure.show(false);
|
||||
} catch (e) {}
|
||||
enclosure.clear();
|
||||
enclosure = new window.CustomCesium.Enclosure(window.$icy);
|
||||
enclosure.start();
|
||||
}
|
||||
};
|
||||
|
||||
export const showEnclosure = (positions) => {
|
||||
enclosure.finish();
|
||||
enclosure.showDataSource(
|
||||
positions, // 数据
|
||||
30, // 高度
|
||||
"yellow" // 颜色默认黄色
|
||||
);
|
||||
enclosure.show(true);
|
||||
};
|
||||
|
||||
export const handlePut = (pos) => {
|
||||
const $mouse = new window.CustomCesium.Mouse(window.$icy);
|
||||
$mouse.mouseRight((e) => {
|
||||
if (entities && entities.children) {
|
||||
entities.children.forEach((e) => {
|
||||
e.destroy();
|
||||
});
|
||||
entities = null;
|
||||
}
|
||||
entities = new window.CustomCesium.GroupModel("摆放地图实例");
|
||||
addEntity("put_entity_00001", "put_entity_00001", e.lng, e.lat, e.alt);
|
||||
pos.value = [e.lng, e.lat, e.alt];
|
||||
});
|
||||
};
|
||||
|
||||
const addEntity = (id, name, lon, lat, height) => {
|
||||
const obj = {};
|
||||
obj.entity = window.$icy.viewer.entities.add(
|
||||
new window.Cesium.Entity({
|
||||
id,
|
||||
name,
|
||||
position: window.Cesium.Cartesian3.fromDegrees(lon, lat, height),
|
||||
billboard: {
|
||||
image: "src/assets/images/map/peoIcon_green.png",
|
||||
height: 36,
|
||||
width: 30,
|
||||
verticalOrigin: window.Cesium.VerticalOrigin.BOTTOM,
|
||||
horizontalOrigin: window.Cesium.HorizontalOrigin.CENTER,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
},
|
||||
})
|
||||
);
|
||||
obj.show = (e) => {
|
||||
obj.entity.show = e;
|
||||
};
|
||||
obj.destroy = () => {
|
||||
window.$icy.viewer.entities.remove(obj.entity);
|
||||
};
|
||||
entities.add(obj);
|
||||
};
|
||||
|
||||
export const handleViewAlarm = (alarm, userList) => {
|
||||
const canvas = document.createElement("canvas");
|
||||
const width = 100;
|
||||
const height = 30;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.fillStyle = "#000000";
|
||||
ctx.fillRect(0, 0, 100, 50);
|
||||
ctx.fillStyle = "#ff0000";
|
||||
ctx.font = "normal bold 20px Arial";
|
||||
ctx.textAlign = "center";
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.fillText("聚集告警", width / 2, height / 2);
|
||||
|
||||
// 聚集圆锥特效
|
||||
const Cone = new window.CustomCesium.Cone(window.$icy);
|
||||
Cone.add(
|
||||
[alarm.lon, alarm.lat, alarm.alt], // 坐标
|
||||
alarm.color, // 圆锥颜色
|
||||
{ width: 20, height: 40 }, // 圆锥的宽高
|
||||
canvas, // 圆锥铭牌
|
||||
"100201", // 圆锥实体id
|
||||
"10020101" // 铭牌实体id
|
||||
);
|
||||
const labelPixelOffset = new window.Cesium.Cartesian2(0, -55);
|
||||
userList.forEach((user) => {
|
||||
const obj = {};
|
||||
obj.entity = window.$icy.viewer.entities.add(
|
||||
new window.Cesium.Entity({
|
||||
id: "user_" + user.card,
|
||||
name: user.psnName,
|
||||
position: window.Cesium.Cartesian3.fromDegrees(
|
||||
user.lon,
|
||||
user.lat,
|
||||
user.alt
|
||||
),
|
||||
billboard: {
|
||||
image: "src/assets/images/map/peoIcon_blueImg.png",
|
||||
height: 36,
|
||||
width: 30,
|
||||
verticalOrigin: window.Cesium.VerticalOrigin.BOTTOM,
|
||||
horizontalOrigin: window.Cesium.HorizontalOrigin.CENTER,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
},
|
||||
label: {
|
||||
text: user.psnName,
|
||||
font: "13px sans-serif",
|
||||
pixelOffset: labelPixelOffset,
|
||||
showBackground: true,
|
||||
// 地图上扎点的名字背景色
|
||||
// eslint-disable-next-line new-cap
|
||||
backgroundColor: new window.Cesium.Color.fromCssColorString(
|
||||
"rgba(20, 58, 142, 1)"
|
||||
),
|
||||
backgroundPadding: new window.Cesium.Cartesian2(7, 5),
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
},
|
||||
})
|
||||
);
|
||||
obj.show = (e) => {
|
||||
obj.entity.show = e;
|
||||
};
|
||||
obj.destroy = () => {
|
||||
window.$icy.viewer.entities.remove(obj.entity);
|
||||
};
|
||||
});
|
||||
};
|
|
@ -10,6 +10,7 @@
|
|||
:highlight-current-row="highlightCurrentRow"
|
||||
:row-key="getRowKey"
|
||||
:row-class-name="rowClassName"
|
||||
:row-style="rowStyle"
|
||||
:show-header="showHeader"
|
||||
:show-summary="showSummary"
|
||||
:summary-method="summaryMethod"
|
||||
|
@ -97,6 +98,9 @@ const props = defineProps({
|
|||
rowClassName: {
|
||||
type: Function,
|
||||
},
|
||||
rowStyle: {
|
||||
type: Function,
|
||||
},
|
||||
summaryMethod: {
|
||||
type: Function,
|
||||
},
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
<template>
|
||||
<el-cascader
|
||||
v-model="modelValue"
|
||||
:options="options"
|
||||
:props="{
|
||||
multiple: true,
|
||||
value: 'id',
|
||||
children: 'nodes',
|
||||
label: 'name',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { layoutFnGetTrainingPlateType } from "@/assets/js/data_dictionary.js";
|
||||
import { useVModel } from "@vueuse/core";
|
||||
|
||||
defineOptions({
|
||||
name: "LayoutTrainingSectionCascader",
|
||||
});
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: [String, Array],
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:modelValue"]);
|
||||
const modelValue = useVModel(props, "modelValue", emits);
|
||||
const options = await layoutFnGetTrainingPlateType();
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -59,8 +59,8 @@ axios.interceptors.response.use(
|
|||
import.meta.env.DEV &&
|
||||
ElMessage.error(`连接错误${error.response.status}`);
|
||||
endLoading();
|
||||
ElMessage.error("登录失效,请重新登陆");
|
||||
router.push("/login").then();
|
||||
// ElMessage.error("登录失效,请重新登陆");
|
||||
// router.push("/login").then();
|
||||
}
|
||||
} else {
|
||||
error.message = "连接到服务器失败";
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import { post } from "@/request/axios.js";
|
||||
import { useUserStore } from "@/pinia/user.js";
|
||||
import pinia from "@/pinia/index.js";
|
||||
import {
|
||||
layoutFnGetEveryProvinceHiddenDangerType
|
||||
} from "@/assets/js/data_dictionary.js";
|
||||
import { layoutFnGetEveryProvinceHiddenDangerType } from "@/assets/js/data_dictionary.js";
|
||||
|
||||
// 获取数据字典
|
||||
export const getLevels = (params) =>
|
||||
|
@ -133,3 +131,27 @@ export const getStandardLevels = () =>
|
|||
post("/hiddenstandardDictionary/list", {
|
||||
loading: false,
|
||||
});
|
||||
// 培训类型
|
||||
export const getTrainingType = (params) =>
|
||||
post("/trainingtype/privateList", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
// 行业类型
|
||||
export const getIndustryType = (params) =>
|
||||
post("/industrytype/getIndustryTree", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
// 岗位类型
|
||||
export const getPostType = (params) =>
|
||||
post("/posttype/listAll", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
// 培训级别
|
||||
export const getTrainingLevel = (params) =>
|
||||
post("/trainleveltype/listAll", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
import { post } from "@/request/axios.js";
|
||||
|
||||
export const setExamPaperManagementDelete = (params) =>
|
||||
post("/stageexampaperinput/delete", params); // 试卷管理删除
|
|
@ -0,0 +1,28 @@
|
|||
import { post, upload } from "@/request/axios.js";
|
||||
|
||||
export const getVideoCoursewareList = (params) =>
|
||||
post("/platform/videocourseware/list", params); // 视频课件列表
|
||||
export const getPreviewingVideo = (params) =>
|
||||
post("/platform/videocourseware/getPlayInfo", params); // 预览视频
|
||||
export const getVideoCoursewareView = (params) =>
|
||||
post("/platform/videocourseware/goEdit", params); // 视频课件查看
|
||||
export const getVideoCoursewareExercisesList = (params) =>
|
||||
post("/platform/question/list", params); // 视频课件习题列表
|
||||
export const getCourseManagementList = (params) =>
|
||||
post("/platform/curriculum/list", params); // 课程管理列表
|
||||
export const setCourseManagementDelete = (params) =>
|
||||
post("/curriculum/delById", params); // 课程管理删除
|
||||
export const getCourseManagementView = (params) =>
|
||||
post("/curriculum/goEdit", params); // 课程管理查看
|
||||
export const getSelectCourseManagementList = (params) =>
|
||||
post("/videocourseware/list", params); // 选择视频课件列表
|
||||
export const setCourseManagementAdd = (params) =>
|
||||
upload("/curriculum/add", params); // 课程管理添加
|
||||
export const setCourseManagementEdit = (params) =>
|
||||
upload("/curriculum/edit", params); // 课程管理修改
|
||||
export const getExamPaperManagementList = (params) =>
|
||||
post("/stageexampaperinput/list", params); // 试卷管理列表
|
||||
export const getExamPaperManagementView = (params) =>
|
||||
post("/stageexampaperinput/goEdit", params); // 试卷管理查看
|
||||
export const getExamPaperManagementTestQuestions = (params) =>
|
||||
post("/paperQuestion/listForInherit", params); // 试卷管理试题
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<layout-card>11</layout-card>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,199 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form
|
||||
:model="searchForm"
|
||||
label-width="100px"
|
||||
@submit.prevent="fnResetPaginationTransfer"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="试卷名称" prop="KEYWORDS">
|
||||
<el-input v-model="searchForm.KEYWORDS" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="创建时间" prop="dates">
|
||||
<el-date-picker
|
||||
v-model="searchForm.dates"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="试卷类型" prop="SOURCETYPE">
|
||||
<el-select v-model="searchForm.SOURCETYPE">
|
||||
<el-option
|
||||
v-for="item in sourceTypeList"
|
||||
:key="item.ID"
|
||||
:label="item.NAME"
|
||||
:value="item.ID"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="合格分数" prop="PASSSCORE">
|
||||
<el-input v-model="searchForm.PASSSCORE" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item label-width="10px">
|
||||
<el-button type="primary" native-type="submit">搜索</el-button>
|
||||
<el-button native-type="reset" @click="fnResetPaginationTransfer">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<layout-card>
|
||||
<layout-table
|
||||
v-model:pagination="pagination"
|
||||
:data="list"
|
||||
@get-data="fnGetDataTransfer"
|
||||
>
|
||||
<el-table-column label="序号" width="60">
|
||||
<template #default="{ $index }">
|
||||
{{ serialNumber(pagination, $index) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="试卷名称"
|
||||
prop="EXAMNAME"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="上传时间" prop="CREATTIME" width="150" />
|
||||
<el-table-column label="满分" prop="EXAMSCORE" width="150" />
|
||||
<el-table-column label="合格分数" prop="PASSSCORE" width="150" />
|
||||
<el-table-column label="试卷类型" width="150">
|
||||
<template #default="{ row }">
|
||||
{{ translationStatus(row.SOURCETYPE, sourceTypeList) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_process_management/exam_paper_management/view',
|
||||
query: { STAGEEXAMPAPERINPUT_ID: row.STAGEEXAMPAPERINPUT_ID },
|
||||
})
|
||||
"
|
||||
>
|
||||
查看
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="row.SOURCETYPE === '1' || row.PAPERUSERCOUNT > 0"
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_process_management/exam_paper_management/edit',
|
||||
query: {
|
||||
STAGEEXAMPAPERINPUT_ID: row.STAGEEXAMPAPERINPUT_ID,
|
||||
type: 'edit',
|
||||
},
|
||||
})
|
||||
"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_process_management/exam_paper_management/inherit',
|
||||
query: {
|
||||
STAGEEXAMPAPERINPUT_ID: row.STAGEEXAMPAPERINPUT_ID,
|
||||
type: 'inherit',
|
||||
},
|
||||
})
|
||||
"
|
||||
>
|
||||
继承
|
||||
</el-button>
|
||||
<el-button
|
||||
v-show="row.SOURCETYPE === '1' || row.PAPERUSERCOUNT > 0"
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnDelete(row.STAGEEXAMPAPERINPUT_ID)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_process_management/exam_paper_management/add',
|
||||
query: { type: 'add' },
|
||||
})
|
||||
"
|
||||
>
|
||||
新建试卷
|
||||
</el-button>
|
||||
</template>
|
||||
</layout-table>
|
||||
</layout-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import { getExamPaperManagementList } from "@/request/training_resource_management.js";
|
||||
import { serialNumber, translationStatus } from "@/assets/js/utils.js";
|
||||
import { useRouter } from "vue-router";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { setExamPaperManagementDelete } from "@/request/training_process_management.js";
|
||||
|
||||
const sourceTypeList = [
|
||||
{ ID: "1", NAME: "平台试卷" },
|
||||
{ ID: "2", NAME: "自建试卷" },
|
||||
];
|
||||
const router = useRouter();
|
||||
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
|
||||
useListData(getExamPaperManagementList);
|
||||
const fnGetDataTransfer = () => {
|
||||
fnGetData({
|
||||
STARTTIME: searchForm.value.dates?.[0],
|
||||
ENDTIME: searchForm.value.dates?.[1],
|
||||
});
|
||||
};
|
||||
const fnResetPaginationTransfer = () => {
|
||||
fnResetPagination({
|
||||
STARTTIME: searchForm.value.dates?.[0],
|
||||
ENDTIME: searchForm.value.dates?.[1],
|
||||
});
|
||||
};
|
||||
const fnDelete = debounce(
|
||||
1000,
|
||||
async (STAGEEXAMPAPERINPUT_ID) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", {
|
||||
type: "warning",
|
||||
});
|
||||
await setExamPaperManagementDelete({ STAGEEXAMPAPERINPUT_ID });
|
||||
ElMessage.success("删除成功");
|
||||
fnResetPaginationTransfer();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,9 @@
|
|||
<template>
|
||||
<view-info />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ViewInfo from "@/views/training_resource_management/exam_paper_management/view.vue";
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,628 @@
|
|||
<template>
|
||||
<layout-card>
|
||||
<el-divider content-position="left">课程基本信息</el-divider>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="data.form"
|
||||
:rules="rules"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="课程名称" prop="CURRICULUMNAME">
|
||||
<el-input v-model="data.form.CURRICULUMNAME" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="培训类型" prop="TRAINTYPE">
|
||||
<layout-learning-train-type
|
||||
ref="trainingTypeRef"
|
||||
v-model="data.form.TRAINTYPE"
|
||||
type="trainingType"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="行业类型" prop="INDUSTRY_LAST">
|
||||
<layout-learning-train-type
|
||||
ref="industryTypeRef"
|
||||
v-model="data.form.INDUSTRY_LAST"
|
||||
type="industryType"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="岗位类型" prop="POSTTYPE">
|
||||
<layout-learning-train-type
|
||||
ref="postTypeRef"
|
||||
v-model="data.form.POSTTYPE"
|
||||
type="postType"
|
||||
:search-value="data.form.TRAINTYPE"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="培训级别" prop="TRAINLEVEL">
|
||||
<layout-learning-train-type
|
||||
ref="trainingLevelRef"
|
||||
v-model="data.form.TRAINLEVEL"
|
||||
type="trainingLevel"
|
||||
:search-value="data.form.POSTTYPE"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="课程描述" prop="CURRICULUMINTRODUCE">
|
||||
<el-input
|
||||
v-model="data.form.CURRICULUMINTRODUCE"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 3 }"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="课程封面" prop="files">
|
||||
<layout-upload
|
||||
v-model:file-list="data.form.files"
|
||||
accept=".jpg,.jpeg,.png"
|
||||
list-type="picture-card"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<el-divider content-position="left">课程目录</el-divider>
|
||||
<div v-if="!CURRICULUM_ID">
|
||||
<div class="mb-10">
|
||||
<el-button
|
||||
:type="data.form.CATALOGUELEVEL === '1' ? 'success' : 'primary'"
|
||||
@click="fnChangeCatLevel('1')"
|
||||
>
|
||||
一级目录样式
|
||||
</el-button>
|
||||
<el-button
|
||||
:type="data.form.CATALOGUELEVEL === '2' ? 'success' : 'primary'"
|
||||
@click="fnChangeCatLevel('2')"
|
||||
>
|
||||
二级目录样式
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="course_directory">
|
||||
<div
|
||||
v-for="(item, index) in data.chapterList"
|
||||
:key="item.no"
|
||||
class="course_item"
|
||||
>
|
||||
<div class="course_row">
|
||||
<div class="course_icon">
|
||||
<el-icon
|
||||
v-if="
|
||||
item.nodes &&
|
||||
item.nodes.length !== 0 &&
|
||||
item.iconDirection === '1'
|
||||
"
|
||||
>
|
||||
<caret-bottom />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="course_number">{{ index + 1 }}</div>
|
||||
<div class="course_play">
|
||||
<el-icon v-if="item.VIDEOCOURSEWARE_ID" size="18">
|
||||
<video-camera />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="course_input">
|
||||
<el-input
|
||||
v-if="item.showNameInput"
|
||||
id="firstInput"
|
||||
v-model="item.NAME"
|
||||
@blur="fnInputBlur(item, $event)"
|
||||
/>
|
||||
<template v-else>{{ item.NAME }}</template>
|
||||
</div>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="fnDeleteChapter(index, item, 'first')"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="item.showNameInput"
|
||||
@click="fnRename(item, 'firstInput')"
|
||||
>
|
||||
重命名
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="data.form.CATALOGUELEVEL === '2'">
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="item.showNameInput"
|
||||
@click="fnAddSecondChapter(item)"
|
||||
>
|
||||
新增二级项
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="data.form.CATALOGUELEVEL === '1'">
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="item.showNameInput"
|
||||
@click="fnAddCourseware(index, '', 'radio')"
|
||||
>
|
||||
{{ item.VIDEOCOURSEWARE_ID ? "更改课件" : "添加课件" }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="item.VIDEOCOURSEWARE_ID">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="fnPreview(item.VIDEOCOURSEWARE_ID, '')"
|
||||
>
|
||||
预览
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(item1, index1) in item.nodes"
|
||||
:key="item1.no"
|
||||
class="course_row ml-30"
|
||||
>
|
||||
<div class="course_icon" />
|
||||
<div class="course_number">{{ index + 1 }}-{{ index1 + 1 }}</div>
|
||||
<div class="course_play">
|
||||
<el-icon v-if="item1.VIDEOCOURSEWARE_ID" size="18">
|
||||
<video-camera />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="course_input">
|
||||
<el-input
|
||||
v-if="item1.showNameInput"
|
||||
id="secondInput"
|
||||
v-model="item1.NAME"
|
||||
@blur="fnInputBlur(item1, $event)"
|
||||
/>
|
||||
<template v-else>{{ item1.NAME }}</template>
|
||||
</div>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="fnDeleteChapter(index1, item, 'second')"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="item1.showNameInput"
|
||||
@click="fnRename(item, 'secondInput')"
|
||||
>
|
||||
重命名
|
||||
</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="item1.showNameInput"
|
||||
@click="fnAddCourseware(index, index1, 'radio')"
|
||||
>
|
||||
{{ item1.VIDEOCOURSEWARE_ID ? "更改课件" : "添加课件" }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="item1.VIDEOCOURSEWARE_ID">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="fnPreview(item1.VIDEOCOURSEWARE_ID, '')"
|
||||
>
|
||||
预览
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-10">
|
||||
<el-button
|
||||
:disabled="data.addFirstChapterFlag"
|
||||
type="primary"
|
||||
@click="fnAddFirstChapter"
|
||||
>
|
||||
新增一级项
|
||||
</el-button>
|
||||
<el-button
|
||||
:disabled="data.addFirstChapterFlag"
|
||||
type="primary"
|
||||
@click="fnAddCourseware('', '', 'multiple')"
|
||||
>
|
||||
批量添加课件
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-tree
|
||||
v-if="!!CURRICULUM_ID"
|
||||
:data="data.chapterList"
|
||||
:props="{ children: 'nodes', label: 'COURSEWARENAME' }"
|
||||
class="directory_style"
|
||||
default-expand-all
|
||||
>
|
||||
<template #default="{ data: item }">
|
||||
<div class="directory_row">
|
||||
<el-icon
|
||||
v-if="item.COURSEWARENAME"
|
||||
class="el-icon-video-camera"
|
||||
size="18"
|
||||
>
|
||||
<video-camera />
|
||||
</el-icon>
|
||||
<span class="directory_name">
|
||||
{{ item.NAME || item.COURSEWARENAME }}
|
||||
</span>
|
||||
<span v-if="item.COURSEWARENAME" class="directory_type">
|
||||
课件时长:{{ secondConversion(item.VIDEOTIME) }}
|
||||
</span>
|
||||
<el-button
|
||||
v-if="item.COURSEWARENAME"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="fnPreview(item.VIDEOCOURSEWARE_ID, item.VIDEOFILES)"
|
||||
>
|
||||
预览
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-tree>
|
||||
<div class="mt-10 tc">
|
||||
<el-button type="primary" @click="fnSubmit">保存</el-button>
|
||||
</div>
|
||||
<layout-video
|
||||
v-model:visible="data.videoDialog.visible"
|
||||
:src="data.videoDialog.src"
|
||||
/>
|
||||
<template v-if="!CURRICULUM_ID">
|
||||
<add-courseware
|
||||
v-model:visible="data.addCoursewareDialog.visible"
|
||||
:chapter-ids="data.addCoursewareDialog.chapterIds"
|
||||
:type="data.addCoursewareDialog.type"
|
||||
:chapter-list="data.chapterList"
|
||||
:catalogue-level="data.form.CATALOGUELEVEL"
|
||||
@confirm="fnAddCoursewareConfirm"
|
||||
/>
|
||||
</template>
|
||||
</layout-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import {
|
||||
getCourseManagementView,
|
||||
getPreviewingVideo,
|
||||
setCourseManagementAdd,
|
||||
setCourseManagementEdit,
|
||||
} from "@/request/training_resource_management.js";
|
||||
import { nextTick, reactive, ref } from "vue";
|
||||
import { secondConversion } from "@/assets/js/utils.js";
|
||||
import { CaretBottom, VideoCamera } from "@element-plus/icons-vue";
|
||||
import LayoutVideo from "@/components/video/index.vue";
|
||||
import LayoutUpload from "@/components/upload/index.vue";
|
||||
import LayoutLearningTrainType from "@/components/learning_train_type/index.vue";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/assets/js/useFormValidate.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import AddCourseware from "./components/add_courseware.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { CURRICULUM_ID } = route.query;
|
||||
const rules = {
|
||||
CURRICULUMNAME: [
|
||||
{ required: true, message: "请输入课程名称", trigger: "blur" },
|
||||
],
|
||||
TRAINTYPE: [{ required: true, message: "请选择培训类型", trigger: "change" }],
|
||||
INDUSTRY_LAST: [
|
||||
{ required: true, message: "请选择行业类型", trigger: "change" },
|
||||
],
|
||||
POSTTYPE: [{ required: true, message: "请选择岗位类型", trigger: "change" }],
|
||||
files: [
|
||||
{
|
||||
required: true,
|
||||
message: "请上传封面",
|
||||
trigger: "change",
|
||||
},
|
||||
],
|
||||
CURRICULUMINTRODUCE: [
|
||||
{ required: true, message: "请输入课程描述", trigger: "blur" },
|
||||
],
|
||||
};
|
||||
const formRef = ref(null);
|
||||
const industryTypeRef = ref(null);
|
||||
const trainingTypeRef = ref(null);
|
||||
const postTypeRef = ref(null);
|
||||
const trainingLevelRef = ref(null);
|
||||
const data = reactive({
|
||||
form: {
|
||||
CURRICULUMNAME: "",
|
||||
TRAINTYPE: "",
|
||||
INDUSTRY_LAST: "",
|
||||
POSTTYPE: "",
|
||||
TRAINLEVEL: "",
|
||||
CURRICULUMINTRODUCE: "",
|
||||
files: [],
|
||||
CATALOGUELEVEL: "1",
|
||||
COLLECTIVE: 1,
|
||||
ISSELL: "1",
|
||||
},
|
||||
chapterList: [],
|
||||
addFirstChapterFlag: false,
|
||||
videoDialog: {
|
||||
visible: false,
|
||||
src: "",
|
||||
},
|
||||
addCoursewareDialog: {
|
||||
chapterIds: [],
|
||||
visible: false,
|
||||
index: "",
|
||||
index1: "",
|
||||
type: "",
|
||||
},
|
||||
});
|
||||
const fnGetData = async () => {
|
||||
if (!CURRICULUM_ID) return;
|
||||
const resData = await getCourseManagementView({ CURRICULUM_ID });
|
||||
data.form = resData.pd;
|
||||
data.chapterList = [...resData.chapterList];
|
||||
};
|
||||
fnGetData();
|
||||
const fnPreview = async (VIDEOCOURSEWARE_ID, VIDEOFILES) => {
|
||||
const resData = await getPreviewingVideo({
|
||||
VIDEOCOURSEWARE_ID,
|
||||
VIDEOFILES,
|
||||
CURRICULUM_ID,
|
||||
});
|
||||
data.videoDialog.src = JSON.stringify(resData.urlList);
|
||||
data.videoDialog.visible = true;
|
||||
};
|
||||
const fnAddFirstChapter = () => {
|
||||
const firstChapter = {
|
||||
VIDEOCOURSEWARE_ID: "",
|
||||
NAME: "",
|
||||
showNameInput: true,
|
||||
SORT: data.chapterList.length + 1,
|
||||
iconDirection: "1",
|
||||
nodes: [],
|
||||
no: Math.random(),
|
||||
};
|
||||
data.addFirstChapterFlag = true;
|
||||
data.chapterList.push(firstChapter);
|
||||
};
|
||||
const fnChangeCatLevel = async (level) => {
|
||||
if (data.form.CATALOGUELEVEL === level) return;
|
||||
if (data.chapterList.length > 0) {
|
||||
await ElMessageBox.confirm("切换目录样式后,将清空目录内容,是否继续?", {
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
data.addFirstChapterFlag = false;
|
||||
data.form.CATALOGUELEVEL = level;
|
||||
data.chapterList = [];
|
||||
};
|
||||
const fnInputBlur = (item, event) => {
|
||||
if (item.NAME) {
|
||||
data.addFirstChapterFlag = false;
|
||||
item.showNameInput = false;
|
||||
} else {
|
||||
ElMessage.warning("请输入名称");
|
||||
event.target.focus();
|
||||
}
|
||||
};
|
||||
const fnRename = async (item, element) => {
|
||||
item.showNameInput = true;
|
||||
await nextTick();
|
||||
document.getElementById(element).focus();
|
||||
};
|
||||
const fnDeleteChapter = async (index, item, whichNumber) => {
|
||||
await ElMessageBox.confirm(
|
||||
whichNumber === "first"
|
||||
? "你确定删除该一级项及下面所有二级项内容?"
|
||||
: "你确定删除该二级项及关联的所有课件和试卷?",
|
||||
{
|
||||
type: "warning",
|
||||
}
|
||||
);
|
||||
if (whichNumber === "first") {
|
||||
data.chapterList.splice(index, 1);
|
||||
} else {
|
||||
item.nodes.splice(index, 1);
|
||||
}
|
||||
data.addFirstChapterFlag = false;
|
||||
};
|
||||
const fnAddSecondChapter = (item) => {
|
||||
const secondChapter = {
|
||||
VIDEOCOURSEWARE_ID: "",
|
||||
NAME: "",
|
||||
showNameInput: true,
|
||||
SORT: item.nodes.length + 1,
|
||||
nodes: [],
|
||||
no: Math.random(),
|
||||
};
|
||||
item.nodes.push(secondChapter);
|
||||
};
|
||||
const fnAddCourseware = (index, index1, type) => {
|
||||
data.addCoursewareDialog.visible = true;
|
||||
data.addCoursewareDialog.index = index;
|
||||
data.addCoursewareDialog.index1 = index1;
|
||||
data.addCoursewareDialog.type = type;
|
||||
data.addCoursewareDialog.chapterIds = [];
|
||||
for (let i = 0; i < data.chapterList.length; i++) {
|
||||
const chapterListItem = data.chapterList[i];
|
||||
if (data.form.CATALOGUELEVEL === "1") {
|
||||
if (chapterListItem.VIDEOCOURSEWARE_ID) {
|
||||
data.addCoursewareDialog.chapterIds.push(
|
||||
chapterListItem.VIDEOCOURSEWARE_ID
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (let j = 0; j < chapterListItem.nodes.length; j++) {
|
||||
if (chapterListItem.nodes[j].VIDEOCOURSEWARE_ID) {
|
||||
data.addCoursewareDialog.chapterIds.push(
|
||||
chapterListItem.nodes[j].VIDEOCOURSEWARE_ID
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const fnAddCoursewareConfirm = (value) => {
|
||||
const { index, index1, type } = data.addCoursewareDialog;
|
||||
if (type === "radio") {
|
||||
if (data.form.CATALOGUELEVEL === "1") {
|
||||
data.chapterList[index].VIDEOCOURSEWARE_ID = value.VIDEOCOURSEWARE_ID;
|
||||
} else {
|
||||
data.chapterList[index].nodes[index1].VIDEOCOURSEWARE_ID =
|
||||
value.VIDEOCOURSEWARE_ID;
|
||||
}
|
||||
} else {
|
||||
data.chapterList = [...value];
|
||||
}
|
||||
};
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await useFormValidate(formRef);
|
||||
for (let i = 0; i < data.chapterList.length; i++) {
|
||||
const chapterListItem = data.chapterList[i];
|
||||
if (data.form.CATALOGUELEVEL === "1") {
|
||||
if (!chapterListItem.VIDEOCOURSEWARE_ID) {
|
||||
ElMessage.warning(`序号${i + 1}课件没空`);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (chapterListItem.nodes.length > 0) {
|
||||
for (let j = 0; j < chapterListItem.nodes.length; j++) {
|
||||
if (!chapterListItem.nodes[j].VIDEOCOURSEWARE_ID) {
|
||||
ElMessage.warning(`序号${i + 1}-${j + 1}课件没空`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ElMessage.warning(`序号${i + 1}没有下级目录`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
const { name, id } = industryTypeRef.value.getIndustryTypeCurrentCheckAll();
|
||||
const form = {
|
||||
...data.form,
|
||||
TRAINTYPE_NAME: trainingTypeRef.value.getCurrentNode().NAME,
|
||||
INDUSTRY_LAST_NAME: name.at(-1),
|
||||
INDUSTRY_ALL_NAME: name.join("-"),
|
||||
INDUSTRY_ALL_TYPE: id.join("-"),
|
||||
POSTTYPE_NAME: postTypeRef.value.getCurrentNode().NAME,
|
||||
TRAINLEVEL_NAME: trainingLevelRef.value.getCurrentNode().NAME || "",
|
||||
chapterList: JSON.stringify(data.chapterList),
|
||||
INDUSTRY_END_ID: data.form.INDUSTRY_LAST,
|
||||
};
|
||||
const formData = new FormData();
|
||||
Object.keys(form).forEach((key) => {
|
||||
formData.append(key, form[key]);
|
||||
});
|
||||
formData.delete("files");
|
||||
for (let i = 0; i < data.form.files.length; i++) {
|
||||
if (data.form.files[i].raw)
|
||||
formData.append("FFILE", data.form.files[i].raw);
|
||||
}
|
||||
!CURRICULUM_ID
|
||||
? await setCourseManagementAdd(formData)
|
||||
: await setCourseManagementEdit(formData);
|
||||
ElMessage.success("保存成功");
|
||||
router.back();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.directory_style {
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.el-icon-video-camera {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.directory_row {
|
||||
.directory_name {
|
||||
width: 260px;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.directory_type {
|
||||
width: 200px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep {
|
||||
.el-tree-node__content {
|
||||
margin-bottom: 10px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.course_directory {
|
||||
.course_item {
|
||||
.course_row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 3px 10px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--el-fill-color-light);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div + div {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.course_icon {
|
||||
color: #c0c4cc;
|
||||
font-size: 12px;
|
||||
width: 12px;
|
||||
height: 14px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.course_play {
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
width: 16px;
|
||||
height: 15px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.course_number {
|
||||
background-color: #0d5aa3;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
padding: 4px 5px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.course_input {
|
||||
width: 300px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,754 @@
|
|||
<template>
|
||||
<el-dialog v-model="visible" title="选择课件" width="90%" :on-close="fnClose">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="type === 'multiple' ? 16 : 24">
|
||||
<el-form
|
||||
:model="searchForm"
|
||||
label-width="100px"
|
||||
@submit.prevent="fnResetPagination"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="课程名称" prop="KEYWORDS">
|
||||
<el-input v-model="searchForm.KEYWORDS" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label-width="10px">
|
||||
<el-button type="primary" native-type="submit">搜索</el-button>
|
||||
<el-button native-type="reset" @click="fnResetPagination">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<layout-table
|
||||
ref="tableRef"
|
||||
v-model:pagination="pagination"
|
||||
row-key="VIDEOCOURSEWARE_ID"
|
||||
:data="list"
|
||||
:row-class-name="fnRowClassName"
|
||||
@get-data="fnGetData"
|
||||
>
|
||||
<el-table-column
|
||||
type="selection"
|
||||
width="55"
|
||||
:selectable="fnIsDisabled"
|
||||
>
|
||||
<template v-if="type === 'radio'" #default="{ row }">
|
||||
<el-radio
|
||||
v-model="data.radioValue"
|
||||
:label="row.VIDEOCOURSEWARE_ID"
|
||||
:disabled="fnIsDisabled(row)"
|
||||
@change="fnRadioChange(row)"
|
||||
>
|
||||
<span />
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="序号" width="60">
|
||||
<template #default="{ $index }">
|
||||
{{ serialNumber(pagination, $index) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="COURSEWARENAME"
|
||||
label="课程名称"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column prop="POSTTYPE_NAME" label="岗位" />
|
||||
<el-table-column prop="INDUSTRY_END_NAME" label="行业类型" />
|
||||
<el-table-column prop="TRAININGTYPE_NAME" label="课件类型" />
|
||||
<el-table-column prop="TEACHERNAME" label="讲师" width="150" />
|
||||
<el-table-column prop="CLASSHOUR" label="课件学时" width="100" />
|
||||
<el-table-column prop="RELATEDTERMNAME" label="相关词条">
|
||||
<template #default="{ row }">
|
||||
{{ row.VIDEOCOURSEWARE_ID }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</layout-table>
|
||||
</el-col>
|
||||
<el-col v-if="type === 'multiple'" :span="8">
|
||||
<div>
|
||||
<el-divider content-position="left">课程章节</el-divider>
|
||||
<div>
|
||||
<div>
|
||||
<el-button
|
||||
:type="data.CATALOGUELEVEL === '1' ? 'success' : 'primary'"
|
||||
@click="fnChangeCatLevel('1')"
|
||||
>
|
||||
一级目录样式
|
||||
</el-button>
|
||||
<el-button
|
||||
:type="data.CATALOGUELEVEL === '2' ? 'success' : 'primary'"
|
||||
@click="fnChangeCatLevel('2')"
|
||||
>
|
||||
二级目录样式
|
||||
</el-button>
|
||||
</div>
|
||||
<el-scrollbar
|
||||
ref="scroll"
|
||||
:wrap-style="[{ 'overflow-x': 'hidden' }]"
|
||||
style="height: 325px; margin-bottom: 10px"
|
||||
>
|
||||
<div class="course_directory mt-10">
|
||||
<div v-if="data.chapterList.length === 0">
|
||||
暂无数据,请在左侧选择数据。
|
||||
</div>
|
||||
<div
|
||||
v-for="(item, index) in data.chapterList"
|
||||
:key="item.no"
|
||||
class="course_item"
|
||||
>
|
||||
<div class="course_row">
|
||||
<div class="course_icon">
|
||||
<el-icon
|
||||
v-if="
|
||||
item.nodes &&
|
||||
item.nodes.length !== 0 &&
|
||||
item.iconDirection === '1'
|
||||
"
|
||||
>
|
||||
<caret-bottom />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="course_number">{{ index + 1 }}</div>
|
||||
<div class="course_play">
|
||||
<el-icon v-if="item.VIDEOCOURSEWARE_ID" size="18">
|
||||
<video-camera />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="course_input">
|
||||
<el-input
|
||||
v-if="item.showNameInput"
|
||||
id="firstInput"
|
||||
v-model="item.NAME"
|
||||
@blur="fnInputBlur(item, $event)"
|
||||
/>
|
||||
<template v-else>{{ item.NAME }}</template>
|
||||
</div>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="fnDeleteChapter(index, item, 'first')"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="item.showNameInput"
|
||||
@click="fnRename(item, 'firstInput')"
|
||||
>
|
||||
重命名
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="data.CATALOGUELEVEL === '2'">
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="item.showNameInput"
|
||||
@click="fnSaveCourseware(index)"
|
||||
>
|
||||
保存课件到此章节下
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="item.VIDEOCOURSEWARE_ID">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="fnPreview(item.VIDEOCOURSEWARE_ID, '')"
|
||||
>
|
||||
预览
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(item1, index1) in item.nodes"
|
||||
:key="item1.no"
|
||||
class="course_row ml-30"
|
||||
>
|
||||
<div class="course_icon" />
|
||||
<div class="course_number">
|
||||
{{ index + 1 }}-{{ index1 + 1 }}
|
||||
</div>
|
||||
<div class="course_play">
|
||||
<el-icon v-if="item1.VIDEOCOURSEWARE_ID" size="18">
|
||||
<video-camera />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="course_input">
|
||||
<el-input
|
||||
v-if="item1.showNameInput"
|
||||
id="secondInput"
|
||||
v-model="item1.NAME"
|
||||
@blur="fnInputBlur(item1, $event)"
|
||||
/>
|
||||
<template v-else>{{ item1.NAME }}</template>
|
||||
</div>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="fnDeleteChapter(index1, item, 'second')"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="item1.showNameInput"
|
||||
@click="fnRename(item, 'secondInput')"
|
||||
>
|
||||
重命名
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="item1.VIDEOCOURSEWARE_ID">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="fnPreview(item1.VIDEOCOURSEWARE_ID, '')"
|
||||
>
|
||||
预览
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<div style="margin-top: 5px">
|
||||
<el-button
|
||||
v-if="data.CATALOGUELEVEL === '1'"
|
||||
:disabled="data.addFirstChapterFlag"
|
||||
type="primary"
|
||||
@click="fnSaveCourseware('')"
|
||||
>
|
||||
保存课件到此章节下
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="data.CATALOGUELEVEL === '2'"
|
||||
:disabled="data.addFirstChapterFlag"
|
||||
type="primary"
|
||||
@click="fnAddFirstChapter"
|
||||
>
|
||||
新增一级项
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<el-button @click="fnClose">取消</el-button>
|
||||
<el-button type="primary" @click="fnConfirm">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<layout-video
|
||||
v-model:visible="data.videoDialog.visible"
|
||||
:src="data.videoDialog.src"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useVModels } from "@vueuse/core";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import {
|
||||
getPreviewingVideo,
|
||||
getSelectCourseManagementList,
|
||||
} from "@/request/training_resource_management.js";
|
||||
import { serialNumber } from "@/assets/js/utils.js";
|
||||
import { nextTick, reactive, watch } from "vue";
|
||||
import { CaretBottom, VideoCamera } from "@element-plus/icons-vue";
|
||||
import LayoutVideo from "@/components/video/index.vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { debounce } from "throttle-debounce";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
chapterIds: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => [],
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
chapterList: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => [],
|
||||
},
|
||||
catalogueLevel: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:visible", "confirm"]);
|
||||
const { visible } = useVModels(props, emits);
|
||||
const { list, searchForm, pagination, fnGetData, tableRef, fnResetPagination } =
|
||||
useListData(getSelectCourseManagementList, {
|
||||
otherParams: {
|
||||
CANUSE: "1",
|
||||
STATE: "0",
|
||||
ISCOMPLETE: "1",
|
||||
},
|
||||
immediate: false,
|
||||
});
|
||||
let currentValue = {};
|
||||
const data = reactive({
|
||||
radioValue: "",
|
||||
CATALOGUELEVEL: "",
|
||||
chapterList: [],
|
||||
addFirstChapterFlag: false,
|
||||
chapterIds: [],
|
||||
videoDialog: {
|
||||
visible: false,
|
||||
src: "",
|
||||
},
|
||||
});
|
||||
watch(
|
||||
() => props.visible,
|
||||
() => {
|
||||
if (props.visible) {
|
||||
list.value = [
|
||||
{
|
||||
COURSEWAREINTRODUCE: "有秒差",
|
||||
OPERATTIME: "2024-02-27 14:16:03",
|
||||
TEACHERNAME: "张迪",
|
||||
VIDEOCOURSEWARE_ID: "ee87b97b7cd64508bf0228c30740c363",
|
||||
ISDELETE: 0,
|
||||
QUESTIONCOUNT: 0,
|
||||
VIDEOFILES: "d0523eabd53771ee80441777b3ce0102",
|
||||
POSTTYPE: "",
|
||||
STATE: "0",
|
||||
SPEAKER: "012af2449ff247e1bf8749a4f4db5b5a",
|
||||
CORPINFO_ID: "",
|
||||
TRAINTYPE: "",
|
||||
ISCOMPLETE: "1",
|
||||
COURSEWARENAME: "视频时长课件",
|
||||
CLASSHOUR: 0.3,
|
||||
VIDEOTIME: "785.05",
|
||||
OPERATOR: "admin",
|
||||
CREATOR: "admin",
|
||||
SOURCE: "1",
|
||||
LIMIT_TIME: "自建课件",
|
||||
VIDEOCAPTURE: "",
|
||||
INDUSTRY_ALL_NAME: "",
|
||||
CREATTIME: "2024-02-27 14:16:03",
|
||||
},
|
||||
{
|
||||
COURSEWAREINTRODUCE: "11",
|
||||
OPERATTIME: "2024-01-18 19:40:24",
|
||||
TEACHERNAME: "张迪",
|
||||
VIDEOCOURSEWARE_ID: "551a8869e9c0438b9c76532ee36fe3a7",
|
||||
ISDELETE: 0,
|
||||
QUESTIONCOUNT: 30,
|
||||
VIDEOFILES: "50646463b5f671ee9e0f16b5feac0102",
|
||||
POSTTYPE: "",
|
||||
STATE: "0",
|
||||
SPEAKER: "012af2449ff247e1bf8749a4f4db5b5a",
|
||||
CORPINFO_ID: "",
|
||||
TRAINTYPE: "",
|
||||
ISCOMPLETE: "1",
|
||||
COURSEWARENAME: "0118-1",
|
||||
CLASSHOUR: 0,
|
||||
VIDEOTIME: "40.536",
|
||||
OPERATOR: "admin",
|
||||
CREATOR: "admin",
|
||||
SOURCE: "1",
|
||||
LIMIT_TIME: "自建课件",
|
||||
VIDEOCAPTURE: "",
|
||||
INDUSTRY_ALL_NAME: "",
|
||||
CREATTIME: "2024-01-18 19:40:24",
|
||||
},
|
||||
{
|
||||
POSTTYPE_NAME: "三级教育培训",
|
||||
COURSEWAREINTRODUCE: "1111",
|
||||
TEACHERNAME: "张迪",
|
||||
ISDELETE: 0,
|
||||
QUESTIONCOUNT: 6,
|
||||
VIDEOFILES: "004e87faa93b71ee9f661777b3de0102",
|
||||
POSTTYPE: "d302da12d8724faaa24e5008adab8ce8",
|
||||
STATE: "0",
|
||||
SPEAKER: "012af2449ff247e1bf8749a4f4db5b5a",
|
||||
TRAININGTYPE_NAME: "全员培训",
|
||||
INDUSTRY_END_NAME: "道路运输业",
|
||||
CREATOR: "admin",
|
||||
LIMIT_TIME: "自建课件",
|
||||
INDUSTRY_ALL_NAME: "道路运输业",
|
||||
OPERATTIME: "2024-01-02 14:55:57",
|
||||
VIDEOCOURSEWARE_ID: "cd455a17ff164e369c4a0bd45f88a6e6",
|
||||
CORPINFO_ID: "",
|
||||
TRAINTYPE: "6128172b7a1144c98cc196044281f66c",
|
||||
ISCOMPLETE: "1",
|
||||
COURSEWARENAME: "51秒视频",
|
||||
CLASSHOUR: 0,
|
||||
VIDEOTIME: "51.714",
|
||||
OPERATOR: "admin",
|
||||
SOURCE: "1",
|
||||
VIDEOCAPTURE: "",
|
||||
CREATTIME: "2024-01-02 14:55:57",
|
||||
},
|
||||
{
|
||||
COURSEWAREINTRODUCE:
|
||||
"术语;产品分类;应急喷淋器;洗眼器;洗眼/洗脸器;复合式装置 ;补充装置;标识和说明\n",
|
||||
OPERATTIME: "2023-12-21 14:13:45",
|
||||
TEACHERNAME: "李娜",
|
||||
VIDEOCOURSEWARE_ID: "a6e69f682a7e409b890912c2dfaf028f",
|
||||
ISDELETE: 0,
|
||||
QUESTIONCOUNT: 15,
|
||||
VIDEOFILES: "c9b18910c7ca71ed87e734b6fdcb0102",
|
||||
STATE: "0",
|
||||
SPEAKER: "abc501710070444f8a6cca7f4682bcdc",
|
||||
CURRICULUM_ID_REMOTE: "cf9a1f623cd74a9682243ccd9c958275",
|
||||
ISCOMPLETE: "1",
|
||||
COURSEWARENAME: "眼面部防护 应急喷淋和洗眼设备 第1部分:技术要求",
|
||||
CLASSHOUR: 1,
|
||||
VIDEOTIME: "2615.89",
|
||||
OPERATOR: "联安众超管",
|
||||
CREATOR: "admin",
|
||||
SOURCE: "2",
|
||||
LIMIT_TIME: "2026-04-30",
|
||||
VIDEOCOURSEWARE_ID_REMOTE: "64e06f64e20b4ed1ab3b5a0dcdae3bb1",
|
||||
CREATTIME: "2023-04-18 09:08:07",
|
||||
},
|
||||
{
|
||||
COURSEWAREINTRODUCE: "包装装潢印刷;其他印刷品印刷;出版物印刷",
|
||||
OPERATTIME: "2023-12-21 10:41:55",
|
||||
TEACHERNAME: "侯彩侠",
|
||||
VIDEOCOURSEWARE_ID: "77d5ac0920c14f07a918e0923e68dced",
|
||||
ISDELETE: 0,
|
||||
QUESTIONCOUNT: 10,
|
||||
VIDEOFILES: "93a42690cfa771edab9316b5feac0102",
|
||||
STATE: "0",
|
||||
SPEAKER: "474f287cf08d491ba3bd53a81aec4eaa",
|
||||
CURRICULUM_ID_REMOTE: "8226ea7cdd9c4231be3a02a00815ef7a",
|
||||
ISCOMPLETE: "1",
|
||||
COURSEWARENAME: "包装装潢及其他印刷业车间级安全生产培训",
|
||||
CLASSHOUR: 1.2,
|
||||
VIDEOTIME: "3214.08",
|
||||
OPERATOR: "admin",
|
||||
CREATOR: "联安众超管",
|
||||
SOURCE: "2",
|
||||
LIMIT_TIME: "2026-04-30",
|
||||
VIDEOCOURSEWARE_ID_REMOTE: "7a5090ef80824568a57f6aedb4e71871",
|
||||
CREATTIME: "2023-05-23 08:15:09",
|
||||
},
|
||||
{
|
||||
POSTTYPE_NAME: "职业健康管理人员",
|
||||
COURSEWAREINTRODUCE: "123",
|
||||
TEACHERNAME: "马博",
|
||||
ISDELETE: 0,
|
||||
QUESTIONCOUNT: 0,
|
||||
VIDEOFILES: "33151180883f71ee828d34b6fdcb0102",
|
||||
POSTTYPE: "79042228778146d9bb7f0547b48a7b14",
|
||||
STATE: "0",
|
||||
SPEAKER: "08122e584d53442d8f57417a8bd129c7",
|
||||
TRAININGTYPE_NAME: "职业健康",
|
||||
INDUSTRY_END_NAME: "公路旅客运输",
|
||||
CREATOR: "admin",
|
||||
LIMIT_TIME: "自建课件",
|
||||
INDUSTRY_ALL_NAME: "道路运输业-公路旅客运输",
|
||||
OPERATTIME: "2023-11-21 15:25:52",
|
||||
VIDEOCOURSEWARE_ID: "38d87d7908d945418e89e27ec77c28ad",
|
||||
CORPINFO_ID: "",
|
||||
TRAINTYPE: "c70bf859512241579a8a30fc5d1ae153",
|
||||
ISCOMPLETE: "1",
|
||||
COURSEWARENAME: "测试视频(此视频无法播放)",
|
||||
CLASSHOUR: 0,
|
||||
VIDEOTIME: "5.033",
|
||||
OPERATOR: "admin",
|
||||
SOURCE: "1",
|
||||
VIDEOCAPTURE: "",
|
||||
CREATTIME: "2023-11-21 15:25:52",
|
||||
},
|
||||
{
|
||||
COURSEWAREINTRODUCE:
|
||||
"51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件",
|
||||
OPERATTIME: "2023-10-17 16:58:51",
|
||||
TEACHERNAME: "张迪",
|
||||
VIDEOCOURSEWARE_ID: "2f8ae0ce434541848a571e5ecc0a44f8",
|
||||
ISDELETE: 0,
|
||||
QUESTIONCOUNT: 0,
|
||||
VIDEOFILES: "63eef6706ccb71eebfd10666a2ec0102",
|
||||
POSTTYPE: "",
|
||||
STATE: "0",
|
||||
SPEAKER: "012af2449ff247e1bf8749a4f4db5b5a",
|
||||
CORPINFO_ID: "",
|
||||
TRAINTYPE: "",
|
||||
ISCOMPLETE: "1",
|
||||
COURSEWARENAME:
|
||||
"51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件51秒课件",
|
||||
CLASSHOUR: 0,
|
||||
VIDEOTIME: "51.714",
|
||||
OPERATOR: "admin",
|
||||
CREATOR: "admin",
|
||||
SOURCE: "1",
|
||||
LIMIT_TIME: "自建课件",
|
||||
VIDEOCAPTURE: "",
|
||||
INDUSTRY_ALL_NAME: "",
|
||||
CREATTIME: "2023-10-17 16:58:51",
|
||||
},
|
||||
{
|
||||
POSTTYPE_NAME: "三级教育培训",
|
||||
COURSEWAREINTRODUCE: "1分30秒视频测试",
|
||||
TEACHERNAME: "刘敬英",
|
||||
ISDELETE: 0,
|
||||
QUESTIONCOUNT: 0,
|
||||
VIDEOFILES: "aa2664b0670e71ee825d1777b3ce0102",
|
||||
POSTTYPE: "d302da12d8724faaa24e5008adab8ce8",
|
||||
STATE: "0",
|
||||
SPEAKER: "01ea51f0b07a402b8a7785111bc79be7",
|
||||
TRAININGTYPE_NAME: "全员培训",
|
||||
INDUSTRY_END_NAME: "道路运输业",
|
||||
CREATOR: "admin",
|
||||
LIMIT_TIME: "自建课件",
|
||||
INDUSTRY_ALL_NAME: "道路运输业",
|
||||
OPERATTIME: "2023-10-17 15:24:36",
|
||||
VIDEOCOURSEWARE_ID: "19f3f065b67e4242906155a3eafc86ef",
|
||||
CORPINFO_ID: "",
|
||||
TRAINTYPE: "6128172b7a1144c98cc196044281f66c",
|
||||
ISCOMPLETE: "1",
|
||||
COURSEWARENAME: "1分30秒视频测试",
|
||||
CLASSHOUR: 0,
|
||||
VIDEOTIME: "88.542",
|
||||
OPERATOR: "admin",
|
||||
SOURCE: "1",
|
||||
VIDEOCAPTURE: "",
|
||||
CREATTIME: "2023-10-10 09:45:20",
|
||||
},
|
||||
{
|
||||
COURSEWAREINTRODUCE: "30秒视频",
|
||||
OPERATTIME: "2023-10-10 09:47:34",
|
||||
TEACHERNAME: "高静",
|
||||
VIDEOCOURSEWARE_ID: "5ec4aeec7178426caaac1cd5c4165858",
|
||||
ISDELETE: 0,
|
||||
QUESTIONCOUNT: 0,
|
||||
VIDEOFILES: "fa09e6a0670e71eebc35752281fd0102",
|
||||
POSTTYPE: "",
|
||||
STATE: "0",
|
||||
SPEAKER: "0a2324c8ffe74152b7ed2bbdb5c35dda",
|
||||
CORPINFO_ID: "",
|
||||
TRAINTYPE: "",
|
||||
ISCOMPLETE: "1",
|
||||
COURSEWARENAME: "30秒视频",
|
||||
CLASSHOUR: 0,
|
||||
VIDEOTIME: "31.0",
|
||||
OPERATOR: "admin",
|
||||
CREATOR: "admin",
|
||||
SOURCE: "1",
|
||||
LIMIT_TIME: "自建课件",
|
||||
VIDEOCAPTURE: "",
|
||||
INDUSTRY_ALL_NAME: "",
|
||||
CREATTIME: "2023-10-10 09:47:34",
|
||||
},
|
||||
{
|
||||
COURSEWAREINTRODUCE: "1分钟视频",
|
||||
TEACHERNAME: "张迪",
|
||||
ISDELETE: 0,
|
||||
QUESTIONCOUNT: 0,
|
||||
VIDEOFILES: "0513fe70664f71ee834c1776b3ce0102",
|
||||
POSTTYPE: "",
|
||||
STATE: "0",
|
||||
SPEAKER: "012af2449ff247e1bf8749a4f4db5b5a",
|
||||
TRAININGTYPE_NAME: "全员培训",
|
||||
INDUSTRY_END_NAME: "选矿厂",
|
||||
CREATOR: "admin",
|
||||
LIMIT_TIME: "自建课件",
|
||||
INDUSTRY_ALL_NAME: "高危行业-金属非金属矿山-选矿厂",
|
||||
OPERATTIME: "2023-10-09 10:53:28",
|
||||
VIDEOCOURSEWARE_ID: "5c097d1b383042728eb99fb6e5c982d3",
|
||||
CORPINFO_ID: "",
|
||||
TRAINTYPE: "6128172b7a1144c98cc196044281f66c",
|
||||
ISCOMPLETE: "1",
|
||||
COURSEWARENAME: "1分钟课件",
|
||||
CLASSHOUR: 0,
|
||||
VIDEOTIME: "54.547",
|
||||
OPERATOR: "admin",
|
||||
SOURCE: "1",
|
||||
VIDEOCAPTURE: "",
|
||||
CREATTIME: "2023-10-09 10:53:28",
|
||||
},
|
||||
];
|
||||
data.CATALOGUELEVEL = props.catalogueLevel;
|
||||
data.chapterList = [...props.chapterList];
|
||||
data.chapterIds = [...props.chapterIds];
|
||||
}
|
||||
}
|
||||
);
|
||||
const fnRadioChange = (row) => {
|
||||
currentValue = row;
|
||||
};
|
||||
const fnRowClassName = ({ row }) => {
|
||||
return data.chapterIds.some((item) => item === row.VIDEOCOURSEWARE_ID)
|
||||
? "text-red"
|
||||
: "";
|
||||
};
|
||||
const fnIsDisabled = (row) => {
|
||||
if (props.type === "radio")
|
||||
return data.chapterIds.some((item) => item === row.VIDEOCOURSEWARE_ID);
|
||||
else return !data.chapterIds.some((item) => item === row.VIDEOCOURSEWARE_ID);
|
||||
};
|
||||
const fnPreview = async (VIDEOCOURSEWARE_ID, VIDEOFILES) => {
|
||||
const resData = await getPreviewingVideo({
|
||||
VIDEOCOURSEWARE_ID,
|
||||
VIDEOFILES,
|
||||
});
|
||||
data.videoDialog.src = JSON.stringify(resData.urlList);
|
||||
data.videoDialog.visible = true;
|
||||
};
|
||||
const fnChangeCatLevel = async (level) => {
|
||||
if (data.CATALOGUELEVEL === level) return;
|
||||
if (data.chapterList.length > 0) {
|
||||
await ElMessageBox.confirm("切换目录样式后,将清空目录内容,是否继续?", {
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
data.addFirstChapterFlag = false;
|
||||
data.CATALOGUELEVEL = level;
|
||||
data.chapterList = [];
|
||||
data.chapterIds = [];
|
||||
};
|
||||
const fnInputBlur = (item, event) => {
|
||||
if (item.NAME) {
|
||||
data.addFirstChapterFlag = false;
|
||||
item.showNameInput = false;
|
||||
} else {
|
||||
ElMessage.warning("请输入名称");
|
||||
event.target.focus();
|
||||
}
|
||||
};
|
||||
const fnRename = async (item, element) => {
|
||||
item.showNameInput = true;
|
||||
await nextTick();
|
||||
document.getElementById(element).focus();
|
||||
};
|
||||
const fnDeleteChapter = async (index, item, whichNumber) => {
|
||||
await ElMessageBox.confirm(
|
||||
whichNumber === "first"
|
||||
? "你确定删除该一级项及下面所有二级项内容?"
|
||||
: "你确定删除该二级项及关联的所有课件和试卷?",
|
||||
{
|
||||
type: "warning",
|
||||
}
|
||||
);
|
||||
if (whichNumber === "first") {
|
||||
data.chapterList.splice(index, 1);
|
||||
} else {
|
||||
item.nodes.splice(index, 1);
|
||||
}
|
||||
data.addFirstChapterFlag = false;
|
||||
};
|
||||
const fnAddFirstChapter = () => {
|
||||
const firstChapter = {
|
||||
VIDEOCOURSEWARE_ID: "",
|
||||
NAME: "",
|
||||
showNameInput: true,
|
||||
SORT: data.chapterList.length + 1,
|
||||
iconDirection: "1",
|
||||
nodes: [],
|
||||
no: Math.random(),
|
||||
};
|
||||
data.addFirstChapterFlag = true;
|
||||
data.chapterList.push(firstChapter);
|
||||
};
|
||||
const fnSaveCourseware = (index) => {
|
||||
const selectionData = tableRef.value.getSelectionRows();
|
||||
if (selectionData.length === 0) {
|
||||
ElMessage.warning("请选择要添加的课件");
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < selectionData.length; i++) {
|
||||
selectionData[i].NAME = selectionData[i].COURSEWARENAME;
|
||||
data.chapterIds.push(selectionData[i].VIDEOCOURSEWARE_ID);
|
||||
}
|
||||
if (data.CATALOGUELEVEL === "1") {
|
||||
data.chapterList = [...data.chapterList, ...selectionData];
|
||||
} else {
|
||||
data.chapterList[index].nodes = [
|
||||
...data.chapterList[index].nodes,
|
||||
...selectionData,
|
||||
];
|
||||
}
|
||||
ElMessage.success("添加成功");
|
||||
tableRef.value.clearSelection();
|
||||
};
|
||||
const fnClose = () => {
|
||||
data.radioValue = "";
|
||||
data.CATALOGUELEVEL = "";
|
||||
data.chapterList = [];
|
||||
data.addFirstChapterFlag = false;
|
||||
data.chapterIds = [];
|
||||
currentValue = {};
|
||||
searchForm.value.KEYWORDS = "";
|
||||
visible.value = false;
|
||||
tableRef.value.clearSelection();
|
||||
};
|
||||
const fnConfirm = debounce(
|
||||
1000,
|
||||
() => {
|
||||
const value = props.type === "radio" ? currentValue : data.chapterList;
|
||||
emits("confirm", value);
|
||||
fnClose();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.course_directory {
|
||||
.course_item {
|
||||
.course_row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 3px 10px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--el-fill-color-light);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div + div {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.course_icon {
|
||||
color: #c0c4cc;
|
||||
font-size: 12px;
|
||||
width: 12px;
|
||||
height: 14px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.course_play {
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
width: 16px;
|
||||
height: 15px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.course_number {
|
||||
width: 100px;
|
||||
background-color: #0d5aa3;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
padding: 4px 5px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.course_input {
|
||||
width: 300px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,201 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form
|
||||
:model="searchForm"
|
||||
label-width="100px"
|
||||
@submit.prevent="fnResetPaginationTransfer"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="课程名称" prop="KEYWORDS">
|
||||
<el-input v-model="searchForm.KEYWORDS" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="创建时间" prop="dates">
|
||||
<el-date-picker
|
||||
v-model="searchForm.dates"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="培训类型" prop="TRAINTYPE">
|
||||
<layout-learning-train-type
|
||||
v-model="searchForm.TRAINTYPE"
|
||||
type="trainingType"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="行业类型" prop="INDUSTRY_END_ID">
|
||||
<layout-learning-train-type
|
||||
v-model="searchForm.INDUSTRY_END_ID"
|
||||
type="industryType"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="岗位类型" prop="POSTTYPE">
|
||||
<layout-learning-train-type
|
||||
v-model="searchForm.POSTTYPE"
|
||||
type="postType"
|
||||
:search-value="searchForm.TRAINTYPE"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="培训级别" prop="TRAINLEVEL">
|
||||
<layout-learning-train-type
|
||||
v-model="searchForm.TRAINLEVEL"
|
||||
type="trainingLevel"
|
||||
:search-value="searchForm.TRAINTYPE"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label-width="10px">
|
||||
<el-button type="primary" native-type="submit">搜索</el-button>
|
||||
<el-button native-type="reset" @click="fnResetPaginationTransfer">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<layout-card>
|
||||
<layout-table
|
||||
v-model:pagination="pagination"
|
||||
:data="list"
|
||||
@get-data="fnGetDataTransfer"
|
||||
>
|
||||
<el-table-column label="序号" width="60">
|
||||
<template #default="{ $index }">
|
||||
{{ serialNumber(pagination, $index) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="课程名称"
|
||||
prop="CURRICULUMNAME"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="上传时间" prop="CREATTIME" width="150" />
|
||||
<el-table-column label="培训类型" prop="TRAININGTYPE_NAME" />
|
||||
<el-table-column label="行业类型">
|
||||
<template #default="{ row }">
|
||||
{{ row.INDUSTRY_END_NAME || row.INDUSTRY_ALL_NAME }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="岗位类型" prop="POSTTYPE_NAME" />
|
||||
<el-table-column label="课件数" prop="COURSEWARECOUNT" width="100" />
|
||||
<el-table-column label="课件时长" width="100">
|
||||
<template #default="{ row }">
|
||||
{{ secondConversion(row.VIDEOTIME) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_resource_management/course_management/view',
|
||||
query: { CURRICULUM_ID: row.CURRICULUM_ID },
|
||||
})
|
||||
"
|
||||
>
|
||||
查看
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="row.IS_CORP_CREATE === 1"
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_resource_management/course_management/add',
|
||||
query: { CURRICULUM_ID: row.CURRICULUM_ID },
|
||||
})
|
||||
"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="row.IS_CORP_CREATE === 1"
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnDelete(row.CURRICULUM_ID)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_resource_management/course_management/add',
|
||||
})
|
||||
"
|
||||
>
|
||||
新增
|
||||
</el-button>
|
||||
</template>
|
||||
</layout-table>
|
||||
</layout-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import {
|
||||
getCourseManagementList,
|
||||
setCourseManagementDelete,
|
||||
} from "@/request/training_resource_management.js";
|
||||
import LayoutLearningTrainType from "@/components/learning_train_type/index.vue";
|
||||
import { secondConversion, serialNumber } from "@/assets/js/utils.js";
|
||||
import { useRouter } from "vue-router";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
|
||||
const router = useRouter();
|
||||
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
|
||||
useListData(getCourseManagementList);
|
||||
const fnGetDataTransfer = () => {
|
||||
fnGetData({
|
||||
STARTTIME: searchForm.value.dates?.[0],
|
||||
ENDTIME: searchForm.value.dates?.[1],
|
||||
});
|
||||
};
|
||||
const fnResetPaginationTransfer = () => {
|
||||
fnResetPagination({
|
||||
STARTTIME: searchForm.value.dates?.[0],
|
||||
ENDTIME: searchForm.value.dates?.[1],
|
||||
});
|
||||
};
|
||||
const fnDelete = debounce(
|
||||
1000,
|
||||
async (CURRICULUM_ID) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", {
|
||||
type: "warning",
|
||||
});
|
||||
await setCourseManagementDelete({ CURRICULUM_ID });
|
||||
ElMessage.success("删除成功");
|
||||
fnResetPaginationTransfer();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,137 @@
|
|||
<template>
|
||||
<layout-card>
|
||||
<el-divider content-position="left">课程基本信息</el-divider>
|
||||
<el-descriptions :column="1" border>
|
||||
<el-descriptions-item label="课程名称">
|
||||
{{ data.info.CURRICULUMNAME }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="培训类型">
|
||||
{{ data.info.TYPENAME }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="课程描述">
|
||||
{{ data.info.CURRICULUMINTRODUCE }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="课程封面">
|
||||
<img
|
||||
v-viewer
|
||||
:src="VITE_FILE_URL + data.info.COVERPATH"
|
||||
alt=""
|
||||
width="100"
|
||||
height="100"
|
||||
/>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-divider content-position="left">课程目录</el-divider>
|
||||
<el-tree
|
||||
:data="data.chapterList"
|
||||
:props="{ children: 'nodes', label: 'COURSEWARENAME' }"
|
||||
class="directory_style"
|
||||
default-expand-all
|
||||
>
|
||||
<template #default="{ data: item }">
|
||||
<div class="directory_row">
|
||||
<el-icon
|
||||
v-if="item.COURSEWARENAME"
|
||||
class="el-icon-video-camera"
|
||||
size="18"
|
||||
>
|
||||
<video-camera />
|
||||
</el-icon>
|
||||
<span class="directory_name">
|
||||
{{ item.NAME || item.COURSEWARENAME }}
|
||||
</span>
|
||||
<span v-if="item.COURSEWARENAME" class="directory_type">
|
||||
课件时长:{{ secondConversion(item.VIDEOTIME) }}
|
||||
</span>
|
||||
<el-button
|
||||
v-if="item.COURSEWARENAME"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="fnPreview(item.VIDEOCOURSEWARE_ID, item.VIDEOFILES)"
|
||||
>
|
||||
预览
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-tree>
|
||||
<layout-video
|
||||
v-model:visible="data.videoDialog.visible"
|
||||
:src="data.videoDialog.src"
|
||||
/>
|
||||
</layout-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRoute } from "vue-router";
|
||||
import {
|
||||
getCourseManagementView,
|
||||
getPreviewingVideo,
|
||||
} from "@/request/training_resource_management.js";
|
||||
import { reactive } from "vue";
|
||||
import { secondConversion } from "@/assets/js/utils.js";
|
||||
import { VideoCamera } from "@element-plus/icons-vue";
|
||||
import LayoutVideo from "@/components/video/index.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const { CURRICULUM_ID } = route.query;
|
||||
const VITE_FILE_URL = import.meta.env.VITE_FILE_URL;
|
||||
const data = reactive({
|
||||
info: {},
|
||||
chapterList: [],
|
||||
videoDialog: {
|
||||
visible: false,
|
||||
src: "",
|
||||
},
|
||||
});
|
||||
const fnGetData = async () => {
|
||||
const resData = await getCourseManagementView({ CURRICULUM_ID });
|
||||
data.info = resData.pd;
|
||||
data.chapterList = resData.chapterList;
|
||||
};
|
||||
fnGetData();
|
||||
const fnPreview = async (VIDEOCOURSEWARE_ID, VIDEOFILES) => {
|
||||
const resData = await getPreviewingVideo({
|
||||
VIDEOCOURSEWARE_ID,
|
||||
VIDEOFILES,
|
||||
CURRICULUM_ID,
|
||||
});
|
||||
data.videoDialog.src = JSON.stringify(resData.urlList);
|
||||
data.videoDialog.visible = true;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.directory_style {
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.el-icon-video-camera {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.directory_row {
|
||||
.directory_name {
|
||||
width: 260px;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.directory_type {
|
||||
width: 200px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep {
|
||||
.el-tree-node__content {
|
||||
margin-bottom: 10px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,118 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form
|
||||
:model="searchForm"
|
||||
label-width="100px"
|
||||
@submit.prevent="fnResetPaginationTransfer"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="试卷名称" prop="KEYWORDS">
|
||||
<el-input v-model="searchForm.KEYWORDS" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="创建时间" prop="dates">
|
||||
<el-date-picker
|
||||
v-model="searchForm.dates"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="满分" prop="EXAMSCORE">
|
||||
<el-input v-model="searchForm.EXAMSCORE" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="合格分数" prop="PASSSCORE">
|
||||
<el-input v-model="searchForm.PASSSCORE" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item label-width="10px">
|
||||
<el-button type="primary" native-type="submit">搜索</el-button>
|
||||
<el-button native-type="reset" @click="fnResetPaginationTransfer">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<layout-card>
|
||||
<layout-table
|
||||
v-model:pagination="pagination"
|
||||
:data="list"
|
||||
@get-data="fnGetDataTransfer"
|
||||
>
|
||||
<el-table-column label="序号" width="60">
|
||||
<template #default="{ $index }">
|
||||
{{ serialNumber(pagination, $index) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="试卷名称"
|
||||
prop="EXAMNAME"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="上传时间" prop="CREATTIME" width="150" />
|
||||
<el-table-column label="满分" prop="EXAMSCORE" width="150" />
|
||||
<el-table-column label="合格分数" prop="PASSSCORE" width="150" />
|
||||
<el-table-column label="试卷状态" width="150">
|
||||
<template #default="{ row }">
|
||||
{{ row.ISSELL === "0" ? "下架" : "上架" }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_resource_management/exam_paper_management/view',
|
||||
query: { STAGEEXAMPAPERINPUT_ID: row.STAGEEXAMPAPERINPUT_ID },
|
||||
})
|
||||
"
|
||||
>
|
||||
查看
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</layout-table>
|
||||
</layout-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import { getExamPaperManagementList } from "@/request/training_resource_management.js";
|
||||
import { serialNumber } from "@/assets/js/utils.js";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const router = useRouter();
|
||||
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
|
||||
useListData(getExamPaperManagementList);
|
||||
const fnGetDataTransfer = () => {
|
||||
fnGetData({
|
||||
STARTTIME: searchForm.value.dates?.[0],
|
||||
ENDTIME: searchForm.value.dates?.[1],
|
||||
});
|
||||
};
|
||||
const fnResetPaginationTransfer = () => {
|
||||
fnResetPagination({
|
||||
STARTTIME: searchForm.value.dates?.[0],
|
||||
ENDTIME: searchForm.value.dates?.[1],
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,109 @@
|
|||
<template>
|
||||
<layout-card>
|
||||
<el-divider content-position="left">试卷基本信息</el-divider>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="试卷名称" :span="2">
|
||||
{{ info.EXAMNAME }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="合格分数">
|
||||
{{ info.PASSSCORE }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="总分数">
|
||||
{{ info.EXAMSCORE }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-divider content-position="left">试卷题目信息</el-divider>
|
||||
<div class="items mt-20 p-20">
|
||||
<div
|
||||
v-for="(item, index) in testPaper"
|
||||
:key="item.PAPER_QUESTION_ID"
|
||||
class="item ptb-20"
|
||||
>
|
||||
<div class="mt-10">
|
||||
{{ index + 1 }}.
|
||||
<span v-if="item.QUESTIONTYPE === '1'"> (单选题) </span>
|
||||
<span v-if="item.QUESTIONTYPE === '2'"> (多选题) </span>
|
||||
<span v-if="item.QUESTIONTYPE === '3'"> (判断题) </span>
|
||||
{{ item.QUESTIONDRY }}
|
||||
<span class="ml-10">(题目分值:{{ item.SCORE }})</span>
|
||||
</div>
|
||||
<div class="mt-10 ml-30">
|
||||
<el-radio-group
|
||||
v-if="item.QUESTIONTYPE === '1'"
|
||||
disabled
|
||||
:model-value="item.ANSWER"
|
||||
>
|
||||
<el-radio label="A">A.{{ item.OPTIONA }}</el-radio>
|
||||
<el-radio label="B">B.{{ item.OPTIONB }}</el-radio>
|
||||
<el-radio label="C">C.{{ item.OPTIONC }}</el-radio>
|
||||
<el-radio label="D">D.{{ item.OPTIOND }}</el-radio>
|
||||
</el-radio-group>
|
||||
<el-checkbox-group
|
||||
v-if="item.QUESTIONTYPE === '2'"
|
||||
disabled
|
||||
:model-value="item.ANSWER?.split('')"
|
||||
>
|
||||
<el-checkbox label="A">A.{{ item.OPTIONA }}</el-checkbox>
|
||||
<el-checkbox label="B">B.{{ item.OPTIONB }}</el-checkbox>
|
||||
<el-checkbox label="C">C.{{ item.OPTIONC }}</el-checkbox>
|
||||
<el-checkbox label="D">D.{{ item.OPTIOND }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
<el-radio-group
|
||||
v-if="item.QUESTIONTYPE === '3'"
|
||||
disabled
|
||||
:model-value="item.ANSWER"
|
||||
>
|
||||
<el-radio label="A">A.{{ item.OPTIONA }}</el-radio>
|
||||
<el-radio label="B">B.{{ item.OPTIONB }}</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="mt-10">答案:{{ item.ANSWER }}</div>
|
||||
<div class="mt-10">答案解析:{{ item.DESCR }}</div>
|
||||
<div class="mt-10">关联课件名称:{{ item.COURSEWARENAME }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</layout-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import {
|
||||
getExamPaperManagementTestQuestions,
|
||||
getExamPaperManagementView,
|
||||
} from "@/request/training_resource_management.js";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const { STAGEEXAMPAPERINPUT_ID } = route.query;
|
||||
const info = ref({});
|
||||
const testPaper = ref([]);
|
||||
const fnGetData = async () => {
|
||||
const { pd } = await getExamPaperManagementView({
|
||||
STAGEEXAMPAPERINPUT_ID,
|
||||
});
|
||||
info.value = pd;
|
||||
const { varList } = await getExamPaperManagementTestQuestions({
|
||||
STAGEEXAMPAPERINPUT_ID,
|
||||
});
|
||||
testPaper.value = varList;
|
||||
};
|
||||
fnGetData();
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.items {
|
||||
border: 1px solid var(--el-border-color);
|
||||
|
||||
.item {
|
||||
border-bottom: 1px dashed #ebeef5;
|
||||
|
||||
&:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<layout-card>
|
||||
<layout-table
|
||||
v-model:pagination="pagination"
|
||||
:data="list"
|
||||
@get-data="fnGetData"
|
||||
>
|
||||
<el-table-column label="题号" prop="QUESTIONNUMBER" width="100" />
|
||||
<el-table-column label="试题类型" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.QUESTIONTYPE === '1'" type="success">单选题</el-tag>
|
||||
<el-tag v-else-if="row.QUESTIONTYPE === '2'">多选题</el-tag>
|
||||
<el-tag v-else-if="row.QUESTIONTYPE === '3'" type="warning">
|
||||
判断题
|
||||
</el-tag>
|
||||
<el-tag v-else-if="row.QUESTIONTYPE === '4'" type="info">
|
||||
填空题
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="题干" prop="QUESTIONDRY" />
|
||||
<el-table-column label="答案" width="100">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.QUESTIONTYPE === '3'">
|
||||
<div v-if="row.ANSWER === 'A'">正确</div>
|
||||
<div v-if="row.ANSWER === 'B'">错误</div>
|
||||
</div>
|
||||
<div v-else>{{ row.ANSWER }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="答案解析" prop="DESCR" />
|
||||
</layout-table>
|
||||
</layout-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import { getVideoCoursewareExercisesList } from "@/request/training_resource_management.js";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const { COURSEWAREID, COURSEWARETYPE } = route.query;
|
||||
const { list, pagination, fnGetData } = useListData(
|
||||
getVideoCoursewareExercisesList,
|
||||
{
|
||||
otherParams: { COURSEWAREID, COURSEWARETYPE },
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,158 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form
|
||||
:model="searchForm"
|
||||
label-width="100px"
|
||||
@submit.prevent="fnResetPagination"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="课程名称" prop="KEYWORDS">
|
||||
<el-input v-model="searchForm.KEYWORDS" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="培训类型" prop="TRAINTYPE">
|
||||
<layout-learning-train-type
|
||||
v-model="searchForm.TRAINTYPE"
|
||||
type="trainingType"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="行业类型" prop="INDUSTRY_END_ID">
|
||||
<layout-learning-train-type
|
||||
v-model="searchForm.INDUSTRY_END_ID"
|
||||
type="industryType"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="岗位类型" prop="POSTTYPE">
|
||||
<layout-learning-train-type
|
||||
v-model="searchForm.POSTTYPE"
|
||||
type="postType"
|
||||
:search-value="searchForm.TRAINTYPE"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label-width="10px">
|
||||
<el-button type="primary" native-type="submit">搜索</el-button>
|
||||
<el-button native-type="reset" @click="fnResetPagination">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<layout-card>
|
||||
<layout-table
|
||||
v-model:pagination="pagination"
|
||||
:data="list"
|
||||
@get-data="fnGetData"
|
||||
>
|
||||
<el-table-column label="序号" width="60">
|
||||
<template #default="{ $index }">
|
||||
{{ serialNumber(pagination, $index) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="课件名称"
|
||||
prop="COURSEWARENAME"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="上传时间" prop="CREATTIME" width="150" />
|
||||
<el-table-column label="培训类型" prop="TRAININGTYPE_NAME" />
|
||||
<el-table-column label="行业类型" prop="INDUSTRY_END_NAME" />
|
||||
<el-table-column label="岗位类型" prop="POSTTYPE_NAME" />
|
||||
<el-table-column label="培训教师" prop="TEACHERNAME" />
|
||||
<el-table-column label="学时" prop="CLASSHOUR" width="100" />
|
||||
<el-table-column label="课件时长" width="100">
|
||||
<template #default="{ row }">
|
||||
{{ secondConversion(row.VIDEOTIME) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="相关词条" prop="RELATEDTERMNAME" />
|
||||
<el-table-column label="习题数" prop="QUESTIONCOUNT" width="100" />
|
||||
<el-table-column label="操作" width="180">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnPreview(row.VIDEOCOURSEWARE_ID, row.VIDEOFILES)"
|
||||
>
|
||||
预览
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_resource_management/video_courseware/view',
|
||||
query: { VIDEOCOURSEWARE_ID: row.VIDEOCOURSEWARE_ID },
|
||||
})
|
||||
"
|
||||
>
|
||||
详情
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_resource_management/video_courseware/exercises',
|
||||
query: {
|
||||
COURSEWAREID: row.VIDEOCOURSEWARE_ID,
|
||||
COURSEWARETYPE: 1,
|
||||
},
|
||||
})
|
||||
"
|
||||
>
|
||||
课件习题
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</layout-table>
|
||||
</layout-card>
|
||||
<layout-video
|
||||
v-model:visible="data.videoDialog.visible"
|
||||
:src="data.videoDialog.src"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import {
|
||||
getPreviewingVideo,
|
||||
getVideoCoursewareList,
|
||||
} from "@/request/training_resource_management.js";
|
||||
import LayoutLearningTrainType from "@/components/learning_train_type/index.vue";
|
||||
import LayoutVideo from "@/components/video/index.vue";
|
||||
import { secondConversion, serialNumber } from "@/assets/js/utils.js";
|
||||
import { useRouter } from "vue-router";
|
||||
import { reactive } from "vue";
|
||||
|
||||
const router = useRouter();
|
||||
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
|
||||
useListData(getVideoCoursewareList);
|
||||
const data = reactive({
|
||||
videoDialog: {
|
||||
visible: false,
|
||||
src: "",
|
||||
},
|
||||
});
|
||||
const fnPreview = async (VIDEOCOURSEWARE_ID, VIDEOFILES) => {
|
||||
const resData = await getPreviewingVideo({ VIDEOCOURSEWARE_ID, VIDEOFILES });
|
||||
data.videoDialog.src = JSON.stringify(resData.urlList);
|
||||
data.videoDialog.visible = true;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,76 @@
|
|||
<template>
|
||||
<layout-card>
|
||||
<el-divider content-position="left">课件基本信息</el-divider>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="课件名称">
|
||||
{{ data.info.COURSEWARENAME }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="培训类型">
|
||||
{{ data.info.TYPENAME }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="讲师名称">
|
||||
{{ data.info.SPEAKERNAME }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="课件文件">
|
||||
{{ data.info.COURSEWARENAME }}
|
||||
<el-button type="primary" size="small" class="ml-10" @click="fnPreview">
|
||||
预览
|
||||
</el-button>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="课件截图">
|
||||
<img
|
||||
v-viewer
|
||||
:src="data.info.VIDEOCAPTURE"
|
||||
alt=""
|
||||
width="100"
|
||||
height="100"
|
||||
/>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="课件描述">
|
||||
{{ data.info.COURSEWAREINTRODUCE }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="相关词条">
|
||||
{{ data.info.RELATEDTERMNAME }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<layout-video
|
||||
v-model:visible="data.videoDialog.visible"
|
||||
:src="data.videoDialog.src"
|
||||
/>
|
||||
</layout-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive } from "vue";
|
||||
import {
|
||||
getPreviewingVideo,
|
||||
getVideoCoursewareView,
|
||||
} from "@/request/training_resource_management.js";
|
||||
import { useRoute } from "vue-router";
|
||||
import LayoutVideo from "@/components/video/index.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const { VIDEOCOURSEWARE_ID } = route.query;
|
||||
const data = reactive({
|
||||
info: {},
|
||||
videoDialog: {
|
||||
visible: false,
|
||||
src: "",
|
||||
},
|
||||
});
|
||||
const fnGetData = async () => {
|
||||
const resData = await getVideoCoursewareView({ VIDEOCOURSEWARE_ID });
|
||||
data.info = resData.pd;
|
||||
};
|
||||
fnGetData();
|
||||
const fnPreview = async () => {
|
||||
const resData = await getPreviewingVideo({
|
||||
VIDEOCOURSEWARE_ID: data.info.VIDEOCOURSEWARE_ID,
|
||||
VIDEOFILES: data.info.VIDEOFILES,
|
||||
});
|
||||
data.videoDialog.src = JSON.stringify(resData.urlList);
|
||||
data.videoDialog.visible = true;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
Loading…
Reference in New Issue