滚动大屏绿十字功能部署

This commit is contained in:
赵正易 2025-04-21 17:49:54 +08:00
parent f015efd80f
commit b5e0e31cb1
5 changed files with 686 additions and 0 deletions

View File

@ -0,0 +1,67 @@
import request from '@/utils/request'
/**
* 现场安全绿色十字架分页查询
* @param {查询条件} data
*/
export function listSiteSafeGreenCross(query) {
return request({
url: 'BZFM/SiteSafeGreenCross/list',
method: 'get',
params: query
})
}
/**
* 新增现场安全绿色十字架
* @param data
*/
export function addSiteSafeGreenCross(data) {
return request({
url: 'BZFM/SiteSafeGreenCross',
method: 'post',
data: data
})
}
/**
* 修改现场安全绿色十字架
* @param data
*/
export function updateSiteSafeGreenCross(data) {
return request({
url: 'BZFM/SiteSafeGreenCross',
method: 'PUT',
data: data
})
}
/**
* 获取现场安全绿色十字架详情
* @param {Id}
*/
export function getSiteSafeGreenCross(id) {
return request({
url: 'BZFM/SiteSafeGreenCross/' + id,
method: 'get'
})
}
/**
* 删除现场安全绿色十字架
* @param {主键} pid
*/
export function delSiteSafeGreenCross(pid) {
return request({
url: 'BZFM/SiteSafeGreenCross/delete/' + pid,
method: 'POST'
})
}
/**
* 现场安全绿色十字架大屏数据展示
*/
export function GetGreenCrossData() {
return request({
url: 'mes/AndonManagement/SafeGreenSmart/greencross',
method: 'get'
})
}

View File

@ -0,0 +1,75 @@
body {
margin: 0;
padding: 0;
}
.background {
padding: 0;
margin: 0;
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
/* background-color: black; */
background: url('./background/background.png') no-repeat;
background-size: 100% 100%;
/* -webkit-filter: brightness(0.1); */
/* filter: brightness(0.1); */
z-index: -1;
}
.border {
border: 2px solid #a9aabc;
}
.screen {
box-sizing: border-box;
padding: 20px; /* Default padding */
margin: 0;
width: 100%;
height: 100%;
color: #eeeeee;
background-color: rgba(32, 163, 250, 0.2);
}
/* Responsive adjustments */
@media (max-width: 1200px) {
.screen {
padding: 10px;
}
}
@media (max-width: 992px) {
.screen {
padding: 5px;
}
}
@media (max-width: 768px) {
.screen {
padding: 5px;
}
}
@media (max-width: 576px) {
.screen {
padding: 2px;
}
}
.screen .header {
/* width: 100%;
height: 100px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center; */
}
.screen .title {
font-size: 30px;
font-weight: 700;
color: #eeeeee;
}
.body {
display: flex;
flex-direction: column;
}
.box {
padding: 20px;
}

View File

@ -0,0 +1,252 @@
<template>
<kbFullScreenBox>
<div class="screen">
<div class="header">
<kbHeader>生产安全绿色十字</kbHeader>
</div>
<kbGap></kbGap>
<div class="body">
<div class="main-title">{{ getDayTitle() }}</div>
<div class="main-content">
<div class="main-top">
<div v-for="(item, index) in topModel" :key="index" :class="getDateItemClass(item)">
{{ item }}
</div>
</div>
<div class="main-left">
<div v-for="(item, index) in leftModel" :key="index" :class="getDateItemClass(item)">
{{ item }}
</div>
</div>
<div class="main-logo">
<span class="logo-text">KJK</span>
</div>
<div class="main-right">
<div v-for="(item, index) in rightModel" :key="index" :class="getDateItemClass(item)">
{{ item }}
</div>
</div>
<div class="main-bottom">
<div v-for="(item, index) in bottomModel" :key="index" :class="getDateItemClass(item)">
{{ item }}
</div>
</div>
</div>
<div class="color-scheme">
<div class="scheme-item safe">安全</div>
<div class="scheme-item warning">轻微事故</div>
<div class="scheme-item danger">重大事故</div>
</div>
</div>
<div class="bottom-text">安全生产挑战劳动 0 灾害</div>
</div>
</kbFullScreenBox>
</template>
<script setup>
import { ref, onMounted } from 'vue'
/// ================ ======================
import kbFullScreenBox from '../可视化素材包/components/kbFullScreenBox.vue'
import kbGap from '../可视化素材包/components/kbGap.vue'
import kbHeader from '../可视化素材包/components/kbHeader.vue'
import kbChartBox from '../可视化素材包/components/kbChartBox.vue'
import kbCountBox from '../可视化素材包/components/kbCountBox.vue'
import kbNumBox from '../可视化素材包/components/kbNumBox.vue'
import kbTitle from '../可视化素材包/components/kbTitle.vue'
/// ================================================
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
/// =================== ======================
import { GetGreenCrossData } from '@/api/andonManagement/sitesafegreencross.js'
function initData() {
GetGreenCrossData().then((res) => {
if (res.code === 200) {
dateStatus.value = res.data
}
})
}
initData()
let timer1 = null
const clearSearchTimer = () => {
clearInterval(timer1)
timer1 = null
}
const createSearchTimer = () => {
clearSearchTimer()
timer1 = setInterval(() => {
initData()
}, 1000 * 60 * 12)
}
onMounted(() => {
createSearchTimer()
})
onUnmounted(() => {
clearSearchTimer()
})
/// ====================================================
//
function getDayTitle() {
return `${proxy.$dayjs().format('YYYY年MM月')}`
}
// 绿
const topModel = [1, 2, 3, 4, 5, 6]
const leftModel = [7, 8, 9, 13, 14, 15, 19, 20, 21]
const rightModel = [10, 11, 12, 16, 17, 18, 22, 23, 24]
const bottomModel = [25, 26, 27, 28, 29, 30, 31, '', '']
//
const dateStatus = ref([])
//
const getDateItemClass = (date) => {
const item = dateStatus.value.find((item) => item.safeDateInt === date)
const status = item ? item.safeNum : 0
if (status === 1) {
return 'date-item safe'
} else if (status === 2) {
return 'date-item warning'
} else if (status === 3) {
return 'date-item danger'
}
return 'date-item'
}
</script>
<style scoped>
@import './index.css';
/* 基本样式 */
.body {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
}
.main-title {
width: 100%;
font-size: 36px;
color: white;
display: flex;
align-items: center;
justify-content: center;
}
.main-content {
display: grid;
grid-template-columns: 20vw 16vw 20vw;
grid-template-rows: 26vh 20vh 26vh;
grid-template-areas:
'. main-top .'
'main-left main-logo main-right'
'. main-bottom .';
gap: 0;
}
.main-top,
.main-left,
.main-right,
.main-bottom {
display: grid;
place-items: center;
border: 1px solid #fff;
}
.main-top {
grid-area: main-top;
grid-template-columns: repeat(3, 1fr);
}
.main-left {
grid-area: main-left;
grid-template-columns: repeat(3, 1fr);
}
.main-right {
grid-area: main-right;
grid-template-columns: repeat(3, 1fr);
}
.main-bottom {
grid-area: main-bottom;
grid-template-columns: repeat(3, 1fr);
}
.main-logo {
grid-area: main-logo;
border: 1px solid #fff;
display: grid;
place-items: center;
}
.date-item {
color: white;
text-align: center;
font-size: 16px;
width: 100%;
height: 100%;
display: grid;
place-items: center;
border: 1px solid #fff;
}
.date-item.safe {
background-color: green;
}
.date-item.warning {
background-color: yellow;
color: black;
}
.date-item.danger {
background-color: red;
}
.logo-text {
color: white;
font-size: 60px; /* 可根据需要调整字体大小 */
font-weight: bold;
}
.logo-placeholder {
width: 40%;
height: 40%;
border: 1px solid gray;
}
.color-scheme {
display: flex;
flex-direction: column;
gap: 8px;
position: absolute;
top: 20px;
right: 20px;
}
.scheme-item {
padding: 5px 10px;
border: 1px solid #fff;
white-space: nowrap;
color: white;
}
.scheme-item.safe {
background-color: green;
}
.scheme-item.warning {
background-color: yellow;
color: black;
}
.scheme-item.danger {
background-color: red;
}
.bottom-text {
width: 100%;
text-align: center;
font-size: 24px;
color: white;
margin-top: 20px;
padding-bottom: 20px;
}
</style>

View File

@ -12,6 +12,9 @@
<el-carousel-item :key="4"> <el-carousel-item :key="4">
<DeviceScreen style="height: 100%"></DeviceScreen> <DeviceScreen style="height: 100%"></DeviceScreen>
</el-carousel-item> </el-carousel-item>
<el-carousel-item :key="5">
<SafeGreenCross style="height: 100%"></SafeGreenCross>
</el-carousel-item>
</el-carousel> </el-carousel>
</template> </template>
@ -20,6 +23,7 @@ import { default as OrderScreen } from '@/views/SmartScreen/OrderScreen/index'
import { default as ReportScreen } from '@/views/SmartScreen/ReportScreen/index' import { default as ReportScreen } from '@/views/SmartScreen/ReportScreen/index'
import { default as QualityScreen } from '@/views/SmartScreen/QualityScreen/index' import { default as QualityScreen } from '@/views/SmartScreen/QualityScreen/index'
import { default as DeviceScreen } from '@/views/SmartScreen/DeviceScreen/index' import { default as DeviceScreen } from '@/views/SmartScreen/DeviceScreen/index'
import { default as SafeGreenCross } from '@/views/SmartScreen/SafeGreenCross/index'
// //
// import { default as AndonFullScreen } from '@/views/andonManagement/analysis/fullscreen/index' // import { default as AndonFullScreen } from '@/views/andonManagement/analysis/fullscreen/index'
// Andon // Andon

View File

@ -0,0 +1,288 @@
<template>
<div>
<el-form :model="queryParams" label-position="right" inline ref="queryRef" v-show="showSearch" @submit.prevent>
<el-form-item label="月份">
<el-date-picker :clearable="false" v-model="queryParams.month" type="month" placeholder="选择月份"> </el-date-picker>
</el-form-item>
<el-form-item>
<el-button icon="search" type="primary" @click="handleQuery">{{ $t('btn.search') }}</el-button>
<el-button icon="refresh" @click="resetQuery">{{ $t('btn.reset') }}</el-button>
</el-form-item>
</el-form>
<!-- 工具区域 -->
<el-row :gutter="15" class="mb10">
<el-col :span="1.5">
<el-button type="primary" v-hasPermi="['sitesafegreencross:add']" plain icon="plus" @click="handleAdd">
{{ $t('btn.add') }}
</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row>
<el-table
:data="dataList"
v-loading="loading"
ref="table"
border
header-cell-class-name="el-table-header-cell"
highlight-current-row
@sort-change="sortChange">
<el-table-column prop="safeDate" label="安全日期" align="center" />
<el-table-column label="安全状态" align="center">
<template #default="scope">
<el-tag :type="getTagType(scope.row.safeNum)" :closable="false">
{{ getSafeStatusText(scope.row.safeNum) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="160">
<template #default="scope">
<el-button
type="success"
size="small"
icon="edit"
title="编辑"
v-hasPermi="['sitesafegreencross:edit']"
@click="handleUpdate(scope.row)"></el-button>
<el-button
type="danger"
size="small"
icon="delete"
title="删除"
v-hasPermi="['sitesafegreencross:delete']"
@click="handleDelete(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<el-dialog :title="title" :lock-scroll="false" v-model="open" modal-append-to-body :close-on-click-modal="false">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-row :gutter="20">
<el-col :lg="12">
<el-form-item label="安全日期" prop="safeDate">
<el-date-picker :clearable="false" v-model="form.safeDate" type="date" placeholder="选择日期" value-format="YYYY-MM-DD 00:00:00">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="安全状态" prop="safeNum">
<el-radio-group v-model="form.safeNum">
<el-radio :value="1">绿色安全</el-radio>
<el-radio :value="2">黄色轻微事故</el-radio>
<el-radio :value="3">红色重大事故</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer v-if="opertype != 3">
<el-button text @click="cancel">{{ $t('btn.cancel') }}</el-button>
<el-button type="primary" @click="submitForm">{{ $t('btn.submit') }}</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup name="sitesafegreencross">
import {
listSiteSafeGreenCross,
addSiteSafeGreenCross,
delSiteSafeGreenCross,
updateSiteSafeGreenCross,
getSiteSafeGreenCross
} from '@/api/andonManagement/sitesafegreencross.js'
import { getCurrentInstance, ref, reactive, toRefs } from 'vue'
import dayjs from 'dayjs'
const { proxy } = getCurrentInstance()
const ids = ref([])
const loading = ref(false)
const showSearch = ref(true)
const queryParams = reactive({
pageNum: 1,
pageSize: 50,
sort: '',
sortType: 'asc',
month: dayjs().format('YYYY-MM')
})
const columns = ref([])
const total = ref(0)
const dataList = ref([])
const queryRef = ref()
const defaultTime = ref([new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)])
var dictParams = []
function getList() {
loading.value = true
listSiteSafeGreenCross(queryParams).then((res) => {
const { code, data } = res
if (code == 200) {
dataList.value = data.result
total.value = data.totalNum
loading.value = false
}
})
}
//
function handleQuery() {
queryParams.pageNum = 1
getList()
}
//
function resetQuery() {
proxy.resetForm('queryRef')
queryParams.month = dayjs().format('YYYY-MM')
handleQuery()
}
//
function sortChange(column) {
var sort = undefined
var sortType = undefined
if (column.prop != null && column.order != null) {
sort = column.prop
sortType = column.order
}
queryParams.sort = sort
queryParams.sortType = sortType
handleQuery()
}
/*************** form操作 ***************/
const formRef = ref()
const title = ref('')
// 1add 2edit 3view
const opertype = ref(0)
const open = ref(false)
const state = reactive({
single: true,
multiple: true,
form: {
safeDate: dayjs().format('YYYY-MM-DD 00:00:00'),
safeNum: 1
},
rules: {
safeDate: [{ required: true, message: '安全日期不能为空', trigger: 'blur' }],
safeNum: [{ required: true, message: '安全状态不能为空', trigger: 'change' }]
},
options: {}
})
const { form, rules, options, single, multiple } = toRefs(state)
// dialog
function cancel() {
open.value = false
reset()
}
//
function reset() {
form.value = {
safeDate: dayjs().format('YYYY-MM-DD 00:00:00'),
safeNum: 1
}
proxy.resetForm('formRef')
}
//
function handleAdd() {
reset()
open.value = true
title.value = '添加现场安全绿色十字架'
opertype.value = 1
}
//
function handleUpdate(row) {
reset()
const id = row.id || ids.value
getSiteSafeGreenCross(id).then((res) => {
const { code, data } = res
if (code == 200) {
open.value = true
title.value = '修改现场安全绿色十字架'
opertype.value = 2
form.value = {
safeDate: data.safeDate,
safeNum: data.safeNum
}
}
})
}
// &
function submitForm() {
proxy.$refs['formRef'].validate((valid) => {
if (valid) {
if (form.value.id != undefined && opertype.value === 2) {
updateSiteSafeGreenCross(form.value).then((res) => {
proxy.$modal.msgSuccess('修改成功')
open.value = false
getList()
})
} else {
addSiteSafeGreenCross(form.value).then((res) => {
proxy.$modal.msgSuccess('新增成功')
open.value = false
getList()
})
}
}
})
}
//
function handleDelete(row) {
const Ids = row.id || ids.value
proxy
.$confirm('是否确认删除参数编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: proxy.$t('common.ok'),
cancelButtonText: proxy.$t('common.cancel'),
type: 'warning'
})
.then(function () {
return delSiteSafeGreenCross(Ids)
})
.then(() => {
getList()
proxy.$modal.msgSuccess('删除成功')
})
}
// tag
function getTagType(safeNum) {
switch (safeNum) {
case 1:
return 'success'
case 2:
return 'warning'
case 3:
return 'danger'
default:
return 'info'
}
}
//
function getSafeStatusText(safeNum) {
switch (safeNum) {
case 1:
return '绿色安全'
case 2:
return '黄色轻微事故'
case 3:
return '红色重大事故'
default:
return '未知状态'
}
}
handleQuery()
</script>