| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458 |
- <template>
- <view class="device-details-page">
- <cu-custom :isBack="true">
- <template slot="content">
- <view class="nav-title">{{ deviceInfo.devName }}</view>
- </template>
- </cu-custom>
- <!-- 设备基本信息 -->
- <view class="device-info">
- <view class="operation" @click.stop="isShowOperation = !isShowOperation">操作</view>
- <view class="operation-container" v-if="isShowOperation" @click="closeOperationHandler">
- <view class="operation-background"></view>
- <view class="operation-content">
- <view class="operation-item" @click="goPage('devControl')">
- <image :src="serviceIcon" class="operation-icon"></image>
- 参数设置
- </view>
- <!-- <view class="operation-item" @click="goPage('simDetail')">
- <image :src="simIcon" class="operation-icon"></image>
- SIM卡
- </view> -->
- <!-- <view class="operation-item" @click="modification">
- <image :src="editIcon" class="operation-icon"></image>
- 修改
- </view> -->
- </view>
- </view>
- <view @click="copy(deviceInfo.devBid)" class="info-item">
- <text class="info-label">设备ID</text>
- <text class="info-value">{{ deviceInfo.devBid }}</text>
- <image
- src="/static/images/device/copy.svg"
- mode=""
- class="info-img"
- ></image>
- </view>
- <view class="info-item">
- <text class="info-label">上报时间</text>
- <text class="info-value">{{ formatTimestamp(deviceInfo.uptime) }}</text>
- </view>
- <view class="info-item">
- <text class="info-label">设备位置</text>
- <text class="info-value">{{ deviceInfo.address }}</text>
- </view>
- <view class="dev-status">{{
- deviceInfo.devStatus == '1' ? '在线' : '离线'
- }}</view>
- </view>
- <!-- 标签页切换 -->
- <view class="tab-container">
- <view class="tab-top">
- <view
- class="tab-item"
- :class="{ active: activeTab === 'monitoring' }"
- @click="switchTab('monitoring')"
- >
- <text class="tab-text">实时数据</text>
- <image
- v-if="activeTab === 'monitoring'"
- src="/static/images/device/smile.svg"
- mode=""
- class="smile"
- ></image>
- </view>
- <view
- class="tab-item"
- :class="{ active: activeTab === 'details' }"
- @click="switchTab('details')"
- >
- <text class="tab-text">历史数据</text>
- <image
- v-if="activeTab === 'details'"
- src="/static/images/device/smile.svg"
- mode=""
- class="smile"
- ></image>
- </view>
- </view>
- <view class="datetime">
- <view class="datetime-left" @click="openDatePicker">
- <view class="datetime-start">
- {{ startDate }}
- </view>
- 至
- <view class="datetime-end">
- {{ endDate }}
- </view>
- </view>
- <view>
- <u-icon name="calendar" size="24"></u-icon>
- </view>
- </view>
- </view>
- <!-- 标签页内容 -->
- <view class="tab-content">
- <!-- 监测要素页面 -->
- <view v-if="activeTab === 'monitoring'" class="monitoring-page">
- <view
- class="data-card"
- >
- <image
- src="https://s3.hnyfwlw.com/webstaticimg/bigdata_app/img/gssq.png"
- alt=""
- class="status-img"
- ></image>
- <view class="data-card-right">
- <view class="device-qx">
- <image src="https://s3.hnyfwlw.com/webstaticimg/bigdata_app/img/trsd.png" alt="" class="qx-img"></image>
- 空气温度:<text style="font-weight: bold;">{{at}}</text>℃
- </view>
- <view class="device-list">
- <view class="device-temp-list">
- <view class="temp-item" v-for="swc in swcList" :key="swc.key">
- <image src="https://s3.hnyfwlw.com/webstaticimg/bigdata_app/img/trwd.png" alt="" class="temp-icon" v-show="swc.isShow"></image>
- <view class="temp-content" v-show="swc.isShow">
- <view class="temp-value">{{swc.val}}
- <text class="unit">%</text>
- </view>
- <view class="temp-name">{{swc.label}}</view>
- </view>
- </view>
- </view>
- <view class="device-swc-list">
- <view class="swc-item" v-for="item in tempList" :key="item.key">
- <image src="https://s3.hnyfwlw.com/webstaticimg/bigdata_app/img/trhsl.png" alt="" class="swc-icon" v-show="item.isShow"></image>
- <view class="swc-content" v-show="item.isShow">
- <view class="swc-value">
- {{item.val}}
- <text class="unit">℃</text>
- </view>
- <view class="swc-name">{{item.label}}</view>
- </view>
- </view>
- </view>
- <view class="device-dept-list">
- <view class="dept-item" v-for="item in ecsList" :key="item.key">
- <image src="https://s3.hnyfwlw.com/webstaticimg/bigdata_app/img/ec.png" alt="" class="dept-icon" v-show="item.isShow"></image>
- <view class="dept-content" v-show="item.isShow">
- <view class="dept-value">
- {{item.val}}
- <text class="unit">ms/cm</text>
- </view>
- <view class="dept-name">{{item.label}}</view>
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- </view>
- <!-- 设备详情页面 -->
- <view v-if="activeTab === 'details'" class="details-page">
- <view class="chart-container">
- <view class="chart-wrap" v-if="dat_char && dat_char.length > 0">
- <canvas
- v-show="!show && !isShowOperation"
- canvas-id="datCharChart"
- id="datCharChart"
- class="charts"
- @touchstart="touchLineA($event)"
- @touchmove="moveLineA($event)"
- @touchend="touchEndLineA($event)"
- disable-scroll="true"
- :style="{'width':'100%','height':cHeight*pixelRatio+'px','transform':'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"
- ></canvas>
- </view>
- <view class="empty-state" v-else>
- <u-empty text="暂无数据" mode="list"></u-empty>
- </view>
- </view>
- <!-- 设备数据表格 -->
- <view class="table-container">
- <view class="table-control">
- <view class="title">历史数据</view>
- <!-- <view class="date-board" @click="openDatePicker">
- <text>{{ startDate }}</text>
- <text class="line">至</text>
- <text>{{ endDate }}</text>
- <image class="date-icon" src="/static/images/device/date.svg" />
- </view> -->
- </view>
- <view class="table-wrap" v-if="tableData && tableData.length > 0">
- <view class="fixed-column">
- <view class="table-cell header">上报时间</view>
- <view
- class="table-cell"
- v-for="(item, idx) in tableData"
- :key="idx"
- >
- {{ formatTimestamp(item.upl_time) }}
- </view>
- </view>
- <view class="table-bg"></view>
- <scroll-view class="scroll-column" scroll-x="true">
- <view class="scroll-content">
- <view class="table-row">
- <view
- class="table-cell header"
- v-for="(item, index) in tableColumn"
- :key="index"
- >{{ item.label }}</view
- >
- </view>
- <view
- class="table-row"
- v-for="(item, idx) in tableData"
- :key="idx"
- >
- <view
- class="table-cell"
- v-for="(item1, index1) in tableColumn"
- :key="index1"
- >{{ item[item1.prop] }}</view
- >
- </view>
- </view>
- </scroll-view>
- </view>
- <view class="empty-state" v-else>
- <u-empty text="暂无数据" mode="list"></u-empty>
- </view>
- <view class="pagination" v-if="tableData && tableData.length > 0">
- <view
- class="page-item prev"
- :class="{ disabled: page <= 1 }"
- @click="prevPage"
- >上一页</view
- >
- <view class="page-info">
- <text class="curret-page">{{ page }}</text>
- <text>/</text>
- <text>{{ totalPages }}</text>
- </view>
- <view
- class="page-item next"
- :class="{ disabled: page >= totalPages }"
- @click="nextPage"
- >下一页</view
- >
- </view>
- </view>
- </view>
- <u-calendar
- v-model="show"
- :mode="mode"
- @change="onDateChange"
- range-color="#999" btn-type="success" active-bg-color="#0BBC58" range-bg-color="rgba(11,188,88,0.13)"
- ref="calendar"
- ></u-calendar>
- </view>
- </view>
- </template>
- <script>
- import uCharts from '../../../components/js_sdk/u-charts/u-charts/u-charts.js';
- var canvaColumnA = null;
- export default {
- onLoad(options) {
- this.deviceInfo = options;
- this.initDateRange(options.uptime);
- this.getEleConfig();
- this.cWidth = uni.upx2px(686); // 页面左右 padding 32rpx,可用宽 750-64=686
- this.cHeight = uni.upx2px(500);
- // this.getDeviceStatus();
- // this.getDeviceData();
- },
- data() {
- return {
- deviceInfo: {},
- isShowOperation: false,
- loadingFull: false,
- at: 0,
- activeTab: 'monitoring',
- monitorList: [],
- realtimedata: {},
- statusList: [],
- legendData: [],
- show: false,
- mode: 'range',
- startDate: '',
- endDate: '',
- page: 1,
- photoIcon:'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/newImg/home/photoIcon.png',
- editIcon:'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/newImg/home/editIcon.png',
- serviceIcon:'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/newImg/home/settingNewIcon.png',
- simIcon:'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/newImg/home/simIcon.png',
- settingIcon:'https://s3.hnyfwlw.com/webstaticimg/bigdata_app/newImg/home/settingIcon.png',
- isShowPhoto:false,
- pageSize: 9,
- total: 0,
- tableData: [],
- swcList: [],
- tempList: [],
- configList: {},
- ecsList: [],
- saltList: [],
- tableColumn: [],
- elemengIsSetting: false,
- currentResData: {},
- dat_char: [],
- depth: '',
- cWidth: '',
- cHeight: '',
- pixelRatio: 1,
- };
- },
- computed: {
- totalPages() {
- return Math.ceil(this.total / this.pageSize) || 1;
- },
- },
- methods: {
- onDateChange(event) {
- if (event && event.startDate && event.endDate) {
- this.startDate = event.startDate;
- this.endDate = event.endDate;
- this.show = false;
- this.page = 1;
- this.getDeviceData();
- }
- },
- formartValue(value){
- return value?.split('#')?.[0] || '';
- },
- closeOperationHandler(){
- this.isShowOperation = false;
- },
- async refreshData(){
- await this.$myRequest({
- url: '/api/api_gateway?method=qxz.device.control',
- data: {
- device_id: this.deviceInfo.devBid,
- cmd: 'READ',
- },
- });
- //弹框提示
- uni.showToast({
- title: '刷新成功',
- icon: 'success',
- });
- this.getDeviceData();
- },
- formatTimestamp(timestamp) {
- if (timestamp === '请选择') return '请选择';
- if (!timestamp) return '';
- const date = new Date(Number(timestamp) * 1000);
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, '0');
- const day = String(date.getDate()).padStart(2, '0');
- const hours = String(date.getHours()).padStart(2, '0');
- const minutes = String(date.getMinutes()).padStart(2, '0');
- const seconds = String(date.getSeconds()).padStart(2, '0');
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
- },
- formatDate(date) {
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, '0');
- const day = String(date.getDate()).padStart(2, '0');
- return `${year}-${month}-${day}`;
- },
- initDateRange(timestamp) {
- if (!timestamp) {
- const today = new Date();
- this.endDate = this.formatDate(today);
- const startDate = new Date(today);
- startDate.setDate(startDate.getDate() - 1);
- this.startDate = this.formatDate(startDate);
- return;
- }
- const date = new Date(Number(timestamp) * 1000);
- this.endDate = this.formatDate(date);
- const startDate = new Date(date);
- startDate.setDate(startDate.getDate() - 1);
- this.startDate = this.formatDate(startDate);
- },
- switchTab(tab) {
- this.activeTab = tab;
- if(tab == 'details'){
- this.getEleConfig();
- }
- },
- copy(item) {
- uni.setClipboardData({
- data: item,
- success: function () {
- },
- });
- },
- goPage(type, eleItem) {
- let url = '';
- if (eleItem && eleItem.key) {
- url = `/pages/deviceDetails/SoilMoisturelist/${type}?deviceInfo=${encodeURIComponent(JSON.stringify(this.deviceInfo))}&eleKey=${eleItem.name}&unit=${eleItem.unit}&key=${eleItem.key}`;
- } else {
- url = `/pages/deviceDetails/SoilMoisturelist/${type}?deviceInfo=${encodeURIComponent(JSON.stringify(this.deviceInfo))}`;
- }
- if (type === 'devRepair') {
- url = `/pages/afterSale/addafter?d_id=${this.deviceInfo.d_id}&device_id=${this.deviceInfo.devBid}&device_type=${this.deviceInfo.deviceType}`;
- }
- uni.navigateTo({
- url,
- });
- },
- openDatePicker() {
- this.show = true;
- },
- prevPage() {
- if (this.page <= 1) return;
- this.page--;
- this.getDeviceData();
- },
- nextPage() {
- if (this.page >= this.totalPages) return;
- this.page++;
- this.getDeviceData();
- },
- // 获取设备最新监测数据
- async getQxzObData() {
- const res = await this.$myRequest({
- url: '/api/api_gateway?method=weather.weather.nd_status',
- data: {
- device_id: this.deviceInfo.devBid,
- },
- });
- const resData = res || {};
- this.realtimedata = resData;
- var arr = resData.depth.split(',');
- this.realtimedata['stepsizelist'] = arr;
- this.loadingFull = false;
- this.at = resData?.at || 0;
- const depth = resData?.depth.split(',') || [];
- const swc = resData?.swc.split(',') || [];
- const temp = resData?.temp.split(',') || [];
- const ecs = resData?.ecs.split(',') || [];
- const salt = resData?.salt.split(',') || [];
- this.swcList = [];
- swc.forEach((item,index) =>{
- if(item){
- this.swcList.push({
- label: depth[index] + 'cm土壤湿度',
- val: item,
- key: 'swc' + index,
- isShow: this.elemengIsSetting ? this.currentResData[depth[index]].includes('swc') : true
- })
- }
- })
- this.tempList = [];
- temp.forEach((item,index) =>{
- if(item){
- this.tempList.push({
- label: depth[index] + 'cm土壤温度',
- val: item,
- key: 'temp' + index,
- isShow:this.elemengIsSetting ? this.currentResData[depth[index]].includes('temp') : true
- })
- }
- })
- this.ecsList = [];
- ecs.forEach((item,index) =>{
- if(item){
- this.ecsList.push({
- label: depth[index] + 'cm土壤EC值',
- val: item,
- key: 'ecs' + index,
- isShow: this.elemengIsSetting ? this.currentResData[depth[index]].includes('ecs') : true
- })
- }
- })
- this.saltList = [];
- salt.forEach((item,index) =>{
- if(item){
- this.saltList.push({
- label: depth[index] + 'cm土壤盐度',
- val: item,
- key: 'salt' + index,
- isShow: this.elemengIsSetting ? this.currentResData[depth[index]].includes('salt') : true
- })
- }
- })
- },
- // 获取设备状态数据
- async getDeviceStatus() {
- const res = await this.$myRequest({
- url: '/api/api_gateway?method=qxz.data.qxz_status',
- data: {
- device_id: this.deviceInfo.devBid,
- },
- });
- const newArr = this.transformObjectToArray(res);
- this.statusList = newArr;
- },
- transformObjectToArray(originalData) {
- if (
- typeof originalData !== 'object' ||
- originalData === null ||
- Array.isArray(originalData)
- ) {
- return [];
- }
- return Object.keys(originalData).map((key) => {
- const [val = '', label = ''] = originalData[key] || [];
- return {
- label,
- val,
- key,
- };
- });
- },
- async getEleConfig(){
- const res = await this.$myRequest({
- url: '/api/api_gateway?method=weather.weather.get_ele_config',
- data: {
- device_id: this.deviceInfo.devBid,
- },
- });
- const resData = res?.data;
- if(resData){
- this.elemengIsSetting = true;
- }else{
- this.elemengIsSetting = false;
- }
- this.currentResData = resData ? JSON.parse(resData) : "{}";
- this.getDeviceData();
- this.getQxzObData();
- },
- // 设备数据列表
- async getDeviceData() {
- const data = await this.$myRequest({
- url: '/api/api_gateway?method=weather.weather.nd_data',
- data: {
- device_id: this.deviceInfo.devBid,
- page: String(this.page),
- begin: String(
- Math.floor(new Date(this.startDate + ' 00:00:00').getTime() / 1000),
- ),
- end: String(
- Math.floor(new Date(this.endDate + ' 23:59:59').getTime() / 1000),
- ),
- },
- });
- this.total = data?.nums || 0;
- this.tableData = data?.dat_list;
- this.dat_char = data?.dat_char || [];
- this.depth = data?.depth || '';
- const depth = data?.depth.split(',');
- let title = this.tableData?.[0]?.swc || '';
- let temp = this.tableData?.[0]?.temp || '';
- let ecs = this.tableData?.[0]?.ecs || '';
- let salt = this.tableData?.[0]?.salt || '';
- const swcMap = title?.split(',') || [];
- const tempMap = temp?.split(',') || [];
- const ecsMap = ecs?.split(',') || [];
- const saltMap = salt?.split(',') || [];
- this.tableColumn = [];
- const swcDataMap = new Map();
- this.tableData.forEach(item=>{
- const swc = item.swc.split(',');
- const temp = item.temp.split(',');
- const ecs = item.ecs.split(',');
- const salt = item.salt.split(',');
- swc.forEach((n,index) => {
- if(this.elemengIsSetting){
- if(this.currentResData[depth[index]] && this.currentResData[depth[index]].includes('swc')){
- item['swc'+ index] = n;
- if(swcDataMap.has(depth[index] + 'cm土壤湿度(%)')){
- swcDataMap.get(depth[index] + 'cm土壤湿度(%)').push(n);
- }else{
- swcDataMap.set(depth[index] + 'cm土壤湿度(%)',[]);
- swcDataMap.get(depth[index] + 'cm土壤湿度(%)').push(n);
- }
- }
- }else{
- item['swc'+ index] = n;
- if(swcDataMap.has(depth[index] + 'cm土壤湿度(%)')){
- swcDataMap.get(depth[index] + 'cm土壤湿度(%)').push(n);
- }else{
- swcDataMap.set(depth[index] + 'cm土壤湿度(%)',[]);
- swcDataMap.get(depth[index] + 'cm土壤湿度(%)').push(n);
- }
- }
- });
- temp.forEach((n,index) => {
- if(this.elemengIsSetting){
- if(this.currentResData[depth[index]] && this.currentResData[depth[index]].includes('temp')){
- item['temp' + index] = n;
- if(swcDataMap.has(depth[index] + 'cm土壤温度(℃)')){
- swcDataMap.get(depth[index] + 'cm土壤温度(℃)').push(n);
- }else{
- swcDataMap.set(depth[index] + 'cm土壤温度(℃)',[]);
- swcDataMap.get(depth[index] + 'cm土壤温度(℃)').push(n);
- }
- }
- }else{
- item['temp' + index] = n;
- if(swcDataMap.has(depth[index] + 'cm土壤温度(℃)')){
- swcDataMap.get(depth[index] + 'cm土壤温度(℃)').push(n);
- }else{
- swcDataMap.set(depth[index] + 'cm土壤温度(℃)',[]);
- swcDataMap.get(depth[index] + 'cm土壤温度(℃)').push(n);
- }
- }
- });
- ecs.forEach((n,index) => {
- if(this.elemengIsSetting){
- if(this.currentResData[depth[index]] && this.currentResData[depth[index]].includes('ecs')){
- item['ecs' + index] = n;
- if(swcDataMap.has(depth[index] + 'cm电导率(ms/cm)')){
- swcDataMap.get(depth[index] + 'cm电导率(ms/cm)').push(n);
- }else{
- swcDataMap.set(depth[index] + 'cm电导率(ms/cm)',[]);
- swcDataMap.get(depth[index] + 'cm电导率(ms/cm)').push(n);
- }
- }
- }else{
- item['ecs' + index] = n;
- if(swcDataMap.has(depth[index] + 'cm电导率(ms/cm)')){
- swcDataMap.get(depth[index] + 'cm电导率(ms/cm)').push(n);
- }else{
- swcDataMap.set(depth[index] + 'cm电导率(ms/cm)',[]);
- swcDataMap.get(depth[index] + 'cm电导率(ms/cm)').push(n);
- }
- }
- });
- salt.forEach((n,index) => {
- if(this.elemengIsSetting){
- if(this.currentResData[depth[index]] && this.currentResData[depth[index]].includes('salt')){
- item['salt' + index] = n;
- if(swcDataMap.has(depth[index] + 'cm盐度(%)')){
- swcDataMap.get(depth[index] + 'cm盐度(%)').push(n);
- }else{
- swcDataMap.set(depth[index] + 'cm盐度(%)',[]);
- swcDataMap.get(depth[index] + 'cm盐度(%)').push(n);
- }
- }
- }else{
- item['salt' + index] = n;
- if(swcDataMap.has(depth[index] + 'cm盐度(%)')){
- swcDataMap.get(depth[index] + 'cm盐度(%)').push(n);
- }else{
- swcDataMap.set(depth[index] + 'cm盐度(%)',[]);
- swcDataMap.get(depth[index] + 'cm盐度(%)').push(n);
- }
- }
- });
- })
-
- tempMap.map((item,index) => {
- if(item){
- if(this.elemengIsSetting){
- if(this.currentResData[depth[index]] && this.currentResData[depth[index]].includes('temp')){
- this.legendData.push(depth[index] + 'cm土壤湿度(%)');
- this.tableColumn.push({
- label: depth[index] + 'cm土壤湿度(%)',
- prop: 'temp' + index,
- index
- });
- }}else{
- this.legendData.push(depth[index] + 'cm土壤湿度(%)');
- this.tableColumn.push({
- label: depth[index] + 'cm土壤湿度(%)',
- prop: 'temp' + index,
- index
- });
- }
- }
- })
- swcMap.map((item,index) => {
- if(item){
- if(this.elemengIsSetting){
- if(this.currentResData[depth[index]] && this.currentResData[depth[index]].includes('swc')){
- this.legendData.push(depth[index] + 'cm土壤温度(℃)');
- this.tableColumn.push({
- label: depth[index] + 'cm土壤温度(℃)',
- prop: 'swc' + index,
- index
- });
- }
- }else{
- this.legendData.push(depth[index] + 'cm土壤温度(℃)');
- this.tableColumn.push({
- label: depth[index] + 'cm土壤温度(℃)',
- prop: 'swc' + index,
- index
- });
- }
- }
- });
- ecsMap.map((item,index) => {
- if(item){
- if(this.elemengIsSetting){
- if(this.currentResData[depth[index]] && this.currentResData[depth[index]].includes('ecs')){
- this.legendData.push(depth[index] + 'cm电导率(ms/cm)');
- this.tableColumn.push({
- label: depth[index] + 'cm电导率(ms/cm)',
- prop: 'ecs' + index,
- index
- });
- }
- }else{
- this.legendData.push(depth[index] + 'cm电导率(ms/cm)');
- this.tableColumn.push({
- label: depth[index] + 'cm电导率(ms/cm)',
- prop: 'ecs' + index,
- index
- });
- }
- }
- });
- saltMap.map((item,index) => {
- if(item){
- if(this.elemengIsSetting){
- if(this.currentResData[depth[index]] && this.currentResData[depth[index]].includes('salt')){
- this.legendData.push(depth[index] + 'cm盐度(%)');
- this.tableColumn.push({
- label: depth[index] + 'cm盐度(%)',
- prop: 'salt',
- index
- });
- }
- }else{
- this.legendData.push(depth[index] + 'cm盐度(%)');
- this.tableColumn.push({
- label: depth[index] + 'cm盐度(%)',
- prop: 'salt',
- index
- });
- }
- }
- });
- this.$nextTick(() => {
- this.renderChart();
- });
- },
- // 渲染历史数据趋势图(温度/湿度/电导率 × 各深度)
- renderChart() {
- const datChar = this.dat_char || [];
- if (!datChar.length) {
- return;
- }
- const depthArr = (this.depth || '').split(',').filter(Boolean);
- const xtitle = [];
- const listArr = []; // [{ name, data: [], hasData: boolean }]
- const ensureSeries = (name) => {
- let s = listArr.find((item) => item.name === name);
- if (!s) {
- s = { name, data: [], hasData: false };
- listArr.push(s);
- }
- return s;
- };
- const markHasData = (s, rawVal) => {
- if (rawVal !== '' && rawVal !== undefined && rawVal !== null) {
- s.hasData = true;
- }
- };
- datChar.forEach((row) => {
- const t = new Date(Number(row.upl_time) * 1000);
- const label =
- String(t.getMonth() + 1).padStart(2, '0') +
- '-' +
- String(t.getDate()).padStart(2, '0') +
- '/' +
- String(t.getHours()).padStart(2, '0') +
- ':' +
- String(t.getMinutes()).padStart(2, '0');
- xtitle.unshift(label);
- const tempArr = (row.temp || '').split(',');
- const swcArr = (row.swc || '').split(',');
- const ecsArr = (row.ecs || '').split(',');
- depthArr.forEach((dep, index) => {
- const tVal = tempArr[index];
- const sVal = swcArr[index];
- const eVal = ecsArr[index];
- const tempSeries = ensureSeries(dep + 'cm土壤温度(℃)');
- tempSeries.data.unshift(Number(tVal));
- markHasData(tempSeries, tVal);
- const swcSeries = ensureSeries(dep + 'cm土壤湿度(%)');
- swcSeries.data.unshift(Number(sVal));
- markHasData(swcSeries, sVal);
- const ecsSeries = ensureSeries(dep + 'cm电导率(ms/cm)');
- ecsSeries.data.unshift(Number(eVal));
- markHasData(ecsSeries, eVal);
- });
- });
- const series = listArr
- .filter((s) => s.hasData)
- .map((s) => ({ name: s.name, data: s.data, legendShape: 'circle' }));
- this.showColumn('datCharChart', xtitle, series);
- },
- showColumn(id, xtitle, xinfo) {
- const _self = this;
- const ctx = uni.createCanvasContext(id, this);
- canvaColumnA = new uCharts({
- context: ctx,
- type: 'area',
- legend: {
- position: 'top',
- float: 'left', // 圆点左对齐
- lineHeight: 19, // 行间距 8px(字号 11 + 8)
- },
- fontSize: 11,
- background: '#FFFFFF',
- pixelRatio: 1,
- animation: true,
- dataLabel: false,
- categories: xtitle,
- series: xinfo,
- enableScroll: true, // 开启图表拖拽功能
- xAxis: {
- disableGrid: true,
- type: 'grid',
- gridType: 'dash',
- itemCount: 4, // x轴单屏显示数据的数量
- scrollShow: true,
- scrollBackgroundColor: '#F7F7FF',
- scrollColor: '#DEE7F7',
- },
- yAxis: {},
- width: _self.cWidth * 1,
- height: _self.cHeight * 1,
- extra: {
- area: {
- type: 'curve',
- opacity: 0.2,
- addLine: true, // 在渐变填充上方同时绘制折线
- width: 2,
- gradient: true, // 折线下方填充渐变色(从折线颜色渐变到透明)
- },
- },
- });
- },
- touchLineA(e) {
- if (canvaColumnA) canvaColumnA.scrollStart(e);
- },
- moveLineA(e) {
- if (canvaColumnA) canvaColumnA.scroll(e);
- },
- touchEndLineA(e) {
- if (!canvaColumnA) return;
- canvaColumnA.scrollEnd(e);
- canvaColumnA.showToolTip(e, {
- format: function (item, category) {
- return category + ' ' + item.name + ':' + item.data;
- },
- });
- },
- },
- };
- </script>
- <style lang="scss">
- .device-details-page {
- background:
- linear-gradient(180deg, #ffffff00 0%, #f5f6fa 23.64%, #f5f6fa 100%),
- linear-gradient(102deg, #bfeadd 6.77%, #b8f1e7 40.15%, #b9eef5 84.02%);
- min-height: 100vh;
- padding: 0 32rpx;
- padding-top: 98rpx;
- }
- .nav-title{
- //超出隐藏
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- text-align: center;
- }
- /* 设备基本信息 */
- .device-info {
- background-color: #ffffff;
- margin: 46rpx 0 24rpx 0;
- padding: 32rpx 24rpx;
- border-radius: 16rpx;
- background: linear-gradient(180deg, #eff 0%, #fff 23.56%);
- position: relative;
- .info-item {
- display: flex;
- align-items: center;
- margin-bottom: 16rpx;
- }
- .info-item:last-child {
- margin-bottom: 0;
- }
- .operation-container{
- position: fixed;
- right: 0;
- top: 0;
- width: 100%;
- height: 100%;
- z-index: 99;
- }
- .operation{
- position: fixed;
- top: 260rpx;
- right: 0;
- z-index: 999;
- width:48rpx;
- height: 100rpx;
- line-height: 50rpx;
- border-radius: 8px 0 0 8px;
- border-top: 4rpx solid #FFF;
- border-bottom: 4rpx solid #FFF;
- border-left: 4rpx solid #FFF;
- background: #dddfe6a3;
- color: #515153;
- text-align: center;
- font-family: "Source Han Sans CN VF";
- font-size: 24rpx;
- font-weight: 500;
- writing-mode: vertical-rl;
- }
- .operation-background{
- position: fixed;
- right: 0;
- top: 0;
- width: 100%;
- height: 100%;
- z-index: 998;
- background: #00000040;
- }
- .operation-content{
- position: fixed;
- top: 240rpx;
- right: 80rpx;
- height: 126rpx;
- display: flex;
- padding: 16rpx 32rpx;
- align-items: center;
- gap: 64rpx;
- z-index: 999;
- border-radius: 32rpx;
- border: 2rpx solid #FFF;
- background: #FFF;
- backdrop-filter: blur(8rpx);
- .operation-item{
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- color: #333333;
- text-align: center;
- font-family: "Source Han Sans CN VF";
- font-size: 24rpx;
- font-weight: 400;
- }
- .operation-icon{
- width: 58rpx;
- height: 58rpx;
- }
- }
- .info-label {
- width: 116rpx;
- color: #999999;
- text-align: right;
- font-family: 'Source Han Sans CN VF';
- font-size: 28rpx;
- font-style: normal;
- font-weight: 400;
- line-height: normal;
- margin-right: 32rpx;
- white-space: nowrap;
- }
- .info-value {
- color: #333333;
- font-family: 'Source Han Sans CN VF';
- font-size: 28rpx;
- font-style: normal;
- font-weight: 400;
- line-height: normal;
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
- }
- .info-img {
- width: 32rpx;
- height: 32rpx;
- margin-left: 16rpx;
- background: #0bbc581a;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .tishi {
- width: 24rpx;
- height: 24rpx;
- }
- .dev-status {
- position: absolute;
- right: 0;
- top: 0;
- border: 2rpx solid #ffffff;
- background: #0bbc581a;
- width: 152rpx;
- height: 56rpx;
- color: #0bbc58;
- text-align: center;
- font-size: 28rpx;
- font-weight: 400;
- line-height: 52rpx;
- border-radius: 0 16rpx 0 64rpx;
- }
- }
- /* 标签页切换 */
- .tab-container {
- background-color: #ffffff;
- border-radius: 16rpx;
- overflow: hidden;
- padding: 0 32rpx;
- margin-bottom: 24rpx;
- .datetime{
- display: flex;
- height: 48rpx;
- padding: 8rpx 24rpx;
- justify-content: space-between;
- align-items: center;
- flex: 1 0 0;
- border-radius: 32rpx;
- background: #F1F4F8;
- margin-bottom: 20rpx;
- color: #656565;
- text-align: center;
- font-family: "Source Han Sans CN VF";
- font-size: 12px;
- font-style: normal;
- font-weight: 400;
- line-height: normal;
- .datetime-left{
- width: 90%;
- display: flex;
- align-items: center;
- justify-content: space-around;
- .datetime-start{
- width: 45%;
- }
- .datetime-end{
- width: 45%;
- }
- }
- }
- .tab-top {
- display: flex;
- }
- .tab-item {
- flex: 1;
- height: 80rpx;
- display: flex;
- flex-direction: column;
- align-items: center;
- position: relative;
- color: #666666;
- text-align: center;
- font-family: 'Source Han Sans CN VF';
- font-size: 28rpx;
- font-style: normal;
- font-weight: 400;
- line-height: normal;
- .tab-text {
- margin-top: 16rpx;
- }
- .smile {
- width: 24rpx;
- height: 18rpx;
- }
- }
- .tab-item.active {
- color: #333333;
- font-weight: 700;
- }
- .time-board {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 16rpx;
- }
- .time-filter {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 256rpx;
- height: 48rpx;
- padding: 6rpx 8rpx;
- border-radius: 32rpx;
- background: #f1f4f8;
- color: #303133;
- font-size: 20rpx;
- font-weight: 400;
- .filter-item {
- padding: 4rpx 16rpx;
- height: 36rpx;
- line-height: 36rpx;
- }
- .active {
- border-radius: 32rpx;
- background: #fff;
- }
- }
- }
- /* 监测要素页面 */
- .monitoring-page {
- padding-bottom: 20px;
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- .data-card {
- position: relative;
- top: 100rpx;
- width: 100%;
- background: url('https://s3.hnyfwlw.com/webstaticimg/bigdata_app/img/solid.png');
- background-size: cover;
- background-position: center center;
- background-repeat: no-repeat;
- border-radius: 16rpx;
- height: 500rpx;
- .status-img{
- position: absolute;
- top: -100rpx;
- left: -20rpx;
- width: 150rpx;
- height: 620rpx;
- }
- .data-card-right{
- width:calc(100% - 150rpx);
- position: absolute;
- top: 0;
- left: 130rpx;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- align-items: center;
- .device-qx{
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 24rpx;
- margin-top: -48rpx;
- .qx-img{
- width: 48rpx;
- height: 48rpx;
- margin-right: 16rpx;
- }
- }
- .device-temp-list{
- width: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 24rpx;
- margin: 24rpx 0;
- .temp-item{
- display: flex;
- align-items: center;
- justify-content: center;
- text-align: center;
- width: 200rpx;
- height: 80rpx;
- margin-bottom: 12rpx;
- }
- .temp-icon{
- width: 48rpx;
- height: 40rpx;
- margin-right: 16rpx;
- }
- .temp-content{
- .temp-value{
- color: #ffffff;
- font-size: 28rpx;
- font-weight: 700;
- }
- .temp-name{
- color: #ffffffcc;
- font-size: 24rpx;
- font-family: "Source Han Sans CN VF";
- font-weight: 400;
- // 超出部分省略号
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- }
- }
- .device-swc-list{
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 24rpx;
- margin: 24rpx 0;
- width: 100%;
- .swc-item{
- display: flex;
- align-items: center;
- justify-content: center;
- text-align: center;
- width: 200rpx;
- height: 80rpx;
- margin-bottom: 12rpx;
- }
- .swc-icon{
- width: 48rpx;
- height: 40rpx;
- margin-right: 16rpx;
- }
- .swc-content{
- .swc-value{
- color: #ffffff;
- font-size: 28rpx;
- font-weight: 700;
- }
- .swc-name{
- color: #ffffffcc;
- font-size: 24rpx;
- font-family: "Source Han Sans CN VF";
- font-weight: 400;
- // 超出部分省略号
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- }
- }
- .device-dept-list{
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 24rpx;
- margin: 24rpx 0;
- width: 100%;
- .dept-item{
- display: flex;
- align-items: center;
- justify-content: center;
- text-align: center;
- width: 200rpx;
- height: 80rpx;
- margin-bottom: 12rpx;
- }
- .dept-icon{
- width: 48rpx;
- height: 40rpx;
- margin-right: 16rpx;
- }
- .dept-content{
- .dept-value{
- color: #ffffff;
- font-size: 28rpx;
- font-weight: 700;
- }
- .dept-name{
- color: #ffffffcc;
- font-size: 24rpx;
- font-family: "Source Han Sans CN VF";
- font-weight: 400;
- // 超出部分省略号
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- }
- }
- .device-list{
- display: flex;
- gap: 24rpx;
- justify-content: space-between;
- margin-top: 40rpx;
- }
- }
- }
- }
- /* 设备详情页面 */
- .details-page {
- .chart-container {
- padding: 16rpx 32rpx 32rpx 32rpx;
- border-radius: 16rpx;
- background: #fff;
- margin-bottom: 24rpx;
- .chart-control {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 16rpx;
- .title {
- color: #042118;
- font-family: 'Source Han Sans CN VF';
- font-size: 28rpx;
- font-style: normal;
- font-weight: 700;
- line-height: normal;
- }
- }
- .chart-wrap {
- height: 520rpx;
- .charts {
- width: 100%;
- height: 100%;
- }
- }
- .empty-state {
- padding: 80rpx 0;
- }
- }
- .table-container {
- padding: 16rpx 32rpx 32rpx 32rpx;
- border-radius: 16rpx;
- background: #fff;
- .table-control {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 16rpx;
- .title {
- color: #042118;
- font-family: 'Source Han Sans CN VF';
- font-size: 28rpx;
- font-style: normal;
- font-weight: 700;
- line-height: normal;
- }
- .date-board {
- display: flex;
- align-items: center;
- color: #020305;
- font-family: 'Source Han Sans CN VF';
- font-size: 24rpx;
- font-weight: 400;
- border-radius: 32rpx;
- background: #f1f4f8;
- padding: 16rpx 24rpx;
- .line {
- color: #656565;
- margin: 0 10rpx;
- }
- .date-icon {
- width: 32rpx;
- height: 32rpx;
- margin-left: 16rpx;
- }
- }
- }
- .table-wrap {
- display: flex;
- width: 100%;
- height: 850rpx;
- box-sizing: border-box;
- margin: 20rpx 0;
- color: #042118;
- font-family: 'Source Han Sans CN VF';
- font-size: 24rpx;
- font-style: normal;
- font-weight: 400;
- line-height: normal;
- .fixed-column {
- width: 250rpx;
- .table-cell {
- width: 100%;
- white-space: nowrap;
- }
- }
- .table-bg {
- width: 16rpx;
- background: linear-gradient(270deg, #ffffff33 0%, #9598a433 100%);
- }
- .scroll-column {
- flex: 1;
- height: auto;
- overflow: hidden;
- margin-left: -10rpx;
- }
- .scroll-content {
- min-width: 100%;
- width: fit-content;
- display: flex;
- flex-direction: column;
- .table-row {
- display: flex;
- .table-cell {
- flex: 1;
- padding-right: 10rpx;
- }
- }
- }
- .table-cell {
- width: 160rpx;
- height: 80rpx;
- line-height: 80rpx;
- padding-right: 10rpx;
- text-align: center;
- border-bottom: 2px solid #e4e7ed;
- box-sizing: border-box;
- overflow: hidden;
- padding: 0 4rpx;
- text-overflow: ellipsis;
- }
- .table-cell.header {
- background: #f6f8fc;
- }
- }
- .pagination {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-top: 24rpx;
- .page-item {
- width: 104rpx;
- height: 48rpx;
- color: #656565;
- font-size: 24rpx;
- line-height: 48rpx;
- text-align: center;
- border: 2rpx solid #e4e7ed;
- border-radius: 8rpx;
- }
- .prev.disabled {
- color: #c0c4cc;
- border-color: #e4e7ed;
- }
- .next {
- color: #0bbc58;
- border: 2px solid #0bbc58;
- }
- .next.disabled {
- color: #c0c4cc;
- border-color: #e4e7ed;
- }
- .page-info {
- color: #999999;
- font-family: 'Source Han Sans CN VF';
- font-size: 24rpx;
- font-style: normal;
- font-weight: 400;
- line-height: normal;
- .curret-page {
- color: #303133;
- }
- }
- }
- .empty-state {
- padding: 80rpx 0;
- }
- }
- }
- ::v-deep .u-calendar__action {
- display: flex;
- justify-content: center;
- }
- </style>
|