junhong 1 week ago
parent 7c24f565a2
commit 819b633897
  1. BIN
      public/favicon.ico
  2. BIN
      src/assets/images/fh.png
  3. 11
      src/components/prompt/api.js
  4. 121
      src/components/prompt/index.vue
  5. 2
      src/layout/index.vue
  6. 20
      src/main.js
  7. 22
      src/router/routes.js
  8. 17
      src/views/constructionScheduling/production-plan/index.vue
  9. 28
      src/views/constructionScheduling/production-plan/options.js
  10. 74
      src/views/constructionScheduling/progress-alert/api.js
  11. 79
      src/views/constructionScheduling/progress-alert/index.vue
  12. 27
      src/views/constructionScheduling/progress-alert/options.js
  13. 66
      src/views/constructionScheduling/progress-monitoring/api.js
  14. 123
      src/views/constructionScheduling/progress-monitoring/echartsOptions.js
  15. 130
      src/views/constructionScheduling/progress-monitoring/index.vue
  16. 94
      src/views/constructionScheduling/progress-monitoring/options.js
  17. 75
      src/views/constructionScheduling/progress-tracking/index.vue
  18. 110
      src/views/constructionScheduling/progress-tracking/options.js
  19. 34
      src/views/large-screen/api.js
  20. 20
      src/views/large-screen/echartsOptions.js
  21. 266
      src/views/large-screen/index.vue

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

@ -0,0 +1,11 @@
import axios from '@/utils/request'
// 查询分页数据:
export const iengineerlogList = (arg) => {
return axios.request({
url: '/iproductionplan/querywarn',
method: 'get',
params: arg,
dataType: 'json',
})
}

@ -0,0 +1,121 @@
<template>
<div>
</div>
</template>
<script setup>
import {
iengineerlogList
} from "./api";
import { ElNotification } from "element-plus";
const { proxy } = getCurrentInstance();
const notify = ref({});
const router = useRouter();
const state = reactive({
show: false,
arr: [],
});
onMounted(() => {
proxy.$getsystemdict('purpose_expenses').then((res) => {
if (res.length > 0) {
iengineerlogList({ day: res[0].value }).then((res) => {
if (res.code == 200) {
res.data.slice(0, 3).map((item) => {
setTimeout(() => {
notify.value[item.id] = ElNotification({
title: "进度预警提示",
zIndex: 999999999999,
duration: 0,
position: "bottom-right",
// message: ' ' + item.name + '' + item.endTime + '',
message: h("div", [
h(
"p",
{},
"有" +
item.planName +
"的计划已滞后"+"需要您查看。"
),
h(
"p",
{
style: "display: flex;justify-content: space-between;",
},
[
h(
"div",
{
style:
"color: #409EFF;cursor: pointer;text-align: right;margin-top: 10px;",
onClick: function () {
router.push({
path:"/constructionScheduling/progressAlert"
})
},
},
// ""
"去查看"
),
]
),
]),
type: "warning",
});
}, 10);
})
}
})
}
})
});
const change = (item) => {
let formData = new FormData();
formData.append("id", item.id);
formData.append("status", 0);
let filenull = new File([""], "", { type: "" });
formData.append("file", filenull);
edit(formData).then((res) => {
if (res.code == 200) {
notify.value[item.id].close();
}
});
};
</script>
<style lang="scss" scoped>
.tisheader {
padding: 0 0.625rem;
padding-top: 0.625rem;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #ebeef5;
padding-bottom: 10px;
}
.shenpibtn {
margin-top: auto;
margin-left: auto;
margin-bottom: 10px;
}
.tixnigbox {
display: flex;
flex-direction: column;
width: 18.75rem;
height: 18.75rem;
height: 0;
background: #fff;
border-top-left-radius: 0.5rem;
position: fixed;
right: 0;
bottom: 0;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
transition: all 0.5s;
z-index: 999;
}
</style>

@ -6,10 +6,12 @@
<template v-else>
<LeftRight></LeftRight>
</template>
<promptfrom></promptfrom>
</div>
</template>
<script setup>
import promptfrom from "../components/prompt/index";
import useSettingsStore from '@/store/modules/settings'
import LeftRight from './components/LeftRight.vue'
import UpDown from './components/UpDown.vue'

@ -94,7 +94,7 @@ app.use(router)
app.use(store)
app.use(elementIcons)
app.use(plugins)
app.use(vue3SeamlessScroll)
//=======================================================
// 动态配置zbry初始化内容
//=======================================================
@ -143,6 +143,24 @@ app.config.globalProperties.$getsystemdict = async (key) => {
})
})
}
app.config.globalProperties.getNameById = function (tree, value, key) {
function findParentObject(treeArray, childId, key) {
for (const item of treeArray) {
if (item[key] == childId) {
return item;
}
if (item.children && item.children.length > 0) {
const parent = findParentObject(item.children, childId, key);
if (parent) {
return parent;
}
}
}
return "";
}
let str = findParentObject(tree, value, key)
return str
}
// app.config.globalProperties.$register = async () => {
// const ElementPlus = await import('element-plus');
// const locale = await import('element-plus/lib/locale/lang/zh-cn');

@ -25,17 +25,17 @@
// 注释“组件库”路由时,请保留数组,否则会导致路由无法正常加载
//===================================================================================
export default [
{
name: "Https://www.zilber.cn/doc/rp/",
path: "https://www.zilber.cn/doc/rp/",
hidden: false,
component: "Layout",
meta: {
title: "组件库",
icon: "guide",
link: "https://www.zilber.cn/doc/rp/"
}
},
// {
// name: "Https://www.zilber.cn/doc/rp/",
// path: "https://www.zilber.cn/doc/rp/",
// hidden: false,
// component: "Layout",
// meta: {
// title: "组件库",
// icon: "guide",
// link: "https://www.zilber.cn/doc/rp/"
// }
// },
{
name: "public",
path: "/public",

@ -44,7 +44,21 @@ const state = reactive({
})
},
beforeSubmit: function (params) {
function calculateDaysBetween(dateString1, dateString2) {
// Date
const date1 = new Date(dateString1);
const date2 = new Date(dateString2);
//
const timeDiff = Math.abs(date2.getTime() - date1.getTime());
// 1 = 24 × 60 × 60 × 1000
const daysDiff = Math.ceil(timeDiff / (1000 * 60 * 60 * 24));
return daysDiff;
}
if (!params.parentId) params.parentId = 0
params.duration = calculateDaysBetween(params.startTime, params.endTime);
return params
},
handleAdd: function (params) {
@ -101,7 +115,8 @@ function handAdd(item) {
<template #control="baseScope">
<el-table-column label="操作" align="center" width="200" fixed="right">
<template #default="scope">
<el-button v-if="scope.row.parentId==0" v-hasPermi="['productionPlan:page:add']" type="text" icon="Plus" @click="handAdd(scope.row)">
<el-button v-if="scope.row.parentId == 0" v-hasPermi="['productionPlan:page:add']" type="text" icon="Plus"
@click="handAdd(scope.row)">
新增
</el-button>
<el-button v-hasPermi="['productionPlan:page:edit']" type="text" icon="EditPen"

@ -92,20 +92,20 @@ export const baseModelOptions = () => {
placeholder: '请选择计划结束时间',
},
},
{
tag: 'el-input-number',
label: '总工期(天):',
key: 'duration',
value: 0,
default: 0,
rules: [
{ required: true, message: '请输入总工期(天)', trigger: 'blur' },
],
attribute: {//属性
min: 0,
placeholder: '请输入总工期(天)',
},
},
// {
// tag: 'el-input-number',
// label: '总工期(天):',
// key: 'duration',
// value: 0,
// default: 0,
// rules: [
// { required: true, message: '请输入总工期(天)', trigger: 'blur' },
// ],
// attribute: {//属性
// min: 0,
// placeholder: '请输入总工期(天)',
// },
// },
{
tag: "el-date-picker",
label: '关键节点时间:',

@ -0,0 +1,74 @@
import axios from '@/utils/request'
// 查询分页数据:
export const iwarnlist = (arg) => {
return axios.request({
url: '/iwarn/list',
method: 'get',
params: arg,
dataType: 'json',
})
}
export const iengineerlogList = (arg) => {
return axios.request({
url: '/iproductionplan/querywarn',
method: 'get',
params: arg,
dataType: 'json',
})
}
// 查询详情数据:
export const iengineerlogGetById = (arg) => {
return axios.request({
url: `/iengineerlog/getById`,
method: 'get',
params: arg,
dataType: 'json',
})
}
// 添加数据:
export const iengineerlogAdd = (arg) => {
return axios.request({
url: '/iengineerlog/add',
method: 'post',
data: arg,
dataType: 'json',
})
}
// 修改数据:
export const iengineerlogUpdate = (arg) => {
return axios.request({
url: '/iengineerlog/update',
method: 'put',
data: arg,
dataType: 'json',
})
}
// 删除数据:
export const iengineerlogDelete = (arg) => {
return axios.request({
url: '/iwarn/delete',
method: 'delete',
params: {
id:arg.id[0]
},
dataType: 'json',
})
}
// 查询分页数据:
export const iproductionplanList = (arg) => {
return axios.request({
url: '/iproductionplan/list',
method: 'get',
params: arg,
dataType: 'json',
})
}

@ -0,0 +1,79 @@
<script setup>
import { reactive } from 'vue'
import { iengineerlogList, iengineerlogAdd, iengineerlogUpdate, iengineerlogDelete, iengineerlogGetById, iproductionplanList, iwarnlist } from './api'
import { baseModelOptions, baseFilterOptions } from './options'
const { proxy } = getCurrentInstance();
const state = reactive({
baseModelOptions: baseModelOptions(),
baseFilterOptions: baseFilterOptions(),
title: "工程日志管理",
baseModelName: '工程日志信息',
addBtnName: '新增工程日志',
editBtnName: '',
delBtnName: '',
primaryKey: 'id',
getTableFn: iwarnlist,
addFn: iengineerlogAdd,
editFn: iengineerlogUpdate,
deleteFn: iengineerlogDelete,
detailFn: iengineerlogGetById,
showEditBtn: false,
showDeleteBtn: false,
showAddBtn: false,
columnCount: 1,
// rowControl: {
// showEditBtn: false,
// showDelBtn: false
// },
permission: {//
add: 'progressAlert:page:list',
edit: 'progressAlert:page:list',
delete: 'progressAlert:page:list',
detail: 'progressAlert:page:list',
},
// baseQuery: { day: "" },
hideselection: true,
pageInfo: { total: 0, base: { limit: 8, current: 1 } },
autoQuery: false,
})
const table = ref()
onMounted(async () => {
proxy.$getsystemdict('purpose_expenses').then(async (res) => {
if (res.length > 0) {
await iengineerlogList({ day: res[0].value })
const {
getTableData, //
} = table.value;
await getTableData();
}
})
})
</script>
<template>
<div class="app-container">
<BaseTablePage :tableOptions="state" ref="table">
<template v-slot:column>
<el-table-column type="index" align="center" label="序号" width="70" />
<el-table-column label="预警事件" align="center" prop="planName" />
<el-table-column label="预警时间" align="center" prop="createTime" />
</template>
<template #control="baseScope">
<el-table-column label="操作" align="center" width="200" fixed="right">
<template #default="scope">
<!-- <el-button v-hasPermi="['progressAlert:page:edit']" type="text" icon="EditPen"
@click="baseScope.handleEdit(scope.$index, scope.row)">
修改
</el-button> -->
<el-button v-hasPermi="['progressAlert:page:remove']" type="text" icon="Delete"
@click="baseScope.deleteTableData(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</template>
</BaseTablePage>
</div>
</template>
<style scoped></style>

@ -0,0 +1,27 @@
export const baseModelOptions = () => {
function validatePhoneNumber(phoneNumber) {
const regex = /^1[3-9]\d{9}$/;
return regex.test(phoneNumber);
}
const validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('请输入现场负责人联系方式'))
} else {
if (!validatePhoneNumber(value)) {
callback(new Error('手机号格式不正确'))
return
}
callback()
}
}
return [
]
}
export const baseFilterOptions = () => {
return [
]
}

@ -0,0 +1,66 @@
import axios from '@/utils/request'
// 查询分页数据:
export const iresourcescheduleList = (arg) => {
return axios.request({
url: '/iproductionplan/statistics',
method: 'get',
params: arg,
dataType: 'json',
})
}
// 查询详情数据:
export const iresourcescheduleGetById = (arg) => {
return axios.request({
url: `/iresourceschedule/getById`,
method: 'get',
params: arg,
dataType: 'json',
})
}
// 添加数据:
export const iresourcescheduleAdd = (arg) => {
return axios.request({
url: '/iresourceschedule/add',
method: 'post',
data: arg,
dataType: 'json',
})
}
// 修改数据:
export const iresourcescheduleUpdate = (arg) => {
return axios.request({
url: '/iresourceschedule/update',
method: 'put',
data: arg,
dataType: 'json',
})
}
// 删除数据:
export const iresourcescheduleDelete = (arg) => {
return axios.request({
url: '/iresourceschedule/delete',
method: 'delete',
params: {
id:arg.id[0]
},
dataType: 'json',
})
}
// 查询分页数据:
export const iproductionplanList = (arg) => {
return axios.request({
url: '/iproductionplan/list',
method: 'get',
params: arg,
dataType: 'json',
})
}

@ -0,0 +1,123 @@
import * as echarts from "echarts";
// import 'echarts-liquidfill/src/liquidFill.js'; //在这里引入
export function echartsZhe({ ydata2, ydata1, xdata }) {
let color = ['#027CFB', '#02FBD1', '#F1C342', '#10F3A4']
let server = [{
type: "line",
name: "计划进度",
symbolSize: 1,
animation: false,
itemStyle: {
normal: {
label: {
show: true,
textStyle: {
color: "#8a989f",
fontSize: 10,
},
position: "top",
},
color: color[0],
lineStyle: {
color: color[0],
width: 1,
},
},
},
data: ydata1 ? ydata1 : [],
}, {
type: "line",
symbolSize: 1,
name: "实际进度",
animation: false,
itemStyle: {
normal: {
label: {
show: true,
textStyle: {
color: "#8a989f",
fontSize: 10,
},
position: "top",
},
color: color[1],
lineStyle: {
color: color[1],
width: 1,
},
},
},
data: ydata2 ? ydata2 : [],
}]
return {
grid: {
left: "5%",
right: "12%",
top: "15%",
bottom: "10%",
},
legend: {
top: "0%",
y: "35",
textStyle: {
fontSize: 14,
},
data: xdata,
},
tooltip: {
trigger: "axis",
},
xAxis: [
{
type: "category",
boundaryGap: false,
axisLabel: {
color: "#8a989f",
formatter: function (value) {
// 使用正则表达式每10个字符换行
return value.replace(/^(.{10})/g, "$1\n");
},
},
axisLine: {
show: false,
lineStyle: {
color: "#E9EAED",
},
},
axisTick: {
show: true,
},
data: [1, 2, 3, 4],
},
],
yAxis: [
{
type: "value",
offset: 0,
axisLabel: {
formatter: "{value}",
marginBottom: 20,
textStyle: {
color: "#8a989f",
},
},
axisLine: {
lineStyle: {
color: "#E9EAED",
},
},
axisTick: {
show: false,
},
splitLine: {
show: true,
lineStyle: {
color: "#E9EAED",
},
},
},
],
series: server,
};
}

@ -0,0 +1,130 @@
<script setup>
import { reactive } from 'vue'
import { iresourcescheduleList, iresourcescheduleAdd, iresourcescheduleUpdate, iresourcescheduleDelete, iresourcescheduleGetById, iproductionplanList } from './api'
import { baseModelOptions, baseFilterOptions } from './options'
const { proxy } = getCurrentInstance();
import { echartsZhe } from './echartsOptions'
import { echart } from "../../../echarts";
const state = reactive({
echart,
echartsZhe,
baseModelOptions: baseModelOptions(),
baseFilterOptions: baseFilterOptions(),
title: "资源调度管理",
baseModelName: '资源调度信息',
addBtnName: '新增资源调度',
editBtnName: '',
delBtnName: '',
primaryKey: 'id',
getTableFn: iresourcescheduleList,
addFn: iresourcescheduleAdd,
editFn: iresourcescheduleUpdate,
deleteFn: iresourcescheduleDelete,
detailFn: iresourcescheduleGetById,
showEditBtn: false,
showDeleteBtn: false,
columnCount: 1,
permission: {//
add: 'progressMonitoring:page:list',
edit: 'progressMonitoring:page:list',
delete: 'progressMonitoring:page:list',
detail: 'progressMonitoring:page:list',
},
hideselection: true,
pageInfo: { total: 0, base: { limit: 7, current: 1 } },
planList: [],
tableData: [],
loading: false
})
const table = ref()
onMounted(async () => {
getList()
})
function getList(params) {
state.loading = true
iresourcescheduleList().then((res) => {
state.tableData = res.data.namelist
let ydata1 = []
let ydata2 = []
nextTick(() => {
res.data.namelist.map((item, index) => {
ydata1.push(res.data.actuallist[index])
ydata2.push(res.data.planlist[index])
state.echart({
id: 'staff' + index,
grid: state.echartsZhe({
ydata1: ydata1,
ydata2: ydata2,
xdata: res.data.namelist
}),
});
})
})
state.loading = false
})
}
</script>
<template>
<div class="app-container" element-loading-text="加载中请稍后..." v-loading="state.loading">
<el-empty style="margin: auto;" v-if="state.tableData.length == 0" description="暂无数据" />
<!-- <BaseFilter ref="filter" :filterOptions="state.baseFilterOptions" :showFilter="true" @doFilter="doFilter">
</BaseFilter> -->
<div class="dispatch-box" ref="table">
<div class="dispatch-item" v-for="item, index in state.tableData">
<div>{{ item }}</div>
<div class="echarts" :id="'staff' + index"></div>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.echarts {
height: calc(100% - 50px);
width: 100%;
}
:deep(.jd .el-progress__text) {
/* color: #fff !important; */
min-width: 30px !important;
}
.suggestion {
background: #ECF2FE;
border-radius: 10px 10px 10px 10px;
padding: 14px;
margin-top: 8px;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 14px;
color: #027CFB;
width: 100%;
}
.dispatch-item {
background: #FFFFFF;
border-radius: 10px 10px 10px 10px;
padding: 24px;
padding-bottom: 0;
height: 341px;
width: 100%;
}
.dispatch-box {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 23px;
// max-height: calc(100% - 150px);
overflow: auto;
/* 子元素超出宽度时换行 */
}
.app-container {}
</style>

@ -0,0 +1,94 @@
export const baseModelOptions = () => {
return [
{
tag: 'BaseSelect',
label: '计划名称:',
key: 'planId',
value: '',
default: '',
rules: [
{ required: true, message: '请选择计划名称', trigger: 'blur' },
],
attribute: { //属性
placeholder: '请选择计划名称',
options: []
},
},
{
tag: 'el-input-number',
label: '当前进度:',
key: 'currentProgress',
value: 0,
default: 0,
rules: [
{ required: true, message: '请输入当前进度', trigger: 'blur' },
],
attribute: {//属性
min: 0,
max: 100,
placeholder: '请输入当前进度',
},
},
{
tag: "el-date-picker",
label: '计划开始时间:',
key: 'startTime',
value: '',
default: '',
rules: [
{ required: true, message: '请选择计划开始时间', trigger: 'blur' },
],
attribute: {//属性
valueFormat: "YYYY-MM-DD",
type: "date",
placeholder: '请选择计划开始时间',
},
},
{
tag: "el-date-picker",
label: '计划结束时间:',
key: 'endTime',
value: '',
default: '',
rules: [
{ required: true, message: '请选择计划结束时间', trigger: 'blur' },
],
attribute: {//属性
valueFormat: "YYYY-MM-DD",
type: "date",
placeholder: '请选择计划结束时间',
},
},
{
tag: 'el-input',
label: '调度建议:',
key: 'advises',
value: '',
default: '',
attribute: {//属性
type: 'textarea',
placeholder: '请输入调度建议',
},
},
]
}
export const baseFilterOptions = () => {
return [
{
tag: 'BaseSelect',
label: '计划名称:',
key: 'planId',
value: '',
default: '',
rules: [
{ required: true, message: '请选择计划名称', trigger: 'blur' },
],
attribute: { //属性
placeholder: '请选择计划名称',
options: []
},
},
]
}

@ -2,9 +2,13 @@
import { reactive } from 'vue'
import { iprogressList, iprogressAdd, iprogressUpdate, iprogressDelete, iprogressGetById, iproductionplanList } from './api'
import { baseModelOptions, baseFilterOptions } from './options'
const currentTime = new Date();
const year = currentTime.getFullYear();
const month = String(currentTime.getMonth() + 1).padStart(2, '0');
const day = String(currentTime.getDate()).padStart(2, '0');
const formattedTime = `${year}-${month}-${day}`;
const { proxy } = getCurrentInstance();
const table = ref()
const state = reactive({
baseModelOptions: baseModelOptions(),
baseFilterOptions: baseFilterOptions(),
@ -19,6 +23,7 @@ const state = reactive({
editFn: iprogressUpdate,
deleteFn: iprogressDelete,
detailFn: iprogressGetById,
rowKey: 'id',
showEditBtn: false,
showDeleteBtn: false,
columnCount: 1,
@ -34,24 +39,38 @@ const state = reactive({
},
hideselection: true,
pageInfo: { total: 0, base: { limit: 8, current: 1 } },
baseQuery: { processDate: formattedTime },
beforeSubmit: function (params) {
let item = state.planList.find((item) => item.id == params.planId)
if (item) {
params.planName = item.planName
}
let child = proxy.getNameById(state.planList, params.planId, 'id')
if (!params.parentId) params.parentId = 0
params.planName = child.planName
return params
},
planList: []
planList: [],
handleAdd: function (params) {
getPlanList().then(() => {
table.value.handleAdd()
})
},
beforeEdit: function (params) {
if (params.parentId == 0) params.parentId = ' '
return new Promise((resolve) => {
getPlanList().then(() => {
resolve(params)
})
})
},
})
onMounted(() => {
getPlanList()
})
function getPlanList(params) {
iproductionplanList({ pageNo: 1, pageSize: 9999 }).then((res) => {
return new Promise(async (resolve) => {
await iproductionplanList({ pageNo: 1, pageSize: 9999 }).then((res) => {
if (res.code == 200) {
state.planList = res.data.list
state.baseModelOptions = proxy.$util.setOptions({
attrName: 'options',//
attrName: 'data',//
data: state.baseModelOptions, //
key: "planId", //key
res: res, //
@ -61,7 +80,7 @@ function getPlanList(params) {
hasChildren: true,
});
state.baseFilterOptions = proxy.$util.setOptions({
attrName: 'options',//
attrName: 'data',//
data: state.baseFilterOptions, //
key: "planId", //key
res: res, //
@ -72,14 +91,38 @@ function getPlanList(params) {
});
}
})
await iprogressList({ pageNo: 1, pageSize: 9999 }).then((res) => {
if (res.code == 200) {
state.baseModelOptions = proxy.$util.setOptions({
attrName: 'data',//
data: state.baseModelOptions, //
key: "parentId", //key
res: res, //
path: res.data.list,
relation: { key: 'value', name: 'label', resKey: 'id', resName: 'planName' },
everClear: true,
hasChildren: true,
});
}
})
resolve(params)
})
}
function handAdd(item) {
state.handleAdd()
nextTick(() => {
table.value.modelRef.setValueByKey('parentId', item.id)
})
}
</script>
<template>
<div class="app-container">
<BaseTablePage :tableOptions="state">
<BaseTablePage :tableOptions="state" ref="table">
<template v-slot:column>
<el-table-column label="项目名称" align="center" prop="planName" />
<el-table-column label="计划名称" align="center" prop="planName" />
<el-table-column label="日期" align="center" prop="processDate" />
<el-table-column label="当日完成进度 " align="center" prop="dayProgress">
<template #default="scope">
<el-progress :stroke-width="6" :percentage="Number(scope.row.dayProgress)" />
@ -90,12 +133,16 @@ function getPlanList(params) {
<el-progress :stroke-width="6" :percentage="Number(scope.row.accumulativeProgress)" />
</template>
</el-table-column>
<el-table-column label="创建人" align="center" prop="creator" />
<el-table-column label="创建时间" align="center" prop="createTime" />
<!-- <el-table-column label="创建人" align="center" prop="creator" /> -->
<!-- <el-table-column label="创建时间" align="center" prop="createTime" /> -->
</template>
<template #control="baseScope">
<el-table-column label="操作" align="center" width="200" fixed="right">
<template #default="scope">
<el-button v-if="scope.row.parentId == 0" v-hasPermi="['progressTracking:page:add']" type="text" icon="Plus"
@click="handAdd(scope.row)">
新增
</el-button>
<el-button v-hasPermi="['progressTracking:page:edit']" type="text" icon="EditPen"
@click="baseScope.handleEdit(scope.$index, scope.row)">
修改

@ -1,17 +1,59 @@
export const baseModelOptions = () => {
return [
{
tag: 'BaseSelect',
label: '项目名称:',
tag: 'el-tree-select',
label: '上级进度:',
key: 'parentId',
value: '',
default: '',
// rules: [
// { required: true, message: '请选择计划名称', trigger: 'blur' },
// ],
attribute: { //属性
clearable: true,
filterable: true,
placeholder: '请选择上级进度',
'render-after-expand': true,
checkStrictly: true,
data: []
},
},
{
tag: 'el-tree-select',
label: '计划名称:',
key: 'planId',
value: '',
default: '',
rules: [
{ required: true, message: '请选择项目名称', trigger: 'blur' },
{ required: true, message: '请选择计划名称', trigger: 'blur' },
],
attribute: { //属性
placeholder: '请选择项目名称',
options: []
clearable: true,
filterable: true,
placeholder: '请选择计划名称',
'render-after-expand': true,
checkStrictly: true,
data: []
},
},
{
tag: "el-date-picker",
label: '日期:',
key: 'processDate',
value: "",
default: "",
rules: [
{
required: true,
message: "请选择日期",
trigger: "blur",
},
],
attribute: {
//属性
placeholder: "请选择日期",
valueFormat: "YYYY-MM-DD",
type: "date",
},
},
{
@ -29,26 +71,68 @@ export const baseModelOptions = () => {
placeholder: '请输入当日完成进度',
},
},
{
tag: 'el-input-number',
label: '累计完成进度:',
key: 'accumulativeProgress',
value: 0,
default: 0,
rules: [
{ required: true, message: '请输入累计完成进度', trigger: 'blur' },
],
attribute: {//属性
min: 0,
max: 100,
placeholder: '请输入累计完成进度',
},
},
]
}
const currentTime = new Date();
const year = currentTime.getFullYear();
const month = String(currentTime.getMonth() + 1).padStart(2, '0');
const day = String(currentTime.getDate()).padStart(2, '0');
const formattedTime = `${year}-${month}-${day}`;
export const baseFilterOptions = () => {
return [
{
tag: 'BaseSelect',
label: '项目名称:',
tag: "el-date-picker",
label: '日期:',
key: 'processDate',
value: formattedTime,
default: formattedTime,
rules: [
{
required: true,
message: "请选择日期",
trigger: "blur",
},
],
attribute: {
//属性
placeholder: "请选择日期",
valueFormat: "YYYY-MM-DD",
type: "date",
},
},
{
tag: 'el-tree-select',
label: '计划名称:',
key: 'planId',
value: '',
default: '',
rules: [
{ required: true, message: '请选择项目名称', trigger: 'blur' },
{ required: true, message: '请选择计划名称', trigger: 'blur' },
],
attribute: { //属性
placeholder: '请选择项目名称',
options: []
clearable: true,
filterable: true,
placeholder: '请选择计划名称',
'render-after-expand': true,
checkStrictly: true,
data: []
},
},
]
}

@ -51,3 +51,37 @@ export const iresourcescheduleList = (arg) => {
dataType: 'json'
})
}
// 设备统计
export const vehiclestat = (arg) => {
return axios.request({
url: '/vehicle/stat',
method: 'get',
params: arg,
dataType: 'json'
})
}
// 进度监控
export const statistics = (arg) => {
return axios.request({
url: '/iproductionplan/bigscreenProgress',
method: 'get',
params: arg,
dataType: 'json'
})
}
export const dataOverview = (arg) => {
return axios.request({
url: '/iproductionplan/dataOverview',
method: 'get',
params: arg,
dataType: 'json'
})
}
export const iwarnlist = (arg) => {
return axios.request({
url: 'iwarn/list',
method: 'get',
params: arg,
dataType: 'json'
})
}

@ -1,15 +1,15 @@
import * as echarts from "echarts";
// import 'echarts-liquidfill/src/liquidFill.js'; //在这里引入
export function echartsBing({ }) {
export function echartsBing({ data, total }) {
return {
color: ['#fff17d', '#23BDF9'],
// 图表标题
title: {
text: '总数',
subtext: 15,
text: '总数:' + (total ? total : 0),
// subtext: '总数',
textStyle: {
color: '#fff',
fontSize: 14,
fontSize: 16,
align: 'center'
},
subtextStyle: {
@ -18,8 +18,8 @@ export function echartsBing({ }) {
align: 'center',
verticalAlign: 'center' // 副标题垂直居中
},
left: '25%', // 整体标题水平居中放置,这里用center替代x属性
top: '48%' // 整体标题垂直居中放置,这里用top替代y属性
left: '23%', // 整体标题水平居中放置,这里用center替代x属性
top: '54%' // 整体标题垂直居中放置,这里用top替代y属性
},
// 图例
legend: [{
@ -57,7 +57,7 @@ export function echartsBing({ }) {
avoidLabelOverlap: false,
label: {
normal: {
formatter:function (params) {
formatter: function (params) {
return params.percent + '%'
},
fontSize: 12,
@ -70,10 +70,7 @@ export function echartsBing({ }) {
labelLine: {
show: false
},
data: [
{ value: 75, name: '施工机械数' },
{ value: 25, name: '运输车辆数' }
]
data: data ? data : []
}]
}
}
@ -88,7 +85,6 @@ export function echartsZhu({
// 设置折线颜色
// color:['linear-gradient( 90deg, rgba(10,254,239,0) 0%, #0AFEEF 100%'],
xAxis: {
// 类目
type: 'category',
data: xdata ? xdata : [],

@ -4,20 +4,21 @@
<div class="gradient">
智慧工地数据大屏
</div>
<div class="xitong" @click="Jump()"></div>
</div>
<div class="main-box">
<div class="top-box">
<!-- 项目介绍 -->
<div class="top-item">
<div class="boxtitle">项目介绍</div>
<div class="boxcontent" style="display: flex;flex-direction: column;padding: 15px 20px;">
<div class="displaybox" style="margin-bottom: 10px;">
<div class="boxcontent" style="display: flex;flex-direction: column;padding: .9375rem 1.25rem;">
<div class="displaybox" style="margin-bottom: .625rem;">
<div class="diamond"></div>项目名称 新火工区建设项目
</div>
<div class="displaybox" style="margin-bottom: 12px;">
<div class="displaybox" style="margin-bottom: .75rem;">
<div class="diamond" style="background-color: #FFAE3C;"></div>工地负责人周运来
</div>
<div class="chaochu" style="flex: 1;font-size: 13px;">
<div class="chaochu" style="flex: 1;font-size: .8125rem;">
项目简介本项目拟新建单体包括一期5305#5601#5806#5826#5827#7310#等6栋单体建筑二期5602#5606#5607#5606#5609#5610#5701#5801#5801-1#5802#5802-1#5803#5805#5807#5808#5810#5810-1#5811#5811-1#5812#5813#5815#5816#5816-1#5817#5818#5821#5822#5828#5829#5830#5831#5909#等34栋单体建筑建筑物基础形式为杯形基础独立基础条形基础主体结构为框架结构排架结构抗爆间室屏院墙体为钢筋混凝土剪力墙结构
</div>
</div>
@ -28,25 +29,25 @@
<div class="boxcontent">
<div class="overview-top">
<div class="data-font">
<span class="number-font">105<span></span></span>
<span class="number-font">{{ state.gk.list }} <span></span></span>
<span>总工期</span>
</div>
<div class="data-font jbborder">
<span class="number-font">105<span>%</span></span>
<span class="number-font">{{ parseFloat(state.gk.gcjd).toFixed(0) }}<span>%</span></span>
<span>工程进度</span>
</div>
<div class="data-font jbborder">
<span class="number-font">105<span></span></span>
<span class="number-font">{{ state.gk.ysg }}<span></span></span>
<span>已施工</span>
</div>
</div>
<div class="overview-top" style="grid-template-columns: repeat(2, 1fr);border-bottom: 0;">
<div class="data-font ">
<span class="number-font">5<span></span></span>
<span class="number-font">{{ state.gk.sg }}<span></span></span>
<span>施工人员</span>
</div>
<div class="data-font jbborder">
<span class="number-font">5<span></span></span>
<span class="number-font">{{ state.gk.gl }}<span></span></span>
<span>管理人员</span>
</div>
</div>
@ -57,18 +58,18 @@
<div class="boxtitle">智能资源调度</div>
<div class="boxcontent" style="display: flex;flex-direction: column;justify-content: space-around;">
<div v-if="state.dispatchList.length == 0">
<el-empty :image-size="100" description="暂无预警" />
<el-empty :image-size="'6.25rem'" description="暂无预警" />
</div>
<div v-for="item, index in state.dispatchList.slice(0, 2)">
<div class="jd-title">
<span style="margin-right: auto;">{{ item.planName }}</span>
<div>
<span>进度</span>
<span style="margin-left: 10px;font-weight: bold;">{{ item.currentProgress
<span style="margin-left: .625rem;font-weight: bold;">{{ item.currentProgress
}}%</span>
</div>
</div>
<div style="width: 100%;margin: 8px 0;"><el-progress class="jdt" color="#1FFFDA"
<div style="width: 100%;margin: .5rem 0;"><el-progress class="jdt" color="#1FFFDA"
:text-inside="true" :stroke-width="12" :percentage="Number(item.currentProgress)">
<span></span>
</el-progress></div>
@ -83,7 +84,7 @@
<div class="top-item">
<div class="boxtitle">工程日志</div>
<div class="boxcontent"
style="display: flex;flex-direction: column;justify-content: space-around;padding: 15px 20px;">
style="display: flex;flex-direction: column;justify-content: space-around;padding: .9375rem 1.25rem;">
<div class="log-top">
<div class="tq-box">
<img src="../../assets/images/riqi.png" alt="">
@ -133,7 +134,7 @@
<el-tooltip v-if="state.logList && state.logList.length > 0"
class="box-item" effect="dark"
:content="state.logList[0].constructionSituation" placement="top">
<div style="width: 160px;" class="chaochutwo">
<div style="width: 10rem;" class="chaochutwo">
{{ state.logList[0].constructionSituation }}</div>
</el-tooltip>
<span v-else>-</span>
@ -154,10 +155,10 @@
<el-empty :image-size="100" description="暂无预警" />
</div>
<div v-else class="boxcontent"
style="display: grid;grid-template-columns: 1fr 1fr ;grid-gap: 12px;padding: 25px 21px;">
style="display: grid;grid-template-columns: 1fr 1fr ;grid-gap: .75rem;padding: 1.5625rem 1.3125rem;">
<div class="yj-box" v-for="item, index in state.warnList.slice(0, 2)" :key="index">
<img class="jgbj" src="../../assets/images/jglv.png" alt="">
<div style="text-align: center;font-size: 14px;">{{ item.planName }}</div>
<div style="text-align: center;font-size: .875rem;">{{ item.planName }}</div>
<div>开始时间{{ item.startTime }}</div>
<div>计划结束时间{{ item.endTime }}</div>
<div style="display: flex;align-items: center;">当前进度<div style="flex: 1;"> <el-progress
@ -165,7 +166,7 @@
</el-progress>
</div>
</div>
<div>备注{{ item.description }}</div>
<div>预警信息{{ item.warnInfo?item.warnInfo:'-' }}</div>
</div>
</div>
</div>
@ -173,11 +174,11 @@
<div class="top-item" style="overflow: hidden;">
<div class="boxtitle">进度监控</div>
<div class="center-item">
<div class="alarm-table-header" style=" grid-template-columns: 1.5fr 2fr 3fr 2.5fr;">
<div class="alarm-table-header" style=" grid-template-columns: 1.5fr 2.5fr 3fr 2.5fr;">
<div>序号</div>
<div>任务</div>
<div>时间</div>
<div>进度状态</div>
<div>累计进度</div>
</div>
<div class="scooll-box" ref="monitor">
<vue3-seamless-scroll style="height: 100%;overflow: hidden;" :scrollbar="{
@ -186,14 +187,14 @@
}" :list="state.monitorList" :hoverStop="true" :hover="true" :step="0.3">
<div v-for="item, index in state.monitorList" :key="index"
:class="index % 2 != 0 ? 'dark' : 'light'" class="table-item"
style=" grid-template-columns: 1.5fr 2fr 3fr 2.5fr;">
style=" grid-template-columns: 1.5fr 2.5fr 3fr 2.5fr;">
<div>{{ index + 1 }}</div>
<div>
{{ 2 }}
{{ item.planName }}
</div>
<div>{{ 3 }}</div>
<div>{{ item.keystageTime }}</div>
<div>
{{ 4 }}
{{ item.accumulativeProgress ? item.accumulativeProgress : 0 }}%
</div>
</div>
<div class="zanwu" v-if="state.monitorList.length == 0">
@ -272,9 +273,10 @@ import { ref, onMounted, reactive, nextTick } from 'vue'
import { echartsZhu, echartsBing } from "./echartsOptions";
import { echart } from "../../echarts";
import { stausList } from './options'
import { getRecordPage, iengineerlogList, querywarn, iuserworkerType, iresourcescheduleList } from './api'
import { getRecordPage, iengineerlogList, querywarn, iuserworkerType, iresourcescheduleList, vehiclestat, statistics, dataOverview, iwarnlist } from './api'
const { proxy } = getCurrentInstance();
const tableTrue = ref(false);
const router = useRouter();
const state = reactive({
echartsBing,
echartsZhu,
@ -285,18 +287,66 @@ const state = reactive({
monitorList: [],
logList: [],
dispatchList: [],
gk: {
"sg": 0,
"gl": 0,
"list": 0,
"ysg": 0,
gcjd: ""
}
})
onMounted(async () => {
await getDataOverview()
await getIresourceschedule()
await getIuserworkerType()
await engineeringLog()
await getQuerywarn()
await accessControl()
await getEcharts()
await getStatistics()
// await getVehiclestat()
// await accessControl()
state.loading = false
})
const scrollContainer = ref()
function getIresourceschedule(params) {
function Jump() {
router.push({
path: "/constructionScheduling/productionPlan"
})
}
function getDataOverview(params) {
dataOverview().then((res) => {
if (res.code == 200) {
state.gk = res.data.data
}
})
}
//
function getStatistics() {
statistics().then((res) => {
if (res.code == 200) {
state.monitorList = res.data
}
})
}
function getVehiclestat() {
vehiclestat().then((res) => {
if (res.code == 200) {
nextTick(() => {
let car = state.echart({
id: 'car',
grid: state.echartsBing({
total: res.data.personal + res.data.aotomobile,
data: [
{ value: res.data.personal, name: '施工机械数' },
{ value: res.data.aotomobile, name: '运输车辆数' }
]
}),
});
})
}
})
}
function getIresourceschedule() {
iresourcescheduleList().then((res) => {
if (res.code == 200) {
state.dispatchList = res.data.list
@ -304,15 +354,15 @@ function getIresourceschedule(params) {
})
}
//
function getIuserworkerType(params) {
function getIuserworkerType() {
iuserworkerType().then((res) => {
if (res.code == 200) {
nextTick(() => {
let staff = state.echart({
state.echart({
id: 'staff',
grid: state.echartsZhu({
ydata: res.data.map(item => item.name),
xdata: res.data.map(item => item.value)
ydata: res.data.map(item => item.value),
xdata: res.data.map(item => item.name)
}),
});
})
@ -321,11 +371,12 @@ function getIuserworkerType(params) {
}
//
function getQuerywarn(params) {
proxy.$getsystemdict('purpose_expenses').then((res) => {
proxy.$getsystemdict('purpose_expenses').then(async (res) => {
if (res.length > 0) {
querywarn({ day: res[0].value }).then((res) => {
// await querywarn({ day: res[0].value })
await iwarnlist().then((res) => {
if (res.code == 200) {
state.warnList = res.data
state.warnList = res.data.list
}
})
}
@ -346,20 +397,20 @@ function engineeringLog(params) {
}
})
}
function getEcharts() {
nextTick(() => {
let car = state.echart({
id: 'car',
grid: state.echartsBing({
}),
});
})
}
</script>
<style scoped lang='scss'>
.xitong {
width: 7rem;
height: 2.5rem;
position: absolute;
left: 1.875rem;
top: 5.625rem;
background: url('../../assets/images/fh.png') no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
.chaochutwo {
white-space: nowrap;
/* 不换行 */
@ -369,40 +420,40 @@ function getEcharts() {
}
.jgbj {
width: 36px;
height: 36px;
width: 2.25rem;
height: 2.25rem;
position: absolute;
left: 14px;
top: -12px;
left: .875rem;
top: -0.75rem;
}
:deep(.jd .el-progress__text) {
color: #fff !important;
min-width: 40px !important;
min-width: 2.5rem !important;
}
.yj-box {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 13px;
font-size: .8125rem;
color: #FFFFFF;
background: url('../../assets/images/yjbj.png') no-repeat;
background-size: 100% 100%;
display: flex;
padding: 0 8px;
padding: 0 .5rem;
flex-direction: column;
position: relative;
>div {
margin-top: 14px;
margin-top: .875rem;
}
}
.zanwu {
font-size: 14px;
font-size: .875rem;
text-align: center;
color: #fff;
padding: 10px;
padding: .625rem;
}
.table-item>div {
@ -410,7 +461,7 @@ function getEcharts() {
align-items: center;
height: 100%;
justify-content: center;
border-right: 1px solid #103B54;
border-right: .0625rem solid #103B54;
}
.table-item>div:last-child {
@ -422,27 +473,27 @@ function getEcharts() {
background: rgba(35, 92, 96, 0.6);
display: grid;
grid-template-columns: 1fr 1.5fr 2fr 4.5fr 2fr 3.5fr 2.5fr;
min-height: 32px;
min-height: 2rem;
font-weight: 400;
font-size: 14px;
font-size: .875rem;
color: #ffffff;
}
.scooll-box {
overflow: hidden;
width: 100%;
height: calc(100% - 32px);
height: calc(100% - 2rem);
}
.alarm-table-header>div {
font-weight: 400;
font-size: 14px;
font-size: .875rem;
color: #ffffff;
display: flex;
align-items: center;
height: 100%;
justify-content: center;
border-right: 1px solid #103B54;
border-right: .0625rem solid #103B54;
}
.alarm-table-header>div:last-child {
@ -451,20 +502,20 @@ function getEcharts() {
.alarm-table-header {
width: 100%;
height: 32px;
height: 2rem;
background: rgba(50, 165, 210, 0.4);
display: grid;
grid-template-columns: 1fr 1.5fr 2fr 4.5fr 2fr 3.5fr 2.5fr;
}
.center-item {
height: calc(100% - 48px);
height: calc(100% - 3rem);
width: 100%;
margin-top: 8px;
margin-top: .5rem;
background: url('../../assets/images/cneterbj.png') no-repeat;
background-size: 100% 100%;
overflow: hidden;
padding: 25px;
padding: 1.5625rem;
}
.dark {
@ -479,7 +530,7 @@ function getEcharts() {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 20px;
grid-gap: 1.25rem;
}
.center-top-item {
@ -489,11 +540,11 @@ function getEcharts() {
.bottom-box {
width: 100%;
height: calc(66.66% - 20px);
margin-top: 20px;
height: calc(66.66% - 1.25rem);
margin-top: 1.25rem;
display: grid;
grid-template-columns: 1fr 2fr 1fr;
grid-gap: 20px;
grid-gap: 1.25rem;
overflow: hidden;
}
@ -501,7 +552,7 @@ function getEcharts() {
width: 100%;
border-collapse: collapse;
font-weight: 400;
font-size: 14px;
font-size: .875rem;
color: #FFFFFF;
background-color: #08223b;
/* 深蓝色背景,可根据实际需求调整颜色值 */
@ -509,17 +560,17 @@ function getEcharts() {
.construction-table th,
.construction-table td {
border: 1px solid #103B54;
border: .0625rem solid #103B54;
/* 蓝色边框,可根据实际需求调整颜色值 */
text-align: left;
padding: 8px 10px;
padding: .5rem .625rem;
}
.construction-table th {
background: rgba(50, 165, 210, 0.4);
font-weight: 400;
font-size: 14px;
font-size: .875rem;
color: #FFFFFF;
/* 表头背景色,可根据实际需求调整颜色值 */
}
@ -536,17 +587,17 @@ function getEcharts() {
align-items: center;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 14px;
font-size: .875rem;
color: #FFFFFF;
>img {
width: 24px;
height: 24px;
width: 1.5rem;
height: 1.5rem;
}
>span:nth-child(2) {
margin-top: 5px;
margin-bottom: 8px;
margin-top: .3125rem;
margin-bottom: .5rem;
}
}
@ -561,22 +612,22 @@ function getEcharts() {
justify-content: flex-end;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 14px;
font-size: .875rem;
color: #FFFFFF;
}
.jgbox {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 12px;
font-size: .75rem;
color: #FFFFFF;
display: flex;
align-items: center;
>img {
height: 20px;
width: 20px;
margin-right: 5px
height: 1.25rem;
width: 1.25rem;
margin-right: .3125rem
}
}
@ -589,13 +640,13 @@ function getEcharts() {
.overview-top {
display: grid;
grid-template-columns: repeat(3, 1fr);
border-bottom: 1px solid;
border-bottom: .0625rem solid;
border-image: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)) 1 1;
height: 50%;
}
.jbborder {
border-left: 1px solid transparent !important;
border-left: .0625rem solid transparent !important;
/* 必须设置边框宽度 */
border-image-source: linear-gradient(to bottom, transparent, white, transparent);
border-image-width: 1;
@ -607,7 +658,7 @@ function getEcharts() {
.data-font {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 14px;
font-size: .875rem;
color: #FFFFFF;
display: flex;
flex-direction: column;
@ -619,8 +670,8 @@ function getEcharts() {
.number-font {
font-family: DIN, DIN;
font-weight: 500;
font-size: 24px;
margin-bottom: 10px;
font-size: 1.5rem;
margin-bottom: .625rem;
color: #19F7FF;
}
@ -630,39 +681,39 @@ function getEcharts() {
}
.diamond {
width: 5px;
height: 5px;
width: .3125rem;
height: .3125rem;
background-color: #3CFFB1;
transform: rotate(45deg);
transform-origin: top left;
margin-right: 5px;
margin-right: .3125rem;
}
.boxcontent {
width: 100%;
height: calc(100% - 47px);
padding: 20px;
height: calc(100% - 2.9375rem);
padding: 1.25rem;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 14px;
font-size: .875rem;
background: url('../../assets/images/datacontentbj.png') no-repeat;
background-size: 100% 100%;
color: #FFFFFF;
margin-top: 7px;
margin-top: .4375rem;
}
.boxtitle {
width: 100%;
height: 40px;
height: 2.5rem;
background: url('../../assets/images/datatitle.png') no-repeat;
background-size: 100% 100%;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: bold;
font-size: 16px;
font-size: 1rem;
color: #FFFFFF;
display: flex;
align-items: center;
padding: 0 25px;
padding: 0 1.5625rem;
}
.top-item {
@ -675,27 +726,28 @@ function getEcharts() {
height: 33.33%;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 20px;
grid-gap: 1.25rem;
overflow: hidden;
}
.main-box {
width: 100%;
height: calc(100% - 158px);
padding: 0 37px;
padding-bottom: 28px;
height: calc(100% - 9.875rem);
padding: 0 1.875rem;
padding-bottom: 1.75rem;
}
.topheader {
width: 100%;
height: 158px;
height: 9.875rem;
background: url('../../assets/images/datatopbj.png') no-repeat;
background-size: 100% 100%;
display: flex;
justify-content: center;
font-weight: 400;
font-size: 52px;
padding-top: 20px;
font-size: 3.25rem;
padding-top: 1.25rem;
position: relative;
}
.gradient {
@ -708,6 +760,6 @@ function getEcharts() {
width: 100%;
height: 100vh;
background: #040614;
height: 1080px;
height: 67.5rem;
}
</style>
Loading…
Cancel
Save