电速宝
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. // 引入 wx-charts(根据实际路径调整)
  2. const wxCharts = require('../../utils/wxcharts.js');
  3. const api = require('../../../api/index.js');
  4. Page({
  5. /**
  6. * 页面的初始数据
  7. */
  8. data: {
  9. currentType: 'day', // 默认按日筛选
  10. selectedDate: '', // 选中的日期
  11. showDate: '', // 展示的日期文本
  12. showPicker: false, // 是否显示日期选择器
  13. today: '', // 今日日期
  14. statData: { // 统计数据
  15. chargeTotal: 0,
  16. dischargeTotal: 0,
  17. netTotal: 0
  18. },
  19. dataList: [], // 明细数据列表
  20. listHeader: '时段', // 列表头部文本
  21. chart: null, // 图表实例,用于更新图表
  22. operationRole:wx.getStorageSync('user').operationRole
  23. },
  24. /**
  25. * 生命周期函数--监听页面加载
  26. */
  27. onLoad(options) {
  28. // 获取今日日期
  29. const now = new Date();
  30. const today = `${now.getFullYear()}-${this.formatNum(now.getMonth() + 1)}-${this.formatNum(now.getDate())}`;
  31. this.setData({
  32. today,
  33. selectedDate: today,
  34. showDate: this.formatShowDate(today, 'day')
  35. });
  36. // 加载初始数据
  37. this.loadData();
  38. },
  39. /**
  40. * 修复:适配屏幕旋转/尺寸变化,重新渲染图表即可
  41. */
  42. onResize() {
  43. // 直接重新渲染,wxCharts无updateCanvasSize方法
  44. if (this.data.dataList.length > 0) {
  45. this.renderChart();
  46. }
  47. },
  48. /**
  49. * 切换筛选类型(日/月/年)
  50. */
  51. changeType(e) {
  52. const type = e.currentTarget.dataset.type;
  53. if (type === this.data.currentType) return;
  54. this.setData({
  55. currentType: type,
  56. showDate: this.formatShowDate(this.data.selectedDate, type),
  57. listHeader: type === 'day' ? '时段' : (type === 'month' ? '日期' : '月份')
  58. });
  59. this.loadData();
  60. },
  61. /**
  62. * 打开日期选择器
  63. */
  64. openDatePicker() {
  65. this.setData({ showPicker: true });
  66. setTimeout(() => {
  67. this.setData({ showPicker: false });
  68. }, 100);
  69. },
  70. /**
  71. * 日期选择器值改变
  72. */
  73. onDateChange(e) {
  74. const selectedDate = e.detail.value;
  75. this.setData({
  76. selectedDate,
  77. showDate: this.formatShowDate(selectedDate, this.data.currentType)
  78. });
  79. this.loadData();
  80. },
  81. /**
  82. * 格式化数字(补零)
  83. */
  84. formatNum(num) {
  85. return num < 10 ? `0${num}` : num;
  86. },
  87. /**
  88. * 格式化展示的日期文本
  89. */
  90. formatShowDate(date, type) {
  91. const [year, month, day] = date.split('-');
  92. switch (type) {
  93. case 'day':
  94. return `${year}-${month}-${day}`;
  95. case 'month':
  96. return `${year}-${month}`;
  97. case 'year':
  98. return `${year}`;
  99. default:
  100. return date;
  101. }
  102. },
  103. /**
  104. * 加载充放电数据
  105. */
  106. loadData() {
  107. let data = {
  108. date:this.data.showDate
  109. }
  110. api.request(`/sysworkorder/workorderstatistics`, 'post', data, { isPublic: false })
  111. .then((data) => {
  112. if (data.code == 200) {
  113. console.log(data);
  114. const { currentType, selectedDate } = this.data;
  115. const [year, month, day] = selectedDate.split('-');
  116. // 模拟接口请求数据(实际开发中替换为真实接口调用)
  117. // let statData = { chargeTotal: 0, dischargeTotal: 0, netTotal: 0 };
  118. let dataList = [];
  119. // 模拟不同维度的测试数据
  120. if (currentType === 'day') {
  121. // 日维度:按小时统计
  122. // 基础校验:避免数据源不存在或非数组导致报错
  123. if (this.data.operationRole==5) {
  124. if (data.data.chargeList && Array.isArray(data.data.chargeList)) {
  125. for (let index = 0; index < data.data.chargeList.length; index++) {
  126. // 获取当前行数据
  127. const item = data.data.chargeList[index];
  128. // 关键修复:先初始化数组元素,再赋值(解决空数组直接赋值报错)
  129. dataList[index] = { ...item }; // 保留原始数据字段
  130. console.log(dataList);
  131. // 保留你的核心逻辑:仅截取小时位相减
  132. // 增加防错处理:避免时间字段为空/格式错误导致NaN
  133. const startHour = data.data.chargeList[index].startworkordertime?.slice(11, 16) || 0;
  134. const endHour = data.data.chargeList[index].endworkordertime?.slice(11, 16) || 0;
  135. dataList[index].time = `${endHour +'-'+ startHour}`;
  136. }
  137. }
  138. }else{
  139. if (data?.data?.dischargeList && Array.isArray(data.data.dischargeList)) {
  140. for (let index = 0; index < data.data.dischargeList.length; index++) {
  141. // 获取当前行数据
  142. const item = data.data.dischargeList[index];
  143. // 关键修复:先初始化数组元素,再赋值(解决空数组直接赋值报错)
  144. dataList[index] = { ...item }; // 保留原始数据字段
  145. console.log(dataList);
  146. // 保留你的核心逻辑:仅截取小时位相减
  147. // 增加防错处理:避免时间字段为空/格式错误导致NaN
  148. const startHour = data.data.dischargeList[index].startworkordertime?.slice(11, 16) || 0;
  149. const endHour = data.data.dischargeList[index].endworkordertime?.slice(11, 16) || 0;
  150. dataList[index].time = `${endHour +'-'+ startHour}`;
  151. }
  152. }
  153. }
  154. } else if (currentType === 'month') {
  155. // 月维度:按日期统计
  156. if (this.data.operationRole==5) {
  157. if (data?.data?.chargeList && Array.isArray(data.data.chargeList)) {
  158. for (let index = 0; index < data.data.chargeList.length; index++) {
  159. // 获取当前行数据
  160. const item = data.data.chargeList[index];
  161. // 关键修复:先初始化数组元素,再赋值(解决空数组直接赋值报错)
  162. dataList[index] = { ...item }; // 保留原始数据字段
  163. console.log(dataList);
  164. // 保留你的核心逻辑:仅截取小时位相减
  165. // 增加防错处理:避免时间字段为空/格式错误导致NaN
  166. const startHour = data.data.chargeList[index].startworkordertime?.slice(8, 10) || 0;
  167. dataList[index].time = startHour;
  168. }
  169. }
  170. }else{
  171. if (data?.data?.dischargeList && Array.isArray(data.data.dischargeList)) {
  172. for (let index = 0; index < data.data.dischargeList.length; index++) {
  173. // 获取当前行数据
  174. const item = data.data.dischargeList[index];
  175. // 关键修复:先初始化数组元素,再赋值(解决空数组直接赋值报错)
  176. dataList[index] = { ...item }; // 保留原始数据字段
  177. console.log(dataList);
  178. // 保留你的核心逻辑:仅截取小时位相减
  179. // 增加防错处理:避免时间字段为空/格式错误导致NaN
  180. const startHour = data.data.dischargeList[index].startworkordertime?.slice(8, 10) || 0;
  181. dataList[index].time = startHour;
  182. }
  183. }
  184. }
  185. } else if (currentType === 'year') {
  186. // 年维度:按月份统计
  187. if (this.data.operationRole==5) {
  188. if (data?.data?.chargeList && Array.isArray(data.data.chargeList)) {
  189. for (let index = 0; index < data.data.chargeList.length; index++) {
  190. // 获取当前行数据
  191. const item = data.data.chargeList[index];
  192. // 关键修复:先初始化数组元素,再赋值(解决空数组直接赋值报错)
  193. dataList[index] = { ...item }; // 保留原始数据字段
  194. console.log(dataList);
  195. // 保留你的核心逻辑:仅截取小时位相减
  196. // 增加防错处理:避免时间字段为空/格式错误导致NaN
  197. const startHour = data.data.chargeList[index].startworkordertime?.slice(5, 7) || 0;
  198. dataList[index].time = startHour;
  199. }
  200. }
  201. }else{
  202. if (data?.data?.dischargeList && Array.isArray(data.data.dischargeList)) {
  203. for (let index = 0; index < data.data.dischargeList.length; index++) {
  204. // 获取当前行数据
  205. const item = data.data.dischargeList[index];
  206. // 关键修复:先初始化数组元素,再赋值(解决空数组直接赋值报错)
  207. dataList[index] = { ...item }; // 保留原始数据字段
  208. console.log(dataList);
  209. // 保留你的核心逻辑:仅截取小时位相减
  210. // 增加防错处理:避免时间字段为空/格式错误导致NaN
  211. const startHour = data.data.dischargeList[index].startworkordertime?.slice(5, 7) || 0;
  212. dataList[index].time = startHour;
  213. }
  214. }
  215. }
  216. }
  217. // 计算总计数据
  218. // dataList.forEach(item => {
  219. // statData.chargeTotal += item.charge;
  220. // statData.dischargeTotal += item.discharge;
  221. // });
  222. // statData.netTotal = (statData.chargeTotal - statData.dischargeTotal).toFixed(1);
  223. // statData.chargeTotal = statData.chargeTotal.toFixed(1);
  224. // statData.dischargeTotal = statData.dischargeTotal.toFixed(1);
  225. this.setData({
  226. statData:data.data,
  227. dataList
  228. });
  229. // 渲染折线图
  230. this.renderChart();
  231. this.setData({
  232. statData: data.data
  233. })
  234. }
  235. })
  236. .catch((err) => {
  237. console.error('获取工单信息失败:', err);
  238. this.showInfo('获取工单信息失败');
  239. });
  240. },
  241. /**
  242. * ✅ 修复完成:渲染充放电折线图 (所有错误已修正)
  243. */
  244. renderChart() {
  245. const { dataList } = this.data;
  246. if (dataList.length === 0) return;
  247. // 提取X轴标签和Y轴数据
  248. const categories = dataList.map(item => item.time);
  249. let chargeData = ''
  250. if(this.data.operationRole==5){
  251. chargeData = dataList.map(item => parseFloat(item.chargeActual));
  252. }else{
  253. chargeData = dataList.map(item => parseFloat(item.dischargeActual));
  254. }
  255. // const dischargeData = dataList.map(item => parseFloat(item.dischargeActual));
  256. // ✅ 修复:获取屏幕宽度 - 正确的PX适配,不乘以pixelRatio
  257. const systemInfo = wx.getSystemInfoSync();
  258. const windowWidth = systemInfo.windowWidth;
  259. // 图表宽度:屏幕宽度 - 左右各16px边距,完美适配所有机型
  260. const chartWidth = windowWidth - 32;
  261. // 图表高度:固定280px,适配性最佳
  262. const chartHeight = 200;
  263. // ✅ 修复:wxCharts 标准正确配置项(删除所有无效配置,修正错误配置)
  264. const chartConfig = {
  265. canvasId: 'chargeDischargeChart', // 必须和wxml的canvas-id一致 ✔️
  266. type: 'line', // 折线图类型 ✔️
  267. categories: categories, // X轴分类 ✔️
  268. // ['1','2','3','4','5','6']
  269. // ========== 新增:图表顶部标题配置【核心代码】 ==========
  270. series: [
  271. {
  272. name: '充电量(kWh)',
  273. data: chargeData,
  274. color: '#07c160' // 绿色充电
  275. }
  276. // {
  277. // name: '放电量(kWh)',
  278. // data: dischargeData,
  279. // color: '#ff4757' // 红色放电
  280. // }
  281. ],
  282. // ✅ 正确的Y轴配置项
  283. yAxis: {
  284. min: 0, // Y轴最小值为0 ✔️
  285. format: (val) => val.toFixed(1), // Y轴数值保留1位小数 ✔️
  286. titleFontSize: 12, // Y轴标题字号
  287. labelFontSize: 10, // Y轴刻度字号 ✔️
  288. fontColor: '#666', // Y轴文字颜色
  289. gridColor: '#eee' // Y轴网格线颜色
  290. },
  291. // ✅ 正确的X轴配置项
  292. xAxis: {
  293. disableGrid: false, // 显示X轴网格线 ✔️
  294. labelFontSize: 10, // X轴刻度字号 ✔️
  295. fontColor: '#666',
  296. gridColor: '#eee'
  297. },
  298. legend: false, // 是否显示图例 (wxCharts中是布尔值,不是对象) ✔️
  299. width: chartWidth, // ✅ 核心修复:正确的宽度PX值
  300. height: 240, // ✅ 微调高度:从280改为300,给顶部标题留出空间,不挤压图表内容
  301. dataLabel: false, // 是否在折线上显示数值 ✔️
  302. dataPointShape: true, // 是否显示数据点 ✔️
  303. fontColor: '#666',
  304. // ✅ 修复:wxCharts 正确的折线样式配置
  305. extra: {
  306. line: {
  307. type: 'curve', // curve=曲线,straight=直线 ✔️
  308. width: 1 // 折线粗细
  309. },
  310. legendTextColor: '#666' // 图例文字颜色
  311. }
  312. };
  313. // ✅ 修复:wxCharts无updateData,更新图表的正确方式 = 重新实例化
  314. // ✅ 修复:用setData赋值图表实例,不是直接修改this.data
  315. const chart = new wxCharts(chartConfig);
  316. this.setData({ chart });
  317. }
  318. });