cxc-szcx-uniapp/pages/views/shengchan/ribaoshuju/trqRbsj.vue

511 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view :class="{ gray: store.isgray == 1 }">
<view style="margin-left: 20rpx"><uni-title :title="strDate + ':生产数据'" type="h1" color="red" /></view>
<view class="progress-bar">
<!-- 动态设置宽度和颜色 -->
<view class="progressTime" :style="{ width: `${timePercent}%`, 'background-color': '#00aaff' }"></view>
<!-- 显示带符号的百分比 -->
<text class="progress-text">全年时间进度:{{ timePercent }}%</text>
</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.dailyVolume || '-' }}</text>
</view>
<view class="content">
<text class="label">年累计</text>
<text class="value">{{ 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>
<!-- 数据弹窗 -->
<uni-popup ref="popup" type="bottom" background-color="#fff">
<view class="popup-content">
<view class="popup-header">
<text class="title">{{ selectedGas }}数据详情 单位(万立方米)</text>
<uni-icons type="closeempty" size="24" color="#666" @click="closePopup"></uni-icons>
</view>
<view class="table">
<!-- 表头 -->
<view class="tr header">
<view class="th1">序号</view>
<view class="th">名称</view>
<view class="th">日气量</view>
<view class="th">年累计</view>
<view class="th1">操作</view>
</view>
<scroll-view scroll-X="true" scroll-Y="true" class="table-container">
<!-- 表格内容 -->
<view class="tr" v-for="(item, index) in filteredData" :key="index" :class="{ even: index % 2 === 0 }">
<view class="td1">{{ index + 1 }}</view>
<view class="td">{{ item.unit }}</view>
<view class="td" :class="{ negative: item.rq < 0 }">
{{ formatNumber(item.rq) }}
</view>
<view class="td" :class="{ negative: item.yearVolume < 0 }">
{{ formatNumber(item.yearVolume) }}
</view>
<view class="td1" style="color: red" @click="goHistory(item)">历史</view>
</view>
<!-- 空数据提示 -->
<view v-if="!filteredData.length" class="empty">暂无相关数据</view>
</scroll-view>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import { ref, onMounted, computed, nextTick, watchEffect } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { queryJinriShengchansj, queryYearShengchansj } from '@/api/shengchan.js';
import { formatDate, getDateAfterDays } from '@/utils/dateTime.js';
import { beforeJump } from '@/utils/index.js';
import { useStore } from '@/store';
import { getYearProgress } from '@/utils/dateTime.js';
const store = useStore();
const shishiArr = ref([
{
gas: '气井气',
dailyVolume: '',
yearVolume: '',
yearPlan: '7500',
yearPerCent: ''
},
{
gas: '伴生气',
dailyVolume: '',
yearVolume: '',
yearPlan: '',
yearPerCent: ''
},
{
gas: '外部气',
dailyVolume: '',
yearVolume: '',
yearPlan: '',
yearPerCent: ''
},
{
gas: '站输差',
dailyVolume: '',
yearVolume: '',
yearPlan: '',
yearPerCent: ''
},
{
gas: '线输差',
dailyVolume: '',
yearVolume: '',
yearPlan: '',
yearPerCent: ''
},
{
gas: '综合输差',
dailyVolume: '',
yearVolume: '',
yearPlan: '100',
yearPerCent: ''
}
]);
const dataJinri = ref([]);
const dataJinriSum = ref([]);
const dataJinriSumUnit = ref([]);
const selectedGas = ref('');
const filteredData = ref([]);
const popup = ref(null);
const timePercent = ref(0);
// 点击卡片处理
const handleCardClick = (gas) => {
selectedGas.value = gas;
filteredData.value = dataJinriSumUnit.value.filter((item) => item.gas === gas);
popup.value.open();
};
// 关闭弹窗
const closePopup = () => {
popup.value.close();
};
onMounted(() => {
getJinriShengchansj();
getYearShengchansj();
timePercent.value = getYearProgress();
});
const strDate = ref('');
// 数字格式化
const formatNumber = (num) => {
if (typeof num !== 'number') return '-';
return num.toFixed(4).replace(/\.?0+$/, '');
};
// 计算属性自动分组
const groupedData = computed(() => {
const groups = [];
for (let i = 0; i < shishiArr.value.length; i += 3) {
groups.push(shishiArr.value.slice(i, i + 3));
}
return groups;
});
// 自动计算综合输差
watchEffect(() => {
const station = shishiArr.value[3]; // 站输差
const line = shishiArr.value[4]; // 线输差
const composite = shishiArr.value[5]; // 综合输差
// 日输气量计算
const dailyStation = parseFloat(station.dailyVolume) || 0;
const dailyLine = parseFloat(line.dailyVolume) || 0;
composite.dailyVolume = (dailyStation + dailyLine).toFixed(4);
// 年输气量计算
const yearStation = parseFloat(station.yearVolume) || 0;
const yearLine = parseFloat(line.yearVolume) || 0;
composite.yearVolume = (yearStation + yearLine).toFixed(4);
composite.yearPerCent = calcPercent(composite.yearPlan, composite.yearVolume);
console.log(composite);
});
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;
// console.log(queryParms);
queryJinriShengchansj(queryParms).then((res) => {
if (res.success) {
// console.log(res);
dataJinri.value = res.result.records;
dataJinriSumUnit.value = sumByUnit(dataJinri.value); //包含gas unit rq cq totalGas
// console.log(dataJinriSumUnit.value);
// 使用 nextTick 等待 DOM 更新
nextTick();
getYearShengchansj(); //再获取今年以来的数据
}
});
};
const getYearShengchansj = () => {
const now = new Date();
let year = formatDate(now).split('-')[0];
let queryParms = {};
queryParms.yearStart = year;
queryParms.yearEnd = year;
// // console.log(2, queryParms.value);
queryYearShengchansj(queryParms).then((res) => {
if (res.success) {
try {
// // console.log(res.result);
let yearData = res.result[year];
// console.log(dataJinriSumUnit.value.length, dataJinriSumUnit.value, yearData.length,
// yearData);
dataJinriSumUnit.value.forEach((item) => {
yearData.forEach((itemYear) => {
// // console.log(item, itemYear);
if (item.unit === itemYear.unit) {
item.yearVolume = itemYear.yearSum || 0;
}
});
});
dataJinriSum.value = sumByGas(dataJinriSumUnit.value);
// console.log(dataJinriSum.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);
item.yearPerCent = calcPercent(item.yearPlan, item.yearVolume);
}
});
});
// console.log(shishiArr);
} catch (error) {
// console.log(error);
}
}
});
};
function goHistory(val) {
uni.navigateTo({
url: '/pages/views/shengchan/ribaoshuju/rbsjLsxq?data=' + JSON.stringify(val)
});
}
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(4)); // 转为数值
}
function sumByGas(records) {
// console.log(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;
if (!unit.includes('区')) {
if (!summaryMap[unit]) {
// 初始化该 gas 类型的汇总对象
summaryMap[unit] = {
unit: unit,
gas: record.gas,
rq: 0,
sq: 0,
totalGas: 0,
yearVolume: 0
};
}
// 无论是否是第一次遇到该 unit 类型,都进行累加操作
summaryMap[unit].rq += record.rq || 0;
summaryMap[unit].sq += record.sq || 0;
summaryMap[unit].totalGas += record.totalGas || 0;
summaryMap[unit].yearVolume += record.yearVolume || 0;
}
});
return Object.values(summaryMap);
} catch (error) {
//TODO handle the exception
// console.log(error);
}
}
</script>
<style lang="scss" scoped>
.container {
display: flex;
flex-wrap: wrap;
padding: 20rpx;
gap: 20rpx;
}
.popup-content {
padding: 30rpx;
max-height: 40vh;
}
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #eee;
.title {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
}
.table-container {
width: 100%;
height: 30vh;
overflow: hidden;
}
.table {
min-width: 100%;
border: 2rpx solid #e8e8e8;
.tr {
display: flex;
border-bottom: 2rpx solid #e8e8e8;
&.header {
background-color: #fafafa;
font-weight: 600;
}
&.even {
background-color: #f8f8f8;
}
}
.th,
.td {
flex: 1;
min-width: 80rpx;
padding: 10rpx;
font-size: 22rpx;
font-weight: bold;
color: #333;
text-align: center;
white-space: nowrap;
height: 30rpx;
vertical-align: middle;
}
.th1,
.td1 {
flex: 1;
max-width: 40rpx;
padding: 10rpx;
font-size: 22rpx;
font-weight: bold;
color: #333;
text-align: center;
white-space: nowrap;
height: 30rpx;
vertical-align: middle;
}
.th {
background-color: #f0f0f0;
}
.td.negative {
color: #ff4444;
font-weight: 500;
}
}
.empty {
padding: 40rpx;
text-align: center;
color: #888;
font-size: 16rpx;
}
.card-item {
flex: 1 1 200rpx; // 基础宽度300rpx自动伸缩 selectedGas formatNumber
min-width: 240rpx;
max-width: calc(50% - 10rpx); // 最大不超过容器一半(考虑间距)
@media (min-width: 768px) {
max-width: calc(33.33% - 14rpx); // 大屏显示3列
}
}
.card {
background: #ffffff;
border-radius: 16rpx;
padding: 10rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
.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-item {
margin-bottom: 20px;
}
.progress-bar {
position: relative;
height: 20px;
background: #f0f0f0;
border-radius: 10px;
overflow: hidden;
}
.progress {
height: 100%;
transition: all 0.3s;
}
.progressTime {
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>