Merge remote-tracking branch 'origin/dev' into dev

pull/1/head
dearlin 2024-01-25 14:22:20 +08:00
commit f7859bdb34
206 changed files with 12109 additions and 5698 deletions

2
.env
View File

@ -2,4 +2,6 @@ VITE_BASE_URL=http://192.168.0.17:8001/
VITE_PROXY=/api/
VITE_FILE_URL=https://file.zcloudchina.com/YTHFile
VITE_TEMPLATE_URL=https://qaaq.qhdsafety.com/file/
VITE_ON_LINE_WEB_SOCKET_URL=wss://qaaq.qhdsafety.com/zxwebsocket/
VITE_LEARNING_WEB_SOCKET_URL=wss://qaaq.qhdsafety.com/websocket/

550
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -15,8 +15,10 @@
"@vueuse/core": "^9.13.0",
"@vueuse/integrations": "^10.7.1",
"animate.css": "^4.1.1",
"autofit.js": "^3.0.7",
"axios": "^1.6.3",
"dayjs": "^1.11.10",
"echarts": "^5.4.3",
"element-plus": "^2.4.4",
"html2canvas": "^1.4.1",
"jspdf": "^2.5.1",
@ -32,7 +34,9 @@
"throttle-debounce": "^5.0.0",
"v-viewer": "^3.0.11",
"vue": "^3.4.3",
"vue-countup-v3": "^1.4.1",
"vue-draggable-plus": "^0.3.4",
"vue-esign": "^1.1.4",
"vue-router": "^4.2.5",
"vue3-pdfjs": "^0.1.6",
"vue3-print-nb": "^0.1.4",

View File

@ -89,9 +89,8 @@
.el-menu-item {
&:hover, &.is-active {
background-image: url("/src/assets/images/public/list_on.png");
background-repeat: no-repeat;
background-size: 100% 100%;
//background: #1d3f77;
background-image: linear-gradient(to right, #1e499a, rgba(0,0,0,0));
}
}
@ -153,6 +152,14 @@
--el-pagination-bg-color: var(--el-fill-color-blank) !important;
}
.el-pagination .el-select {
width: 128px !important;
}
.el-pagination--small .el-select {
width: 100px !important;
}
.el-radio {
--el-radio-input-bg-color: #091839 !important;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View File

@ -1007,7 +1007,7 @@ export default [
component: "children",
children: [
{
path: "/online_learn_exam/task",
path: "",
component: "online_learn_exam/task/index",
},
{
@ -1080,64 +1080,123 @@ export default [
},
],
},
{
path: "/online_learn_exam/my_task",
meta: { title: "我的任务", isSubMenu: false },
component: "children",
children: [
{
path: "",
component: "online_learn_exam/my_task/index",
},
{
path: "/online_learn_exam/my_task/start_learning",
meta: {
title: "开始学习",
activeMenu: "/online_learn_exam/my_task",
},
component: "children",
children: [
{
path: "",
component: "online_learn_exam/my_task/start_learning",
},
{
path: "/online_learn_exam/my_task/start_learning/learning_video",
meta: {
title: "学习",
activeMenu: "/online_learn_exam/my_task",
},
component: "online_learn_exam/my_task/learning_video",
},
{
path: "/online_learn_exam/my_task/start_learning/learning_pdf",
meta: {
title: "学习",
activeMenu: "/online_learn_exam/my_task",
},
component: "online_learn_exam/my_task/learning_pdf",
},
],
},
{
path: "/online_learn_exam/my_task/task_exam",
meta: {
title: "任务考试",
activeMenu: "/online_learn_exam/my_task",
},
component: "online_learn_exam/my_task/task_exam",
},
{
path: "/online_learn_exam/my_task/exam_details",
meta: {
title: "考试详情",
activeMenu: "/online_learn_exam/my_task",
},
component: "online_learn_exam/my_task/exam_details",
},
],
},
],
},
{
path: "/archives",
redirect: "/archives/user",
path: "/signature_information_management",
meta: { title: "签字信息管理", model: MODEL["2"], isSubMenu: false },
component: "signature_information_management/index",
},
{
path: "/file_management",
redirect: "/file_management/personnel",
meta: { title: "档案管理", model: MODEL["2"] },
component: "children",
children: [
{
path: "/archives/user",
path: "/file_management/personnel",
meta: { title: "一人一档", isSubMenu: false },
component: "children",
children: [
{ path: "", component: "file_management/personnel/index" },
{
path: "",
component: "archives/user/index",
},
{
path: "/archives/user/task_list",
path: "/file_management/personnel/task_details",
meta: {
title: "任务详情",
activeMenu: "/archives/user",
activeMenu: "/file_management/personnel",
},
component: "archives/user/task_list",
},
{
path: "/archives/user/detail",
meta: {
title: "任务详情",
activeMenu: "/archives/user",
},
component: "archives/user/detail",
component: "children",
children: [
{ path: "", component: "file_management/personnel/task_details" },
{
path: "/file_management/personnel/task_details/file_details",
meta: {
title: "档案详情",
activeMenu: "/file_management/personnel",
},
component: "file_management/personnel/file_details",
},
],
},
],
},
{
path: "/archives/semester",
path: "/file_management/stage",
meta: { title: "一期一档", isSubMenu: false },
component: "children",
children: [
{ path: "", component: "file_management/stage/index" },
{
path: "",
component: "archives/semester/index",
},
{
path: "/archives/semester/catalogue",
path: "/file_management/stage/archival_catalogue",
meta: {
title: "档案目录",
activeMenu: "/archives/semester",
activeMenu: "/file_management/stage",
},
component: "archives/corp/catalogue",
component: "file_management/stage/archival_catalogue",
},
],
},
{
path: "/archives/corp",
path: "/file_management/enterprise",
meta: { title: "一企一档", isSubMenu: false },
component: "archives/corp/index",
component: "file_management/enterprise/index",
},
],
},
@ -1466,4 +1525,97 @@ export default [
},
],
},
{
path: "/package_protect_person",
redirect: "/package_protect_person/performance_statistics",
meta: { title: "企业安全包保责任人", model: MODEL["4"] },
component: "children",
children: [
{
path: "/package_protect_person/performance_statistics",
meta: { title: "履职统计", isSubMenu: false },
component: "package_protect_person/performance_statistics/index",
},
],
},
{
path: "/safety_commitment",
redirect: "/safety_commitment/company_level",
meta: { title: "安全承诺", model: MODEL["4"] },
component: "children",
children: [
{
path: "/safety_commitment/company_level",
meta: { title: "公司级承诺公告", isSubMenu: false },
component: "children",
children: [
{ path: "", component: "safety_commitment/company_level/index" },
{
path: "/safety_commitment/company_level/add",
meta: {
title: "补录",
activeMenu: "/safety_commitment/company_level",
},
component: "safety_commitment/company_level/add",
},
{
path: "/safety_commitment/company_level/view",
meta: {
title: "查看",
activeMenu: "/safety_commitment/company_level",
},
component: "safety_commitment/company_level/view",
},
],
},
{
path: "/safety_commitment/workshop_level",
meta: { title: "车间级承诺公告", isSubMenu: false },
component: "children",
children: [
{ path: "", component: "safety_commitment/workshop_level/index" },
{
path: "/safety_commitment/workshop_level/add",
meta: {
title: "补录",
activeMenu: "/safety_commitment/workshop_level",
},
component: "safety_commitment/workshop_level/add",
},
{
path: "/safety_commitment/workshop_level/view",
meta: {
title: "查看",
activeMenu: "/safety_commitment/workshop_level",
},
component: "safety_commitment/workshop_level/view",
},
],
},
{
path: "/safety_commitment/team_level",
meta: { title: "班组级承诺公告", isSubMenu: false },
component: "children",
children: [
{ path: "", component: "safety_commitment/team_level/index" },
{
path: "/safety_commitment/team_level/add",
meta: {
title: "补录",
activeMenu: "/safety_commitment/team_level",
},
component: "safety_commitment/team_level/add",
},
{
path: "/safety_commitment/team_level/view",
meta: {
title: "查看",
activeMenu: "/safety_commitment/team_level",
},
component: "safety_commitment/team_level/view",
},
],
},
],
},
];

View File

@ -39,7 +39,16 @@ const props = defineProps({
type: Boolean,
default: false,
},
autoplay: {
type: Boolean,
default: true,
},
playTime: {
type: Number,
default: 0,
},
});
const emits = defineEmits(["ended", "timeupdate"]);
const visibility = useDocumentVisibility();
onMounted(() => {
watch(
@ -80,7 +89,6 @@ const fnCreateAliPlayer = async () => {
format: "m3u8",
encryptType: 1,
mediaType: "video",
autoplay: true,
isLive: false,
rePlay: false,
playsinline: true,
@ -89,14 +97,23 @@ const fnCreateAliPlayer = async () => {
cover: props.cover,
width: props.width,
height: props.height,
autoplay: true,
autoplay: props.autoplay,
useH5Prism: true,
},
(player) => {
player.play();
props.autoplay && player.play();
player.on("ended", fnPlayerEnded);
player.on("timeupdate", fnPlayTimeUpdate);
player.seek(props.playTime);
}
);
};
const fnPlayerEnded = () => {
emits("ended");
};
const fnPlayTimeUpdate = () => {
emits("timeupdate", player.getCurrentTime());
};
const fnDisposeAliPlayer = () => {
if (!player) return;
player.dispose();

View File

@ -4,7 +4,7 @@
:model-value="visible && model === 'dialog'"
@update:model-value="visible = false"
>
<div v-if="visible">
<div v-if="visible" style="height: 690px; overflow-y: auto">
<vue-pdf
v-for="page in numOfPages"
:key="page"
@ -13,7 +13,11 @@
/>
</div>
</el-dialog>
<div v-if="model === 'normal'" :key="src">
<div
v-if="model === 'normal'"
:key="src"
style="height: 690px; overflow-y: auto"
>
<vue-pdf
v-for="page in numOfPages"
:key="page"
@ -41,7 +45,6 @@ const props = defineProps({
visible: {
type: Boolean,
default: false,
required: true,
},
model: {
type: String,

View File

@ -0,0 +1,100 @@
<template>
<div v-if="!dialog">
<div>
<el-button type="primary" @click="fnOpen"></el-button>
</div>
<div style="border: 1px dashed #ccc" class="mt-10" v-if="modelValue">
<img :src="modelValue" alt="" style="width: 100%" />
</div>
</div>
<el-dialog v-model="visible" title="签字">
<vue-esign
ref="signRef"
:width="800"
:height="300"
:isCrop="false"
:lineWidth="6"
lineColor="red"
/>
<template #footer>
<el-button @click="fnReset"></el-button>
<el-button type="primary" @click="fnGenerate"></el-button>
<el-button @click="fnClose"></el-button>
</template>
</el-dialog>
</template>
<script setup>
import VueEsign from "vue-esign";
import { ref } from "vue";
import { ElMessage } from "element-plus";
import { useVModel } from "@vueuse/core";
defineOptions({
name: "LayoutSign",
});
const props = defineProps({
modelValue: {
type: String,
default: "",
},
dialog: {
type: Boolean,
default: false,
},
visible: {
type: Boolean,
default: false,
},
});
const emits = defineEmits(["update:modelValue", "update:visible", "confirm"]);
const signRef = ref(null);
const visible = props.dialog ? useVModel(props, "visible", emits) : ref(false);
const fnOpen = () => {
visible.value = true;
};
const fnReset = () => {
signRef.value.reset();
};
const fnGenerate = () => {
signRef.value
.generate()
.then((res) => {
emits("update:modelValue", res);
emits("confirm", res);
fnClose();
})
.catch(() => {
ElMessage.warning("请签字!");
});
};
const fnClose = () => {
fnReset();
visible.value = false;
};
</script>
<style scoped lang="scss">
.title {
display: flex;
justify-content: space-between;
div {
flex-basis: 33.333%;
&:nth-child(2) {
text-align: center;
}
&:nth-child(3) {
padding-right: 30px;
text-align: right;
}
}
}
canvas {
border: 1px dashed #7e7d7d;
margin: auto;
}
</style>

View File

@ -28,7 +28,7 @@
/>
<el-button v-else type="primary">点击选择文件上传</el-button>
<template #tip>
<div class="ml text-red"><slot name="tip"></slot></div>
<div class="mt-10 text-red"><slot name="tip"></slot></div>
</template>
</el-upload>
<el-dialog v-model="visible" title="查看图片">

View File

@ -4,12 +4,16 @@
<div class="logo">管理平台</div>
<div class="menu">
<ul>
<li @click="router.push({ path: '/BI' })">
<!-- <div v-for="item1 in 4" :key="item1" :class="'horn' + item1" />-->
<div class="title">BI</div>
</li>
<template v-for="(item, index) in MENU" :key="index">
<li
@click="switchMenu(item.model)"
:class="{ active: item.model === menuStore.getModel }"
>
<div v-for="item1 in 4" :key="item1" :class="'horn' + item1" />
<!-- <div v-for="item1 in 4" :key="item1" :class="'horn' + item1" />-->
<div class="title">{{ item.title }}</div>
</li>
</template>
@ -106,6 +110,19 @@ const fnGetUserInfo = async () => {
const switchMenu = (model) => {
menuStore.setModel(model);
};
const fnInitWebSocket = () => {
const { send } = useWebSocket(
encodeURI(import.meta.env.VITE_ON_LINE_WEB_SOCKET_URL),
{
onMessage: (ws, event) => {
const data = JSON.parse(event.data);
if (data.type === "goOut") fnSignOut();
else if (data.type === "thegoout") fnSignOut();
},
}
);
send("[join]" + nanoid());
};
const fnGetInfo = async () => {
const resData = await getInfo();
try {
@ -121,20 +138,7 @@ const fnGetInfo = async () => {
...userStore.getUserInfo,
...resData,
});
const { send } = useWebSocket(
encodeURI("wss://qaaq.qhdsafety.com/zxwebsocket/"),
{
onMessage: (ws, event) => {
const data = JSON.parse(event.data);
if (data.type === "goOut") {
fnSignOut();
} else if (data.type === "thegoout") {
fnSignOut();
}
},
}
);
send("[join]" + nanoid());
fnInitWebSocket();
};
fnGetInfo();
const fnSignOut = async () => {
@ -176,51 +180,27 @@ const fnSignOut = async () => {
display: flex;
li {
width: 120px;
height: 40px;
line-height: 40px;
text-align: center;
cursor: pointer;
background-color: #051748;
clip-path: polygon(0% 0%, 80% 0%, 100% 100%, 20% 100%);
position: relative;
box-shadow: rgba(11, 62, 110, 0.7) 0 0 13px inset;
box-shadow: rgba(23, 66, 130, 1) 0px 0px 30px inset;
color: #fff;
min-width: 100px;
border: 1px solid #283d6f;
list-style: none;
padding: 0 20px;
margin-right: 20px;
border-radius: 2px;
&.active {
background-image: url("/src/assets/images/public/tguang.png");
background-repeat: no-repeat;
background-size: 100% 100%;
border: 1px solid #2870bb;
}
@for $i from 1 through 4 {
.horn#{$i} {
width: 8px;
height: 8px;
background-image: url("/src/assets/images/public/menu_horn#{$i}.png");
background-repeat: no-repeat;
background-size: 100% 100%;
position: absolute;
z-index: 2;
@if $i == 1 {
top: 0;
left: 2px;
}
@if $i == 2 {
top: 0;
right: 21px;
}
@if $i == 3 {
bottom: 0;
left: 21px;
}
@if $i == 4 {
bottom: 0;
right: 2px;
}
}
}
.title {
padding-left: 3px;
font-size: 14px;
@ -242,7 +222,6 @@ const fnSignOut = async () => {
position: absolute;
right: 0;
top: 0;
border-bottom: 1px solid #1f3869;
.el-dropdown {
margin-right: 55px;

View File

@ -1,134 +0,0 @@
import { post, upload } from "@/request/axios.js";
export const getUserList = (params) => post("/user/list", params); // 档案管理-一人一档-获取人员列表
export const getUserInfo = (params) => post("/user/goEditUser", params); // 档案管理-一人一档-获取人员详情
export const getTaskListByUser = (params) =>
post("/studytask/userlist", params); // 档案管理-一人一档-获取任务详情列表
export const getStudyTaskInfo = (params) => post("/studytask/goEdit", params); // 档案管理-一人一档-档案详情-获取任务信息
export const getAllCourseware = (params) =>
post("/studytask/getAllCourseware", params); // 档案管理-一人一档-档案详情-获取课程列表
export const getArchivesPaper = (params) =>
post("/studytask/getArchivesPaper", params); // 档案管理-一人一档-档案详情-获取试卷
export const getSignByStudyTask = (params) =>
post("/studytasksign/getListByStudytaskID", params); // 档案管理-一人一档-档案详情-任务人员的签字信息
export const getUserExamScoreByStudyTaskId = (params) =>
post("/stageexam/getUserExamScoreByStudystaskId", params); // 档案管理-一人一档-档案详情-???
export const getTaskList = (params) => post("/studytask/list", params); // 档案管理-一期一档-获取任务列表
export const getArchivesFileList = (params) =>
post("/archivesfiles/list", params); // 档案管理-获取文件列表
export const deleteArchivesFile = (params) =>
post("/archivesfiles/delete", params); // 档案管理-删除文件
export const uploadArchivesFile = (params) =>
upload("/archivesfiles/add", params); // 档案管理-上传文件
export const getArchivesCapitalList = (params) =>
post("/archivescapital/list", params); // 档案管理-一企一档-获取年度培训资金提取和使用情况管理台账列表
export const deleteArchivesCapital = (params) =>
post("/archivescapital/delete", params); // 档案管理-一企一档-删除年度培训资金提取和使用情况管理台账
export const getArchivesCapital = (params) =>
post("/archivescapital/goEdit", params); // 档案管理-一企一档-获取年度培训资金提取和使用情况管理台账
export const addArchivesCapital = (params) =>
post("/archivescapital/add", params); // 档案管理-一企一档-新增年度培训资金提取和使用情况管理台账
export const editArchivesCapital = (params) =>
post("/archivescapital/edit", params); // 档案管理-一企一档-修改年度培训资金提取和使用情况管理台账
export const getArchivesEdumanagerList = (params) =>
post("/archivesedumanager/list", params); // 档案管理-一企一档-获取年度安全培训教育管理台账列表
export const deleteArchivesEdumanager = (params) =>
post("/archivesedumanager/delete", params); // 档案管理-一企一档-删除年度安全培训教育管理台账
export const getArchivesEdumanager = (params) =>
post("/archivesedumanager/goEdit", params); // 档案管理-一企一档-获取年度安全培训教育管理台账
export const addArchivesEdumanager = (params) =>
post("/archivesedumanager/add", params); // 档案管理-一企一档-新增年度安全培训教育管理台账
export const editArchivesEdumanager = (params) =>
post("/archivesedumanager/edit", params); // 档案管理-一企一档-修改年度安全培训教育管理台账
export const getArchivesEduplanList = (params) =>
post("/archiveseduplan/list", params); // 档案管理-一企一档-获取年度安全培训教育计划列表
export const deleteArchivesEduplan = (params) =>
post("/archiveseduplan/delete", params); // 档案管理-一企一档-删除年度安全培训教育计划
export const getArchivesEduplan = (params) =>
post("/archiveseduplan/goEdit", params); // 档案管理-一企一档-获取年度安全培训教育计划
export const addArchivesEduplan = (params) =>
post("/archiveseduplan/add", params); // 档案管理-一企一档-新增年度安全培训教育计划
export const editArchivesEduplan = (params) =>
post("/archiveseduplan/edit", params); // 档案管理-一企一档-修改年度安全培训教育计划
export const getArchivesTeacherList = (params) =>
post("/archivesteacher/list", params); // 档案管理-一企一档-获取年度本单位师资管理台账列表
export const deleteArchivesTeacher = (params) =>
post("/archivesteacher/delete", params); // 档案管理-一企一档-删除年度本单位师资管理台账
export const getArchivesTeacher = (params) =>
post("/archivesteacher/goEdit", params); // 档案管理-一企一档-获取年度本单位师资管理台账
export const addArchivesTeacher = (params) =>
post("/archivesteacher/add", params); // 档案管理-一企一档-新增年度本单位师资管理台账
export const editArchivesTeacher = (params) =>
post("/archivesteacher/edit", params); // 档案管理-一企一档-修改年度本单位师资管理台账
export const getArchivesPostmanList = (params) =>
post("/archivespostman/list", params); // 档案管理-一企一档-获取年度三岗人员管理台账列表
export const deleteArchivesPostman = (params) =>
post("/archivespostman/delete", params); // 档案管理-一企一档-删除年度三岗人员管理台账
export const getArchivesPostman = (params) =>
post("/archivespostman/goEdit", params); // 档案管理-一企一档-获取年度三岗人员管理台账
export const addArchivesPostman = (params) =>
post("/archivespostman/add", params); // 档案管理-一企一档-新增年度三岗人员管理台账
export const editArchivesPostman = (params) =>
post("/archivespostman/edit", params); // 档案管理-一企一档-修改年度三岗人员管理台账
export const getArchivesTrainingScheduleList = (params) =>
post("/trainingschedule/list", params); // 档案管理-一期一档-获取培训计划列表
export const deleteArchivesTrainingSchedule = (params) =>
post("/trainingschedule/delete", params); // 档案管理-一期一档-删除培训计划
export const getArchivesTrainingSchedule = (params) =>
post("/trainingschedule/goEdit", params); // 档案管理-一期一档-获取培训计划
export const addArchivesTrainingSchedule = (params) =>
post("/trainingschedule/add", params); // 档案管理-一期一档-新增培训计划
export const editArchivesTrainingSchedule = (params) =>
post("/trainingschedule/edit", params); // 档案管理-一期一档-修改培训计划
export const getAllCoursewareByHandout = (params) =>
post("/studytask/getAllCoursewareByHandout", params); // 档案管理-一期一档-安全培训教材或课程讲义-获取课件
export const getStudentByTaskId = (params) =>
post("/stagestudentrelation/listAllByStudyTaskId", params); // 档案管理-一期一档-安全培训教育记录及签字表-获取学生
export const getPaperByTaskId = (params) => post("/studytask/getPaper", params); // 档案管理-一期一档-培训考核试卷-获取试卷
export const getAllCurriculum = (params) =>
post("/studytask/getAllcurriculum", params); // 档案管理-一期一档-本期综合考评报告-获取课程

View File

@ -0,0 +1,73 @@
import { post, upload } from "@/request/axios.js";
export const getPersonnelTaskDetailsList = (params) =>
post("/studytask/userlist", params); // 一人一档任务详情列表
export const getStudyTaskCoursewareList = (params) =>
post("/studytask/getAllCourseware", params); // 学习任务课件
export const getStudyTaskSign = (params) =>
post("/studytasksign/getListByStudytaskID", params); // 任务人员的签字信息
export const getUserExamScore = (params) =>
post("/stageexam/getUserExamScoreByStudystaskId", params); // 获取考试成绩
export const getArchivesStudyTaskPaper = (params) =>
post("/studytask/getArchivesPaper", params); // 获取考卷
export const getStageList = (params) => post("/studytask/list", params); // 一期一档列表
export const getHandoutView = (params) =>
post("/studytask/getAllCoursewareByHandout", params); // 查看安全培训教材或课程讲义
export const getStudyTaskPaper = (params) =>
post("/studytask/getPaper", params); // 获取考卷
export const getArchivesFilesList = (params) =>
post("/archivesfiles/list", params); // 获取附件
export const setArchivesFilesUpload = (params) =>
upload("/archivesfiles/add", params); // 上传附件
export const setArchivesFilesDelete = (params) =>
post("/archivesfiles/delete", params); // 删除附件
export const getCurriculumAll = (params) =>
post("/studytask/getAllcurriculum", params); // 获取课程
export const getTrainingScheduleList = (params) =>
post("/trainingschedule/list", params); // 培训日程安排通知列表
export const setTrainingScheduleDelete = (params) =>
post("/trainingschedule/delete", params); // 培训日程安排通知删除
export const getTrainingScheduleView = (params) =>
post("/trainingschedule/goEdit", params); // 培训日程安排通知查看
export const setTrainingScheduleAdd = (params) =>
post("/trainingschedule/add", params); // 培训日程安排通知添加
export const setTrainingScheduleEdit = (params) =>
post("/trainingschedule/edit", params); // 培训日程安排通知修改
export const getPostmanList = (params) => post("/archivespostman/list", params); // 三岗人员管理台账列表
export const getPostmanView = (params) =>
post("/archivespostman/goEdit", params); // 三岗人员管理台账查看
export const setPostmanDelete = (params) =>
post("/archivespostman/delete", params); // 三岗人员管理台账删除
export const setPostmanAdd = (params) => post("/archivespostman/add", params); // 三岗人员管理台账添加
export const setPostmanEdit = (params) => post("/archivespostman/edit", params); // 三岗人员管理台账修改
export const getTeacherList = (params) => post("/archivesteacher/list", params); // 本单位师资管理台账列表
export const getTeacherView = (params) =>
post("/archivesteacher/goEdit", params); // 本单位师资管理台账查看
export const setTeacherDelete = (params) =>
post("/archivesteacher/delete", params); // 本单位师资管理台账删除
export const setTeacherAdd = (params) => post("/archivesteacher/add", params); // 本单位师资管理台账添加
export const setTeacherEdit = (params) => post("/archivesteacher/edit", params); // 本单位师资管理台账修改
export const getEduplanList = (params) => post("/archiveseduplan/list", params); // 年度安全培训教育计划列表
export const getEduplanView = (params) =>
post("/archiveseduplan/goEdit", params); // 年度安全培训教育计划查看
export const setEduplanDelete = (params) =>
post("/archiveseduplan/delete", params); // 年度安全培训教育计划删除
export const setEduplanAdd = (params) => post("/archiveseduplan/add", params); // 年度安全培训教育计划添加
export const setEduplanEdit = (params) => post("/archiveseduplan/edit", params); // 年度安全培训教育计划修改
export const getEdumanagerList = (params) =>
post("/archivesedumanager/list", params); // 年度安全培训教育管理台账列表
export const getEdumanagerView = (params) =>
post("/archivesedumanager/goEdit", params); // 年度安全培训教育管理台账查看
export const setEdumanagerDelete = (params) =>
post("/archivesedumanager/delete", params); // 年度安全培训教育管理台账删除
export const setEdumanagerAdd = (params) =>
post("/archivesedumanager/add", params); // 年度安全培训教育管理台账添加
export const setEdumanagerEdit = (params) =>
post("/archivesedumanager/edit", params); // 年度安全培训教育管理台账修改
export const getCapitalList = (params) => post("/archivescapital/list", params); // 年度培训资金提取和使用情况管理台账列表
export const getCapitalView = (params) =>
post("/archivescapital/goEdit", params); // 年度培训资金提取和使用情况管理台账查看
export const setCapitalDelete = (params) =>
post("/archivescapital/delete", params); // 年度培训资金提取和使用情况管理台账删除
export const setCapitalAdd = (params) => post("/archivescapital/add", params); // 年度培训资金提取和使用情况管理台账添加
export const setCapitalEdit = (params) => post("/archivescapital/edit", params); // 年度培训资金提取和使用情况管理台账修改

View File

@ -68,3 +68,17 @@ export const getTaskExamDetailsList = (params) =>
post("/stagestudentrelation/list", params); // 任务管理考试详情列表
export const getTaskExamPaperDetails = (params) =>
post("/stageexam/findResult", params); // 任务管理考卷详情查看
export const getMyTaskList = (params) =>
post("/stagestudentrelation/pageTaskByUser", params); // 我的任务列表
export const setMyTaskSign = (params) =>
post("/stagestudentrelation/sign", params); // 我的任务签字
export const getMyTasksStartLearningList = (params) =>
post("/kcmiddlekj/list", params); // 我的任务开始学习列表
export const setMyTasksVideoProgress = (params) =>
post("/coursestudyvideorecord/save", params); // 我的任务存视频播放进度
export const getMyTasksVideoProgress = (params) =>
post("/coursestudyvideorecord/getVideoProgress", params); // 我的任务获取视频播放进度
export const getMyTasksTaskExamExamPaperInfo = (params) =>
post("/stageexampaper/getExam", params); // 我的任务任务考试试卷信息
export const setMyTasksTaskExamSubmit = (params) =>
post("/stageexam/submit", params); // 我的任务任务考试交卷

View File

@ -0,0 +1,4 @@
import { post } from "@/request/axios.js";
export const getPerformanceStatisticsList = (params) =>
post("/report/getBaoBaoForm", params); // 履职统计列表

View File

@ -0,0 +1,24 @@
import { post } from "@/request/axios.js";
export const getSafetyCommitmentList = (params) =>
post("/department/list", params); // 安全承诺列表
export const getCompanyLevelViewSignature = (params) =>
post("/commitmentcompany/list", params); // 安全承诺公司级承诺查看签字情况
export const getCompanyLevelViewSignatureInfo = (params) =>
post("/commitmentcompany/goEdit", params); // 安全承诺公司级承诺查看
export const getCompanyLevelAcceptancePeople = (params) =>
post("/user/listCascaderByDeptLevel", params); // 安全承诺承诺人
export const setCompanyLevelSubmit = (params) =>
post("/commitmentcompany/replenishSave", params); // 安全承诺公司级承诺提交
export const getWorkshopLevelViewSignature = (params) =>
post("/commitmentworkshop/list", params); // 安全承诺车间级承诺查看签字情况
export const getWorkshopLevelViewSignatureInfo = (params) =>
post("/commitmentworkshop/goEdit", params); // 安全承诺车间级承诺查看
export const setWorkshopLevelSubmit = (params) =>
post("/commitmentworkshop/replenishSave", params); // 安全承诺车间级承诺提交
export const getTeamLevelViewSignatureInfo = (params) =>
post("/commitmentteam/goEdit", params); // 安全承诺班组级承诺查看
export const getTeamLevelViewSignature = (params) =>
post("/commitmentteam/list", params); // 安全承诺班组级承诺查看签字情况
export const setTeamLevelSubmit = (params) =>
post("/commitmentteam/replenishSave", params); // 安全承诺班组级承诺提交

View File

@ -0,0 +1,4 @@
import { post } from "@/request/axios.js";
export const setSwitchUserStatus = (params) =>
post("/user/updataSignType", params); // 签字信息管理切换人员状态

View File

@ -29,6 +29,12 @@ const routes = [
},
],
},
{
path: "/BI",
name: "/BI",
meta: { title: "BI", isBreadcrumb: false, isMenu: false },
component: () => import("@/views/BI/index"),
},
{
path: "/404",
name: "/404",

View File

@ -0,0 +1,429 @@
<template>
<div class="container">
<div
class="options"
v-for="(item, index) in data.bottomOptionsList"
:key="item.title"
@click="fnBottomOptionsListChange(item, index)"
>
<div class="option">
<img :src="item.check ? item.imgSelect : item.img" alt="" />
<div class="title">{{ item.title }}</div>
</div>
<div :class="['child_container', { active: item.check }]">
<div class="child_options">
<div
class="child_option"
v-for="(item1, index1) in item.list"
:key="item1.title"
@click.stop="fnBottomChildOptionsListChange(index, item1, index1)"
>
<img :src="item1.check ? item1.imgSelect : item1.img" alt="" />
<div class="tit" :class="item1.check ? 'active' : ''">
{{ item1.title }}
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { reactive, markRaw } from "vue";
import Personnel from "@/views/BI/components/personnel.vue";
import WorkSafely from "@/views/BI/components/work_safely.vue";
import EntranceControl from "@/views/BI/components/entrance_control.vue";
import GraveDangerous from "@/views/BI/components/grave_dangerous.vue";
import VideoAIAnalysis from "@/views/BI/components/video_ai_analysis.vue";
import VideoAIAnalysisRight from "@/views/BI/components/video_ai_analysisRight.vue";
import { useVModels } from "@vueuse/core";
const props = defineProps({
leftCurrentComponent: {
type: [Object, Function, String],
required: true,
default: "",
},
rightCurrentComponent: {
type: [Object, Function, String],
required: true,
default: "",
},
rightOption: {
type: Boolean,
required: true,
default: false,
},
});
const emits = defineEmits([
"update:leftCurrentComponent",
"update:rightCurrentComponent",
"update:rightOption",
]);
const { leftCurrentComponent, rightCurrentComponent, rightOption } = useVModels(
props,
emits
);
const bottomOptionsList = [
{
img: new URL("/src/assets/images/map/bico1.png", import.meta.url).href,
imgSelect: new URL("/src/assets/images/map/bico1_on.png", import.meta.url)
.href,
title: "人员定位",
type: "personnelPositioning",
check: false,
components: [markRaw(Personnel)],
list: [
{
img: new URL("/src/assets/images/map/bottom/ico1.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico1_on.png",
import.meta.url
).href,
title: "人员",
type: "personnel",
check: false,
},
{
img: new URL("/src/assets/images/map/bottom/ico2.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico2_on.png",
import.meta.url
).href,
title: "视频",
type: "video",
check: false,
},
{
img: new URL("/src/assets/images/map/bottom/ico3.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico3_on.png",
import.meta.url
).href,
title: "电子围栏",
type: "electronicFence",
check: false,
},
],
},
{
img: new URL("/src/assets/images/map/bico2.png", import.meta.url).href,
imgSelect: new URL("/src/assets/images/map/bico2_on.png", import.meta.url)
.href,
title: "安全作业",
type: "workSafely",
check: false,
components: [markRaw(WorkSafely)],
list: [
{
img: new URL("/src/assets/images/map/bottom/ico4.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico4_on.png",
import.meta.url
).href,
title: "动火作业",
type: "hotWork",
check: false,
},
{
img: new URL("/src/assets/images/map/bottom/ico5.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico5_on.png",
import.meta.url
).href,
title: "受限空间作业",
type: "acceptance",
check: false,
},
{
img: new URL("/src/assets/images/map/bottom/ico6.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico6_on.png",
import.meta.url
).href,
title: "临时用电作业",
type: "temporaryElectricalWork",
check: false,
},
{
img: new URL("/src/assets/images/map/bottom/ico7.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico7_on.png",
import.meta.url
).href,
title: "高处作业",
type: "workAtHeight",
check: false,
},
{
img: new URL("/src/assets/images/map/bottom/ico8.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico8_on.png",
import.meta.url
).href,
title: "断路作业",
type: "circuitBreakingOperations",
check: false,
},
{
img: new URL("/src/assets/images/map/bottom/ico9.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico9_on.png",
import.meta.url
).href,
title: "动土作业",
type: "groundbreakingWork",
check: false,
},
{
img: new URL("/src/assets/images/map/bottom/ico10.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico10_on.png",
import.meta.url
).href,
title: "吊装作业",
type: "hoistingOperations",
check: false,
},
{
img: new URL("/src/assets/images/map/bottom/ico11.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico11_on.png",
import.meta.url
).href,
title: "盲板抽堵作业",
type: "blindPlatePluggingOperation",
check: false,
},
{
img: new URL("/src/assets/images/map/bottom/ico12.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico12_on.png",
import.meta.url
).href,
title: "摄像头",
type: "camera",
check: false,
},
],
},
{
img: new URL("/src/assets/images/map/bico3.png", import.meta.url).href,
imgSelect: new URL("/src/assets/images/map/bico3_on.png", import.meta.url)
.href,
title: "口门门禁",
type: "entranceControl",
check: false,
components: [markRaw(EntranceControl)],
list: [
{
img: new URL("/src/assets/images/map/bottom/ico13.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico13_on.png",
import.meta.url
).href,
title: "人员",
type: "personnel",
check: false,
},
{
img: new URL("/src/assets/images/map/bottom/ico14.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico14_on.png",
import.meta.url
).href,
title: "车辆",
type: "vehicle",
check: false,
},
{
img: new URL("/src/assets/images/map/bottom/ico15.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico15_on.png",
import.meta.url
).href,
title: "摄像头",
type: "camera",
check: false,
},
],
},
{
img: new URL("/src/assets/images/map/bico4.png", import.meta.url).href,
imgSelect: new URL("/src/assets/images/map/bico4_on.png", import.meta.url)
.href,
title: "重大危险源",
type: "significantSourcesOfDanger",
check: false,
components: [markRaw(GraveDangerous)],
list: [
{
img: new URL("/src/assets/images/map/bottom/ico16.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico16_on.png",
import.meta.url
).href,
title: "储罐区",
type: "tankFarms",
check: false,
},
{
img: new URL("/src/assets/images/map/bottom/ico17.png", import.meta.url)
.href,
imgSelect: new URL(
"/src/assets/images/map/bottom/ico17_on.png",
import.meta.url
).href,
title: "压力管道",
type: "pressurePiping",
check: false,
},
],
},
{
img: new URL("/src/assets/images/map/bico5.png", import.meta.url).href,
imgSelect: new URL("/src/assets/images/map/bico5_on.png", import.meta.url)
.href,
title: "视频AI分析",
type: "videoAIAnalysis",
check: false,
components: [markRaw(VideoAIAnalysis), markRaw(VideoAIAnalysisRight)],
},
];
const data = reactive({
bottomOptionsList,
});
const fnBottomOptionsListChange = (item, index) => {
for (let i = 0; i < data.bottomOptionsList.length; i++) {
if (index === i) {
data.bottomOptionsList[index].check =
!data.bottomOptionsList[index].check;
continue;
}
data.bottomOptionsList[i].check = false;
}
leftCurrentComponent.value = data.bottomOptionsList[index].check
? item.components[0]
: "";
rightCurrentComponent.value = data.bottomOptionsList[index].check
? item.components[1]
: "";
rightOption.value = index !== 4;
};
const fnBottomChildOptionsListChange = (index, item1, index1) => {
data.bottomOptionsList[index].list[index1].check =
!data.bottomOptionsList[index].list[index1].check;
};
</script>
<style scoped lang="scss">
.container {
width: 100%;
position: relative;
.options {
width: 80px;
height: 95px;
position: absolute;
text-align: center;
cursor: pointer;
&:nth-child(1) {
left: 130px;
bottom: -54px;
}
&:nth-child(2) {
left: 280px;
bottom: -34px;
}
&:nth-child(3) {
left: 430px;
bottom: -25px;
}
&:nth-child(4) {
left: 580px;
bottom: -34px;
}
&:nth-child(5) {
left: 730px;
bottom: -54px;
}
.title {
margin-top: 5px;
font-size: 14px;
}
.child_container {
position: relative;
width: 80px;
height: 95px;
left: 0;
top: -95px;
display: none;
&.active {
display: block;
}
.child_options {
position: absolute;
left: 50%;
top: -120px;
transform: translateX(-50%);
background-image: linear-gradient(
to right,
rgba(0, 0, 0, 0) 0%,
rgba(0, 0, 0, 0.4) 50%,
rgba(0, 0, 0, 0) 100%
);
border: 1px solid;
border-image: linear-gradient(
to right,
rgba(0, 0, 0, 0) 0%,
rgba(2, 119, 142, 1) 50%,
rgba(255, 255, 255, 0) 100%
)
1;
border-left: none;
border-right: none;
display: flex;
animation: 0.5s all;
.child_option {
text-align: center;
display: inline-block;
padding: 15px 25px;
.tit {
white-space: nowrap;
}
.active {
color: #28b9fe;
}
}
}
}
}
}
</style>

View File

@ -0,0 +1,370 @@
<template>
<div class="container">
<div class="block1">
<layout-title title="设备在线情况" />
<div class="option">
<div
class="list"
v-for="(item, index) in data.block1OptionsList"
:key="index"
>
<img :src="item.img" alt="" class="img" />
<div class="label">{{ item.label }}</div>
<div class="num">
<count-up :end-val="item.count"></count-up>
</div>
</div>
</div>
</div>
<div class="block2">
<layout-title title="堆料场进出数据" />
<div class="options">
<div class="option">
<div class="title">今日人员情况</div>
<div class="wraps">
<div class="wrap">进堆料场人员数: 0</div>
<div class="wrap">出堆料场人员数: 0</div>
<div class="wrap">堆料场内人员数: 0</div>
</div>
</div>
<div class="option">
<div class="title">今日车辆情况</div>
<div class="wraps">
<div class="wrap">进堆料场车辆数: 0</div>
<div class="wrap">出堆料场车辆数: 0</div>
<div class="wrap">堆料场内车辆数: 0</div>
</div>
</div>
</div>
</div>
<div class="block3">
<layout-title title="口门进出记录" />
<div class="option">
<div class="tab_list">
<div
class="list"
v-for="(item, index) in tabsList"
:class="['item', { active: index === tabIndex }]"
:key="index"
@click="tabIndex = index"
>
{{ item }}
</div>
</div>
<div class="table">
<div class="tr">
<div class="td">卡口名称</div>
<div class="td">车牌</div>
<div class="td">时间</div>
<div class="td">状态</div>
</div>
<div class="tr" v-for="(item, index) in data.block3List" :key="index">
<div class="td line-1">{{ item.name }}</div>
<div class="td">{{ item.licensePlate }}</div>
<div class="td line-1">{{ item.time }}</div>
<div class="td">{{ item.state }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import LayoutTitle from "./title.vue";
import CountUp from "vue-countup-v3";
import { reactive, ref } from "vue";
const data = reactive({
block1OptionsList: [
{
img: new URL("/src/assets/images/map/img7.png", import.meta.url).href,
label: "人员闸机数",
count: 3500,
},
{
img: new URL("/src/assets/images/map/img8.png", import.meta.url).href,
label: "车辆闸机数",
count: 3500,
},
{
img: new URL("/src/assets/images/map/img9.png", import.meta.url).href,
label: "摄像头数",
count: 3500,
},
],
block3List: [
{
name: "南大门卡口",
licensePlate: "冀CAD097",
time: "2023-5-16 12:36:25",
state: "正常",
},
{
name: "南大门卡口",
licensePlate: "冀CAD097",
time: "2023-5-16 12:36:25",
state: "正常",
},
{
name: "南大门卡口",
licensePlate: "冀CAD097",
time: "2023-5-16 12:36:25",
state: "正常",
},
{
name: "南大门卡口",
licensePlate: "冀CAD097",
time: "2023-5-16 12:36:25",
state: "正常",
},
{
name: "南大门卡口",
licensePlate: "冀CAD097",
time: "2023-5-16 12:36:25",
state: "正常",
},
{
name: "南大门卡口",
licensePlate: "冀CAD097",
time: "2023-5-16 12:36:25",
state: "正常",
},
{
name: "南大门卡口",
licensePlate: "冀CAD097",
time: "2023-5-16 12:36:25",
state: "正常",
},
{
name: "南大门卡口",
licensePlate: "冀CAD097",
time: "2023-5-16 12:36:25",
state: "正常",
},
{
name: "南大门卡口",
licensePlate: "冀CAD097",
time: "2023-5-16 12:36:25",
state: "正常",
},
],
});
const tabsList = ["人员闸机", "车辆闸机"];
const tabIndex = ref(0);
</script>
<style scoped lang="scss">
.container {
width: 100%;
.block1 {
width: 430px;
.option {
width: 100%;
min-height: 100px;
background-image: linear-gradient(
to bottom,
rgba(0, 0, 0, 0),
rgba(0, 0, 0, 0.8)
);
border-radius: 10px;
border: 1px solid;
border-image: linear-gradient(
to bottom,
rgba(58, 122, 149, 0),
rgba(16, 188, 236, 1)
)
1;
border-top: none;
display: flex;
justify-content: space-around;
padding: 20px 0;
text-align: center;
.list {
text-align: center;
width: 33%;
.img {
animation: slideY 2s infinite;
}
.label {
margin-top: 5px;
}
.num {
font-size: 24px;
margin-top: 10px;
background: linear-gradient(to top, #ffffff, #00a8ff);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-weight: bold;
font-family: "Pingfang SC", "Microsoft YaHei", "Monospaced Number",
"Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, "PingFang SC", "Hiragino Sans GB", "Helvetica Neue",
Helvetica, Arial, sans-serif;
text-shadow: 0 0 20px #2c67ec;
}
}
}
}
.block2 {
width: 430px;
margin-top: 10px;
.options {
width: 100%;
min-height: 100px;
background-image: linear-gradient(
to bottom,
rgba(0, 0, 0, 0),
rgba(0, 0, 0, 0.8)
);
border-radius: 10px;
border: 1px solid;
border-image: linear-gradient(
to bottom,
rgba(58, 122, 149, 0),
rgba(16, 188, 236, 1)
)
1;
border-top: none;
padding: 10px;
text-align: left;
display: flex;
flex-direction: column;
.option {
width: 100%;
.title {
background: rgba(10, 69, 203, 0.5);
border: 1px solid;
border-image: linear-gradient(
to bottom,
rgba(58, 122, 149, 0),
rgba(16, 188, 236, 1)
)
1;
border-top: none;
display: inline-block;
padding: 6px 20px;
margin: 10px 0;
}
.wraps {
width: 100%;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.wrap {
width: 45%;
text-align: left;
margin: 10px;
}
}
}
}
}
.block3 {
width: 430px;
margin-top: 10px;
.tab_list {
}
.option {
width: 100%;
min-height: 100px;
background-image: linear-gradient(
to bottom,
rgba(0, 0, 0, 0),
rgba(0, 0, 0, 0.8)
);
border-radius: 10px;
border: 1px solid;
border-image: linear-gradient(
to bottom,
rgba(58, 122, 149, 0),
rgba(16, 188, 236, 1)
)
1;
border-top: none;
padding: 10px;
.tab_list {
display: flex;
background: rgba(52, 147, 245, 0.3);
border: 1px solid rgba(63, 145, 197, 0.4);
border-radius: 2px;
width: 38%;
justify-content: space-between;
.list {
padding: 8px 10px;
cursor: pointer;
&:hover,
&.active {
background-image: linear-gradient(
to bottom,
rgba(1, 168, 255, 1),
rgba(17, 74, 152, 1)
);
}
}
}
.table {
margin-top: 5px;
.tr {
display: flex;
&:nth-child(odd) {
background-color: rgba(42, 86, 158, 0.53);
}
.td {
flex: 1;
text-align: left;
font-size: 14px;
color: #fff;
padding: 10px 10px;
&:nth-child(1) {
flex-basis: 25%;
}
&:nth-child(2) {
flex-basis: 25%;
}
&:nth-child(3) {
flex-basis: 35%;
}
&:nth-child(4) {
flex-basis: 15%;
}
}
.empty {
flex: 1;
text-align: center;
font-size: 12px;
color: #fff;
padding: 5px;
}
}
}
}
}
@keyframes slideY {
0% {
transform: translateY(0);
}
50% {
transform: translateY(-5px);
}
100% {
transform: translateY(0);
}
}
}
</style>

Some files were not shown because too many files have changed in this diff Show More