|
@@ -0,0 +1,267 @@
|
|
|
|
|
+import React, { useEffect, useState } from 'react';
|
|
|
|
|
+import { PageContainer } from '@ant-design/pro-components';
|
|
|
|
|
+import { Card, Space, Table } from 'antd';
|
|
|
|
|
+import type { ColumnsType } from 'antd/es/table';
|
|
|
|
|
+import { queryScenes } from '@/services/scene';
|
|
|
|
|
+import SceneHistory from '@/pages/SceneManagement/sceneHistory';
|
|
|
|
|
+
|
|
|
|
|
+interface DataType {
|
|
|
|
|
+ name: string;
|
|
|
|
|
+ home_name: number;
|
|
|
|
|
+ type_name: string;
|
|
|
|
|
+ creator_name: string;
|
|
|
|
|
+ description_expr: string;
|
|
|
|
|
+ record_id: string;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 场景管理
|
|
|
|
|
+ * @constructor
|
|
|
|
|
+ */
|
|
|
|
|
+const SceneManagement: React.FC = () => {
|
|
|
|
|
+ const [loading, setLoading] = useState(false);
|
|
|
|
|
+ const [pagination, setPagination] = useState({ total: 0, current: 1, pageSize: 10 });
|
|
|
|
|
+ const [dataList, setDataList] = useState([]);
|
|
|
|
|
+ const [visible, setVisible] = useState(false);
|
|
|
|
|
+ const [recordId, setRecordId] = useState('');
|
|
|
|
|
+ const weekArray = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
|
|
|
|
+
|
|
|
|
|
+ // 获取列表数据
|
|
|
|
|
+ const getList = () => {
|
|
|
|
|
+ const params = {
|
|
|
|
|
+ q: 'page',
|
|
|
|
|
+ current: pagination.current,
|
|
|
|
|
+ pageSize: pagination.pageSize,
|
|
|
|
|
+ };
|
|
|
|
|
+ queryScenes(params).then((res) => {
|
|
|
|
|
+ if (res && res.code === 0) {
|
|
|
|
|
+ setDataList(res.data.list);
|
|
|
|
|
+ setPagination(res.data.pagination);
|
|
|
|
|
+ setLoading(false);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ useEffect(() => {
|
|
|
|
|
+ setLoading(true);
|
|
|
|
|
+ getList();
|
|
|
|
|
+ }, []);
|
|
|
|
|
+
|
|
|
|
|
+ // 分页切换
|
|
|
|
|
+ const tableChange = (page: any) => {
|
|
|
|
|
+ setLoading(true);
|
|
|
|
|
+ const params = {
|
|
|
|
|
+ q: 'page',
|
|
|
|
|
+ current: page.current,
|
|
|
|
|
+ pageSize: page.pageSize,
|
|
|
|
|
+ };
|
|
|
|
|
+ queryScenes(params).then((res) => {
|
|
|
|
|
+ if (res && res.code === 0) {
|
|
|
|
|
+ setDataList(res.data.list);
|
|
|
|
|
+ setPagination(res.data.pagination);
|
|
|
|
|
+ setLoading(false);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 跳转到历史记录弹框中
|
|
|
|
|
+ const toHistory = (record: any) => {
|
|
|
|
|
+ setVisible(true);
|
|
|
|
|
+ setRecordId(record.record_id);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 历史弹框回调
|
|
|
|
|
+ const onHistoryCallback = () => {
|
|
|
|
|
+ setVisible(false);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 转换成星期 例: 0,1,1,1,1,1,1 => 周一,周二,周三,周四,周五,周六
|
|
|
|
|
+ const convertToWeekdays = (binaryStr: string) => {
|
|
|
|
|
+ // 判断 binaryStr 是否存在
|
|
|
|
|
+ if (!binaryStr || typeof binaryStr !== 'string') {
|
|
|
|
|
+ return '';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const days = binaryStr.split(',');
|
|
|
|
|
+
|
|
|
|
|
+ // 判断是否全为 0(仅此一次)
|
|
|
|
|
+ if (days.every((day) => parseInt(day) === 0)) {
|
|
|
|
|
+ return '仅此一次';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 判断是否全为 1(每天)
|
|
|
|
|
+ if (days.every((day) => parseInt(day) === 1)) {
|
|
|
|
|
+ return '每天';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 其他情况按原逻辑处理
|
|
|
|
|
+ return days
|
|
|
|
|
+ .map((day, index) => (parseInt(day) === 1 ? weekArray[index] : ''))
|
|
|
|
|
+ .filter((day) => day !== '')
|
|
|
|
|
+ .join(',');
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const columns: ColumnsType<DataType> = [
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '序号',
|
|
|
|
|
+ align: 'center',
|
|
|
|
|
+ key: 'index',
|
|
|
|
|
+ width: 80,
|
|
|
|
|
+ render: (_: any, row: any, index: number) => index + 1,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '房间名称',
|
|
|
|
|
+ dataIndex: 'home_name',
|
|
|
|
|
+ key: 'home_name',
|
|
|
|
|
+ width: 250,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '场景名称',
|
|
|
|
|
+ dataIndex: 'name',
|
|
|
|
|
+ key: 'name',
|
|
|
|
|
+ width: 250,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '场景类型',
|
|
|
|
|
+ dataIndex: 'type_name',
|
|
|
|
|
+ key: 'type_name',
|
|
|
|
|
+ width: 250,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '关联设备数',
|
|
|
|
|
+ dataIndex: 'device_infos',
|
|
|
|
|
+ key: 'device_infos',
|
|
|
|
|
+ width: 250,
|
|
|
|
|
+ render: (v) => {
|
|
|
|
|
+ if (v) {
|
|
|
|
|
+ return `${v.length}个`;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return `0个`;
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '动作',
|
|
|
|
|
+ dataIndex: 'action_desc',
|
|
|
|
|
+ key: 'action_desc',
|
|
|
|
|
+ width: 250,
|
|
|
|
|
+ render: (v: string) => {
|
|
|
|
|
+ if (!v || typeof v !== 'string') {
|
|
|
|
|
+ return <div style={{ color: 'gray' }}>暂无动作数据</div>;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return v.split(';').map((item: string) => {
|
|
|
|
|
+ return <div key={item}>{item}</div>;
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '条件',
|
|
|
|
|
+ dataIndex: 'conditions',
|
|
|
|
|
+ key: 'conditions',
|
|
|
|
|
+ width: 350,
|
|
|
|
|
+ render: (v: string) => {
|
|
|
|
|
+ if (!v || !Array.isArray(v) || v.length === 0) {
|
|
|
|
|
+ return <div style={{ color: 'gray' }}>暂无条件数据</div>;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return v.map((item: any, index: number) => {
|
|
|
|
|
+ const key = item.record_id || `condition-${index}`;
|
|
|
|
|
+
|
|
|
|
|
+ switch (item.entity_type) {
|
|
|
|
|
+ case 'timer':
|
|
|
|
|
+ const time = item.expr?.time || '';
|
|
|
|
|
+ const loops = item.expr?.loops || '';
|
|
|
|
|
+ return <div key={key}>{`定时:${time} | ${convertToWeekdays(loops)};`}</div>;
|
|
|
|
|
+ case 'weather':
|
|
|
|
|
+ const weatherName = item.weather_name || '';
|
|
|
|
|
+ const weatherValueName = item.weather_value_name || '';
|
|
|
|
|
+ const location = item.expr?.location || '';
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div key={key}>{`${weatherName}: ${weatherValueName} | 地址:${location};`}</div>
|
|
|
|
|
+ );
|
|
|
|
|
+ case 'device_status':
|
|
|
|
|
+ const statusFuncName = item.status_func_name || '';
|
|
|
|
|
+ const statusFuncValueName = item.status_func_value_name || '';
|
|
|
|
|
+ const deviceName = item.device_name || '';
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div key={key}>{`${statusFuncName}: ${statusFuncValueName} | ${deviceName};`}</div>
|
|
|
|
|
+ );
|
|
|
|
|
+ default:
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div key={key} style={{ color: 'gray' }}>
|
|
|
|
|
+ 暂无条件数据
|
|
|
|
|
+ </div>
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '执行条件',
|
|
|
|
|
+ dataIndex: 'description_expr',
|
|
|
|
|
+ key: 'description_expr',
|
|
|
|
|
+ width: 250,
|
|
|
|
|
+ render: (v: string) => {
|
|
|
|
|
+ return <span>{{ or: '满足任一条件', and: '满足所有条件' }[v]}</span>;
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '创建者',
|
|
|
|
|
+ dataIndex: 'creator_name',
|
|
|
|
|
+ key: 'creator_name',
|
|
|
|
|
+ width: 250,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '操作',
|
|
|
|
|
+ key: 'action',
|
|
|
|
|
+ width: 150,
|
|
|
|
|
+ render: (_, record) => (
|
|
|
|
|
+ <Space size="middle">
|
|
|
|
|
+ <a
|
|
|
|
|
+ onClick={() => {
|
|
|
|
|
+ toHistory(record);
|
|
|
|
|
+ }}
|
|
|
|
|
+ >
|
|
|
|
|
+ 历史记录
|
|
|
|
|
+ </a>
|
|
|
|
|
+ </Space>
|
|
|
|
|
+ ),
|
|
|
|
|
+ },
|
|
|
|
|
+ ];
|
|
|
|
|
+ const paginationProps = {
|
|
|
|
|
+ showSizeChanger: true,
|
|
|
|
|
+ showQuickJumper: true,
|
|
|
|
|
+ showTotal: (total: number) => {
|
|
|
|
|
+ return <span> 共 {total}条 </span>;
|
|
|
|
|
+ },
|
|
|
|
|
+ ...pagination,
|
|
|
|
|
+ };
|
|
|
|
|
+ return (
|
|
|
|
|
+ <PageContainer>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <Card>
|
|
|
|
|
+ <Table
|
|
|
|
|
+ columns={columns}
|
|
|
|
|
+ dataSource={dataList}
|
|
|
|
|
+ rowKey={(record) => record.record_id}
|
|
|
|
|
+ pagination={paginationProps}
|
|
|
|
|
+ loading={loading}
|
|
|
|
|
+ onChange={tableChange}
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ {visible && (
|
|
|
|
|
+ <SceneHistory
|
|
|
|
|
+ visible={visible}
|
|
|
|
|
+ editCallback={() => {
|
|
|
|
|
+ onHistoryCallback();
|
|
|
|
|
+ }}
|
|
|
|
|
+ recordId={recordId}
|
|
|
|
|
+ />
|
|
|
|
|
+ )}
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </PageContainer>
|
|
|
|
|
+ );
|
|
|
|
|
+};
|
|
|
|
|
+export default SceneManagement;
|