Merge remote-tracking branch 'remotes/origin/master'

# Conflicts:
#	env/.env.development
#	manifest.config.ts
#	src/manifest.json
This commit is contained in:
yangzhq68909 2025-09-22 09:44:39 +08:00
commit 875d6e7168
36 changed files with 2032 additions and 818 deletions

View File

@ -8,9 +8,11 @@ VITE_SHOW_SOURCEMAP = true
#VITE_WEBAPP = 'D://opt//AppUpdateTest'
VITE_WEBAPP = ''
#VITE_SERVER_BASEURL = 'http://10.75.15.247:8080/jeecg-boot'
#VITE_SERVER_BASEURL = 'http://10.96.108.144:8080/jeecg-boot'
VITE_SERVER_BASEURL = 'http://10.75.166.6:8080/jeecg-boot'
#VITE_SERVER_BASEURL = 'http://10.75.173.194:8080/jeecg-boot'
#VITE_SERVER_BASEURL = 'https://10.75.166.6/test'
VITE_SERVER_BASEURL = 'https://36.112.48.190/jeecg-boot'
#VITE_SERVER_BASEURL = 'https://36.112.48.190/jeecg-boot'
#VITE_SERVER_BASEURL = 'https://szcx.zyyt.sinopec.com/jeecg-boot'

4
env/.env.production vendored
View File

@ -8,7 +8,7 @@ VITE_SHOW_SOURCEMAP = false
#VITE_WEBAPP = 'D://opt//AppUpdateTest'
VITE_WEBAPP = ''
VITE_SERVER_BASEURL = 'https://szcx.zyyt.sinopec.com/jeecg-boot'
VITE_SERVER_BASEURL = 'https://10.75.166.6/test'
#VITE_SERVER_BASEURL = 'https://szcx.zyyt.sinopec.com/jeecg-boot'
#VITE_SERVER_BASEURL = 'https://szcx.zyyt.sinopec.com/wwapi'
#VITE_SERVER_BASEURL = 'https://szcx.zyyt.sinopec.com/yjapi'

View File

@ -17,8 +17,8 @@ export default defineManifestConfig({
name: VITE_APP_TITLE,
appid: VITE_UNI_APPID,
description: '',
versionName: '2.2.0',
versionCode: '20250909',
versionName: '2.3.0',
versionCode: '202509011',
transformPx: false,
locale: VITE_FALLBACK_LOCALE, // 'zh-Hans'
/* 5+App特有相关 */

View File

@ -10,6 +10,15 @@ export function gethomelist(config : object) { // 获取房间信息
})
}
export function gethomelistforApp(config : object) { //
return http({
url: '/RoomOperation/RoomOperation/gethomelistforApp',
method: 'GET',
data: config
})
}
export function testcontiont(config : object) { //
return http({
url: mqtturl + '/mqttSubclient/mqttSubclient/testgetcontint',

View File

@ -5,6 +5,7 @@ export function listApi(config : object) {
return http({
url: '/cxc_rlzy.zb/cxcRlzyZb/list',
method: 'GET',
timeout: 5000,
data: config
})
}

View File

@ -49,3 +49,19 @@ export function queryJldDataByZc(params : object) { // 获取站场计量点实
data: params
})
}
export function queryJldDataByJldID(params : object) { //
return http({
url: 'http://10.75.166.6:9999/Gyk/jldls/cxcSssjLssjJldls/getLssjByJldId',
method: 'GET',
data: params
})
}
export function queryJldRbDataByJldID(params : object) { //
return http({
url: '/tbqr/cxcScdtRbTbqr/listJldZongHe',
method: 'GET',
data: params
})
}

View File

@ -80,6 +80,7 @@
iframeWin.value = iframe.value.contentWindow
console.log(iframe.value)
console.log(iframe.value.contentWindow)
console.log(props.fileName)
try {
iframeWin.value.postMessage({
filename: props.fileName,
@ -138,7 +139,7 @@
if(props.taskDefKey=='task1715564108096'){ //
return flag = true; //
}
return flag = true; //
// return flag = true; //
if (sign.value) {
return flag = true; //
} else {

View File

@ -0,0 +1,61 @@
<template>
<view class="timeText">
<wd-text type="primary" :text="nowDateTime"></wd-text>
</view>
</template>
<script setup>
import {
ref,
onMounted,
computed,
nextTick,
watchEffect,
onUnmounted,
} from 'vue';
import {
onHide,
onShow
} from '@dcloudio/uni-app'
import {
formatDate
} from '@/utils/dateTime.ts';
const timer1 = ref(null);
const nowDateTime = ref("")
//
const getDateTime = () => {
//
if (timer1.value) {
clearInterval(timer1.value);
timer1.value = null;
}
timer1.value = setInterval(() => {
nowDateTime.value = formatDate(new Date(), "YYYY年MM月DD日 HH:mm:ss")
}, 1000);
};
onMounted(() => {
getDateTime()
})
onUnmounted(() => {
clearInterval(timer1.value);
})
onHide(() => {
clearInterval(timer1.value);
timer1.value = null;
})
onShow(() => {
getDateTime()
})
</script>
<style scoped>
.timeText {
text-align: center;
width: 100vw;
font-size: 20px;
}
</style>

View File

@ -2,8 +2,8 @@
"name": "数智产销",
"appid": "__UNI__9F097F0",
"description": "",
"versionName": "2.2.0",
"versionCode": "20250909",
"versionName": "2.3.0",
"versionCode": "202509011",
"transformPx": false,
"app-plus": {
"usingComponents": true,

View File

@ -75,6 +75,7 @@
if(info.value.jdsqwj){
info.value.jdsqwj = info.value.jdsqwj.replace("PdfFiles/PdfFile/",'')
}
console.log(info.value.jdsqwj)
}else{
toast.error(res.message)
}

View File

@ -13,30 +13,11 @@
<text class="info-value">{{ room.ssbmname }}</text>
</view>
</view>
<!-- 补位元素确保网格始终保持两列布局 -->
<view v-if="floor.rooms.length % 2 !== 0" class="room-placeholder"></view>
</view>
</view>
</view>
<!-- <view class="connection-section">
<button v-if="!connected" @click="connectWebSocket" class="connect-btn">
连接WebSocket
</button>
<button @click="disconnectWebSocket" class="disconnect-btn">
断开连接
</button>
<text :class="['status', connected ? 'connected' : 'disconnected']">
{{ connectionStatus }}
</text>
</view>
<view class="message-container">
<text class="subtitle">消息记录</text>
<scroll-view scroll-y="true" class="message-list">
<view v-for="(item, index) in messages" :key="index" :class="['message-item', item.type]">
<text class="message-content">{{ item.content }}</text>
</view>
</scroll-view>
</view> -->
</view>
</template>
@ -48,6 +29,7 @@
} from 'vue'
import {
gethomelist,
gethomelistforApp,
getMqttPushClient,
selectfjkzbmforfjid,
createdSwitch,
@ -90,7 +72,8 @@
//
const getofficehomelist = async () => {
await gethomelist().then((res) => {
//20250811,,
await gethomelistforApp().then((res) => {
if (res.success) {
homelist.value = res.result.map((item, index) => ({
...item,

View File

@ -1,6 +1,6 @@
<template>
<PageLayout :navbarShow="false">
<wd-card style="margin: 10px;" id="top1">
<wd-card style="margin: 10px;padding: 10px;" id="top1">
<wd-row>
<wd-col :span="24"><uni-title title="所属单位" align="left" type="h5"></uni-title></wd-col>
</wd-row>
@ -16,11 +16,12 @@
</wd-row>
<wd-row>
<wd-col :span="12">
<uni-easyinput v-model="realname" placeholder="姓名模糊查询" @change="getList" @clear="getList" />
<wd-input v-model="realname" clearable placeholder="姓名模糊查询" @change="getList"
@clear="getList"></wd-input>
</wd-col>
<wd-col :span="12">
<uni-easyinput v-model="contractNumber" placeholder="劳动合同号模糊查询" @change="getList"
@clear="getList" />
<wd-input v-model="contractNumber" clearable placeholder="劳动合同号模糊查询" @change="getList"
@clear="getList"></wd-input>
</wd-col>
</wd-row>
</wd-card>

View File

@ -0,0 +1,22 @@
<route lang="json5" type="page">
{
layout: 'default',
style: {
navigationStyle: 'custom',
navigationBarTitleText: '计划财务 ',
},
}
</route>
<template>
<PageLayout :navbarShow="false">
<view>
财务管理
</view>
</PageLayout>
</template>
<script>
</script>
<style>
</style>

View File

@ -0,0 +1,22 @@
<route lang="json5" type="page">
{
layout: 'default',
style: {
navigationStyle: 'custom',
navigationBarTitleText: '经营考核 ',
},
}
</route>
<template>
<PageLayout :navbarShow="false">
<view>
经营管理
</view>
</PageLayout>
</template>
<script>
</script>
<style>
</style>

View File

@ -0,0 +1,203 @@
<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>
{{startTime}}
</view>
<view>
<uni-datetime-picker type="daterange" v-model="lssjTimeRange" @change="getTime" start-placeholder="开始时间"
end-placeholder="结束时间">
</uni-datetime-picker>
</view>
<view style="text-align: center;padding: 5px;">
<wd-button custom-class="custom-value" size="small" plain clickable @click="handleForward">上一月</wd-button>
<wd-button custom-class="custom-value" size="small" plain clickable @click="handleThis">本月</wd-button>
<wd-button custom-class="custom-value" size="small" plain clickable @click="handleNext">后一月</wd-button>
<wd-button custom-class="custom-value" size="small" plain clickable @click="handleQuery">查询数据</wd-button>
<wd-button custom-class="custom-value" size="small" plain clickable @click="handleDrawLine">生成曲线</wd-button>
</view>
<view>
<scroll-view direction="vertical" style="height: 200px;">
<wd-table :data="chartData" height="200px">
<wd-table-col prop="scrq" label="日期" align="center"></wd-table-col>
<wd-table-col prop="jldname" label="计量点名称" align="center"></wd-table-col>
<wd-table-col prop="ljql" label="流量(m³)" align="center">
</wd-table-col>
</wd-table>
</scroll-view>
</view>
<view v-if="drawLineFlag">
<cxc-szcx-multiLineChart :data-list="chartData" x-field="scrq"
:y-fields="lineFields"></cxc-szcx-multiLineChart>
</view>
</PageLayout>
</template>
<script setup>
import {
queryJldRbDataByJldID
} from '@/api/production'
import {
formatDate
} from '@/utils/dateTime.ts';
import {
ref,
onMounted,
computed,
nextTick,
watchEffect,
onUnmounted,
} from 'vue';
const lineFields = ref([
{
name: '日流量',
field: 'ljql',
min: '0',
max: '500000',
unit: '10^4m³'
}
])
const props = defineProps({
jldData: {
type: Object,
default: () => {}
}
})
const chartData = ref([])
const drawLineFlag = ref(false)
function handleQuery() {
const dwmc = props.jldData.qu;
const zcmc = props.jldData.zhan;
const jldmc = props.jldData.jldname;
console.log(dwmc, zcmc, jldmc)
queryJldRbDataByJldID({
fenzu: 'a.scrq',
dwmc: dwmc,
zcmc: zcmc,
jldname: jldmc,
startTime: startTime.value,
endTime: endTime.value
}).then(res => {
console.log(res)
chartData.value = res.result
})
}
function handleDrawLine() {
drawLineFlag.value = true
}
// -
function handleForward() {
const now = new Date(startTime.value);
now.setMonth(now.getMonth() - 1);
const year = now.getFullYear();
const month = now.getMonth();
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month + 1, 0);
startTime.value = formatDate(firstDay, "YYYY-MM-DD");
endTime.value = formatDate(lastDay, "YYYY-MM-DD");
lssjTimeRange.value = [formatDate(firstDay, "YYYY-MM-DD"), formatDate(lastDay, "YYYY-MM-DD")];
getTime(); //
}
//
function handleThis() {
lssjTimeRange.value = getDefaultTimeRange()
getTime(); //
}
//
function handleNext() {
const now = new Date(startTime.value);
now.setMonth(now.getMonth() + 1);
const year = now.getFullYear();
const month = now.getMonth();
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month + 1, 0);
startTime.value = formatDate(firstDay, "YYYY-MM-DD");
endTime.value = formatDate(lastDay, "YYYY-MM-DD");
lssjTimeRange.value = [formatDate(firstDay, "YYYY-MM-DD"), formatDate(lastDay, "YYYY-MM-DD")];
getTime(); //
}
// 8:007:59
const getDefaultTimeRange = () => {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth();
//
const start = new Date(year, month, 1);
//
const end = new Date(year, month + 1, 0);
//
const formattedStart = formatDate(start, 'YYYY-MM-DD');
const formattedEnd = formatDate(end, 'YYYY-MM-DD');
//
startTime.value = formattedStart;
endTime.value = formattedEnd;
return [formattedStart, formattedEnd];
};
onMounted(() => {
//
setTimeout(() => {
lssjTimeRange.value = getDefaultTimeRange(0)
}, 500)
console.log(lssjTimeRange.value);
})
const startTime = ref('')
const endTime = ref('')
const lssjTimeRange = ref([])
//
const getTime = (e) => {
if (e && e.length === 2) {
startTime.value = formatDate(e[0], 'YYYY-MM-DD')
endTime.value = formatDate(e[1], 'YYYY-MM-DD')
// updateChart()
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,231 @@
<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>
<view style="text-align: center;padding: 5px;">
<wd-button custom-class="custom-value" size="small" plain clickable @click="handleForward">前一天</wd-button>
<wd-button custom-class="custom-value" size="small" plain clickable @click="handleNext">后一天</wd-button>
<wd-button custom-class="custom-value" size="small" plain clickable @click="handleQuery">查询数据</wd-button>
<wd-button custom-class="custom-value" size="small" plain clickable @click="handleDrawLine">生成曲线</wd-button>
</view>
<view>
<scroll-view direction="vertical" style="height: 200px;">
<wd-table :data="chartData" height="200px">
<wd-table-col prop="createTime" label="日期" align="center"></wd-table-col>
<wd-table-col prop="jldName" label="计量点名称" align="center"></wd-table-col>
<wd-table-col prop="yl" label="压力(MPa)" align="center"></wd-table-col>
<wd-table-col prop="wd" label="温度(℃)" align="center"></wd-table-col>
<wd-table-col prop="yc" label="差压(kPa)" align="center"></wd-table-col>
<wd-table-col prop="ssll" label="瞬时流量(m³/d)" align="center">
</wd-table-col>
<wd-table-col prop="jrl" label="今日流量(m³)" align="center">
</wd-table-col>
</wd-table>
</scroll-view>
</view>
<view v-if="drawLineFlag">
<cxc-szcx-multiLineChart :data-list="chartData" x-field="createTime"
:y-fields="lineFields"></cxc-szcx-multiLineChart>
</view>
</PageLayout>
</template>
<script setup>
import {
queryJldDataByJldID
} from '@/api/production'
import {
formatDate
} from '@/utils/dateTime.ts';
import {
ref,
onMounted,
computed,
nextTick,
watchEffect,
onUnmounted,
} from 'vue';
const lineFields = ref([{
name: '压力',
field: 'yl',
min: '0',
max: '2',
unit: 'MPa'
},
{
name: '温度',
field: 'wd',
min: '-10',
max: '40',
unit: '℃'
},
{
name: '差压',
field: 'yc',
min: '0',
max: '60',
unit: 'kPa'
},
{
name: '瞬时流量',
field: 'ssll',
min: '0',
max: '50000',
unit: 'm³/d'
},
{
name: '今日流量',
field: 'jrl',
min: '0',
max: '50000',
unit: 'm³'
}
])
const props = defineProps({
jldData: {
type: Object,
default: () => {}
}
})
const chartData = ref([])
const drawLineFlag = ref(false)
function handleQuery() {
const jldid = props.jldData.id;
queryJldDataByJldID({
jldId: jldid,
startTime: startTime.value,
endTime: endTime.value
}).then(res => {
chartData.value = JSON.parse(res.result)
chartData.value.forEach(item => {
item.createTime = formatDate(item.createTime, "YYYY-MM-DD HH:mm ss")
})
console.log(123, chartData.value)
})
}
function handleDrawLine() {
drawLineFlag.value = true
}
// -
function handleForward() {
// 使
lssjTimeRange.value = getDefaultTimeRange(-1);
}
//
function handleNext() {
//
const currentStart = new Date(startTime.value);
// 8
const today8AM = new Date();
today8AM.setHours(8, 0, 0, 0);
//
if (currentStart < today8AM || isSameDay(currentStart, today8AM)) {
lssjTimeRange.value = getDefaultTimeRange(1);
} else {
//
uni.showToast({
title: '已是最新数据',
icon: 'none',
duration: 1500
});
}
}
// 8:007:59
const getDefaultTimeRange = (days) => {
// 使
var baseDate;
if (startTime.value && new Date(startTime.value).toString() !== 'Invalid Date') {
baseDate = new Date(startTime.value);
} else {
// 使 fallback
baseDate = new Date();
}
// +
const targetDate = new Date(baseDate);
targetDate.setDate(baseDate.getDate() + days);
// 8:00:00
const start = new Date(targetDate);
start.setHours(8, 0, 0, 0);
// +17:59:59
const end = new Date(targetDate);
end.setDate(targetDate.getDate() + 1);
end.setHours(7, 59, 59, 0);
//
const formattedStart = formatDate(start, 'YYYY-MM-DD HH:mm:ss');
const formattedEnd = formatDate(end, 'YYYY-MM-DD HH:mm:ss');
//
startTime.value = formattedStart;
endTime.value = formattedEnd;
return [formattedStart, formattedEnd];
};
//
const isSameDay = (date1, date2) => {
return date1.getFullYear() === date2.getFullYear() &&
date1.getMonth() === date2.getMonth() &&
date1.getDate() === date2.getDate();
};
onMounted(() => {
//
setTimeout(() => {
lssjTimeRange.value = getDefaultTimeRange(0)
}, 500)
console.log(lssjTimeRange.value);
})
const startTime = ref('')
const endTime = ref('')
const lssjTimeRange = ref([])
//
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,50 @@
<route lang="json5" type="page">
{
layout: 'default',
style: {
navigationStyle: 'custom',
navigationBarTitleText: '实时数据 ',
},
}
</route>
<template>
<PageLayout :navbarShow="false">
<view>
<view style="text-align:center;padding:10px">
<date-time-show></date-time-show>
</view>
<wd-card title="天然气实时数据">
天然气实时数据汇总计算结果用标签显示出各类天然气的实时数据需要工业库后台进行计算
<template #footer>
<wd-button size="small" @click="gotoTrqSssj" plain>查看详情</wd-button>
</template>
</wd-card>
<wd-card title="管道运行实时数据">
各条管线的天然气实时数据汇总计算结果用标签显示出各类天然气的实时数据需要工业库后台进行计算
<template #footer>
<wd-button size="small" @click="gotoGdSssj" plain>查看详情</wd-button>
</template>
</wd-card>
</view>
</PageLayout>
</template>
<script setup>
import dateTimeShow from '@/components/dataTimeShow.vue'
function gotoTrqSssj() {
uni.navigateTo({
url: '/pages-production/shishishuju/trqSssj'
})
}
function gotoGdSssj() {
uni.navigateTo({
url: '/pages-production/shishishuju/trqSssj'
})
}
</script>
<style>
</style>

View File

@ -0,0 +1,361 @@
<route lang="json5" type="page">
{
layout: 'default',
style: {
navigationStyle: 'custom',
navigationBarTitleText: '天然气实时数据',
},
}
</route>
<template>
<PageLayout navTitle="天然气实时数据" routeMethod="pushTab">
<!-- 标题行 -->
<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="sssjFlag" position="bottom" custom-style="width:100%;height: 70vh;" @close="handleClose">
<sssj-chart :jldData="jldData"></sssj-chart>
</wd-popup>
<wd-popup v-model="lssjFlag" position="bottom" custom-style="width:100%;height: 70vh;" @close="handleClose">
<lssj-chart :jldData="jldData"></lssj-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) {
lssjFlag.value = true;
jldData.value = e
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()
// stationID.value = "1267633458481725442"
})
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

@ -183,47 +183,6 @@
"navigationBarTitleText": "工作台",
"navigationStyle": "custom"
}
},
{
"path": "pages/production/ribaoshuju/rbsjLsxq",
"type": "page",
"layout": "default",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "历史数据"
}
},
{
"path": "pages/production/ribaoshuju/trqRbsj",
"type": "page"
},
{
"path": "pages/production/ribaoshuju/yyRbsj",
"type": "page"
},
{
"path": "pages/production/shishishuju/aqbjSssj",
"type": "page"
},
{
"path": "pages/production/shishishuju/gycsSssj",
"type": "page"
},
{
"path": "pages/production/shishishuju/index",
"type": "page"
},
{
"path": "pages/production/shishishuju/nyxhSssj",
"type": "page"
},
{
"path": "pages/production/shishishuju/trqSssj",
"type": "page"
},
{
"path": "pages/production/shishishuju/ysjSssj",
"type": "page"
}
],
"subPackages": [
@ -384,6 +343,15 @@
{
"root": "pages-operate",
"pages": [
{
"path": "caiwu/index",
"type": "page",
"layout": "default",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "计划财务 "
}
},
{
"path": "file/detail",
"type": "page",
@ -402,6 +370,15 @@
"navigationBarTitleText": "公文/通知公告/法律法规/上级制度/厂级制度"
}
},
{
"path": "jingying/index",
"type": "page",
"layout": "default",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "经营考核 "
}
},
{
"path": "sc/index",
"type": "page",
@ -630,6 +607,80 @@
"type": "page"
}
]
},
{
"root": "pages-production",
"pages": [
{
"path": "ribaoshuju/rbsjLsxq",
"type": "page",
"layout": "default",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "历史数据"
}
},
{
"path": "ribaoshuju/trqRbsj",
"type": "page"
},
{
"path": "ribaoshuju/yyRbsj",
"type": "page"
},
{
"path": "shishishuju/aqbjSssj",
"type": "page"
},
{
"path": "shishishuju/gycsSssj",
"type": "page"
},
{
"path": "shishishuju/index",
"type": "page",
"layout": "default",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "实时数据 "
}
},
{
"path": "shishishuju/nyxhSssj",
"type": "page"
},
{
"path": "shishishuju/trqSssj",
"type": "page",
"layout": "default",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "天然气实时数据"
}
},
{
"path": "shishishuju/ysjSssj",
"type": "page"
},
{
"path": "shishishuju/chart/lssjChart",
"type": "page",
"layout": "default",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "历史数据图表"
}
},
{
"path": "shishishuju/chart/sssjChart",
"type": "page",
"layout": "default",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "历史数据图表"
}
}
]
}
]
}

View File

@ -9,8 +9,118 @@
</route>
<template>
<PageLayout :navbarShow="false">
<view style="margin: 100px;">
功能正在开发中... 请耐心等待
<view class="nav">
<view class="nav_box">
<scroll-view direction="horizontal">
<uni-segmented-control :current="current" :values="items" styleType="string" mode="segmented"
@clickItem="onClickItem"></uni-segmented-control>
</scroll-view>
</view>
</view>
<view class="content">
<view v-if="current === 0">
<scroll-view scroll-y :style="{ height: scrollViewHeight + 'px' }">
<caiwu-guanli></caiwu-guanli>
</scroll-view>
</view>
<view v-if="current === 1">
<scroll-view scroll-y :style="{ height: scrollViewHeight + 'px' }">
<jingying-guanli></jingying-guanli>
</scroll-view>
</view>
</view>
</PageLayout>
</template>
<script setup>
import {
ref,
onMounted,
computed,
nextTick,
watchEffect,
onUnmounted
} from 'vue';
import caiwuGuanli from '@/pages-operate/caiwu/index'
import jingyingGuanli from '@/pages-operate/jingying/index'
const items = ref(['计划财务', '经营考核', '外部市场'])
const current = ref(0)
const res = wx.getSystemInfoSync();
const statusHeight = res.statusBarHeight; //
const cusnavbarheight = (statusHeight + 50) + "px";
const scrollViewHeight = ref(0); //
const activeColor = ref("#0000ff")
const inActiveColor = ref("#000000")
function onClickItem(e) {
if (current.value != e.currentIndex) {
current.value = e.currentIndex;
}
}
onMounted(() => {
calculateScrollViewHeight();
// 使 Uniapp
uni.onWindowResize(calculateScrollViewHeight);
});
onUnmounted(() => {
// Uniapp
uni.offWindowResize(calculateScrollViewHeight);
});
const calculateScrollViewHeight = () => {
//
const screenHeight = uni.getSystemInfoSync().windowHeight;
//
const query = uni.createSelectorQuery();
//
query
.select('.nav')
.boundingClientRect();
//
query.exec((res) => {
let totalHeight = 0;
res.forEach((element) => {
if (element) {
totalHeight += element.height;
}
});
// scroll-view
scrollViewHeight.value = screenHeight - totalHeight;
});
};
</script>
<style lang="scss" scoped>
.nav {
width: calc(100%);
height: v-bind(cusnavbarheight);
font-size: 24rpx;
//color: #333333;
position: fixed;
z-index: 99;
background-image: url('@/static/navbg.png');
background-repeat: no-repeat;
background-size: 750rpx 458rpx;
}
.nav_box {
font-size: 18;
position: absolute;
bottom: 6rpx;
width: calc(100% - 60rpx);
left: 30rpx;
right: 30rpx;
}
.content {
position: absolute;
top: v-bind(cusnavbarheight);
width: 100%;
min-height: calc(100vh - v-bind(cusnavbarheight));
}
</style>

View File

@ -9,51 +9,35 @@
</route>
<template>
<PageLayout :navbarShow="false">
<view>
<view class="placeholder"></view>
<view style="width: 100%; display: grid; place-items: center">
<uni-title :title="dateDate + ':生产情况'" type="h1" color="blue" />
<view class="nav">
<view class="nav_box">
<scroll-view direction="horizontal">
<uni-segmented-control :current="current" :values="items" styleType="string" mode="segmented"
@clickItem="onClickItem"></uni-segmented-control>
</scroll-view>
</view>
<view style="margin: 0 10px;">
<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>
<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 v-if="current === 1">
<scroll-view scroll-y :style="{ height: scrollViewHeight + 'px' }">
<sssjForm></sssjForm>
</scroll-view>
</view>
</view>
</view>
</PageLayout>
</template>
<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 {
ref,
onMounted,
@ -62,14 +46,19 @@
watchEffect,
onUnmounted
} 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/index';
const items = ref(['实时数据', '日报数据', '安全管理', '工程技术', '仪控设备'])
const current = ref(0)
const res = wx.getSystemInfoSync();
const statusHeight = res.statusBarHeight; //
const cusnavbarheight = statusHeight + 44 + 'px';
const scrollViewHeight = ref(0); //
const timePercent = ref(0);
const dateDate = ref('');
const cusnavbarheight = (statusHeight + 50) + "px";
const scrollViewHeight = ref(0); //
const activeColor = ref("#0000ff")
const inActiveColor = ref("#000000")
function onClickItem(e) {
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(() => {
dateDate.value = strDate();
timePercent.value = getYearProgress();
calculateScrollViewHeight();
//
window.addEventListener('resize', calculateScrollViewHeight);
// 使 Uniapp
uni.onWindowResize(calculateScrollViewHeight);
});
onUnmounted(() => {
//
window.removeEventListener('resize', calculateScrollViewHeight);
// Uniapp
uni.offWindowResize(calculateScrollViewHeight);
});
onHide(()=>{ // by
current.value = 0;
})
const calculateScrollViewHeight = () => {
//
const screenHeight = uni.getSystemInfoSync().windowHeight;
@ -111,18 +85,7 @@
query
.select('.nav')
.boundingClientRect();
query
.select('.placeholder')
.boundingClientRect();
query
.select('.uni-title')
.boundingClientRect();
query
.select('.uni-segmented-control')
.boundingClientRect();
query
.select('.progress-bartime')
.boundingClientRect();
//
query.exec((res) => {
let totalHeight = 0;
@ -132,62 +95,38 @@
}
});
// scroll-view
scrollViewHeight.value = screenHeight - totalHeight - 80;
scrollViewHeight.value = screenHeight - totalHeight;
});
};
</script>
<style lang="scss" scoped>
.nav {
width: calc(100% - 60rpx);
padding: 0 30rpx;
width: calc(100%);
height: v-bind(cusnavbarheight);
font-size: 24rpx;
color: #ffffff;
//color: #333333;
position: fixed;
top: 0;
left: 0;
z-index: 99;
background-image: url('../../static/my/navbg.png');
background-image: url('@/static/navbg.png');
background-repeat: no-repeat;
background-size: 750rpx 458rpx;
}
.placeholder {
height: v-bind(cusnavbarheight);
}
.nav_box {
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;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: red;
/* 保持红色 */
font-size: 16px;
font-weight: bold;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
/* 提升可读性 */
bottom: 6rpx;
width: calc(100% - 60rpx);
left: 30rpx;
right: 30rpx;
}
.content {
position: absolute;
top: v-bind(cusnavbarheight);
width: 100%;
min-height: calc(100vh - v-bind(cusnavbarheight));
}
</style>

View File

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

View File

@ -1,293 +0,0 @@
<template>
<PageLayout :navbarShow="false">
<!-- 标题行 -->
<view class="header-row">
<view class="title">天然气实时数据</view>
<view style="min-width: 200px;">
<cxc-szcx-stationJl-select v-model="stationID" returnCodeOrID="id" @change="onChange">
</cxc-szcx-stationJl-select>
</view>
</view>
<!-- <button size="mini" @click="getData">连接WebSocket</button> -->
<view class="container">
<view v-for="(item, index) in jlData" :key="index" class="card">
<view class="field-item">
<text class="titlejl">{{ stationName }}--{{ 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-label">瞬时流量(/d)</text>
<text class="field-value">{{ formatNumber(item.ssll) || '-' }}</text>
</view>
<!-- 今日流量 -->
<view class="field-item">
<text class="field-label">今日流量()</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>
</PageLayout>
</template>
<script setup>
import {
queryJldZcList,
queryJldDataByZc
} from '@/api/production'
import {
formatDate,
getDateAfterDays
} from '@/utils/dateTime';
const stationList = ref([])
//
const popupSelect = ref(null);
const stationID = ref("")
const stationName = ref("")
const jlData = ref([])
const sssjUrl = ref('wss://szcx.zyyt.sinopec.com/Gyk/websocket/')
const jlByzc = ref('https://szcx.zyyt.sinopec.com/Gyk/sssj/GetJlByZc')
//websocket线
// websocket
function connectSocketInit() {
console.log(11, )
let userID = '1412198011559055361'
// this.socketTasksocket
uni.connectSocket({
// ,使ws://127.0.0.1:9099
// url: 'wss://'+this.$api.sellerWebsocket+'/'+this.userinfo.id,
url: sssjUrl.value + userID,
success(data) {
console.log(data);
console.log('websocket连接成功');
}
});
// ,
uni.onSocketOpen(function(res) {
console.log('WebSocket连接已打开');
});
uni.onSocketMessage(function(res) {
console.log('收到服务器内容:' + res.data);
});
// socket
uni.onSocketClose(function(res) {
console.log('WebSocket 已关闭!');
});
}
function getData() {
connectSocketInit()
}
function onChange(e, data) {
console.log(2, e, data.value);
stationID.value = e
stationName.value = data.value.title
getScData(); //
}
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 websock = ref(null);
const timer2 = ref(null);
//
const websocketheart = () => {
timer2.value = setInterval(() => {
if (websock.value && websock.value.readyState === 1) {
//
// connectSocketInit()
}
if(stationID.value){
getScData();
}
}, 1000);
};
onMounted(() => {
queryJldZcList({
pId: '1267633406031953921'
}).then((res) => {
if (res.success) {
stationList.value = res.result
console.log(1, stationList.value)
}
})
websocketheart()
})
onUnmounted(()=>{ //
//
console.log(22222)
clearInterval(timer2.value);
})
//
const formatNumber = (num) => {
let temp = 0;
try {
temp = parseFloat(num);
} catch (error) {
//TODO handle the exception
}
return temp.toFixed(4).replace(/\.?0+$/, '');
};
</script>
<style 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;
}
.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: 8px;
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;
}
</style>

View File

@ -19,15 +19,6 @@ interface NavigateToOptions {
"/pages/sljd/index" |
"/pages/user/people" |
"/pages/workHome/index" |
"/pages/production/ribaoshuju/rbsjLsxq" |
"/pages/production/ribaoshuju/trqRbsj" |
"/pages/production/ribaoshuju/yyRbsj" |
"/pages/production/shishishuju/aqbjSssj" |
"/pages/production/shishishuju/gycsSssj" |
"/pages/production/shishishuju/index" |
"/pages/production/shishishuju/nyxhSssj" |
"/pages/production/shishishuju/trqSssj" |
"/pages/production/shishishuju/ysjSssj" |
"/pages-home/device-control/office/ALLleader" |
"/pages-home/device-control/office/index" |
"/pages-home/device-control/office/officehomedevice" |
@ -44,8 +35,10 @@ interface NavigateToOptions {
"/pages-sub/online/online" |
"/pages-sub/online/onlineCard" |
"/pages-sub/online/onlineTable" |
"/pages-operate/caiwu/index" |
"/pages-operate/file/detail" |
"/pages-operate/file/index" |
"/pages-operate/jingying/index" |
"/pages-operate/sc/index" |
"/pages-humanResource/absence/add" |
"/pages-humanResource/absence/detail" |
@ -78,7 +71,18 @@ interface NavigateToOptions {
"/pages-bpm/SuperiorSystem/index" |
"/pages-bpm/unconventional/index" |
"/pages-bpm/unconventional/stamp" |
"/pages-bpm/zbkh/index";
"/pages-bpm/zbkh/index" |
"/pages-production/ribaoshuju/rbsjLsxq" |
"/pages-production/ribaoshuju/trqRbsj" |
"/pages-production/ribaoshuju/yyRbsj" |
"/pages-production/shishishuju/aqbjSssj" |
"/pages-production/shishishuju/gycsSssj" |
"/pages-production/shishishuju/index" |
"/pages-production/shishishuju/nyxhSssj" |
"/pages-production/shishishuju/trqSssj" |
"/pages-production/shishishuju/ysjSssj" |
"/pages-production/shishishuju/chart/lssjChart" |
"/pages-production/shishishuju/chart/sssjChart";
}
interface RedirectToOptions extends NavigateToOptions {}

View File

@ -0,0 +1,314 @@
<template>
<view>
<l-echart ref="chart" @finished="drawChart" />
</view>
</template>
<script setup>
import * as echarts from 'echarts';
import {
ref,
watch,
onMounted,
onUnmounted
} from 'vue'; // refAPI
import {
formatDate,
getDateAfterDays,
getDateAfterMonths
} from '@/utils/dateTime';
const props = defineProps({
dataList: {
type: Array,
default: () => [],
required: true
},
xField: {
type: String,
default: 'createTime' // xField'rqDate'createTimecreateTime
},
yFields: {
type: Object, // yFields线StringArray
default: () => [],
required: true
}
});
//
const colorData = ref([{
color: '#000000'
},
{
color: '#00007f'
},
{
color: '#ff0000'
},
{
color: '#005500'
},
{
color: '#55007f'
},
{
color: '#ffff00'
}
]);
const chart = ref(null);
const chartOption = ref({}); // undefined
const chartTitle = ref('历史趋势'); // watch
// 1. chartOption.value
const generateOptions = () => {
const serie = []; //
const yData = []; // Y
const xData = []; // X
const legendData = []; //
let positionIndex = 0;
const yDataNum = props.yFields.length; // Y = 线
// X
for (let i = 0; i < yDataNum; i++) {
xData.push('');
}
// 线Y
for (let i = 0; i < props.yFields.length; i++) {
const yFieldItem = props.yFields[i]; //
// Y
const yaxisTemp = {
type: 'value',
nameRotate: 270,
nameLocation: 'middle',
nameGap: 20,
name: '',
position: 'left',
axisLabel: {
formatter: '{value}'
},
axisLine: {
lineStyle: {
color: '#61A0A8',
width: 1
}
}
};
// +
const legendName = `${yFieldItem.name}(${yFieldItem.unit})`;
legendData.push(legendName);
// Yssll
if (yFieldItem.field === 'ssll') {
yaxisTemp.position = 'left';
yaxisTemp.nameGap = -15;
} else {
yaxisTemp.position = 'right';
yaxisTemp.offset = 30 * positionIndex;
positionIndex++;
}
// Yv[i].maxyFieldItem.max
yaxisTemp.name = legendName;
yaxisTemp.min = yFieldItem.min ?? 0; // min0
yaxisTemp.max = yFieldItem.max ?? 100; // max100
yaxisTemp.axisLine.lineStyle.color = colorData.value[i]?.color || '#61A0A8'; //
// yaxisTemp.show=false
yData.push(yaxisTemp);
//
const serieTemp = {
field: yFieldItem.field,
name: legendName,
showSymbol: false,
type: 'line',
lineStyle: {
width: 2
},
data: [],
yAxisIndex: i // iY
};
// this.serie.pushseriepush
serie.push(serieTemp);
}
//
return {
color: ['#000000', '#00007f', '#ff0000', '#005500', '#55007f', '#ffff00'],
title: {
textAlign: 'auto',
text: chartTitle.value
},
tooltip: {
trigger: 'axis',
alwaysShowContent: true,
axisPointer: {
type: 'line',
show: false
}
},
toolbox: {
showTitle: true,
orient: 'horizontal',
feature: {
dataView: {
show: true,
readOnly: false
},
restore: {
show: true
},
saveAsImage: {
show: true
}
},
right: '10%',
top: '0'
},
legend: {
data: legendData,
itemGap: 5,
padding: [35, 5, 25, 5],
type: 'scroll',
show: true
},
grid: {
width: 'auto',
top: '20%',
left: '5px',
right: '5px', // Y
bottom: 20,
containLabel: true
},
xAxis: {
type: 'category',
axisTick: {
alignWithLabel: true
},
show: true,
data: xData
},
yAxis: yData,
series: serie
};
};
// 2. 访
const processSeriesData = () => {
const ssData = props.dataList;
// 访chartOption.value
const xData = [...chartOption.value.xAxis.data]; // X series
const serie = [...chartOption.value.series]; //
const yData = [...chartOption.value.yAxis]; // Y
//
xData.length = 0;
serie.forEach(item => (item.data.length = 0));
//
ssData.forEach(item => {
// Xprops.xFieldcreateTime
const ctime = item[props.xField];
xData.push(ctime);
// 线
serie.forEach((serieItem, j) => {
const field = props.yFields[j].field;
const tempValue = item[field];
// 0
serieItem.data.push(tempValue ?? 0);
});
});
// Ythis.seriethis.maxArrValue
serie.forEach((serieItem, mm) => {
const maxValue = maxArrValue(serieItem.data);
console.log(1, maxValue)
yData[mm].max = Math.round(maxValue * 12) / 10 || 100; // 0100
console.log(2, yData[mm].max)
});
// .value
chartOption.value = {
...chartOption.value, //
xAxis: {
...chartOption.value.xAxis,
data: xData
},
series: serie,
yAxis: yData
};
};
// 3. NaN
const maxArrValue = (data) => {
// Number
const validNumbers = data
.map(item => Number(item))
.filter(item => !isNaN(item));
// 0
return validNumbers.length > 0 ?
Math.max(...validNumbers) :
0;
};
// 4. 使
watch(
() => props.dataList,
(newVal) => {
if (newVal.length === 0) return; //
drawChart()
}, {
deep: true,
immediate: true
} //
);
// 5. chartOption.value
const drawChart = async () => {
//
chartOption.value = generateOptions();
processSeriesData()
if (!chart.value) return;
// EChartssetTimeoutasync/await
const myChart = await chart.value.init(echarts);
myChart.setOption(chartOption.value);
};
//
onMounted(() => {
setTimeout(() => {
drawChart();
}, 500)
});
//
onUnmounted(() => {
if (chart.value) {
const myChart = chart.value.getInstance();
myChart.dispose();
chart.value = null;
}
window.removeEventListener('resize', () => {}); //
});
</script>
<style scoped>
</style>

View File

@ -0,0 +1,97 @@
{
"id": "cxc-szcx-multiLineChart",
"displayName": "cxc-szcx-multiLineChart",
"version": "1.0.0",
"description": "cxc-szcx-multiLineChart",
"keywords": [
"cxc-szcx-multiLineChart"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0",
"uni-app": "^3.1.0",
"uni-app-x": "^3.1.0"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "",
"data": "",
"permissions": ""
},
"npmurl": "",
"darkmode": "-",
"i18n": "-",
"widescreen": "-"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "-",
"aliyun": "-",
"alipay": "-"
},
"client": {
"uni-app": {
"vue": {
"vue2": "-",
"vue3": "-"
},
"web": {
"safari": "-",
"chrome": "-"
},
"app": {
"vue": "-",
"nvue": "-",
"android": "-",
"ios": "-",
"harmony": "-"
},
"mp": {
"weixin": "-",
"alipay": "-",
"toutiao": "-",
"baidu": "-",
"kuaishou": "-",
"jd": "-",
"harmony": "-",
"qq": "-",
"lark": "-"
},
"quickapp": {
"huawei": "-",
"union": "-"
}
},
"uni-app-x": {
"web": {
"safari": "-",
"chrome": "-"
},
"app": {
"android": "-",
"ios": "-",
"harmony": "-"
},
"mp": {
"weixin": "-"
}
}
}
}
}
}

View File

@ -0,0 +1,34 @@
# cxc-szcx-multiLineChart
# 这个多字段趋势图组件具有以下特点和功能:
类型安全:使用 TypeScript 定义了清晰的接口,确保数据类型正确
灵活配置:通过 props 参数可以配置需要展示的字段、时间字段、标题等
多字段展示:支持同时展示多个数据字段的趋势线(如 yl, wd, yc 等)
参考线功能:每个字段都可以设置参考值,自动生成对应的参考线
交互功能:
支持图例筛选,可单独显示 / 隐藏某个字段
提供数据缩放功能,可查看局部数据
悬停时显示详细数据信息
窗口大小变化时自动调整图表
使用示例:
<template>
<view class="container">
<multi-field-trend-chart
:data-list="dataList"
time-field="createTime"
:fields="[
{ field: 'yl', name: '压力', referenceValue: 0.73 },
{ field: 'wd', name: '温度', color: '#ff6347' },
{ field: 'yc', name: '压力差' },
{ field: 'ssll', name: '瞬时流量' },
{ field: 'jrl', name: '累计流量' }
]"
title="文增伴生气外输数据趋势"
height="600rpx"
/>
</view>
</template>
<script setup lang="ts">
import MultiFieldTrendChart from '@/components/MultiFieldTrendChart.vue';
import { dataList } from '@/data/trendData'; // 导入您的数据
</script>

View File

@ -71,7 +71,8 @@ export default ({ command, mode }) => {
'src/pages-integrated',
'src/pages-politics',
'src/pages-process',
'src/pages-bpm'
'src/pages-bpm',
'src/pages-production'
], // pages
dts: 'src/types/uni-pages.d.ts',
}),