// pages/privacy/index.js import * as echarts from '../../ec-canvas/echarts'; // import * as liquidFill from '../../ec-canvas/echarts-liquidfill.min'; const api = require('../../api/index.js'); const {timestamp,getYesterday} = require('../../utils/util.js'); Page({ /** * 页面的初始数据 */ data: { // 状态栏高度 statusBarHeight: '', // 导航栏高度 navBarHeight: '', // 导航栏和状态栏高度 navStatusBarHeight: '', // 胶囊 menu: '', ec: { lazyLoad: true }, workorder: [], index: '', objectArray: [], powerdata: [], ech: { lazyLoad: true }, ymdlist: [], chargeTotal: [], currentUnit: 'day', // 当前选中单位:day=日,month=月,year=年 currentDate: '', // 动态格式显示日期 actualDate: '', // 底层存储完整日期(YYYY-MM-DD) minDate: '2025-9-01', // 最小可选日期(可外部设置) maxDate: '', // 最大可选日期(可外部设置,默认当前日期) visible: false, // 日历选择器显隐 // 禁用状态标识 isMin: false, // 当前单位下是否已到最小边界 isMax: false, // 当前单位下是否已到最大边界 isUpperMin: false, // 上级单位下是否已到最小边界 isUpperMax: false, // 上级单位下是否已到最大边界 mintimeDate: '', maxtimeDate: '', currentTime: '', activeBarIndex: 0, activeBardata: [], choicedaydata: ['晟运电站', '南山电站', '晟运电站', '南山电站', '晟运电站', '南山电站'] }, /** * 生命周期函数--监听页面加载 */ onLoad(options) { // 日期字符串转时间戳 const currentTimestamp = Date.now(); // 初始化最大日期为当前日期,可通过options接收外部传入的日期范围 const today = this.formatDate(new Date(), 'day'); // 支持通过页面参数设置最小/最大日期(如从其他页面跳转时传入) const minDate = options.minDate || this.data.minDate; const maxDate = options.maxDate || today; // 确保实际日期在有效范围内 let initialDate = today; if (new Date(initialDate) < new Date(minDate)) { initialDate = minDate; } else if (new Date(initialDate) > new Date(maxDate)) { initialDate = maxDate; } const mintimeDate = this.convertTimestamp(minDate); const maxtimeDate = this.convertTimestamp(maxDate); console.log(initialDate); this.setData({ minDate, maxDate, mintimeDate, maxtimeDate, actualDate: initialDate, actualDate: initialDate, currentDate: this.formatDate(new Date(initialDate), 'day'), // currentDate: getYesterday(), currentTime: currentTimestamp, }, () => { this.updateDisableStatus(); }); if (wx.getStorageSync('powerstationId') == '') { wx.setStorage({ key: 'powerstationId', // 存储的key值 data: '' }); } this.getShowScreenHeight() this.setData({ statusBarHeight: wx.getStorageSync('statusBarHeight'), navBarHeight: wx.getStorageSync('navBarHeight'), navStatusBarHeight: wx.getStorageSync('navStatusBarHeight'), menu: wx.getStorageSync('menu') }) this.ecline2 = this.selectComponent('#mychart_line2'); this.ecline = this.selectComponent('#mychart_line'); this.getpowestation() // 电站数据 }, getShowScreenHeight() { //系统信息 const systemInfo = wx.getWindowInfo() //胶囊位置 const capsuleInfo = wx.getMenuButtonBoundingClientRect() //计算导航栏高度 let navHeight = systemInfo.statusBarHeight + capsuleInfo.height + (capsuleInfo.top - systemInfo.statusBarHeight) * 2 //计算tabbar高度 let tabHeight = systemInfo.safeArea.bottom - systemInfo.safeArea.height //计算可现实内容高度(中间区域) // let screenHeight = systemInfo.screenHeight-navHeight-tabHeight-30 const menu = wx.getMenuButtonBoundingClientRect() wx.setStorageSync('menu', menu) // 手机系统状态栏高度 wx.setStorageSync('statusBarHeight', tabHeight) // 导航栏高度 wx.setStorageSync('navBarHeight', menu.height + (menu.top - systemInfo.statusBarHeight) * 2) // 状态栏加导航栏 wx.setStorageSync('navStatusBarHeight', navHeight) }, rolelocate(e) { wx.navigateTo({ url: '/pages/statistics/index', }) }, // 工单统计 getworkoder() { let data = { workorderType: '' } api.request(`/workoder/statistics`, 'POST', data) .then((res) => { console.log(res); this.setData({ workorder: res.data }) }) .catch((err) => { console.error('请求失败:', err); // 在这里处理请求失败的情况 }); }, gitpower() { let data = { day: this.data.currentDate } api.request(`/syspowerstation/selectpowerstattiondata`, 'POST', data) .then((res) => { console.log(res.data); this.setData({ powerdata: res.data }) if (this.data.index == 0 || this.data.index == '') { this.setData({ activeBardata: res.data.sysPowerstationdatalist[this.data.activeBarIndex], ymdlist: res.data.sysPowerstationdatalist.map(item => item.powerstationName), chargeTotal: res.data.sysPowerstationdatalist.map(item => item.dailydischarge * 1), }) console.log(this.data.ymdlist); console.log(this.data.chargeTotal); this.initChart_right(); } else { this.initChartright() } }) .catch((err) => { console.error('请求失败:', err); // 在这里处理请求失败的情况 }); }, // 电容量 initChartright: function () { let _this = this; // 初始化图表 this.ecline.init((canvas, width, height, dpr) => { const chart = echarts.init(canvas, null, { width: width, height: height, devicePixelRatio: dpr }); // 初始数据 let initialData = { accumulatedchargetime: this.data.powerdata.dayfaultlossrate || 0, accumulateddischargetime: this.data.powerdata.monthlycumulativelossrate || 0 }; // 设置初始选项 let option = _this.getChartOption(initialData); chart.setOption(option); // _this.chartInstance2 = chart; return chart; }); }, // 辅助函数,用于生成图表选项 getChartOption: function (data) { let _this = this; return { backgroundColor: "#ffffff", legend: [{ left: '0', bottom: 20, itemHeight: 8, itemWidth: 8, icon: "circle", textStyle: { color: '#999999', // 设置文字颜色为灰色 fontSize: 10 // 设置字号为20px }, formatter: function (name) { return name + ` ${(data.accumulatedchargetime * 1).toFixed(2)} %`; }, rich: { a: { color: '#222222', fontSize: 12 // 设置字号为20px } }, data: [{ name: '当日损失率' }] }, { left: '0', bottom: 0, itemHeight: 8, itemWidth: 8, icon: "circle", textStyle: { color: '#999999', // 设置文字颜色为灰色 fontSize: 10 // 设置字号为20px }, formatter: function (name) { return name + ` ${(data.accumulateddischargetime * 1).toFixed(2)} %`; }, data: [{ name: '月累计损失率' }] }], tooltip: { trigger: 'item' }, series: [{ type: 'pie', radius: ['40%', '60%'], center: ['50%', '40%'], avoidLabelOverlap: false, label: { show: false, position: 'center' }, emphasis: { label: { show: true, fontSize: 0, fontWeight: 'bold' } }, labelLine: { show: false }, data: [{ value: (data.accumulatedchargetime * 1).toFixed(2), name: '当日损失率', itemStyle: { color: '#4DF096' } }, { value: (data.accumulateddischargetime * 1).toFixed(2), name: '月累计损失率', itemStyle: { color: '#3C9EFA' } }] }] }; }, onInformation() { wx.navigateTo({ url: '/pages/Information/index', }) }, // 查询电站 getpowestation() { api.request(`/syspowerstation/selectpowestation`, 'POST', {}) .then((res) => { if (res.code == 200) { res.data.unshift({ powerstationAddress: "", powerstationId: "", powerstationImg: "", powerstationName: "全部电站" }) this.setData({ objectArray: res.data }) this.getaddredisredis() for (let index = 0; index < res.data.length; index++) { if (res.data[index].powerstationId == wx.getStorageSync('powerstationId')) { this.setData({ index: index }) return } else { this.setData({ index: '' }) } } } }) .catch((err) => { console.error('请求失败:', err); // 在这里处理请求失败的情况 }); }, getaddredisredis(){ let data = { powerstationId: wx.getStorageSync('powerstationId') } api.request(`/syspowerstation/addredisredis`, 'POST', data) .then((res) => { console.log(res); }) .catch((err) => { console.error('请求失败:', err); // 在这里处理请求失败的情况 }); }, bindPickerChange: function (e) { console.log('picker发送选择改变,携带值为', e.detail.value) this.setData({ index: e.detail.value }) wx.setStorage({ key: 'powerstationId', // 存储的key值 data: this.data.objectArray[e.detail.value].powerstationId }); let data = { powerstationId: this.data.objectArray[e.detail.value].powerstationId } api.request(`/syspowerstation/addredisredis`, 'POST', data) .then((res) => { console.log(res); if (this.data.index == '') { this.gitpower() } else { this.getworkoder() this.gitpower() } }) .catch((err) => { console.error('请求失败:', err); // 在这里处理请求失败的情况 }); }, initChart_right: function () { var unitName = '上网电量/万kWh' let _this = this; // 初始化选中索引(-1表示无选中) // this.setData({ activeBarIndex: 0 }); this.ecline2.init((canvas, width, height, dpr) => { const chart = echarts.init(canvas, null, { width: width, height: height, devicePixelRatio: dpr }); canvas.setChart(chart); // 原始柱体颜色(默认样式) const originalColor = 'rgba(60, 158, 250, 0.5)'; // 高亮颜色 const highlightColor = 'rgba(60, 158, 250, 1)'; // 图表配置项 var option = { title: { subtext: unitName, textStyle: { color: 'rgba(0, 0, 0, 0)' } }, grid: { left: '1%', top: '18%', right: '1%', bottom: '20%', containLabel: true }, xAxis: { type: 'category', data: _this.data.ymdlist, axisTick: { show: false }, axisLabel: { interval: 0 } }, yAxis: { type: 'value', x: 'center', axisTick: { show: false }, splitLine: { show: false } }, dataZoom: { type: 'inside', start: 0, end: 50 }, series: [{ type: "bar", barMaxWidth: 20, label: { show: true, position: 'top', color: '#222' }, data: _this.data.chargeTotal, itemStyle: { color: function (params) { // 只有选中的柱体用高亮色,其他保持原始色 return params.dataIndex === _this.data.activeBarIndex ? highlightColor : originalColor; }, barBorderRadius: [2, 2, 0, 0], // 选中柱体悬停增强 emphasis: { shadowBlur: 10, shadowColor: 'rgba(0, 0, 0, 0)' } } }] }; chart.setOption(option); // 柱体点击事件 chart.on('click', function (params) { if (params.componentType !== 'series' || params.seriesType !== 'bar') { return; } const clickedIndex = params.dataIndex; // 切换选中状态(点击已选中的柱体则取消高亮) if (clickedIndex === _this.data.activeBarIndex) { return } const newActiveIndex = clickedIndex; _this.setData({ activeBarIndex: newActiveIndex }, () => { // 重新设置颜色样式 chart.setOption({ series: [{ itemStyle: { color: function (p) { return p.dataIndex === _this.data.activeBarIndex ? highlightColor : originalColor; } } }] }); }); _this.choicestation() }); return chart; }); }, //点击的柱体 choicestation() { console.log(this.data.activeBarIndex); console.log(this.data.powerdata); this.setData({ activeBardata: this.data.powerdata.sysPowerstationdatalist[this.data.activeBarIndex] }) }, convertTimestamp(value, unit = 'day') { // 如果是数字,视为时间戳,转换为日期字符串 if (typeof value === 'number') { // 处理毫秒级和秒级时间戳 const timestamp = value.toString().length === 10 ? value * 1000 : value; return this.formatDate(new Date(timestamp), unit); } // 如果是字符串,视为日期字符串,转换为时间戳(毫秒) if (typeof value === 'string') { // 支持 YYYY-MM-DD、YYYY-MM、YYYY 三种格式 const dateParts = value.split('-'); let year = parseInt(dateParts[0], 10); let month = dateParts.length > 1 ? parseInt(dateParts[1], 10) - 1 : 0; // 月份从0开始 let day = dateParts.length > 2 ? parseInt(dateParts[2], 10) : 1; // 处理无效日期 const date = new Date(year, month, day); if (isNaN(date.getTime())) { console.error('无效的日期格式:', value); return null; } return date.getTime(); } console.error('不支持的转换类型:', typeof value); return null; }, /** * 切换日/月/年单位 */ handleUnitChange(e) { console.log(e); const targetClass = e.currentTarget.dataset.name; let currentUnit = 'day'; if (targetClass == "choiceday") currentUnit = 'day'; else if (targetClass == "choicemoon") currentUnit = 'month'; else if (targetClass == "choiceyear") currentUnit = 'year'; const formattedDate = this.formatDate(new Date(this.data.actualDate), 'day'); this.setData({ currentUnit, currentDate: formattedDate }, () => { this.updateDisableStatus(); }); }, // 选择电站 bindchart(e) { console.log(e); this.setData({ activeBarIndex: e.currentTarget.dataset.index, activeBardata: this.data.powerdata.sysPowerstationdatalist[e.currentTarget.dataset.index] }) this.initChart_right(); }, /** * 处理翻页逻辑:单箭头=当前单位,双箭头=上级单位 */ handleDateNav(e) { const { currentUnit, actualDate, minDate, maxDate } = this.data; const action = e.currentTarget.dataset.action; const currentDateObj = new Date(actualDate); const minDateObj = new Date(minDate); const maxDateObj = new Date(maxDate); let newDateObj; // 确定翻页单位 const navUnit = action.includes('day') ? currentUnit : this.getUpperUnit(currentUnit); // 计算新日期 switch (navUnit) { case 'day': newDateObj = new Date(currentDateObj); action.startsWith('prev') ? newDateObj.setDate(currentDateObj.getDate() - 1) : newDateObj.setDate(currentDateObj.getDate() + 1); break; case 'month': newDateObj = new Date(currentDateObj); action.startsWith('prev') ? newDateObj.setMonth(newDateObj.getMonth() - 1) : newDateObj.setMonth(newDateObj.getMonth() + 1); // 处理跨月日期溢出 if (newDateObj.getDate() !== currentDateObj.getDate()) { newDateObj.setDate(0); } break; case 'year': newDateObj = new Date(currentDateObj); action.startsWith('prev') ? newDateObj.setFullYear(newDateObj.getFullYear() - 1) : newDateObj.setFullYear(newDateObj.getFullYear() + 1); // 处理闰年2月29日特殊情况 if (newDateObj.getDate() !== currentDateObj.getDate()) { newDateObj.setDate(0); } break; } console.log(newDateObj); // 检查是否超出最小/最大日期范围 if (newDateObj.getTime() < minDateObj.getTime() || newDateObj.getTime() > maxDateObj.getTime()) { wx.showToast({ title: '超出时间范围', icon: 'none' }); return; // 超出范围则不更新 } // 正常更新日期 const newActualDate = this.formatDate(newDateObj, 'day'); const newDisplayDate = this.formatDate(newDateObj, currentUnit); console.log(newActualDate); console.log(newDisplayDate); this.setData({ actualDate: newActualDate, currentDate: newDisplayDate }, () => { this.updateDisableStatus(); }); this.gitpower() }, /** * 获取上级单位 */ getUpperUnit(unit) { const upperMap = { day: 'month', month: 'year', year: 'year' }; return upperMap[unit]; }, /** * 更新禁用状态:同时判断最小和最大日期边界 */ updateDisableStatus() { const { currentUnit, actualDate, minDate, maxDate } = this.data; const currentObj = new Date(actualDate); const minObj = new Date(minDate); const maxObj = new Date(maxDate); const upperUnit = this.getUpperUnit(currentUnit); const status = { isMin: false, isMax: false, isUpperMin: false, isUpperMax: false }; // 判断当前单位边界 status.isMin = this.isDateEqual(currentObj, minObj, currentUnit); status.isMax = this.isDateEqual(currentObj, maxObj, currentUnit); // 判断上级单位边界 status.isUpperMin = this.isDateEqual(currentObj, minObj, upperUnit); status.isUpperMax = this.isDateEqual(currentObj, maxObj, upperUnit); this.setData(status); }, /** * 按指定单位比较两个日期是否相等 */ isDateEqual(date1, date2, unit) { if (unit === 'day') { return date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate(); } else if (unit === 'month') { return date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth(); } else if (unit === 'year') { return date1.getFullYear() === date2.getFullYear(); } return false; }, /** * 日历选择器相关方法 */ onCalendarClick() { console.log(this.data.currentDate); // console.log(dateToTimestamp.dateToTimestamp(this.data.currentDate)); this.setData({ currentTime: new Date(this.data.currentDate).getTime() }) console.log(this.data.currentTime); this.setData({ visible: true }); }, handleConfirm(e) { console.log(e); // 1761062400000 // 1761753600000 const selectedDate = e.detail.value; const { minDate, maxDate, currentUnit } = this.data; const selectedObj = new Date(selectedDate); const minObj = new Date(minDate); const maxObj = new Date(maxDate); // 检查选中日期是否在有效范围内 if (selectedObj.getTime() < minObj.getTime() || selectedObj.getTime() > maxObj.getTime()) { this.setData({ visible: false }); return; } console.log(timestamp(selectedObj)); // const formattedDate = this.formatDate(new Date(selectedDate), currentUnit); const formattedDate = timestamp(selectedObj) console.log(formattedDate); this.setData({ actualDate: selectedDate, currentDate: formattedDate, visible: false }, () => { this.updateDisableStatus(); }); this.gitpower() }, onClose(e) { console.log(e); this.setData({ visible: false }); }, /** * 动态格式化日期 */ formatDate(date, unit) { // 处理传入的date参数(兼容字符串格式的日期) const targetDate = new Date(date); // 校验日期有效性 if (isNaN(targetDate.getTime())) { console.error('无效的日期格式:', date); return ''; // 或返回默认值 } // 从传入的日期中获取年、月、日 const year = targetDate.getFullYear(); const month = String(targetDate.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需+1 const day = String(targetDate.getDate()).padStart(2, '0'); // 根据单位返回对应格式 switch (unit) { case 'day': return `${year}-${month}-${day}`; // 例如:2025-11-04 case 'month': return `${year}-${month}`; // 例如:2025-11 case 'year': return `${year}`; // 例如:2025 default: return `${year}-${month}-${day}`; // 默认返回完整日期 } }, /** * 外部调用接口:设置最小日期 */ setMinDate(minDate) { if (new Date(minDate) && this.isValidDate(minDate)) { this.setData({ minDate }, () => { this.checkDateInRange(); this.updateDisableStatus(); }); } }, /** * 外部调用接口:设置最大日期 */ setMaxDate(maxDate) { if (new Date(maxDate) && this.isValidDate(maxDate)) { this.setData({ maxDate }, () => { this.checkDateInRange(); this.updateDisableStatus(); }); } }, /** * 检查当前日期是否在有效范围内,不在则自动调整 */ checkDateInRange() { const { actualDate, minDate, maxDate, currentUnit } = this.data; const currentObj = new Date(actualDate); const minObj = new Date(minDate); const maxObj = new Date(maxDate); let adjustedDate = actualDate; if (currentObj.getTime() < minObj.getTime()) { adjustedDate = minDate; } else if (currentObj.getTime() > maxObj.getTime()) { adjustedDate = maxDate; } if (adjustedDate !== actualDate) { this.setData({ actualDate: adjustedDate, currentDate: this.formatDate(new Date(adjustedDate), currentUnit) }); } }, /** * 验证日期格式是否有效 */ isValidDate(dateString) { const regExp = /^\d{4}-\d{2}-\d{2}$/; if (!regExp.test(dateString)) return false; const date = new Date(dateString); return date.toISOString().slice(0, 10) === dateString; }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady() { }, /** * 生命周期函数--监听页面显示 */ onShow() { // this.initChartright() this.gitpower() }, /** * 生命周期函数--监听页面隐藏 */ onHide() { }, /** * 生命周期函数--监听页面卸载 */ onUnload() { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ async onPullDownRefresh() { await this.getworkoder() await this.gitpower() await wx.stopPullDownRefresh(); }, /** * 页面上拉触底事件的处理函数 */ onReachBottom() { }, /** * 用户点击右上角分享 */ onShareAppMessage() { } })