本文档面向已经了解 面板小程序开发 的开发者,您需要充分的了解什么是面板小程序,什么是 DP 功能。

相关知识

在某些设备的面板中需要提供给 C 端用户查看设备数据的能力,并需要导出数据使用户能够进一步分析。这里一般会导出如:温度、湿度、PM2.5 等的数据,涂鸦提供了相关的接口,可以按小时、天、月等粒度导出数据,把数据生成 Excel 文件,并通过邮件的方式发送给用户。

按小时粒度导出数据接口

入参

参数名称

参数类型

是否必选

默认值

描述

email

string

接收导出文件的邮箱地址

devId

string

待操作的设备 ID

dpExcelQuery

string

具体 DP 点的查询条件

date

string

待导出数据的日期,格式:20230901

type

string

DP 点的统计类型,支持:sum/avg/minux/min/max/count 等

auto

number

0

补数据的类型, 0:代表无数据补 0,1:代表无数据时会拿上一个时间点的数据补到当前时间点,2:代表无数据时补#

keepScalaPoint

boolean

false

是否按照 dp 点上报扩大倍数保留小数点

lang

string

多语言 code

title

string

邮件标题

按天粒度导出数据接口

入参

参数名称

参数类型

是否必选

默认值

描述

email

string

接收导出文件的邮箱地址

devId

string

待操作的设备 ID

dpExcelQuery

string

具体 DP 点的查询条件

startDay

string

待导出数据的开始日期,格式:20230901

endDay

string

待导出数据的结束日期,格式:20230930

type

string

DP 点的统计类型,支持:sum/avg/minux/min/max/count 等

keepScalaPoint

boolean

false

是否按照 dp 点上报扩大倍数保留小数点

lang

string

多语言 code

title

string

邮件标题

按月粒度导出数据接口

入参

参数名称

参数类型

是否必选

默认值

描述

email

string

接收导出文件的邮箱地址

devId

string

待操作的设备 ID

dpExcelQuery

string

具体 DP 点的查询条件

startMonth

string

待导出数据的开始年月,格式:202309

endMonth

string

待导出数据的结束年月,格式:202309

type

string

DP 点的统计类型,支持:sum/avg/minux/min/max/count 等

keepScalaPoint

boolean

false

是否按照 dp 点上报扩大倍数保留小数点

lang

string

多语言 code

title

string

邮件标题

dpExcelQuery 的结构

此值为一个数组结构的 JSON 字符串,数组元素的结构为:

属性名称

类型

是否必须

描述

dpId

Number

DP 功能的 ID

name

String

DP 功能名称

handler

String

可支持温度的转换,值可为 temperatureF2C 或 temperatureC2F

示例

[{"dpId":"101","name":"华氏度转摄氏度","handler":"temperatureF2C"}]
        

示例为:需要导出设备的温度 (101)、湿度 (102)两个 DP 的数据,并且需要支持将温度的单位转为华氏度。

功能描述

UI 实现

import React, { FC, useState, useCallback, useRef } from
          "react";
          import { View, Text, Button, Checkbox, showToast } from "@ray-js/ray";
          import SwitchButton from "@ray-js/components-ty-switch";
          import ActionSheet from "@ray-js/components-ty-actionsheet";
          import List from "@ray-js/components-ty-cell";
          import DatePicker from "@ray/components-ty-datetime-picker";
          import Input from "@ray-js/components-ty-input";
          import { hooks } from "@ray-js/panel-sdk";
          import * as api from "./api";

          const langs = {
          hour: "时",
          day: "天",
          month: "月",
          };

          const exportFn = {
          hour: api.exportHour,
          day: api.exportDay,
          month: api.exportMonth,
          };

          const formDate = (date, format = "YYYYMMDD") => {
          const year = date.getFullYear();
          const month = date.getMonth() + 1;
          const day = date.getDate();

          return format
          .replace("YYYY", year)
          .replace("MM", month.toString().padStart(2, "0"))
          .replace("DD", day.toString().padStart(2, "0"));
          };

          const Page: FC = () => {
          const devInfo = hooks.useDevInfo();
          const [unit, setUnit] = useState(false);
          const [type, setType] = useState("hour");
          const [email, setEmail] = useState("");
          const isEnd = useRef(false);
          const [showList, setShowList] = useState(false);
          const [showTime, setShowTime] = useState(false);
          const [startTime, setStartTime] = useState(new Date());
          const [endTime, setEndTime] = useState(new Date());

          const handleShowEnd = useCallback(() => {
          isEnd.current = true;
          setShowTime(true);
          }, []);
          const handleShowStart = useCallback(() => {
          isEnd.current = false;
          setShowTime(true);
          }, []);
          const handleSelectTime = useCallback((v) => {
          if (isEnd.current) {
          setEndTime(v);
          } else {
          setStartTime(v);
          }
          }, []);

          const handleExport = useCallback(() => {
          if (!email) {
          showToast({
          title: "请输入邮箱",
          icon: "error",
          });
          return;
          }
          const format = type === "month" ? "YYYYMM" : "YYYYMMDD";
          let start = formDate(startTime, format);
          let end = formDate(startTime, format);
          const data = {
          title: "温湿度数据表",
          devId: devInfo.devId,
          email,
          dpExcelQuery: [
          {
          dpId: "101",
          name: "室内温度",
          handler: unit ? "temperatureC2F" : undefined,
          },
          { dpId: "102", name: "室内湿度" },
          ],
          };

          switch (type) {
          case "hour":
          data.date = start;
          break;
          case "day":
          data.startDay = start;
          data.endDay = end;
          break;
          case "month":
          data.startMonth = start;
          data.endMonth = end;
          break;
          }
          exportFn[type](data);
          }, [type, email, unit, startTime, endTime, devInfo?.devId]);

          return (
          <View>
          <List>
          <List.Item
          title="使用华氏度"
          content={<SwitchButton checked={unit} onChange={(v) => setUnit(v)} />}
          />
          <List.Item
          title="粒度"
          onClick={() => setShowList(true)}
          content={<Text>{langs[type]}</Text>}
          />
          <List.Item
          title={type === "hour" ? "时间" : "开始时间"}
          onClick={handleShowStart}
          content={
          <Text>
          {formDate(startTime, type === "month" ? "YYYYMM" : "YYYYMMDD")}
          </Text>
          }
          />
          {type !== "hour" && (
          <List.Item
          title="结束时间"
          onClick={handleShowEnd}
          content={
          <Text>
          {formDate(endTime, type === "month" ? "YYYYMM" : "YYYYMMDD")}
          </Text>
          }
          />
          )}

          <List.Item
          title="邮箱"
          content={
          <Input
          placeholder="请输入"
          value={email}
          onInput={(e) => setEmail(e.value)}
          />
          }
          />
          </List>
          <ActionSheet
          show={showList}
          header="选择粒度"
          onCancel={() => setShowList(false)}
          okText=""
          >
          <List.Row
          dataSource={Object.keys(langs).map((key) => {
          return {
          title: langs[key],
          content: type === key ? <Checkbox checked /> : null,
          onClick: () => {
          setType(key);
          setShowList(false);
          },
          };
          })}
          />
          </ActionSheet>
          <ActionSheet
          show={showTime}
          header="选择时间"
          onCancel={() => setShowTime(false)}
          onOk={() => setShowTime(false)}
          >
          <DatePicker
          onChange={handleSelectTime}
          type={type === "month" ? "year-month" : "date"}
          />
          </ActionSheet>
          <Button onClick={handleExport}>导出</Button>
          </View>
          );
          };

          export default Page;
        

API 封装

api.js 文件内容

import {
          exportStatisticsDay,
          exportStatisticsHour,
          exportStatisticsMonth,
          } from "@ray-js/ray";

          // 导出小时数据
          export const exportHour = async (params) => {
          try {
          await exportStatisticsHour({
          email: params.email,
          devId: params.devId,
          dpExcelQuery: JSON.stringify(params.dpExcelQuery),
          date: params.date,
          type: "avg",
          auto: 2,
          keepScalaPoint: true,
          lang: "cn",
          });

          // 导出成功
          } catch {
          // 导出失败
          }
          };

          // 导出天数据
          export const exportDay = async (params) => {
          try {
          await exportStatisticsDay({
          email: params.email,
          devId: params.devId,
          dpExcelQuery: JSON.stringify(params.dpExcelQuery),
          startDay: params.startDay,
          endDay: params.endDay,
          type: "avg",
          keepScalaPoint: true,
          lang: "cn",
          });

          // 导出成功
          } catch {
          // 导出失败
          }
          };

          // 导出月数据
          export const exportMonth = async (params) => {
          try {
          await exportStatisticsMonth({
          email: params.email,
          devId: params.devId,
          dpExcelQuery: JSON.stringify(params.dpExcelQuery),
          startMonth: params.startMonth,
          endMonth: params.endMonth,
          type: "avg",
          keepScalaPoint: true,
          lang: "cn",
          });

          // 导出成功
          } catch {
          // 导出失败
          }
          };