|
@@ -19,8 +19,8 @@
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
// 场景类历史数据公共组件!
|
|
|
- // 用于服务场景类历史数据业务,这类数据通常由一条数据返回多个子设备的信息,例如:{ forcFan1Temp, forcFan2Temp };
|
|
|
- // 而此组件可以将这些数据分类,例如:表格只有 温度 一列,但可以根据所选的子设备展示不同的数据;
|
|
|
+ // 用于服务带子设备的设备历史数据业务,这类数据通常由一条数据返回多个子设备的信息,例如:{ forcFan1Temp, forcFan2Temp };
|
|
|
+ // 而此组件可以将这些数据分类,例如:表格只有 温度 一列,但可以根据所选的子设备展示子设备1的数据:forcFan1Temp;
|
|
|
// 综上所述,此组件在基础的历史数据组件上添加了子设备下拉框(由字典驱动),用户选择子设备后表头将动态调整以适配数据展示;
|
|
|
//
|
|
|
// 使用方法如下:
|
|
@@ -28,7 +28,7 @@
|
|
|
//
|
|
|
// 1、配置设备字段(参考公司端综合设备管理-设备字段管理)
|
|
|
// 以压风机为例,设压风机设备的历史数据编码为forcFan_history。
|
|
|
- // 那么字段code中需要把所有字段悉数配置,例子如下:
|
|
|
+ // 那么需要把所有字段悉数配置,例子如下:
|
|
|
// 显示字段 字段code
|
|
|
// 温度 forcFanTemp
|
|
|
// 安装位置 name
|
|
@@ -51,6 +51,10 @@
|
|
|
// 温度 安装位置
|
|
|
// 取forcFan1Temp 取name
|
|
|
// 当设备字段不含数据字典关键词(forcFan)时不做处理,当设备字段包含关键词但已指定编号(即字段包含数字)时不做处理
|
|
|
+ //
|
|
|
+ // 5、历史数据模式选择
|
|
|
+ // 历史数据的请求分为redis分站模式、其他模式,redis分站模式将不支持子设备选择,参考基础的历史数据组件逻辑(本组件已做兼容)
|
|
|
+ // 历史数据查询模式分为多设备查询模式、单设备查询模式,单设备查询模式将不支持设备多选,两种模式本组件都支持
|
|
|
import { computed, onMounted, ref, shallowRef } from 'vue';
|
|
|
import { BasicColumn, PaginationProps, BasicTable } from '/@/components/Table';
|
|
|
import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
|
|
@@ -94,11 +98,11 @@
|
|
|
}
|
|
|
);
|
|
|
|
|
|
- // 创建表格,此表格目前不具备常用功能,需要初始化后使用(props指定表格配置时除外)
|
|
|
+ // 未经过处理的原始表头,即项目配置的表头
|
|
|
let originColumns: BasicColumn[] = [];
|
|
|
- const scroll = computed(() => {
|
|
|
- return { ...props.scroll, y: props.scroll.y - 100 };
|
|
|
- });
|
|
|
+ // 表格数据
|
|
|
+ const data = shallowRef([]);
|
|
|
+
|
|
|
const { tableContext, onExportXls, onExportXlsPost } = useListPage({
|
|
|
tableProps: {
|
|
|
columns: [
|
|
@@ -127,7 +131,9 @@
|
|
|
size: 'small',
|
|
|
showIndexColumn: true,
|
|
|
tableLayout: 'auto',
|
|
|
- scroll: scroll,
|
|
|
+ scroll: computed(() => {
|
|
|
+ return { ...props.scroll, y: props.scroll.y - 100 };
|
|
|
+ }),
|
|
|
pagination: props.pagination,
|
|
|
},
|
|
|
exportConfig: {
|
|
@@ -137,16 +143,62 @@
|
|
|
});
|
|
|
const [register, { getForm, setLoading, getPaginationRef, setPagination, setColumns }] = tableContext;
|
|
|
|
|
|
+ // 已选中的设备信息
|
|
|
+ const deviceInfo = ref<Record<string, unknown>>({});
|
|
|
+ // 设备下拉框选项
|
|
|
+ const deviceOptions = ref<Record<string, unknown>[]>([]);
|
|
|
+ // 子设备下拉框选项
|
|
|
+ const dictOptions = ref<Record<string, unknown>[]>([]);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取设备信息列表、子设备字典,初始化设备可选项、子设备可选项并选中首个设备
|
|
|
+ */
|
|
|
+ async function fetchDevice() {
|
|
|
+ const results = await getDeviceList({ devicetype: props.deviceCode, pageSize: 10000 });
|
|
|
+ const dicts = await initDictOptions(props.dictCode);
|
|
|
+
|
|
|
+ const options = results.map((item) => {
|
|
|
+ return {
|
|
|
+ label: item.strinstallpos,
|
|
|
+ value: item.id || item.deviceID,
|
|
|
+ deviceType: item.strtype || item.deviceType,
|
|
|
+ devicekind: item.devicekind,
|
|
|
+ stationtype: item.stationtype,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ deviceOptions.value = options;
|
|
|
+ dictOptions.value = dicts;
|
|
|
+ onDeviceChangeCallback(null, options[0]);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
- * 初始化表格,该方法将根据参数设定新的表头、表单,如果提供了自定义的表头、表单配置则不作操作。
|
|
|
+ * 选择任意设备后的回调,根据设备信息刷新表格、表头及其数据
|
|
|
+ */
|
|
|
+ function onDeviceChangeCallback(__, option) {
|
|
|
+ // 生成所有需要查询的表头编码,例如 forcFan_auto 对应 forcFan_auto_history、forcFan_history 这两个
|
|
|
+ const codes: string[] = [];
|
|
|
+ deviceInfo.value = option;
|
|
|
+ if (deviceInfo.value && deviceInfo.value.deviceType) {
|
|
|
+ const arr = (deviceInfo.value.deviceType as string).split('_');
|
|
|
+ while (arr.length) {
|
|
|
+ codes.push(arr.join('_').concat('_history'));
|
|
|
+ arr.pop();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 如此,例如deviceType为forcFan_auto, 则查询表头按 forcFan_auto_history、forcFan_history、columnsCode 为顺序
|
|
|
+ initTable(codes.concat(props.columnsCode));
|
|
|
+ search();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化表格,该方法将根据参数设定新的表头、表单。
|
|
|
*
|
|
|
- * 之所以将设备相关的信息作参数传入,是因为这样可以确认依赖关系,即需要有设备信息之后再初始化表格。
|
|
|
+ * 需要有设备信息之后再初始化表格。
|
|
|
*
|
|
|
* @param deviceCodes 获取表头所用的编码,从左到右依次尝试,直到找到第一个有表头信息的为止
|
|
|
- * @param deviceOptions 设备下拉框对应的选项
|
|
|
*/
|
|
|
- function initTable(deviceCodes: string[], deviceOptions: any[], dictOptions: any[]) {
|
|
|
- const defaultSchemas = getDefaultSchemas(dictOptions, deviceOptions, () => search());
|
|
|
+ function initTable(deviceCodes: string[]) {
|
|
|
+ const defaultSchemas = getDefaultSchemas(dictOptions.value, deviceOptions.value, onDeviceChangeCallback);
|
|
|
for (const code of deviceCodes) {
|
|
|
const cols = getTableHeaderColumns(code);
|
|
|
if (cols.length) {
|
|
@@ -160,6 +212,35 @@
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 搜索,核心方法
|
|
|
+ *
|
|
|
+ * 该方法获取表单、处理表单数据后尝试获取数据并设置表头
|
|
|
+ */
|
|
|
+ async function search() {
|
|
|
+ if (!deviceInfo.value) return;
|
|
|
+
|
|
|
+ const form = getForm();
|
|
|
+ await form.validate();
|
|
|
+ const formData = form.getFieldsValue();
|
|
|
+
|
|
|
+ setLoading(true);
|
|
|
+ const pagination = getPaginationRef() as PaginationProps;
|
|
|
+ const deviceCode = (deviceInfo.value.deviceType || props.deviceCode.concat('*')) as string;
|
|
|
+ const { records, total, current } = await list(deviceCode, deviceInfo, formData, pagination).finally(() => {
|
|
|
+ setLoading(false);
|
|
|
+ });
|
|
|
+ setPagination({
|
|
|
+ current,
|
|
|
+ total,
|
|
|
+ });
|
|
|
+ records.forEach((item) => {
|
|
|
+ Object.assign(item, item.readData);
|
|
|
+ });
|
|
|
+ data.value = records;
|
|
|
+ updateColumns(formData.deviceNum);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 更新表头,表头默认情况下需要和子设备联动
|
|
|
* @param prefix 子设备的值,即为表头取数据时字段的前缀
|
|
|
*/
|
|
@@ -185,89 +266,14 @@
|
|
|
setColumns(cols);
|
|
|
}
|
|
|
|
|
|
- // 表格数据相关的字段
|
|
|
- const data = shallowRef([]);
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取列表的数据
|
|
|
- *
|
|
|
- * 这些参数确认了依赖关系,即需要有表单数据、设备信息之后再尝试获取表格数据。
|
|
|
- *
|
|
|
- * @param formData 表格上方的表单数据
|
|
|
- * @param deviceCode 设备编码
|
|
|
- * @param deviceInfo 设备信息
|
|
|
- */
|
|
|
- function fetchData(formData: Record<string, unknown>, deviceCode: string, deviceInfo: any) {
|
|
|
- setLoading(true);
|
|
|
- const pagination = getPaginationRef() as PaginationProps;
|
|
|
- return list(deviceCode, deviceInfo, formData, pagination)
|
|
|
- .then(({ records, total, current }) => {
|
|
|
- setPagination({
|
|
|
- current,
|
|
|
- total,
|
|
|
- });
|
|
|
- records.forEach((item) => {
|
|
|
- Object.assign(item, item.readData);
|
|
|
- });
|
|
|
- data.value = records;
|
|
|
- })
|
|
|
- .finally(() => {
|
|
|
- setLoading(false);
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // 设备信息相关的字段
|
|
|
- const deviceInfo = ref<Record<string, unknown>>({});
|
|
|
- const deviceOptions = ref<Record<string, unknown>[]>([]);
|
|
|
- const dictOptions = ref<Record<string, unknown>[]>([]); // 子设备下拉框选项
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取设备信息列表,初始化设备信息及设备可选项
|
|
|
- */
|
|
|
- async function fetchDevice() {
|
|
|
- const results = await getDeviceList({ devicetype: props.deviceCode, pageSize: 10000 });
|
|
|
- const dicts = await initDictOptions(props.dictCode);
|
|
|
-
|
|
|
- const options = results.map((item) => {
|
|
|
- return {
|
|
|
- label: item.strinstallpos,
|
|
|
- value: item.id || item.deviceID,
|
|
|
- deviceType: item.strtype || item.deviceType,
|
|
|
- devicekind: item.devicekind,
|
|
|
- stationtype: item.stationtype,
|
|
|
- };
|
|
|
- });
|
|
|
- deviceOptions.value = options;
|
|
|
- deviceInfo.value = results[0] || {};
|
|
|
- dictOptions.value = dicts;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 搜索,核心方法
|
|
|
- *
|
|
|
- * 该方法获取表单、处理表单数据后尝试获取数据并设置表头
|
|
|
- */
|
|
|
- async function search() {
|
|
|
- const form = getForm();
|
|
|
- await form.validate();
|
|
|
- const formData = form.getFieldsValue();
|
|
|
- const info = deviceOptions.value.find((opt) => {
|
|
|
- return opt.value === formData.gdeviceids.split(',')[0];
|
|
|
- });
|
|
|
- if (!info) return;
|
|
|
- deviceInfo.value = info;
|
|
|
- const code = (deviceInfo.value.deviceType || props.deviceCode.concat('*')) as string;
|
|
|
- await fetchData(formData, code, deviceInfo.value);
|
|
|
- updateColumns(formData.deviceNum);
|
|
|
- }
|
|
|
-
|
|
|
/** 导出表格内容为excel */
|
|
|
async function exportXls() {
|
|
|
const form = getForm();
|
|
|
await form.validate();
|
|
|
const formData = form.getFieldsValue();
|
|
|
const pagination = getPaginationRef() as PaginationProps;
|
|
|
- const params = adaptFormData(props.deviceCode, deviceInfo.value, formData, pagination);
|
|
|
+ const deviceCode = (deviceInfo.value.deviceType || props.deviceCode.concat('*')) as string;
|
|
|
+ const params = adaptFormData(deviceCode, deviceInfo.value, formData, pagination);
|
|
|
if (deviceInfo.value.stationtype === 'redis') {
|
|
|
return onExportXlsPost(params);
|
|
|
} else {
|
|
@@ -275,20 +281,17 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // watch(
|
|
|
+ // () => props.deviceCode,
|
|
|
+ // async () => {
|
|
|
+ // await fetchDevice();
|
|
|
+ // onDeviceChangeCallback(null, deviceInfo.value);
|
|
|
+ // }
|
|
|
+ // );
|
|
|
+
|
|
|
onMounted(async () => {
|
|
|
await fetchDevice();
|
|
|
- // 生成所有需要查询的表头编码,例如 forcFan_auto 对应 forcFan_auto_history、forcFan_history 这两个
|
|
|
- const codes: string[] = [];
|
|
|
- if (deviceInfo.value && deviceInfo.value.deviceType) {
|
|
|
- const arr = (deviceInfo.value.deviceType as string).split('_');
|
|
|
- while (arr.length) {
|
|
|
- codes.push(arr.join('_').concat('_history'));
|
|
|
- arr.pop();
|
|
|
- }
|
|
|
- }
|
|
|
- // 如此,例如deviceType为forcFan_auto, 则查询表头按 forcFan_auto_history、forcFan_history、columnsCode 为顺序
|
|
|
- initTable(codes.concat(props.columnsCode), deviceOptions.value, dictOptions.value);
|
|
|
- search();
|
|
|
+ onDeviceChangeCallback(null, deviceInfo.value);
|
|
|
});
|
|
|
</script>
|
|
|
|