修改生产模块页面,增加顶部标签,新建分包pages-production,将生产页面移动至分包下面。

下一步制作曲线页面,统计页面,继续做好设备,安防等页面。
This commit is contained in:
liaodeyun 2025-09-11 17:58:34 +08:00
parent adcdb86db7
commit 81a70dfee5
12 changed files with 2259 additions and 116 deletions

View File

@ -0,0 +1,274 @@
<route lang="json5" type="page">
{
layout: 'default',
style: {
navigationStyle: 'custom',
navigationBarTitleText: '历史数据',
},
}
</route>
<template>
<PageLayout navTitle="历史数据">
<view class="stats-container">
<uni-title v-if="type === 'trq'" :title="name.unit + '天然气---单位(万方)'" color="blue" type="h2"></uni-title>
<uni-title v-if="type === 'yy'" :title="name.dw + '原油---单位(吨)'" color="blue" type="h2"></uni-title>
</view>
<view class="dateSelect">
<cxc-szcx-dateRangeSelect :mode="'range'" v-model="dateRange"></cxc-szcx-dateRangeSelect>
</view>
<cxc-szcx-lineChart v-if="type === 'trq'" :dataList="dataList" x-field="rqDate" y-field="rq" legend-field="unit"
:reference-value="0"></cxc-szcx-lineChart>
<cxc-szcx-lineChart v-if="type === 'yy'" :dataList="dataList" x-field="scrq" y-field="rcwy" legend-field="dw"
:reference-value="0"></cxc-szcx-lineChart>
<view style="margin: 0 15px">
<view class="stats-container">
<view class="stats-item">最大值: {{ dataStats.max }}</view>
<view class="stats-item">最小值: {{ dataStats.min }}</view>
<view class="stats-item">平均值: {{ dataStats.average }}</view>
</view>
<wd-table :data="dataList" :height="800" v-if="type === 'trq'" :index="true">
<wd-table-col prop="unit" label="名称" :width="screenWidth / 3" align="center"></wd-table-col>
<wd-table-col prop="rqDate" label="日期" :width="screenWidth / 4" align="center"></wd-table-col>
<wd-table-col prop="rq" label="日气量" :width="screenWidth / 5" align="center"></wd-table-col>
</wd-table>
<wd-table :data="dataList" :height="800" v-if="type === 'yy'" :index="true">
<wd-table-col prop="dw" label="名称" :width="screenWidth / 3" align="center"></wd-table-col>
<wd-table-col prop="scrq" label="日期" :width="screenWidth / 4" align="center"></wd-table-col>
<wd-table-col prop="rcwy" label="日油量" :width="screenWidth / 5" align="center"></wd-table-col>
</wd-table>
</view>
</PageLayout>
</template>
<script setup>
import {
queryJinriShengchansj,
queryJinriYuanyouShengchansj
} from '@/api/production';
import {
formatDate,
getDateAfterDays,
getDateAfterMonths
} from '@/utils/dateTime';
const name = ref({});
const type = ref('');
const dateRange = ref([]);
const dataList = ref([]);
const endDate = ref('');
const startDate = ref('');
const dataStats = ref({
min: 0,
max: 0,
avg: 0
});
const screenWidth = ref(0)
const calculateTableHeight = () => {
const systemInfo = uni.getSystemInfoSync();
screenWidth.value = systemInfo.screenWidth;
}
const getJinriShengchansj = (tempDateRange) => {
// console.log(tempDateRange);
//
if (!tempDateRange || tempDateRange.some((date) => !convertToDate(date))) {
console.error('收到无效日期范围:', tempDateRange);
return;
}
let queryParms = {};
dataList.value = [];
queryParms.gas = name.value.gas;
queryParms.unit = name.value.unit;
queryParms.rqDate_begin = formatDate(tempDateRange[0]);
queryParms.rqDate_end = formatDate(tempDateRange[1]);
queryParms.pageSize = 500;
//
if (!queryParms.rqDate_begin || !queryParms.rqDate_end) {
console.error('参数格式化失败:', queryParms);
return;
}
// console.log(queryParms);
queryJinriShengchansj(queryParms).then((res) => {
if (res.success) {
// console.log(res);
dataList.value = res.result.records;
dataStats.value = calculateStats(dataList.value, 'rq');
}
});
};
const getJinriYuanyouShengchansj = (tempDateRange) => {
console.log(tempDateRange);
//
if (!tempDateRange || tempDateRange.some((date) => !convertToDate(date))) {
console.error('收到无效日期范围:', tempDateRange);
return;
}
let queryParms = {};
dataList.value = [];
queryParms.dw = name.value.dw;
queryParms.scrq_begin = formatDate(tempDateRange[0]);
queryParms.scrq_end = formatDate(tempDateRange[1]);
queryParms.pageSize = 500;
//
if (!queryParms.scrq_begin || !queryParms.scrq_end) {
console.error('参数格式化失败:', queryParms);
return;
}
console.log(queryParms);
queryJinriYuanyouShengchansj(queryParms).then((res) => {
if (res.success) {
console.log(res);
dataList.value = res.result.records;
dataStats.value = calculateStats(dataList.value, 'rcwy').reverse();
}
});
};
function calculateStats(data, field) {
// field null undefined
const validData = data.filter((item) => item[field] !== null && item[field] !== undefined);
if (validData.length === 0) {
return {
max: null,
min: null,
average: null
};
}
//
let max = validData[0][field];
let min = validData[0][field];
let sum = 0;
//
for (let i = 0; i < validData.length; i++) {
const value = validData[i][field];
//
if (value > max) {
max = value;
}
//
if (value < min) {
min = value;
}
//
sum += value;
}
//
const average = (sum / validData.length).toFixed(4);
return {
max: max,
min: min,
average: average
};
}
function convertToDate(str) {
try {
const date = new Date(str);
//
if (isNaN(date.getTime())) {
return false;
}
return true;
} catch (error) {
return false;
//TODO handle the exception
}
}
//
watch(
[() => type.value, dateRange], // type dateRange
([newType, newDateRange]) => {
if (!newDateRange || !convertToDate(newDateRange[0]) || !convertToDate(newDateRange[1])) {
// console.error(':', newDateRange);
return;
}
// console.log(newType, newDateRange);
switch (
newType // 使 newType
) {
case 'trq':
getJinriShengchansj(newDateRange);
break;
case 'yy':
getJinriYuanyouShengchansj(newDateRange);
break;
default:
console.warn('未知类型:', newType);
}
}, {
immediate: true,
deep: true
}
);
onMounted(() => {
// nextTick();
// getJinriShengchansj(dateRange.value);
calculateTableHeight();
//
uni.onWindowResize(() => {
calculateTableHeight();
});
});
onLoad((options) => {
name.value = JSON.parse(options.data);
type.value = options.type;
// console.log(name.value, type.value);
const now = new Date();
if (now.getHours() < 11) {
endDate.value = getDateAfterDays(now, -1); //11
startDate.value = getDateAfterMonths(endDate.value, -1); //11
} else {
endDate.value = now;
startDate.value = getDateAfterMonths(endDate.value, -1); //11
}
dateRange.value = [startDate.value, endDate.value];
// console.log(1111, dateRange.value);
});
</script>
<style scoped>
.stats-container {
display: flex;
justify-content: space-around;
align-items: center;
text-align: center;
background-color: #f5f5f5;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding: 10px;
margin: 15 15px;
}
.dateSelect {
display: flex;
justify-content: space-around;
align-items: center;
text-align: center;
background-color: #f5f5f5;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding: 5px;
margin: 10px;
}
.stats-item {
font-size: 12px;
color: #00aa00;
font-weight: bold;
}
.stats-item+.stats-item {
border-left: 1px solid #ccc;
padding-left: 16px;
}
</style>

View File

@ -0,0 +1,633 @@
<template>
<view class="content">
<!-- 标题行 -->
<view class="header-row">
<view class="title">天然气产量</view>
<view class="more" @click="selectMore">更多>></view>
</view>
</view>
<view class="container">
<view v-for="(item, index) in shishiArrSelect" :key="index" class="card-item"
@click="handleCardClick(item.gas)">
<view class="card">
<text class="title">{{ item.gas }}</text>
<view class="content">
<text class="label">气量</text>
<text class="value">{{ formatNumber(item.dailyVolume) || '-' }}</text>
</view>
<view class="content">
<text class="label">年累计</text>
<text class="value">{{ formatNumber(item.yearVolume) || '-' }}</text>
</view>
<view class="progress-bar">
<!-- 动态设置宽度和颜色 -->
<view class="progress"
:style="{ width: `${Math.abs(item.yearPerCent)}%`, 'background-color': item.yearPerCent < 0 ? '#ff4444' : '#007aff' }">
</view>
<!-- 显示带符号的百分比 -->
<text v-if="!(item.yearPlan === '' || item.yearPlan === '0')"
class="progress-text">{{ item.yearPerCent }}%</text>
</view>
</view>
</view>
</view>
<wd-popup v-model="popupSelect" position="top" background-color="#fff">
<view style="margin-top: 50px">
<view class="titlepopup">选择显示更多生产数据</view>
<view class="popupBtn">
<button size="mini" @click="selectDefault" style="padding: 8px 16px;">默认</button>
<button size="mini" @click="selectAll" style="padding: 8px 16px;">全选</button>
<button size="mini" @click="selectNo" style="padding: 8px 16px;">全不选</button>
</view>
<view class="popupcheckbox">
<uni-data-checkbox style="font-size: 14px" @change="onselectionchange" :localdata="shishiArr"
v-model="shishiArrDisplay" multiple :map="{ value: 'gas', text: 'gas' }"></uni-data-checkbox>
</view>
</view>
</wd-popup>
<!-- 数据弹窗 -->
<wd-popup v-model="popup" position="bottom" closable custom-style="height: 400px;" @close="handleClose">
<wd-cell-group :title="tableTitle">
<wd-table :data="filteredData" :height="800">
<wd-table-col prop="unit" label="名称" :width="screenWidth * 57 / 140 " align="center"></wd-table-col>
<wd-table-col prop="rq" label="日气量" :width="screenWidth / 5" align="center"></wd-table-col>
<wd-table-col prop="yearVolume" label="年累计" :width="screenWidth / 4" align="center"></wd-table-col>
<wd-table-col prop="" label="操作" :width="screenWidth / 7" align="center">
<template #value="{row}">
<text style="color: red;" @click="goHistory(row)">历史</text>
</template>
</wd-table-col>
</wd-table>
</wd-cell-group>
</wd-popup>
</template>
<script setup>
import {
queryJinriShengchansj,
queryYearShengchansj,
queryJinriTrqShengchansj
} from '@/api/production';
import {
formatDate,
getDateAfterDays
} from '@/utils/dateTime';
const shishiArr = ref([]);
const shishiArrSelect = ref([]);
const shishiArrDisplay = ref(['气井气', '商品量', '站线综合输差']);
const dataJinriUnit = ref([]);
const tableTitle = ref('')
const filteredData = ref([]);
const popup = ref(false);
const popupSelect = ref(false);
const strDate = ref('');
const dataJinri = ref([]);
const dataJinriSum = ref([]);
const dataJinriSumUnit = ref([]);
const qjqNdjs = ref(7500);
const splNdjs = ref(7220);
const zhqNdjs = ref(300);
const zhscNdjs = ref(50);
const screenWidth = ref(0)
const handleClose = () => {
popup.value = false
}
//
// const handleCardClick = (gas) => {
// let queryParms = {};
// filteredData.value = [];
// queryParms.day = strDate.value;
// queryParms.gas = gas;
// queryParms.unit = '23,';
// console.log(queryParms);
// queryJinriTrqShengchansj(queryParms).then((res) => {
// if (res.success) {
// console.log(res);
// filteredData.value = res.result;
// }
// });
// popup.value.open();
// };
function selectMore() {
popupSelect.value = true
}
function selectAll() {
shishiArrDisplay.value = [];
// console.log(9, shishiArr.value)
shishiArr.value.forEach((item) => {
// console.log(10, item)
shishiArrDisplay.value.push(item.gas);
});
onselectionchange()
popup.value = false;
}
function selectNo() {
shishiArrDisplay.value = [];
onselectionchange()
popup.value = false;
}
function selectDefault() {
shishiArrDisplay.value = ['气井气', '商品量', '站线综合输差'];
onselectionchange()
popup.value = false;
}
const onselectionchange = () => {
shishiArrSelect.value = [];
shishiArrDisplay.value.forEach((item) => {
shishiArrSelect.value.push(shishiArr.value.filter((item1) => item1.gas === item)[0]);
});
};
const handleCardClick = (gas) => {
tableTitle.value = gas + '数据详情 单位(万立方米)'
filteredData.value = dataJinriSumUnit.value.filter((item) => item.gas === gas);
filteredData.value = filteredData.value.map(item => {
return {
...item,
rq: formatNumber(item.rq),
yearVolume: formatNumber(item.yearVolume)
}
})
popup.value = true;
};
//
const closePopup = () => {
popup.value = false;
};
const calculateTableHeight = () => {
const systemInfo = uni.getSystemInfoSync();
screenWidth.value = systemInfo.screenWidth;
}
onMounted(() => {
getJinriTrqShengchansj();
getJinriShengchansj();
calculateTableHeight();
//
uni.onWindowResize(() => {
calculateTableHeight();
});
});
//
const formatNumber = (num) => {
let temp = 0;
try {
temp = parseFloat(num);
} catch (error) {
//TODO handle the exception
}
return temp.toFixed(4).replace(/\.?0+$/, '');
};
//
function calcZhsc(tempArray) {
let totalJinqi = {
gas: '总进气',
dailyVolume: 0,
yearVolume: 0,
yearPlan: '100',
yearPerCent: 0
};
let totalChuqi = {
gas: '总出气',
dailyVolume: 0,
yearVolume: 0,
yearPlan: '100',
yearPerCent: 0
};
const compositeZx = {
gas: '站线综合输差',
dailyVolume: 0,
yearVolume: 0,
yearPlan: '100',
yearPerCent: 0
}; //
const compositeJc = {
gas: '进出综合输差',
dailyVolume: 0,
yearVolume: 0,
yearPlan: '100',
yearPerCent: 0
};
const trqSpl = {
gas: '商品量',
dailyVolume: 0,
yearVolume: 0,
yearPlan: '7220',
yearPerCent: 0
};
//
tempArray.forEach((item) => {
if (item.gas === '站输差' || item.gas === '线输差') {
compositeZx.dailyVolume += parseFloat(item.dailyVolume) || 0;
compositeZx.yearVolume += parseFloat(item.yearVolume) || 0;
}
if (item.gas === '气井气' || item.gas === '外部气' || item.gas === '返回气') {
totalJinqi.dailyVolume += parseFloat(item.dailyVolume) || 0;
totalJinqi.yearVolume += parseFloat(item.yearVolume) || 0;
}
if (item.gas === '自耗气' || item.gas === '用户气' || item.gas === '返采油厂干气') {
totalChuqi.dailyVolume += parseFloat(item.dailyVolume) || 0;
totalChuqi.yearVolume += parseFloat(item.yearVolume) || 0;
}
if (item.gas === '气井气' || item.gas === '站输差' || item.gas === '线输差') {
trqSpl.dailyVolume += parseFloat(item.dailyVolume) || 0;
trqSpl.yearVolume += parseFloat(item.yearVolume) || 0;
}
if (item.gas === '自耗气') {
trqSpl.dailyVolume -= parseFloat(item.dailyVolume) || 0;
trqSpl.yearVolume -= parseFloat(item.yearVolume) || 0;
}
});
compositeZx.yearPerCent = calcPercent(compositeZx.yearPlan, compositeZx.yearVolume);
trqSpl.yearPerCent = calcPercent(trqSpl.yearPlan, trqSpl.yearVolume);
compositeJc.dailyVolume = (-totalJinqi.dailyVolume + totalChuqi.dailyVolume).toFixed(4);
compositeJc.yearVolume = (-totalJinqi.yearVolume + totalChuqi.yearVolume).toFixed(4);
compositeJc.yearPerCent = calcPercent(compositeJc.yearPlan, compositeJc.yearVolume);
tempArray.push(compositeZx);
tempArray.push(trqSpl);
return tempArray;
}
const getJinriTrqShengchansj = () => {
const now = new Date();
if (now.getHours() < 11) {
strDate.value = formatDate(getDateAfterDays(now, -1)).toString(); //11
} else {
strDate.value = formatDate(now).toString();
}
let queryParms = {};
shishiArr.value = [];
queryParms.day = strDate.value;
queryJinriTrqShengchansj(queryParms).then((res) => {
if (res.success) {
console.log(1, res);
let temp = res.result;
temp.forEach((item) => {
if (item.gas === '气井气') {
item.yearPlan = 7500;
item.yearPerCent = calcPercent(item.yearPlan, item.yearVolume);
}
});
shishiArr.value = calcZhsc(temp);
nextTick();
onselectionchange();
}
});
};
function goHistory(val) {
uni.navigateTo({
url: '/pages/production/ribaoshuju/rbsjLsxq?data=' + JSON.stringify(val) + '&type=trq'
});
}
function calcPercent(yearJihua, yearShiji) {
// 0
// 100
let plan = parseFloat(yearJihua === '' ? 0 : yearJihua);
let shiji = parseFloat(yearShiji);
let percent = 0;
//
if (plan > 0) {
percent = (shiji / plan) * 100;
percent = Math.min(percent, 100); // 100%
}
return parseFloat(percent.toFixed(2)); //
}
const getJinriShengchansj = () => {
const now = new Date();
if (now.getHours() < 11) {
strDate.value = formatDate(getDateAfterDays(now, -1)).toString(); //11
} else {
strDate.value = formatDate(now).toString();
}
let queryParms = {};
dataJinri.value = [];
dataJinriSum.value = [];
dataJinriSumUnit.value = [];
queryParms.rqDate = strDate.value;
queryParms.pageSize = 100;
queryJinriShengchansj(queryParms).then((res) => {
if (res.success) {
dataJinri.value = res.result.records;
dataJinriSumUnit.value = sumByUnit(dataJinri.value); //gas unit rq cq totalGas
// // 使 nextTick DOM
nextTick();
getYearShengchansj(); //
}
});
};
const getYearShengchansj = () => {
const now = new Date();
let year = formatDate(now).split('-')[0];
let queryParms = {};
queryParms.yearStart = year;
queryParms.yearEnd = year;
queryYearShengchansj(queryParms).then((res) => {
if (res.success) {
try {
let yearData = res.result[year];
dataJinriSumUnit.value.forEach((item) => {
yearData.forEach((itemYear) => {
// // console.log(item, itemYear);
if (item.setId === itemYear.setId) {
item.yearVolume = itemYear.yearSum || 0;
}
});
});
dataJinriSum.value = sumByGas(dataJinriSumUnit.value);
shishiArr.value.forEach((item) => {
dataJinriSum.value.forEach((itemjinri) => {
if (item.gas === itemjinri.gas) {
item.dailyVolume = itemjinri.rq.toFixed(4);
item.yearVolume = itemjinri.yearVolume.toFixed(4);
}
});
});
} catch (error) {
// console.log(error);
}
}
});
};
function sumByGas(records) {
const summaryMap = {};
try {
records.forEach((record) => {
const gas = record.gas;
if (!summaryMap[gas]) {
// gas
summaryMap[gas] = {
gas: gas,
rq: 0,
sq: 0,
totalGas: 0,
yearVolume: 0
};
}
// gas
summaryMap[gas].rq += record.rq || 0;
summaryMap[gas].sq += record.sq || 0;
summaryMap[gas].totalGas += record.totalGas || 0;
summaryMap[gas].yearVolume += record.yearVolume || 0;
});
return Object.values(summaryMap);
} catch (error) {
//TODO handle the exception
// console.log(error);
}
}
function sumByUnit(records) {
console.log(records);
const summaryMap = {};
try {
records.forEach((record) => {
const unit = record.unit;
const gas = record.gas;
// setId
const setId = record.setId
if (gas != "区输差") {
if (!summaryMap[setId]) {
// gas
summaryMap[setId] = {
unit: unit,
setId: setId,
gas: record.gas,
rq: 0,
sq: 0,
totalGas: 0,
yearVolume: 0
};
}
// unit
summaryMap[setId].rq += record.rq || 0;
summaryMap[setId].sq += record.sq || 0;
summaryMap[setId].totalGas += record.totalGas || 0;
summaryMap[setId].yearVolume += record.yearVolume || 0;
}
});
return Object.values(summaryMap);
} catch (error) {
//TODO handle the exception
// console.log(error);
}
}
</script>
<style lang="scss" scoped>
.header-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10 10rpx;
border-bottom: 1rpx solid #eee;
margin-left: 10px;
margin-right: 10px;
}
.title {
font-size: 30rpx;
font-weight: bold;
color: #333;
}
.titlepopup {
font-size: 35rpx;
font-weight: bold;
color: #333;
text-align: center;
padding: 20px;
margin-top: 10px;
}
/* 给包裹按钮的容器设置样式 */
.popupBtn {
display: grid;
/* 创建三个等宽的列 */
grid-template-columns: repeat(3, 1fr);
/* 设置列与列之间的间距 */
gap: 2px;
margin-bottom: 20px;
}
/* 添加按钮按下效果 */
.popupBtn button:active {
opacity: 0.8;
transform: scale(0.98);
transition: all 0.1s ease;
}
/* 给按钮设置通用样式 */
.popupBtn button {
border: none;
padding: 0px 10px;
background-color: #007BFF;
color: white;
border-radius: 5px;
cursor: pointer;
}
/* 鼠标悬停在按钮上时的样式 */
.popupBtn button:hover {
background-color: #0056b3;
}
.more {
font-size: 26rpx;
color: #666;
cursor: pointer;
}
.more::after {
content: '';
width: 8rpx;
height: 8rpx;
border-top: 2rpx solid #666;
border-right: 2rpx solid #666;
transform: rotate(45deg);
margin-left: 8rpx;
vertical-align: middle;
}
/* 鼠标悬停效果 */
.more:hover {
color: #007aff;
}
.popupcheckbox {
/* 使用 Flexbox 布局 */
display: flex;
flex-wrap: wrap;
/* 允许换行 */
gap: 2px;
/* 设置复选框之间的间距 */
margin-left: 20px;
margin-bottom: 10px;
}
.popupcheckbox .uni-data-checkbox__item {
flex-basis: calc((100% / var(4)) - 10px);
box-sizing: border-box;
}
.container {
display: flex;
flex-wrap: wrap;
padding: 20rpx;
gap: 20rpx;
}
.empty {
padding: 40rpx;
text-align: center;
color: #888;
font-size: 16rpx;
}
.card-item {
flex: 1 1 200rpx; // 300rpx formatNumber
min-width: 240rpx;
max-width: calc(50% - 10rpx); //
@media (min-width: 768px) {
max-width: calc(33.33% - 14rpx); // 3
}
}
.card {
background: #ececec;
border-radius: 16rpx;
padding: 15rpx;
box-shadow: 0 4rpx 12rpx rgba(179, 179, 179, 0.1);
.title {
display: block;
font-size: 28rpx;
font-weight: 600;
color: #333;
margin-bottom: 16rpx;
}
.content {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
&:last-child {
margin-bottom: 0;
}
.label {
font-size: 24rpx;
color: #666;
}
.value {
font-size: 28rpx;
color: #0000ff;
font-weight: 500;
}
}
}
.progress-bar {
position: relative;
height: 20px;
background: #f0f0f0;
border-radius: 10px;
overflow: hidden;
}
.progress {
height: 100%;
transition: all 0.3s;
}
.progress-text {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
// color: red;
/* 保持红色 */
font-size: 12px;
font-weight: bold;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
/* 提升可读性 */
}
</style>

View File

@ -0,0 +1,317 @@
<template>
<!-- <view style="margin-left: 20rpx;"> <uni-title :title="strDate + ':生产数据'" type="h1" color="red" /> -->
<!-- </view> -->
<view class="content">
<!-- 标题行 -->
<view class="header-row">
<view class="title">原油产量</view>
<view class="more"></view>
</view>
</view>
<view class="container">
<view v-for="(item, index) in shishiArr" :key="index" class="card-item" @click="handleCardClick(item.gas)">
<view class="card">
<!-- <text class="title">{{ item.gas }}</text> -->
<view class="content">
<text class="label">日油量</text>
<text class="value">{{ item.rcwy || '-' }}</text>
</view>
<view class="content">
<text class="label">月累计</text>
<text class="value">{{ item.yl || '-' }}</text>
</view>
<view class="content">
<text class="label">年累计</text>
<text class="value">{{ item.nl || '-' }}</text>
</view>
<view class="progress-bar">
<!-- 动态设置宽度和颜色 -->
<view class="progress" :style="{
width: `${Math.abs(item.yearPerCent)}%`,
'background-color': item.yearPerCent < 0 ? '#ff4444' : '#007aff'
}"></view>
<!-- 显示带符号的百分比 -->
<text v-if="!(item.yearPlan === '' || item.yearPlan === '0')"
class="progress-text">{{ item.yearPerCent }}%</text>
</view>
</view>
</view>
</view>
<!-- 数据弹窗 -->
<wd-popup v-model="popup" position="bottom" closable custom-style="height: 400px;" @close="handleClose">
<wd-cell-group title="原油数据详情 单位(吨)">
<wd-table :data="dataJinri" :height="800">
<wd-table-col prop="dw" label="名称" :width="screenWidth * 29 / 140" align="center"></wd-table-col>
<wd-table-col prop="rcwy" label="日油量" :width="screenWidth / 5" align="center"></wd-table-col>
<wd-table-col prop="yl" label="月累计" :width="screenWidth / 5" align="center"></wd-table-col>
<wd-table-col prop="nl" label="年累计" :width="screenWidth / 4" align="center"></wd-table-col>
<wd-table-col prop="" label="操作" :width="screenWidth / 7" align="center">
<template #value="{row}">
<text style="color: red;" @click="goHistory(row)">历史</text>
</template>
</wd-table-col>
</wd-table>
</wd-cell-group>
</wd-popup>
</template>
<script setup>
import {
queryJinriYuanyouShengchansj
} from '@/api/production';
import {
formatDate,
getDateAfterDays
} from '@/utils/dateTime';
const shishiArr = ref([{
gas: '原油产量',
rcwy: '',
yl: '',
nl: '',
yearPlan: '1500',
yearPerCent: ''
}]);
const screenWidth = ref(0)
const dataJinri = ref([]);
const dataJinriSum = ref([]);
const popup = ref(false);
//
const handleCardClick = () => {
popup.value = true
};
//
const closePopup = () => {
popup.value = false
};
onMounted(() => {
getJinriYuanyouShengchansj();
// getYearShengchansj();
calculateTableHeight();
//
uni.onWindowResize(() => {
calculateTableHeight();
});
});
const strDate = ref('');
//
const formatNumber = (num) => {
if (typeof num !== 'number') return '-';
return num.toFixed(4).replace(/\.?0+$/, '');
};
const handleClose = () => {
popup.value = false
}
function goHistory(val) {
uni.navigateTo({
url: '/pages/production/ribaoshuju/rbsjLsxq?data=' + JSON.stringify(val) + '&type=yy'
});
}
const calculateTableHeight = () => {
const systemInfo = uni.getSystemInfoSync();
screenWidth.value = systemInfo.screenWidth;
}
const getJinriYuanyouShengchansj = () => {
const now = new Date();
if (now.getHours() < 11) {
strDate.value = formatDate(getDateAfterDays(now, -1)).toString(); //11
} else {
strDate.value = formatDate(now).toString();
}
let queryParms = {};
dataJinri.value = [];
dataJinriSum.value = [];
queryParms.scrq = strDate.value;
queryParms.pageSize = 100;
queryJinriYuanyouShengchansj(queryParms).then((res) => {
if (res.success) {
dataJinri.value = res.result.records;
dataJinriSum.value = sumByOil(dataJinri.value); //gas unit rq cq totalGas
// // console.log(dataJinriSum.value);
nextTick();
shishiArr.value.forEach((item) => {
dataJinriSum.value.forEach((itemjinri) => {
item.rcwy = itemjinri.rcwy.toFixed(4);
item.nl = itemjinri.nl.toFixed(4);
item.yl = itemjinri.yl.toFixed(4);
item.yearPerCent = calcPercent(item.yearPlan, item.nl);
});
});
dataJinri.value = dataJinri.value.map(item => {
return {
...item,
rcwy: formatNumber(item.rcwy),
yl: formatNumber(item.yl),
nl: formatNumber(item.nl)
}
})
// getYearShengchansj(); //
}
});
};
function calcPercent(yearJihua, yearShiji) {
// 0
// 100
let plan = parseFloat(yearJihua === '' ? 0 : yearJihua);
let shiji = parseFloat(yearShiji);
let percent = 0;
//
if (plan > 0) {
percent = (shiji / plan) * 100;
percent = Math.min(percent, 100); // 100%
}
return parseFloat(percent.toFixed(2)); //
}
function sumByOil(records) {
// console.log(records);
const summaryMap = {};
try {
records.forEach((record) => {
const gas = record.gas;
if (!summaryMap[gas]) {
// gas
summaryMap[gas] = {
rcwy: 0,
yl: 0,
nl: 0
};
}
// gas
summaryMap[gas].rcwy += record.rcwy || 0;
summaryMap[gas].yl += record.yl || 0;
summaryMap[gas].nl += record.nl || 0;
});
return Object.values(summaryMap);
} catch (error) {
//TODO handle the exception
// console.log(error);
}
}
</script>
<style lang="scss" scoped>
.header-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15rpx 0;
border-bottom: 1rpx solid #eee;
margin-left: 10px;
margin-right: 10px;
}
.title {
font-size: 30rpx;
font-weight: bold;
color: #333;
}
.more {
font-size: 26rpx;
color: #666;
cursor: pointer;
}
.more::after {
content: '';
width: 8rpx;
height: 8rpx;
border-top: 2rpx solid #666;
border-right: 2rpx solid #666;
transform: rotate(45deg);
margin-left: 8rpx;
vertical-align: middle;
}
/* 鼠标悬停效果 */
.more:hover {
color: #007aff;
}
.container {
display: flex;
flex-wrap: wrap;
padding: 20rpx;
gap: 20rpx;
}
.card-item {
flex: 1 1 200rpx; // 300rpx selectedGas formatNumber
min-width: 200rpx;
max-width: calc(50% - 10rpx); //
@media (min-width: 768px) {
max-width: calc(33.33% - 14rpx); // 3
}
}
.card {
background: #ececec;
border-radius: 16rpx;
padding: 15rpx;
box-shadow: 0 4rpx 12rpx rgba(197, 197, 197, 0.1);
.title {
display: block;
font-size: 28rpx;
font-weight: 600;
color: #333;
margin-bottom: 16rpx;
}
.content {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
&:last-child {
margin-bottom: 0;
}
.label {
font-size: 24rpx;
color: #666;
}
.value {
font-size: 28rpx;
color: #0000ff;
font-weight: 500;
}
}
}
.progress-bar {
position: relative;
height: 20px;
background: #f0f0f0;
border-radius: 10px;
overflow: hidden;
}
.progress {
height: 100%;
transition: all 0.3s;
}
.progress-text {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: red;
/* 保持红色 */
font-size: 12px;
font-weight: bold;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
/* 提升可读性 */
}
</style>

View File

@ -0,0 +1,8 @@
<template>
</template>
<script>
</script>
<style>
</style>

View File

@ -0,0 +1,507 @@
<route lang="json5" type="page">
{
layout: 'default',
style: {
navigationStyle: 'custom',
navigationBarTitleText: '历史数据图表',
},
}
</route>
<template>
<PageLayout navTitle="历史数据图表" backRouteName="index" routeMethod="pushTab">
<view class="chart-container">
<view class="chart-header">
<view class="chart-title-container">
<text class="chart-title">{{ chartTitle }}</text>
</view>
<view class="filter-section">
<view class="date-picker">
<uni-datetime-picker type="datetimerange" v-model="lssjTimeRang" @change="getTime"
:placeholder="['开始时间', '结束时间']" />
</view>
<view class="checkbox-container">
<label class="checkbox">
<checkbox :checked="tableVisibled" @change="onChangeTable" />
<text>{{ checkBoxText }}</text>
</label>
</view>
</view>
</view>
<!-- 图表容器 -->
<view id="myCharts" class="chart"></view>
<!-- 数据表格 -->
<view v-if="tableVisibled" class="table-container">
<uni-table border stripe emptyText="暂无数据" :loading="loading">
<uni-tr>
<uni-th width="60" align="center">序号</uni-th>
<uni-th align="center">日期时间</uni-th>
<uni-th align="center">温度()</uni-th>
<uni-th align="center">压力(MPa)</uni-th>
<uni-th align="center">压差(kPa)</uni-th>
<uni-th align="center">瞬时量(Nm³/d)</uni-th>
<uni-th align="center">今日量()</uni-th>
<uni-th align="center">今日时间()</uni-th>
<uni-th align="center">仪表状态</uni-th>
</uni-tr>
<uni-tr v-for="(item, index) in dataSource" :key="index">
<uni-td align="center">{{ index + 1 }}</uni-td>
<uni-td align="center">{{ formatTableTime(item.createTime) }}</uni-td>
<uni-td align="center">{{ item.wd }}</uni-td>
<uni-td align="center">{{ item.yl }}</uni-td>
<uni-td align="center">{{ item.yc }}</uni-td>
<uni-td align="center">{{ item.ssll }}</uni-td>
<uni-td align="center">{{ item.jrl }}</uni-td>
<uni-td align="center">{{ item.jrsj }}</uni-td>
<uni-td align="center">{{ item.zt }}</uni-td>
</uni-tr>
</uni-table>
<view class="pagination">
<uni-pagination :current="ipagination.current" :pageSize="ipagination.pageSize"
:total="ipagination.total" @change="handlePageChange" showTotal />
</view>
</view>
</view>
</PageLayout>
</template>
<script setup>
import {
ref,
onMounted,
onUnmounted,
watch,
nextTick
} from 'vue'
import {
onLoad
} from '@dcloudio/uni-app'
import {
formatDate
} from '@/utils/dateTime.ts'
// props
const props = defineProps({
lineData: {
type: Object,
default: () => ({})
}
})
//
const urljlByJldID = ref('https://szcx.zyyt.sinopec.com/Gyk/jldls/cxcSssjLssjJldls/getLssjByJldId')
const colorData = [{
color: '#000000'
},
{
color: '#00007f'
},
{
color: '#ff0000'
},
{
color: '#005500'
},
{
color: '#55007f'
},
{
color: '#ffff00'
}
]
const option = ref({})
const legendData = ref([])
const xData = ref([])
const yaxis = ref({
type: 'value',
name: '',
min: 0,
max: 500,
position: 'left',
axisLabel: {
formatter: '{value}'
},
axisLine: {
lineStyle: {
color: '#61A0A8'
}
}
})
const yAxis = ref([])
const series = ref([])
const serie = ref({
field: '',
name: '',
showSymbol: false,
type: 'line',
data: [],
yAxisIndex: 1,
lineStyle: {
color: '#61A0A8',
width: 1
},
connectNulls: false
})
const tableVisibled = ref(false)
const checkBoxText = ref('显示历史报表')
const dataSource = ref([])
const loading = ref(false)
const ipagination = ref({
current: 1,
pageSize: 10,
total: 0
})
const jldID = ref('')
const jldName = ref('')
const chartTitle = ref('')
const lineName = ref([])
const startTime = ref('')
const endTime = ref('')
const lssjTimeRang = ref([])
const myCharts = ref(null)
//
const getDefaultTimeRange = () => {
const now = new Date()
const start = new Date(now)
start.setHours(8, 0, 0, 0)
const end = new Date(now)
end.setDate(end.getDate() + 1)
end.setHours(7, 59, 59, 0)
return [start.getTime(), end.getTime()]
}
//
const initChart = () => {
series.value = []
yAxis.value = []
xData.value = []
let positionIndex = 0
for (let i = 0; i < lineName.value.length; i++) {
const yaxisTemp = JSON.parse(JSON.stringify(yaxis.value))
legendData.value.push(`${lineName.value[i].name}(${lineName.value[i].unit})`)
if (lineName.value[i].field === 'ssll') {
yaxisTemp.position = 'left'
} else {
yaxisTemp.position = 'right'
yaxisTemp.offset = lineName.value[i].field === 'jrl' ? 60 * positionIndex : 55 * positionIndex
positionIndex += 1
}
yaxisTemp.name = `${lineName.value[i].name}(${lineName.value[i].unit})`
yaxisTemp.min = lineName.value[i].min
yaxisTemp.max = lineName.value[i].max
yaxisTemp.axisLine.lineStyle.color = colorData[i].color
yAxis.value.push(yaxisTemp)
const serieTemp = JSON.parse(JSON.stringify(serie.value))
serieTemp.name = `${lineName.value[i].name}(${lineName.value[i].unit})`
serieTemp.field = lineName.value[i].field
serieTemp.lineStyle.color = colorData[i].color
serieTemp.yAxisIndex = i
series.value.push(serieTemp)
}
option.value = {
color: ['#000000', '#00007f', '#ff0000', '#005500', '#55007f', '#ffff00'],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
dataZoom: [{
connectNulls: false,
id: 'dataZoomX',
type: "inside",
roam: false,
show: true,
xAxisIndex: [0],
filterMode: 'empty',
throttle: 50,
zoomOnMouseWheel: true,
moveOnMouseMove: true
}, {
id: 'dataZoomY',
type: 'inside',
filterMode: 'empty',
zoomLock: false,
throttle: 50,
zoomOnMouseWheel: true,
moveOnMouseMove: true
}],
toolbox: {
feature: {
dataView: {
show: false,
readOnly: false
},
restore: {
show: false
},
saveAsImage: {
show: false
}
}
},
legend: {
data: legendData.value
},
grid: {
top: '10%',
left: '3%',
right: '10%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
axisTick: {
alignWithLabel: true
},
data: xData.value
},
yAxis: yAxis.value,
series: series.value
}
}
//
const getTime = (e) => {
if (e && e.length === 2) {
startTime.value = formatDate(e[0], 'yyyy-MM-dd hh:mm:ss')
endTime.value = formatDate(e[1], 'yyyy-MM-dd hh:mm:ss')
updateChart()
}
}
//
const onChangeTable = (e) => {
tableVisibled.value = !tableVisibled.value
checkBoxText.value = tableVisibled.value ? '显示历史趋势' : '显示历史报表'
}
//
const handlePageChange = (e) => {
ipagination.value.current = e.current
ipagination.value.pageSize = e.pageSize
}
//
const formatTableTime = (time) => {
if (!time) return ''
return formatDate(time, 'yyyy-MM-dd hh:mm:ss')
}
//
const maxArrValue = (data) => {
if (!data || data.length === 0) return 0
const list = []
for (let i in data) {
if (data[i] !== null) {
list.push(parseInt(data[i]))
}
}
if (list.length === 0) return 0
list.sort((num1, num2) => num1 - num2)
return list[list.length - 1]
}
//
const updateChart = () => {
dataSource.value = []
xData.value = []
for (let j = 0; j < series.value.length; j++) {
series.value[j].data = []
}
loading.value = true
getAction(url.list, {
jldId: jldID.value,
startTime: startTime.value,
endTime: endTime.value
}).then(res => {
loading.value = false
if (res.success) {
const ssData = JSON.parse(res.result)
dataSource.value = ssData
ipagination.value.total = ssData.length
for (let i = 0; i < ssData.length; i++) {
const ctime = formatDate(ssData[i].createTime, 'yyyy-MM-dd hh:mm:ss')
xData.value.push(ctime)
for (let j = 0; j < series.value.length; j++) {
let tempValue = ssData[i][lineName.value[j].field]
tempValue = tempValue === 0 ? null : tempValue
series.value[j].data.push(tempValue)
}
}
for (let mm = 0; mm < series.value.length; mm++) {
const maxVal = maxArrValue(series.value[mm].data)
yAxis.value[mm].max = Math.round(maxVal * 1.2)
}
option.value.xAxis.data = xData.value
if (myCharts.value) {
myCharts.value.setOption(option.value)
}
}
}).catch(() => {
loading.value = false
})
}
// ECharts
const initECharts = () => {
nextTick(() => {
// Uniapp使uni.createCanvasContext使ucharts
// 使Uniapp
const canvas = document.getElementById('myCharts')
if (canvas) {
// ECharts
myCharts.value = echarts.init(canvas)
myCharts.value.setOption(option.value)
}
})
}
// lineData
watch(() => props.lineData, (val) => {
jldID.value = val.jldID
jldName.value = val.jldName
chartTitle.value = `${val.jldName}历史趋势`
lineName.value = JSON.parse(JSON.stringify(val.lineName))
startTime.value = val.startTime
endTime.value = val.endTime
try {
if (val.startTime && val.endTime) {
const sDt = new Date(val.startTime)
const eDt = new Date(val.endTime)
lssjTimeRang.value = [sDt.getTime(), eDt.getTime()]
} else {
lssjTimeRang.value = getDefaultTimeRange()
}
} catch (e) {
console.error('时间格式错误', e)
lssjTimeRang.value = getDefaultTimeRange()
}
initChart()
updateChart()
}, {
deep: true,
immediate: true
})
//
onLoad(() => {
//
lssjTimeRang.value = getDefaultTimeRange()
// Uniappecharts使
setTimeout(() => {
initECharts()
}, 500)
})
//
onUnmounted(() => {
if (myCharts.value) {
myCharts.value.dispose()
}
})
</script>
<style scoped>
.chart-container {
width: 100%;
height: 100%;
padding: 20rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.chart-header {
margin-bottom: 20rpx;
}
.chart-title-container {
width: 100%;
text-align: center;
margin-bottom: 20rpx;
}
.chart-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.filter-section {
display: flex;
flex-direction: column;
gap: 20rpx;
margin-bottom: 20rpx;
}
.date-picker {
width: 100%;
}
.checkbox-container {
display: flex;
align-items: center;
}
.checkbox {
display: flex;
align-items: center;
font-size: 28rpx;
}
.chart {
width: 100%;
height: 600rpx;
background-color: #fff;
border-radius: 10rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
margin-bottom: 20rpx;
}
.table-container {
width: 100%;
overflow-x: auto;
}
.pagination {
margin-top: 20rpx;
display: flex;
justify-content: center;
}
</style>

View File

@ -0,0 +1,78 @@
<route lang="json5" type="page">
{
layout: 'default',
style: {
navigationStyle: 'custom',
navigationBarTitleText: '历史数据图表',
},
}
</route>
<template>
<PageLayout :navbarShow="false" class="page-layout">
<view style="color: blue;font-size:18px;text-align: center;margin: 10px;width: 100%;">
<wd-text :text="jldData.jldname+ '实时趋势'" style="color: blue;font-size:18px;" ></wd-text>
</view>
<view>
<uni-datetime-picker type="datetimerange" v-model="lssjTimeRange" @change="getTime" start-placeholder="开始时间"
end-placeholder="结束时间" />
</view>
</PageLayout>
</template>
<script setup>
import {
formatDate
} from '@/utils/dateTime.ts';
import {
ref,
onMounted,
computed,
nextTick,
watchEffect,
onUnmounted,
} from 'vue';
const props = defineProps({
jldData: {
type: Object,
default: () => {}
}
})
onMounted(() => {
//
setTimeout(() => {
lssjTimeRange.value = getDefaultTimeRange()
}, 500)
console.log(lssjTimeRange.value);
})
const startTime = ref('')
const endTime = ref('')
const lssjTimeRange = ref([])
//
const getDefaultTimeRange = () => {
const now = new Date()
const start = new Date(now)
start.setHours(8, 0, 0, 0)
const end = new Date(now)
end.setDate(end.getDate() + 1)
end.setHours(7, 59, 59, 0)
return [formatDate(start, "YYYY-MM-DD HH:mm:ss"), formatDate(end, "YYYY-MM-DD HH:mm:ss")]
}
//
const getTime = (e) => {
if (e && e.length === 2) {
startTime.value = formatDate(e[0], 'YYYY-MM-DD HH:mm:ss')
endTime.value = formatDate(e[1], 'YYYY-MM-DD HH:mm:ss')
// updateChart()
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,8 @@
<template>
</template>
<script>
</script>
<style>
</style>

View File

@ -0,0 +1,7 @@
<template>
<trqSssjVue></trqSssjVue>
</template>
<script setup>
import trqSssjVue from './trqSssj';
</script>

View File

@ -0,0 +1,8 @@
<template>
</template>
<script>
</script>
<style>
</style>

View File

@ -0,0 +1,356 @@
<route lang="json5" type="page">
{
layout: 'default',
style: {
navigationStyle: 'custom',
navigationBarTitleText: '生产数据',
},
}
</route>
<template>
<PageLayout :navbarShow="false" class="page-layout">
<!-- 标题行 -->
<wd-text :text="stationName ? stationName + '实时数据' : '实时数据'" style="color: blue;font-size:18px;text-align: center;margin: 5px;"></wd-text>
<wd-cell :title="'时间:' + nowDateTime " center>
<wd-button custom-class="custom-value" size="small" plain clickable
@click="handleStop">{{caijiText}}</wd-button>
<wd-button custom-class="custom-value" size="small" plain clickable
@click="handleRightClick">选择站场</wd-button>
</wd-cell>
<scroll-view direction="vertical" class="scroll-container">
<view class="container">
<view v-for="(item, index) in jlData" :key="index" class="card">
<view class="field-item">
<text class="titlejl">{{ item.jldname }}</text>
<view class="status-circle"
:style="{ backgroundColor: item.yxzt==='运行' ? '#4CAF50' : '#F44336' }">
{{item.yxzt}}
</view>
</view>
<view class="field-list">
<!-- 压力 -->
<view class="field-item">
<text class="field-label">压力(MPa)</text>
<text class="field-value">{{ formatNumber(item.yl) || '-' }}</text>
</view>
<!-- 差压 -->
<view class="field-item">
<text class="field-label">差压(kPa)</text>
<text class="field-value">{{ formatNumber(item.yc) || '-' }}</text>
</view>
<!-- 温度 -->
<view class="field-item">
<text class="field-label">温度()</text>
<text class="field-value">{{ formatNumber(item.wd) || '-' }}</text>
</view>
<!-- 瞬时流量 -->
<view class="field-item">
<text class="field-labelssll" @click="openSssjChart(item)">瞬时流量(m³/d)</text>
<text class="field-value">{{ formatNumber(item.ssll) || '-' }}</text>
</view>
<!-- 今日流量 -->
<view class="field-item">
<text class="field-labelssll" @click="openlssjChart(item)">今日流量(m³)</text>
<text class="field-value">{{ formatNumber(item.jrl) || '-' }}</text>
</view>
<!-- 昨日流量 -->
<view class="field-item">
<text class="field-label">昨日流量()</text>
<text class="field-value">{{ formatNumber(item.zrl) || '-' }}</text>
</view>
<!-- 昨日时间 -->
<view class="field-item">
<text class="field-label">昨日时间(min)</text>
<text class="field-value">{{ formatNumber(item.zrsj) || '-' }}</text>
</view>
<!-- 今日时间 -->
<view class="field-item">
<text class="field-label">今日时间(min)</text>
<text class="field-value">{{ formatNumber(item.jrsj) || '-' }}</text>
</view>
</view>
</view>
</view>
</scroll-view>
<wd-popup v-model="selectZc" position="bottom" custom-style="width:100%;height: 300px;" @close="handleClose">
<view style="font-size: 18px;text-align: center;color: blue;margin: 10px;">选择采输气站场</view>
<cxc-szcx-stationJl-select v-model="stationID" returnCodeOrID="id" @change="onChange">
</cxc-szcx-stationJl-select>
</wd-popup>
<wd-popup v-model="lssjFlag" position="bottom" custom-style="width:100%;height: 300px;" @close="handleClose">
<lssj-chart></lssj-chart>
</wd-popup>
<wd-popup v-model="sssjFlag" position="bottom" custom-style="width:100%;height: 70vh;" @close="handleClose">
<sssj-chart :jldData="jldData" ></sssj-chart>
</wd-popup>
</PageLayout>
</template>
<script setup>
import {
queryJldZcList,
queryJldDataByZc
} from '@/api/production'
import {
ref,
onMounted,
computed,
nextTick,
watchEffect,
onUnmounted,
} from 'vue';
import {
onHide,
onShow
} from '@dcloudio/uni-app'
import {formatDate} from '@/utils/dateTime.ts';
import SssjChart from './chart/sssjChart'
import LssjChart from './chart/lssjChart'
const res = wx.getSystemInfoSync();
const statusHeight = res.statusBarHeight; //
const cusnavbarheight = (statusHeight + 30) + "px";
const selectZc = ref(false)
const lssjFlag = ref(false)
const sssjFlag = ref(false)
const nowDateTime =ref("")
const caijiText = ref("停止采集")
const stationList = ref([])
const stationID = ref("")
const stationName = ref(" ")
const jlData = ref([])
const jldData = ref({})
const sssjUrl = ref('wss://szcx.zyyt.sinopec.com/Gyk/websocket/')
const jlByzc = ref('https://szcx.zyyt.sinopec.com/Gyk/sssj/GetJlByZc')
function openSssjChart(e) {
sssjFlag.value = true;
console.log(11, e)
jldData.value = e
console.log(selectZc.value)
}
function openlssjChart(e) {
sssjFlag.value = true;
console.log(selectZc.value)
}
function handleRightClick() {
selectZc.value = true;
console.log(selectZc.value)
}
function handleClose() {
console.log(selectZc.value)
}
function onChange(e, data) {
console.log(2, e, data.value);
stationID.value = e
stationName.value = data.value.title
getScData(); //
}
function handleStop() {
if (caijiText.value === "停止采集") {
console.log('清除定时器,停止采集')
caijiText.value = "开始采集"
clearInterval(timer2.value);
timer2.value = null;
} else {
console.log('开始采集,打开定时器')
caijiText.value = "停止采集"
websocketheart()
}
}
const websock = ref(null);
const timer2 = ref(null);
//
const websocketheart = () => {
//
if (timer2.value) {
clearInterval(timer2.value);
timer2.value = null;
}
timer2.value = setInterval(() => {
nowDateTime.value=formatDate(new Date(),"YYYY-MM-DD HH:mm:ss")
if (websock.value && websock.value.readyState === 1) {
//
// connectSocketInit()
}
if (stationID.value) {
getScData();
}
}, 1000);
};
onMounted(() => {
websocketheart()
})
onUnmounted(() => {
clearInterval(timer2.value);
})
onHide(() => {
console.log('页面隐藏,清除定时器')
clearInterval(timer2.value);
timer2.value = null;
})
onShow(() => {
//
websocketheart()
})
const getScData = () => {
uni.request({
url: jlByzc.value + '?zhanc=' + stationID.value + '&jldLx=0',
method: 'GET',
success: (res) => {
console.log(res)
jlData.value = JSON.parse(res.data.result).JlData;
}
})
}
//
const formatNumber = (num) => {
let temp = 0;
try {
temp = parseFloat(num);
} catch (error) {
//TODO handle the exception
}
return temp.toFixed(4).replace(/\.?0+$/, '');
};
</script>
<style lang="scss" scoped>
.header-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10 10rpx;
border-bottom: 1rpx solid #eee;
margin-left: 10px;
margin-right: 10px;
}
.title {
font-weight: bold;
color: #333;
}
.titlejl {
font-size: 20rpx;
vertical-align: middle;
font-weight: bold;
color: #0055ff;
margin-bottom: 15px;
}
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 16px;
padding: 16px;
}
.card {
background: #fff;
border-radius: 8px;
padding: 5px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
}
.field-list {
margin-top: 10px;
display: flex;
flex-wrap: wrap;
/* 允许子元素换行 */
gap: 3px;
}
.field-item {
display: flex;
height: 30px;
justify-content: space-between;
align-items: center;
padding: 5px 5px;
background: #f8f9fa;
border-radius: 4px;
flex-basis: calc(50% - 10px);
/* 每个元素占据约一半宽度,减去间隙 */
box-sizing: border-box;
/* 包含内边距和边框 */
}
/* 当屏幕宽度较小时,每个元素占据整行 */
@media (max-width: 200px) {
.field-item {
flex-basis: 100%;
}
}
.field-label {
color: #666;
font-size: 10px;
flex: 1;
margin-right: 2px;
width: 80px;
font-weight: 500;
}
.field-labelssll {
color: #0000ff;
text-decoration: underline;
font-size: 10px;
flex: 1;
margin-right: 2px;
width: 80px;
font-weight: 500;
}
.field-value {
color: #1890ff;
font-weight: 500;
font-size: 12px;
text-align: right;
width: 60px;
overflow: hidden;
text-overflow: ellipsis;
}
.status-circle {
width: 70rpx;
height: 30rpx;
font-size: 12px;
vertical-align: middle;
}
.page-layout {
display: flex;
flex-direction: column;
height: 100vh;
}
.scroll-container {
flex: 1;
overflow-y: auto;
}
</style>

View File

@ -0,0 +1,8 @@
<template>
</template>
<script>
</script>
<style>
</style>

View File

@ -9,51 +9,35 @@
</route> </route>
<template> <template>
<PageLayout :navbarShow="false"> <PageLayout :navbarShow="false">
<view> <view class="nav">
<view class="placeholder"></view> <view class="nav_box">
<view style="width: 100%; display: grid; place-items: center"> <scroll-view direction="horizontal">
<uni-title :title="dateDate + ':生产情况'" type="h1" color="blue" /> <uni-segmented-control :current="current" :values="items" styleType="string" mode="segmented"
</view> @clickItem="onClickItem"></uni-segmented-control>
<view style="margin: 0 10px;"> </scroll-view>
<uni-segmented-control style="margin-top: 10px;margin-bottom: 10px" :current="current" :values="items"
@clickItem="onClickItem" styleType="button" activeColor="#0055ff"></uni-segmented-control>
</view>
<view class="content">
<view v-if="current === 0">
<view style="padding: 0 10px">
<view class="progress-bartime">
<!-- 动态设置宽度和颜色 -->
<view class="progressTime"
:style="{ width: `${timePercent}%`, 'background-color': '#0055ff' }">
</view>
<!-- 显示带符号的百分比 -->
<text class="progress-text">全年时间进度:{{ timePercent }}%</text>
</view>
</view>
<scroll-view scroll-y :style="{ height: scrollViewHeight + 'px' }">
<trq-data></trq-data>
<yy-data></yy-data>
</scroll-view>
</view>
<view v-if="current === 1">
<scroll-view scroll-y :style="{ height: scrollViewHeight + 'px' }">
<sssjForm></sssjForm>
</scroll-view>
</view>
</view> </view>
</view> </view>
<view class="content">
<view v-if="current === 0">
<scroll-view scroll-y :style="{ height: scrollViewHeight + 'px' }">
<sssjData></sssjData>
</scroll-view>
</view>
<view v-if="current === 1">
<scroll-view scroll-y :style="{ height: scrollViewHeight + 'px' }">
<trq-data></trq-data>
<yy-data></yy-data>
</scroll-view>
</view>
</view>
</PageLayout> </PageLayout>
</template> </template>
<script setup> <script setup>
import trqData from './ribaoshuju/trqRbsj';
import yyData from './ribaoshuju/yyRbsj';
import sssjForm from './shishishuju/index';
import {
formatDate,
getDateAfterDays,
getYearProgress
} from '@/utils/dateTime';
import { import {
ref, ref,
onMounted, onMounted,
@ -62,14 +46,19 @@
watchEffect, watchEffect,
onUnmounted onUnmounted
} from 'vue'; } from 'vue';
const items = ref(['日报数据', '实时数据']) //
import trqData from '@/pages-production/ribaoshuju/trqRbsj';
import yyData from '@/pages-production/ribaoshuju/yyRbsj';
import sssjData from '@/pages-production/shishishuju/trqSssj';
const items = ref(['油气实时', '油气历史', '管线运行', '安防监控', '设备运行'])
const current = ref(0) const current = ref(0)
const res = wx.getSystemInfoSync(); const res = wx.getSystemInfoSync();
const statusHeight = res.statusBarHeight; // const statusHeight = res.statusBarHeight; //
const cusnavbarheight = statusHeight + 44 + 'px'; const cusnavbarheight = (statusHeight + 50) + "px";
const scrollViewHeight = ref(0); // const scrollViewHeight = ref(0); //
const timePercent = ref(0);
const dateDate = ref(''); const activeColor = ref("#0000ff")
const inActiveColor = ref("#000000")
function onClickItem(e) { function onClickItem(e) {
if (current.value != e.currentIndex) { if (current.value != e.currentIndex) {
@ -77,31 +66,16 @@
} }
} }
const strDate = () => {
const now = new Date();
if (now.getHours() < 11) {
return formatDate(getDateAfterDays(now, -1)); //11
} else {
return formatDate(now);
}
};
onMounted(() => { onMounted(() => {
dateDate.value = strDate();
timePercent.value = getYearProgress();
calculateScrollViewHeight(); calculateScrollViewHeight();
// // 使 Uniapp
window.addEventListener('resize', calculateScrollViewHeight); uni.onWindowResize(calculateScrollViewHeight);
}); });
onUnmounted(() => { onUnmounted(() => {
// // Uniapp
window.removeEventListener('resize', calculateScrollViewHeight); uni.offWindowResize(calculateScrollViewHeight);
}); });
onHide(()=>{ // by
current.value = 0;
})
const calculateScrollViewHeight = () => { const calculateScrollViewHeight = () => {
// //
const screenHeight = uni.getSystemInfoSync().windowHeight; const screenHeight = uni.getSystemInfoSync().windowHeight;
@ -111,18 +85,7 @@
query query
.select('.nav') .select('.nav')
.boundingClientRect(); .boundingClientRect();
query
.select('.placeholder')
.boundingClientRect();
query
.select('.uni-title')
.boundingClientRect();
query
.select('.uni-segmented-control')
.boundingClientRect();
query
.select('.progress-bartime')
.boundingClientRect();
// //
query.exec((res) => { query.exec((res) => {
let totalHeight = 0; let totalHeight = 0;
@ -132,62 +95,38 @@
} }
}); });
// scroll-view // scroll-view
scrollViewHeight.value = screenHeight - totalHeight - 80; scrollViewHeight.value = screenHeight - totalHeight;
}); });
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.nav { .nav {
width: calc(100% - 60rpx); width: calc(100%);
padding: 0 30rpx;
height: v-bind(cusnavbarheight); height: v-bind(cusnavbarheight);
font-size: 24rpx; font-size: 24rpx;
color: #ffffff; //color: #333333;
position: fixed; position: fixed;
top: 0;
left: 0;
z-index: 99; z-index: 99;
background-image: url('../../static/my/navbg.png'); background-image: url('@/static/navbg.png');
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 750rpx 458rpx; background-size: 750rpx 458rpx;
} }
.placeholder { .nav_box {
height: v-bind(cusnavbarheight); font-size: 18;
}
.progress-bartime {
position: relative;
height: 25px;
background: #f0f0f0;
border-radius: 10px;
overflow: hidden;
margin-bottom: 20rpx;
}
.progress {
height: 100%;
transition: all 0.3s;
}
.progressTime {
height: 100%;
transition: all 0.3s;
padding: 0 20px;
}
.progress-text {
position: absolute; position: absolute;
left: 50%; bottom: 6rpx;
top: 50%; width: calc(100% - 60rpx);
transform: translate(-50%, -50%); left: 30rpx;
color: red; right: 30rpx;
/* 保持红色 */ }
font-size: 16px;
font-weight: bold; .content {
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); position: absolute;
/* 提升可读性 */ top: v-bind(cusnavbarheight);
width: 100%;
min-height: calc(100vh - v-bind(cusnavbarheight));
} }
</style> </style>