diff --git a/src/assets/js/data_dictionary.js b/src/assets/js/data_dictionary.js index 542ceff..dc19f53 100644 --- a/src/assets/js/data_dictionary.js +++ b/src/assets/js/data_dictionary.js @@ -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); +}; diff --git a/src/components/inspection_type/index.vue b/src/components/inspection_type/index.vue deleted file mode 100644 index 0710553..0000000 --- a/src/components/inspection_type/index.vue +++ /dev/null @@ -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> diff --git a/src/components/learning_train_type/index.vue b/src/components/learning_train_type/index.vue index 74dc6b9..c05f606 100644 --- a/src/components/learning_train_type/index.vue +++ b/src/components/learning_train_type/index.vue @@ -1,14 +1,23 @@ <template> + <el-select v-if="type !== 'industryType'" v-model="modelValue"> + <el-option + v-for="item in data" + :key="item[keys[type]]" + :label="item.NAME" + :value="item[keys[type]]" + /> + </el-select> <el-tree-select + v-else-if="type === 'industryType'" ref="treeSelectRef" v-model="modelValue" :data="data" :props="{ - value: 'id', + value: 'INDUSTRYTYPE_ID', children: 'nodes', - label: 'name', + label: 'NAME', }" - node-key="id" + node-key="INDUSTRYTYPE_ID" :render-after-expand="false" accordion check-strictly @@ -18,13 +27,14 @@ </template> <script setup> -import { - layoutFnGetTrainingIndustryType, - layoutFnGetTrainingPlateType, - layoutFnGetTrainingPostType, -} from "@/assets/js/data_dictionary"; -import { ref } from "vue"; +import { ref, watchEffect } from "vue"; import { useVModel } from "@vueuse/core"; +import { + layoutFnGetIndustryType, + layoutFnGetPostType, + layoutFnGetTrainingLevel, + layoutFnGetTrainingType, +} from "@/assets/js/data_dictionary.js"; defineOptions({ name: "LayoutLearningTrainType", @@ -40,10 +50,16 @@ const props = defineProps({ required: true, default: "", validator: (value) => { - // industry: 培训行业类型 - // post: 岗位培训类型 - // plate: 培训板块类型 - const typeList = ["industry", "post", "plate"]; + // trainingType: 培训类型 + // industryType: 行业类型 + // postType: 岗位类型 + // trainingLevel: 培训级别 + const typeList = [ + "trainingType", + "industryType", + "postType", + "trainingLevel", + ]; if (typeList.includes(value)) { return true; } else { @@ -55,20 +71,1261 @@ const props = defineProps({ type: Boolean, default: false, }, + searchValue: { + type: String, + default: "", + }, }); +const keys = { + trainingType: "TRAININGTYPE_ID", + postType: "POSTTYPE_ID", + trainingLevel: "TRAINLEVEL_ID", +}; const emits = defineEmits(["update:modelValue"]); const modelValue = useVModel(props, "modelValue", emits); const treeSelectRef = ref(null); +const data = ref([]); const getCurrentNode = () => { + if (props.type !== "industryType") { + if (data.value.length === 0) return {}; + for (let i = 0; i < data.value.length; i++) { + if (data.value[i][keys[props.type]] === props.modelValue) { + return data.value[i]; + } + } + } return treeSelectRef.value.getCurrentNode(); }; +const getNode = (value = getCurrentNode()) => { + if (props.type !== "industryType") return ""; + return treeSelectRef.value.getNode(getCurrentNode(value)); +}; +const getIndustryTypeCurrentCheckAll = () => { + const name = []; + const id = []; + if (props.type !== "industryType") return { name, id }; + let currentNode = getNode(); + name.unshift(currentNode.data.NAME); + id.unshift(currentNode.data.INDUSTRYTYPE_ID); + for (let i = currentNode.level; i > 1; i--) { + name.unshift(currentNode.parent.data.NAME); + id.unshift(currentNode.parent.data.INDUSTRYTYPE_ID); + currentNode = currentNode.parent; + } + return { name, id }; +}; defineExpose({ getCurrentNode, + getNode, + getIndustryTypeCurrentCheckAll, +}); +const fnGetTrainingType = async () => { + data.value = [ + { + OPERATTIME: "2023-05-24 08:26:00", + TRAININGTYPE_ID: "c70bf859512241579a8a30fc5d1ae153", + ISDELETE: "0", + OPERATOR: "联安众超管", + CREATOR: "联安众超管", + SORT: 2, + NAME: "职业健康", + PARENT_ID: "0", + CREATTIME: "2023-05-24 08:26:00", + }, + { + OPERATTIME: "2023-04-08 13:28:01", + TRAININGTYPE_ID: "6128172b7a1144c98cc196044281f66c", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + SORT: 111, + NAME: "全员培训", + PARENT_ID: "0", + CREATTIME: "2023-04-08 13:28:01", + }, + ]; + const resData = await layoutFnGetTrainingType(); + data.value = resData.value; +}; +const fnGetIndustryType = async () => { + data.value = [ + { + OPERATTIME: "2023-05-24 13:42:22", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-05-24 13:42:38", + ISDELETE: "0", + OPERATOR: "联安众超管", + CREATOR: "联安众超管", + INDUSTRYTYPE_ID: "41da504607804bd1b966e157c2b4e9f0", + SORT: 1, + NAME: "公路旅客运输", + PARENT_ID: "26b046958f8a46e7a016425c1c4e2fc9", + CREATTIME: "2023-05-24 13:42:38", + }, + ], + OPERATOR: "", + CREATOR: "联安众超管", + INDUSTRYTYPE_ID: "26b046958f8a46e7a016425c1c4e2fc9", + SORT: 1, + NAME: "道路运输业", + PARENT_ID: "0", + CREATTIME: "2023-05-24 13:40:19", + }, + { + OPERATTIME: "2023-02-27 10:14:32", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-02-27 10:08:20", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-02-27 10:09:17", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "d38ed992d2f84f13890f73a65a52f6df", + SORT: 1, + NAME: "选矿厂", + PARENT_ID: "655e9bc29a1d4a1ea39bbe59487a182e", + CREATTIME: "2023-02-27 10:09:17", + }, + { + OPERATTIME: "2023-02-27 10:09:23", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "34c3a66d82bc43b7acc398e07f2edaee", + SORT: 2, + NAME: "地下矿山", + PARENT_ID: "655e9bc29a1d4a1ea39bbe59487a182e", + CREATTIME: "2023-02-27 10:09:23", + }, + { + OPERATTIME: "2023-04-04 14:52:03", + ISDELETE: "0", + OPERATOR: "", + CREATOR: "admin", + INDUSTRYTYPE_ID: "017aeaf1602b4eed8a53d6a110262016", + SORT: 3, + NAME: "露天矿山", + PARENT_ID: "655e9bc29a1d4a1ea39bbe59487a182e", + CREATTIME: "2023-02-27 10:09:28", + }, + ], + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "655e9bc29a1d4a1ea39bbe59487a182e", + SORT: 0, + NAME: "金属非金属矿山", + PARENT_ID: "1b250e1ec1e24576aaa84daa804e9ab2", + CREATTIME: "2023-02-27 10:08:20", + }, + { + OPERATTIME: "2023-02-27 10:08:27", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-02-27 10:09:39", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "462db2c330354524ad912aade071e109", + SORT: 1, + NAME: "生产经营单位", + PARENT_ID: "fa95c820e1b2491e8f9cb0d03558696b", + CREATTIME: "2023-02-27 10:09:39", + }, + ], + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "fa95c820e1b2491e8f9cb0d03558696b", + SORT: 1, + NAME: "危险化学品", + PARENT_ID: "1b250e1ec1e24576aaa84daa804e9ab2", + CREATTIME: "2023-02-27 10:08:27", + }, + { + OPERATTIME: "2023-02-27 10:08:33", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-02-27 10:13:14", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "30d22d43a79f4c929e434139dea85935", + SORT: 1, + NAME: "炼铁", + PARENT_ID: "4ecff39fff9a417ebf343f09ecc58e46", + CREATTIME: "2023-02-27 10:13:14", + }, + { + OPERATTIME: "2023-02-27 10:13:23", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "bbda6b7ddc224592be73d5f1cda29220", + SORT: 2, + NAME: "炼钢", + PARENT_ID: "4ecff39fff9a417ebf343f09ecc58e46", + CREATTIME: "2023-02-27 10:13:23", + }, + { + OPERATTIME: "2023-02-27 10:13:30", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "35c0879727774eb99d53ac523aae3225", + SORT: 3, + NAME: "黑色金属铸造", + PARENT_ID: "4ecff39fff9a417ebf343f09ecc58e46", + CREATTIME: "2023-02-27 10:13:30", + }, + ], + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "4ecff39fff9a417ebf343f09ecc58e46", + SORT: 2, + NAME: "金属冶炼", + PARENT_ID: "1b250e1ec1e24576aaa84daa804e9ab2", + CREATTIME: "2023-02-27 10:08:33", + }, + { + OPERATTIME: "2023-02-27 10:08:38", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-02-27 10:13:41", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "e4e457b98c724b5786e7173bb921f365", + SORT: 1, + NAME: "生产经营单位", + PARENT_ID: "6ec61b50449c48059a264046323423d0", + CREATTIME: "2023-02-27 10:13:41", + }, + ], + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "6ec61b50449c48059a264046323423d0", + SORT: 3, + NAME: "烟花爆竹", + PARENT_ID: "1b250e1ec1e24576aaa84daa804e9ab2", + CREATTIME: "2023-02-27 10:08:38", + }, + ], + OPERATOR: "", + CREATOR: "admin", + INDUSTRYTYPE_ID: "1b250e1ec1e24576aaa84daa804e9ab2", + SORT: 1, + NAME: "高危行业", + PARENT_ID: "0", + CREATTIME: "2023-02-27 09:54:38", + }, + { + OPERATTIME: "2023-02-27 10:14:35", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-02-27 10:13:53", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-02-27 10:16:33", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "b935b913b0e749c0a509968011cc6c45", + SORT: 1, + NAME: "炼铁", + PARENT_ID: "5f464ef0c4f741759a713fef2bb732ac", + CREATTIME: "2023-02-27 10:16:33", + }, + { + OPERATTIME: "2023-02-27 10:16:39", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "1aeb4cfedee5403da5f996d04772fc12", + SORT: 2, + NAME: "炼钢", + PARENT_ID: "5f464ef0c4f741759a713fef2bb732ac", + CREATTIME: "2023-02-27 10:16:39", + }, + { + OPERATTIME: "2023-02-27 10:16:46", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "c486471667d44257843595346abd250b", + SORT: 3, + NAME: "钢压延加工", + PARENT_ID: "5f464ef0c4f741759a713fef2bb732ac", + CREATTIME: "2023-02-27 10:16:46", + }, + ], + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "5f464ef0c4f741759a713fef2bb732ac", + SORT: 1, + NAME: "冶金行业", + PARENT_ID: "f39f6967559f42448eb619da8eb0fce4", + CREATTIME: "2023-02-27 10:13:53", + }, + { + OPERATTIME: "2023-02-27 10:14:26", + ISDELETE: "0", + OPERATOR: "", + CREATOR: "admin", + INDUSTRYTYPE_ID: "6e9b1e9172214d648981a74d3649c3a1", + SORT: 2, + NAME: "有色行业", + PARENT_ID: "f39f6967559f42448eb619da8eb0fce4", + CREATTIME: "2023-02-27 10:14:03", + }, + { + OPERATTIME: "2023-02-27 10:14:20", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-02-27 10:16:57", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "1e57be917b8c4d448ae6529499ae96c7", + SORT: 1, + NAME: "水泥制造", + PARENT_ID: "9b620e5b89514abb85f306fcf337c3a3", + CREATTIME: "2023-02-27 10:16:57", + }, + { + OPERATTIME: "2023-02-27 10:17:04", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "fcef5e12dd9b4fd4953682ab84671aeb", + SORT: 2, + NAME: "石灰和石膏制造", + PARENT_ID: "9b620e5b89514abb85f306fcf337c3a3", + CREATTIME: "2023-02-27 10:17:04", + }, + { + OPERATTIME: "2023-02-27 10:17:09", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "001a60ece1294f2d967ea5a461461e70", + SORT: 3, + NAME: "平板玻璃制造", + PARENT_ID: "9b620e5b89514abb85f306fcf337c3a3", + CREATTIME: "2023-02-27 10:17:09", + }, + { + OPERATTIME: "2023-02-27 10:17:15", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "61de0885dc244d98bddf99afc4425267", + SORT: 4, + NAME: "特种玻璃制造", + PARENT_ID: "9b620e5b89514abb85f306fcf337c3a3", + CREATTIME: "2023-02-27 10:17:15", + }, + { + OPERATTIME: "2023-02-27 10:17:22", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "bd0aca3819fd4da7bbf7be90335f6020", + SORT: 5, + NAME: "玻璃纤维及制品制造", + PARENT_ID: "9b620e5b89514abb85f306fcf337c3a3", + CREATTIME: "2023-02-27 10:17:22", + }, + { + OPERATTIME: "2023-02-27 10:17:28", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "b83ab8eef2534ebfa85a488c11bea300", + SORT: 6, + NAME: "玻璃纤维增强塑料制品制造", + PARENT_ID: "9b620e5b89514abb85f306fcf337c3a3", + CREATTIME: "2023-02-27 10:17:28", + }, + { + OPERATTIME: "2023-02-27 10:17:35", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "a2aa5cd30b1249aba6f9e0a569afb774", + SORT: 7, + NAME: "建筑陶瓷制品制造", + PARENT_ID: "9b620e5b89514abb85f306fcf337c3a3", + CREATTIME: "2023-02-27 10:17:35", + }, + { + OPERATTIME: "2023-02-27 10:17:41", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "229c19358708403397b905330b9a8224", + SORT: 8, + NAME: "卫生陶瓷制品制造", + PARENT_ID: "9b620e5b89514abb85f306fcf337c3a3", + CREATTIME: "2023-02-27 10:17:41", + }, + { + OPERATTIME: "2023-05-24 11:51:41", + ISDELETE: "0", + OPERATOR: "联安众超管", + CREATOR: "联安众超管", + INDUSTRYTYPE_ID: "4563908d4bc54895a0dbbb397d247537", + SORT: 9, + NAME: "粘土砖瓦及建筑砌块制造", + PARENT_ID: "9b620e5b89514abb85f306fcf337c3a3", + CREATTIME: "2023-05-24 11:51:41", + }, + { + OPERATTIME: "2023-05-24 14:18:08", + ISDELETE: "0", + OPERATOR: "联安众超管", + CREATOR: "联安众超管", + INDUSTRYTYPE_ID: "67e09e268ef142768df4e334ff8a629d", + SORT: 10, + NAME: "其他建筑材料制造", + PARENT_ID: "9b620e5b89514abb85f306fcf337c3a3", + CREATTIME: "2023-05-24 14:18:08", + }, + { + OPERATTIME: "2023-05-24 14:22:15", + ISDELETE: "0", + OPERATOR: "联安众超管", + CREATOR: "联安众超管", + INDUSTRYTYPE_ID: "7af5a6dccffc444faba1d70ffc763bfb", + SORT: 11, + NAME: "其他陶瓷制品制造", + PARENT_ID: "9b620e5b89514abb85f306fcf337c3a3", + CREATTIME: "2023-05-24 14:22:15", + }, + ], + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "9b620e5b89514abb85f306fcf337c3a3", + SORT: 3, + NAME: "建材行业", + PARENT_ID: "f39f6967559f42448eb619da8eb0fce4", + CREATTIME: "2023-02-27 10:14:20", + }, + { + OPERATTIME: "2023-02-27 10:15:45", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-02-27 10:17:51", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "19909ff1724d4f9d8a50b1310f670954", + SORT: 1, + NAME: "金属结构制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:17:51", + }, + { + OPERATTIME: "2023-02-27 10:17:56", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "b59ee1617abd4d3fbdc797bf0f87de7b", + SORT: 2, + NAME: "金属门窗制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:17:56", + }, + { + OPERATTIME: "2023-02-27 10:18:05", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "3f5b738f21d442ebbd00e4e5f872d6da", + SORT: 3, + NAME: "金属包装容器及材料制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:18:05", + }, + { + OPERATTIME: "2023-02-27 10:18:11", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "d52ca8f2d82543a8841ff47c3bd0c124", + SORT: 4, + NAME: "金属丝绳及其制品制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:18:11", + }, + { + OPERATTIME: "2023-02-27 10:18:18", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "8d90b34941504a109bf127a19894cf47", + SORT: 5, + NAME: "金属表面处理及热处理加工", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:18:18", + }, + { + OPERATTIME: "2023-02-27 10:18:24", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "435c52ced633412caa07ffda98855587", + SORT: 6, + NAME: "电工机械专用设备制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:18:24", + }, + { + OPERATTIME: "2023-02-27 10:18:29", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "6fb88ffd31ac4a4dbd15593c07f28403", + SORT: 7, + NAME: "半导体器件专用设备制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:18:29", + }, + { + OPERATTIME: "2023-02-27 10:18:35", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "a8099ba67c304b84a3c6d6a196fdd0c9", + SORT: 8, + NAME: "电子元器件与机电组件设备制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:18:35", + }, + { + OPERATTIME: "2023-02-27 10:18:40", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "52d7c2b30a7c432dbeb73002a2521a57", + SORT: 9, + NAME: "汽车车身、挂车制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:18:40", + }, + { + OPERATTIME: "2023-02-27 10:18:49", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "52f2786f738c4cbb813481ee74d4d263", + SORT: 10, + NAME: "汽车零部件及配件制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:18:49", + }, + { + OPERATTIME: "2023-02-27 10:18:56", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "4515268e11d44dc184c70427daf60f00", + SORT: 11, + NAME: "变压器、整流器和电感器制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:18:56", + }, + { + OPERATTIME: "2023-02-27 10:19:01", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "d4c627411c5244e790dbaeb038e143d7", + SORT: 12, + NAME: "电容器及其配套设备制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:19:01", + }, + { + OPERATTIME: "2023-02-27 10:19:13", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "30eb3d1f582841bca3d5ceda3864d60e", + SORT: 13, + NAME: "光伏设备及元器件制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:19:13", + }, + { + OPERATTIME: "2023-02-27 10:19:21", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "cc1481db4b7d411ab71fad23f0774b10", + SORT: 14, + NAME: "电线、电缆制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:19:21", + }, + { + OPERATTIME: "2023-02-27 10:19:28", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "c5ed9abf21024bc1b42a8d2edaad54e8", + SORT: 15, + NAME: "电子专用材料制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:19:28", + }, + { + OPERATTIME: "2023-02-27 10:19:35", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "2723dac483e946efaf79e222148ca254", + SORT: 16, + NAME: "电工仪器仪表制造", + PARENT_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + CREATTIME: "2023-02-27 10:19:35", + }, + ], + OPERATOR: "", + CREATOR: "admin", + INDUSTRYTYPE_ID: "e042d66d3c4a4952bbd716adfd5b57f0", + SORT: 4, + NAME: "机械行业", + PARENT_ID: "f39f6967559f42448eb619da8eb0fce4", + CREATTIME: "2023-02-27 10:15:34", + }, + { + OPERATTIME: "2023-02-27 10:16:00", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-02-27 10:19:45", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "9e5a99038a894d1dae1ec014aa4b1456", + SORT: 1, + NAME: "水产品冷冻加工", + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-02-27 10:19:45", + }, + { + OPERATTIME: "2023-02-27 10:19:51", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "5c9c06268c47400a95cd12e9b5a258e5", + SORT: 2, + NAME: "淀粉及淀粉制品制造", + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-02-27 10:19:51", + }, + { + OPERATTIME: "2023-02-27 10:19:56", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "a05f300720344c078cf60be21e351bac", + SORT: 3, + NAME: "速冻食品制造", + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-02-27 10:19:56", + }, + { + OPERATTIME: "2023-02-27 10:20:02", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "af2c521d98fb43ce8bdeb6e33f6f17c0", + SORT: 4, + NAME: "白酒制造", + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-02-27 10:20:02", + }, + { + OPERATTIME: "2023-02-27 10:20:09", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "824878a5c0ea41d4b5b208da2d4a494d", + SORT: 5, + NAME: "啤酒制造", + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-02-27 10:20:09", + }, + { + OPERATTIME: "2023-02-27 10:20:16", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "be49153fc87c44a98246d43ff0f734fd", + SORT: 6, + NAME: "葡萄酒制造", + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-02-27 10:20:16", + }, + { + OPERATTIME: "2023-02-27 10:20:22", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "6a34916f17e3467995a21c34a4555378", + SORT: 7, + NAME: "果菜汁及果菜汁饮料制造", + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-02-27 10:20:22", + }, + { + OPERATTIME: "2023-02-27 10:20:29", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "5209604046014d00afdd8472df2d77b5", + SORT: 8, + NAME: "木片加工", + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-02-27 10:20:29", + }, + { + OPERATTIME: "2023-02-27 10:20:35", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "fb569e85fefd42caa91c514b7c299afa", + SORT: 9, + NAME: "包装装潢及其他印刷", + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-02-27 10:20:35", + }, + { + OPERATTIME: "2023-02-27 10:20:42", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "212cce1973e54b66ab737ea144602815", + SORT: 10, + NAME: "橡胶板、管、带制造", + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-02-27 10:20:42", + }, + { + OPERATTIME: "2023-02-27 10:20:51", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "2aac1e584fa140a9a3c0a021c0887b83", + SORT: 11, + NAME: "光学玻璃制造", + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-02-27 10:20:51", + }, + { + OPERATTIME: "2023-05-24 11:48:32", + ISDELETE: "0", + OPERATOR: "联安众超管", + CREATOR: "联安众超管", + INDUSTRYTYPE_ID: "455f097da53544f1a5e78a6d33cf3a3f", + SORT: 11, + NAME: "植物油加工", + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-05-24 11:48:32", + }, + { + OPERATTIME: "2023-05-24 14:56:11", + ISDELETE: "0", + OPERATOR: "联安众超管", + INDUSTRYTYPE_ID: "3df1e485646948fd95805a8ce0997384", + SORT: 11, + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-05-24 14:56:11", + }, + { + OPERATTIME: "2023-02-27 10:20:57", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "9082363f85844844b4483c87f8ef7341", + SORT: 12, + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-02-27 10:20:57", + }, + { + OPERATTIME: "2023-05-24 11:49:16", + ISDELETE: "0", + INDUSTRYTYPE_ID: "60b14e3fc45d409caa55bd3b852ffe7e", + SORT: 12, + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-05-24 11:49:16", + }, + { + OPERATTIME: "2023-02-27 10:21:04", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "bee15c59606b447a81f59c9469f13103", + SORT: 13, + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-02-27 10:21:04", + }, + { + OPERATTIME: "2023-05-24 14:27:18", + ISDELETE: "0", + INDUSTRYTYPE_ID: "fdabec905a704b09a0eb683ca72c9f02", + SORT: 14, + PARENT_ID: "c23e931ddcca467e91ee276ea2b3ae34", + CREATTIME: "2023-05-24 14:27:18", + }, + ], + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "c23e931ddcca467e91ee276ea2b3ae34", + SORT: 5, + PARENT_ID: "f39f6967559f42448eb619da8eb0fce4", + CREATTIME: "2023-02-27 10:16:00", + }, + { + OPERATTIME: "2023-02-27 10:16:09", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-02-27 10:21:18", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "23d086ff44b549168f8cf15889db005c", + SORT: 1, + NAME: "棉纺纱加工", + PARENT_ID: "568e833dee3640a1bb3b141f39af1d0f", + CREATTIME: "2023-02-27 10:21:18", + }, + { + OPERATTIME: "2023-02-27 10:21:23", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "1842606b879f4654bd2f7d528ed62e5a", + SORT: 2, + NAME: "棉织造加工", + PARENT_ID: "568e833dee3640a1bb3b141f39af1d0f", + CREATTIME: "2023-02-27 10:21:23", + }, + { + OPERATTIME: "2023-02-27 10:21:30", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "bf1a53b278924a7fa29866660d4c4f60", + SORT: 3, + NAME: "棉印染精加工", + PARENT_ID: "568e833dee3640a1bb3b141f39af1d0f", + CREATTIME: "2023-02-27 10:21:30", + }, + { + OPERATTIME: "2023-02-27 10:21:36", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "8c9bc93bfef148a7bf356fb5b352fa87", + SORT: 4, + NAME: "化纤织造加工", + PARENT_ID: "568e833dee3640a1bb3b141f39af1d0f", + CREATTIME: "2023-02-27 10:21:36", + }, + { + OPERATTIME: "2023-02-27 10:21:42", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "f729f10497814c54b9a01cab4c575556", + SORT: 5, + NAME: "化纤织物染整精加工", + PARENT_ID: "568e833dee3640a1bb3b141f39af1d0f", + CREATTIME: "2023-02-27 10:21:42", + }, + { + OPERATTIME: "2023-02-27 10:21:47", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "44f42467181842499260a052a73ffcbe", + SORT: 6, + NAME: "非织造布制造", + PARENT_ID: "568e833dee3640a1bb3b141f39af1d0f", + CREATTIME: "2023-02-27 10:21:47", + }, + { + OPERATTIME: "2023-02-27 10:21:53", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "99fcc9294a634856851afeee30d1f171", + SORT: 7, + NAME: "运动机织服装制造", + PARENT_ID: "568e833dee3640a1bb3b141f39af1d0f", + CREATTIME: "2023-02-27 10:21:53", + }, + { + OPERATTIME: "2023-02-27 10:22:00", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "76ffa02414c1499bbcb6eaa505d242c3", + SORT: 8, + NAME: "运动休闲针织服装制造", + PARENT_ID: "568e833dee3640a1bb3b141f39af1d0f", + CREATTIME: "2023-02-27 10:22:00", + }, + ], + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "568e833dee3640a1bb3b141f39af1d0f", + SORT: 6, + NAME: "纺织行业", + PARENT_ID: "f39f6967559f42448eb619da8eb0fce4", + CREATTIME: "2023-02-27 10:16:09", + }, + { + OPERATTIME: "2023-02-27 10:16:17", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "e9f98e1322f24da4b15a6b6ff3550c55", + SORT: 7, + NAME: "烟草行业", + PARENT_ID: "f39f6967559f42448eb619da8eb0fce4", + CREATTIME: "2023-02-27 10:16:17", + }, + { + OPERATTIME: "2023-02-27 10:16:24", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-02-27 10:22:11", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "aab96f05c88046d69733280389cc58d9", + SORT: 1, + NAME: "服装批发", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:22:11", + }, + { + OPERATTIME: "2023-02-27 10:22:16", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "e49e397df49840b59158e8d4d5abb6eb", + SORT: 2, + NAME: "百货零售", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:22:16", + }, + { + OPERATTIME: "2023-02-27 10:22:20", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "933a77ffa9a74e0dbb6bcf57384ad40f", + SORT: 3, + NAME: "超级市场零售", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:22:20", + }, + { + OPERATTIME: "2023-02-27 10:22:26", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "19585964fe8b46af8f145790966db65c", + SORT: 4, + NAME: "便利店零售", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:22:26", + }, + { + OPERATTIME: "2023-02-27 10:22:31", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "8f824a4d57e7402d955dc4f112505e24", + SORT: 5, + NAME: "汽车新车零售", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:22:31", + }, + { + OPERATTIME: "2023-02-27 10:22:37", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "7a02c2bd1dd045e9ad0d662cdaba57db", + SORT: 6, + NAME: "汽车旧车零售", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:22:37", + }, + { + OPERATTIME: "2023-02-27 10:22:43", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "2efafba8fbeb4376ac32d5c195e81efa", + SORT: 7, + NAME: "汽车零配件零售", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:22:43", + }, + { + OPERATTIME: "2023-02-27 10:22:49", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "90874226c22e4a59b00a3af05562e645", + SORT: 8, + NAME: "摩托车及零配件零售", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:22:49", + }, + { + OPERATTIME: "2023-02-27 10:22:55", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "4acb8986ca1d4f1ab045548f18d8cbe7", + SORT: 9, + NAME: "日用家电零售", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:22:55", + }, + { + OPERATTIME: "2023-02-27 10:23:02", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "0bbf430e0bb24627bc93f135d2166e36", + SORT: 10, + NAME: "五金零售", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:23:02", + }, + { + OPERATTIME: "2023-02-27 10:23:08", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "a4fdd353d8564e038ec7fecd23699776", + SORT: 11, + NAME: "灯具零售", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:23:08", + }, + { + OPERATTIME: "2023-02-27 10:23:15", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "c008d95c73224907b91fb0a146a80522", + SORT: 12, + NAME: "家具零售", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:23:15", + }, + { + OPERATTIME: "2023-02-27 10:23:22", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "0a061308f2ae49c297221c667ad12881", + SORT: 13, + NAME: "涂料零售", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:23:22", + }, + { + OPERATTIME: "2023-02-27 10:23:30", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "3fe1317bf3b24334b2e6716d8babda92", + SORT: 14, + NAME: "旅游饭店", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:23:30", + }, + { + OPERATTIME: "2023-02-27 10:23:36", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "4b2e94dbbb0c42768c997c057be2bb89", + SORT: 15, + NAME: "经济型连锁酒店", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:23:36", + }, + { + OPERATTIME: "2023-02-27 10:23:41", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "a3d83a53bc484a7fa84a61a6885aa667", + SORT: 16, + NAME: "民宿服务", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:23:41", + }, + { + OPERATTIME: "2023-02-27 10:23:47", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "6079ee40b1e14b3fb336fbf6490a598b", + SORT: 17, + NAME: "正餐服务", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:23:47", + }, + { + OPERATTIME: "2023-02-27 10:23:54", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "a7cf17c7ca8b42e68d8822566b06fc39", + SORT: 18, + NAME: "快餐服务", + PARENT_ID: "84b7ed71d06d400b9e99df728928d6ce", + CREATTIME: "2023-02-27 10:23:54", + }, + ], + OPERATOR: "admin", + CREATOR: "admin", + INDUSTRYTYPE_ID: "84b7ed71d06d400b9e99df728928d6ce", + SORT: 8, + NAME: "商贸行业", + PARENT_ID: "f39f6967559f42448eb619da8eb0fce4", + CREATTIME: "2023-02-27 10:16:24", + }, + ], + OPERATOR: "", + CREATOR: "admin", + INDUSTRYTYPE_ID: "f39f6967559f42448eb619da8eb0fce4", + SORT: 2, + NAME: "一般行业", + PARENT_ID: "0", + CREATTIME: "2023-02-27 09:54:52", + }, + { + OPERATTIME: "2023-05-24 11:40:03", + ISDELETE: "0", + nodes: [ + { + OPERATTIME: "2023-05-24 11:40:14", + ISDELETE: "0", + OPERATOR: "联安众超管", + CREATOR: "联安众超管", + INDUSTRYTYPE_ID: "e74ad1f963f8423291a64cf9070558a3", + SORT: 1, + NAME: "井工煤矿", + PARENT_ID: "eb392a55110f4d9899d8554b84537aa0", + CREATTIME: "2023-05-24 11:40:14", + }, + { + OPERATTIME: "2023-05-24 11:40:26", + ISDELETE: "0", + OPERATOR: "联安众超管", + CREATOR: "联安众超管", + INDUSTRYTYPE_ID: "6a19f1511de34b9fae955f0d61668e91", + SORT: 2, + NAME: "露天煤矿", + PARENT_ID: "eb392a55110f4d9899d8554b84537aa0", + CREATTIME: "2023-05-24 11:40:26", + }, + ], + OPERATOR: "联安众超管", + CREATOR: "联安众超管", + INDUSTRYTYPE_ID: "eb392a55110f4d9899d8554b84537aa0", + SORT: 3, + NAME: "煤矿", + PARENT_ID: "0", + CREATTIME: "2023-05-24 11:40:03", + }, + ]; + const resData = await layoutFnGetIndustryType(); + data.value = resData.value; +}; +const fnGetPostType = async () => { + data.value = [ + { + OPERATTIME: "2023-07-20 18:12:26", + TRAININGTYPE_ID: "c70bf859512241579a8a30fc5d1ae153", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "联安众超管", + POSTTYPE_ID: "61a74c83ece848f59d8b154e9370201d", + SORT: 12, + NAME: "职业健康主要负责人", + PARENT_ID: "0", + CREATTIME: "2023-05-24 08:28:18", + }, + { + OPERATTIME: "2023-07-20 18:12:40", + TRAININGTYPE_ID: "c70bf859512241579a8a30fc5d1ae153", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "联安众超管", + POSTTYPE_ID: "79042228778146d9bb7f0547b48a7b14", + SORT: 13, + NAME: "职业健康管理人员", + PARENT_ID: "0", + CREATTIME: "2023-05-24 08:28:49", + }, + { + OPERATTIME: "2023-07-20 18:12:43", + TRAININGTYPE_ID: "c70bf859512241579a8a30fc5d1ae153", + ISDELETE: "0", + OPERATOR: "admin", + CREATOR: "联安众超管", + POSTTYPE_ID: "2b49f40b0c1545019d78cde8a5a218a4", + SORT: 14, + NAME: "劳动者", + PARENT_ID: "0", + CREATTIME: "2023-05-24 08:29:00", + }, + ]; + const resData = await layoutFnGetPostType({ + TRAININGTYPE_ID: props.searchValue, + }); + data.value = resData.value; +}; +const fnGetTrainingLevel = async () => { + const resData = await layoutFnGetTrainingLevel({ + POSTTYPE_ID: props.searchValue, + }); + data.value = resData.value; +}; +if (props.type === "trainingType") fnGetTrainingType(); +if (props.type === "industryType") fnGetIndustryType(); +watchEffect(() => { + if (props.type === "postType" && props.searchValue) fnGetPostType(); + if (props.type === "trainingLevel" && props.searchValue) fnGetTrainingLevel(); }); -let data = []; -if (props.type === "industry") data = await layoutFnGetTrainingIndustryType(); -if (props.type === "post") data = await layoutFnGetTrainingPostType(); -if (props.type === "plate") data = await layoutFnGetTrainingPlateType(); </script> <style scoped></style> diff --git a/src/components/map_tools/alarm_view.vue b/src/components/map_tools/alarm_view.vue deleted file mode 100644 index 1e0eb4e..0000000 --- a/src/components/map_tools/alarm_view.vue +++ /dev/null @@ -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> diff --git a/src/components/map_tools/index.vue b/src/components/map_tools/index.vue deleted file mode 100644 index aa027d0..0000000 --- a/src/components/map_tools/index.vue +++ /dev/null @@ -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> diff --git a/src/components/map_tools/loadglb.js b/src/components/map_tools/loadglb.js deleted file mode 100644 index dd19449..0000000 --- a/src/components/map_tools/loadglb.js +++ /dev/null @@ -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; - } -} diff --git a/src/components/map_tools/map.js b/src/components/map_tools/map.js deleted file mode 100644 index aedec0f..0000000 --- a/src/components/map_tools/map.js +++ /dev/null @@ -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); - }; - }); -}; diff --git a/src/components/table/index.vue b/src/components/table/index.vue index 07a4ad3..0a40b25 100644 --- a/src/components/table/index.vue +++ b/src/components/table/index.vue @@ -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, }, diff --git a/src/components/training_section_cascader/index.vue b/src/components/training_section_cascader/index.vue deleted file mode 100644 index 5dbfdf4..0000000 --- a/src/components/training_section_cascader/index.vue +++ /dev/null @@ -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> diff --git a/src/request/axios.js b/src/request/axios.js index 2fc5409..80f06e9 100644 --- a/src/request/axios.js +++ b/src/request/axios.js @@ -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 = "连接到服务器失败"; diff --git a/src/request/data_dictionary.js b/src/request/data_dictionary.js index 9bafe7c..d3ee094 100644 --- a/src/request/data_dictionary.js +++ b/src/request/data_dictionary.js @@ -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, + }); diff --git a/src/request/training_process_management.js b/src/request/training_process_management.js new file mode 100644 index 0000000..ad0934b --- /dev/null +++ b/src/request/training_process_management.js @@ -0,0 +1,4 @@ +import { post } from "@/request/axios.js"; + +export const setExamPaperManagementDelete = (params) => + post("/stageexampaperinput/delete", params); // 试卷管理删除 diff --git a/src/request/training_resource_management.js b/src/request/training_resource_management.js new file mode 100644 index 0000000..40fd990 --- /dev/null +++ b/src/request/training_resource_management.js @@ -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); // 试卷管理试题 diff --git a/src/views/training_process_management/exam_paper_management/add.vue b/src/views/training_process_management/exam_paper_management/add.vue new file mode 100644 index 0000000..f157976 --- /dev/null +++ b/src/views/training_process_management/exam_paper_management/add.vue @@ -0,0 +1,7 @@ +<template> + <layout-card>11</layout-card> +</template> + +<script setup></script> + +<style scoped lang="scss"></style> diff --git a/src/views/training_process_management/exam_paper_management/index.vue b/src/views/training_process_management/exam_paper_management/index.vue new file mode 100644 index 0000000..722d561 --- /dev/null +++ b/src/views/training_process_management/exam_paper_management/index.vue @@ -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> diff --git a/src/views/training_process_management/exam_paper_management/view.vue b/src/views/training_process_management/exam_paper_management/view.vue new file mode 100644 index 0000000..363f851 --- /dev/null +++ b/src/views/training_process_management/exam_paper_management/view.vue @@ -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> diff --git a/src/views/training_resource_management/course_management/add.vue b/src/views/training_resource_management/course_management/add.vue new file mode 100644 index 0000000..142a84e --- /dev/null +++ b/src/views/training_resource_management/course_management/add.vue @@ -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> diff --git a/src/views/training_resource_management/course_management/components/add_courseware.vue b/src/views/training_resource_management/course_management/components/add_courseware.vue new file mode 100644 index 0000000..06f1b46 --- /dev/null +++ b/src/views/training_resource_management/course_management/components/add_courseware.vue @@ -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> diff --git a/src/views/training_resource_management/course_management/index.vue b/src/views/training_resource_management/course_management/index.vue new file mode 100644 index 0000000..6499034 --- /dev/null +++ b/src/views/training_resource_management/course_management/index.vue @@ -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> diff --git a/src/views/training_resource_management/course_management/view.vue b/src/views/training_resource_management/course_management/view.vue new file mode 100644 index 0000000..52abe4b --- /dev/null +++ b/src/views/training_resource_management/course_management/view.vue @@ -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> diff --git a/src/views/training_resource_management/exam_paper_management/index.vue b/src/views/training_resource_management/exam_paper_management/index.vue new file mode 100644 index 0000000..39be22e --- /dev/null +++ b/src/views/training_resource_management/exam_paper_management/index.vue @@ -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> diff --git a/src/views/training_resource_management/exam_paper_management/view.vue b/src/views/training_resource_management/exam_paper_management/view.vue new file mode 100644 index 0000000..fe912f3 --- /dev/null +++ b/src/views/training_resource_management/exam_paper_management/view.vue @@ -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> diff --git a/src/views/training_resource_management/video_courseware/exercises.vue b/src/views/training_resource_management/video_courseware/exercises.vue new file mode 100644 index 0000000..467a6b8 --- /dev/null +++ b/src/views/training_resource_management/video_courseware/exercises.vue @@ -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> diff --git a/src/views/training_resource_management/video_courseware/index.vue b/src/views/training_resource_management/video_courseware/index.vue new file mode 100644 index 0000000..5323308 --- /dev/null +++ b/src/views/training_resource_management/video_courseware/index.vue @@ -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> diff --git a/src/views/training_resource_management/video_courseware/view.vue b/src/views/training_resource_management/video_courseware/view.vue new file mode 100644 index 0000000..89fbde5 --- /dev/null +++ b/src/views/training_resource_management/video_courseware/view.vue @@ -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>