门户中用自定义实现自定义报表的查询

介绍

用户在门户展板中想要显示一个列表,显示后台返回的数据,并且每一个数据有一个操作列,进行跳转到对应的功能列表中

效果图

注意:图中数据字段与数据均为测试数据,不作为参考对象

实现逻辑

  • 1、在门户引擎中先写第一个自定义的页面如:全局搜索;代码如下:
/**
 * 编辑器内,暴露了可以直接在代码中使用的全局变量如下:
 * JE:公共类库,提供了常用的类库
 * const vue = JE.useVue();  // Vue库
 * const ui = JE.useUi();  // UI库
 * const utils = JE.useUtils();  // 工具库
 * const system = JE.useSystem();  // 系统类库
 */
const {h,ref} = JE.useVue();
const {Button,DatePicker} = JE.useUi();
const {container,$portal,refreshParams,$func} = EventOptions;
const today = new Date();
const yesterdayTimestamp = today.getTime() - (24 * 60 * 60 * 1000);
const yesterday = new Date(yesterdayTimestamp);
const yesterdayDate = yesterday.toISOString().slice(0, 10);
const formData = {
    //开始时间
    startDateText: yesterdayDate + " 00:00:00",
    //结束时间
    endDateText: yesterdayDate + " 23:59:59",
};
const onButtonClick = ()=>{
    // 查找包含"获取后台数据"文本的按钮
    const buttons = Array.from(document.querySelectorAll('button'));
    const targetButton = buttons.find(btn =>
      btn.textContent.includes('搜 索') &&
      //btn.textContent.includes('获取后台数据') &&
      btn.classList.contains('ant-btn-primary')//ant-btn ant-btn-primary
    );
    if (targetButton) {
      targetButton.click(); // 触发点击事件
    } else {
      console.error('未找到目标按钮');
    }
};

const onExportClick = ()=>{
  console.log("startDateText:"+formData.startDateText);
  console.log("endDateText:"+formData.endDateText);

  const ZRDW = document.getElementById('form_item_责任单位').value;//责任单位 ASSIGN_COMPANY
  const SJLX = document.getElementById('form_item_事件类型').value;//事件类型 EVENT_TYPE
  console.log("责任单位:"+ZRDW);
  console.log("事件类型:"+SJLX);
  //导出过滤参数 开始时间START_TIME,结束时间END_TIME,责任单位ASSIGN_COMPANY,事件类型EVENT_TYPE
  const baseUrl = JE.useUtils().getAjaxBaseURL();
  window.open(baseUrl + "/je/demo/event/countData/export?pd=tcdm&START_TIME="+formData.startDateText+"&END_TIME="+formData.endDateText+"&ASSIGN_COMPANY="+ZRDW+"&EVENT_TYPE="+SJLX);
};

// 渲染 UI
const node = h('div', { style: { display: 'flex', gap: '10px', alignItems: 'center' } }, [
  h(DatePicker,{value:formData.startDateText,picker:"dateTime",
                'onUpdate:value': function (val) {
                    formData.startDateText= val;
                },
                getPopupContainer:() => document.body,
                style:{width:'200px'},
                id:'startDates'
           }),
    h('span', '至'),
    h(DatePicker,{value:formData.endDateText,picker:"dateTime",
                'onUpdate:value': function (val) {
                    formData.endDateText= val;
                },
                getPopupContainer:() => document.body,
                style:{width:'200px'},
                id:'endDates'
           }),
    // 检索按钮
 h(Button,{type:"primary",onClick:()=>{
        if(formData.startDateText && formData.endDateText){
            onButtonClick()
        }else {
            JE.alert('请选择时间!')
        }
    },style: { marginLeft: '10px' , width: '100px'}},'检索'),

  // 导出按钮
  h(Button, {
    type: 'primary',
    onClick: ()=>{onExportClick()},
    style: { marginLeft: '10px' , width: '100px'}
  }, '导出'),
]);
return node;
  • 2、编写列表代码,并获取相关数据
/**
 * 使用JE框架的UI组件和Vue组合式API
 */
const { Modal, Form, Input, Grid, Button, Row, Col, Select,InputSelect,Data} = JE.useUi();
const {h,createVNode,ref,reactive,onMounted}= JE.useVue();
const {container,$portal,refreshParams,$func,options} = EventOptions;

let gridStore = Data.Store.useGridStore({data:[]});
// 列表列配置
const gridColumn = [
    { field: 'zrdw', title: '责任单位', width: '200' },
    { field: 'type', title: '事件类型', width: '150' },
    { field: 'total', title: '总数', width: '50' },
    { field: 'finish', title: '已完成', width: '80' },
    { field: 'processing', title: '处理中', width: '80' },
    { field: 'pending', title: '未处理', width: '80' },
    { field: 'timeoutResponse', title: '超时响应', width: '90' },
    { field: 'timeoutHandle', title: '超时处理', width: '90' },
    { field: 'avgResponse', title: '平均响应时长(分钟)', width: '160' },
    { field: 'avgHandle', title: '平均处理时长(分钟)', width: '160' },
    { field: 'timeoutResponseRate', title: '超时响应率', width: '100' },
    { field: 'timeoutHandleRate', title: '超时处理率', width: '100' },
    { field: 'finishRate', title: '完成率', width: '90' },
    { field: 'reason', title: '处理中原因分类', width: '120' },
    {
        field: 'actionbutton',
        title: '查看详情',
        width: '150',
        editType: Button
    }
];
// 列表数据
let originData = [];
// 响应式数据
let gridData = ref([...originData]);
const loading = ref(true);
let gridKey = ref(0);
let searchForm = reactive({ //搜索框默认值
    // company: '',
    // event: '',
});

gridStore.loading = true;
onMounted(async () => {
  setTimeout(() => {
    const buttons = Array.from(document.querySelectorAll('button'));
    const targetButton = buttons.find(btn =>
      btn.textContent.includes('搜 索') &&
      btn.classList.contains('ant-btn-primary')//ant-btn ant-btn-primary
    );
    if (targetButton) {
      targetButton.click(); // 触发点击事件
    } else {
      console.error('未找到目标按钮');
    }
  }, 10);

});

// 修正后的搜索方法
const handleSearch = async () => {
    // 1. 首先清空原有数据
    originData.length = 0; // 清空原始数据数组
    gridStore.loadData([]); // 清空表格数据
    gridStore.loading = true;
    try {
        let startDates = document.getElementById('startDates').value;//开始时间
        let endDates = document.getElementById('endDates').value;//结束时间
        let params = {
            START_TIME: startDates,
            END_TIME: endDates,
            EVENT_TYPE: searchForm.event,
            ASSIGN_COMPANY: searchForm.company
        };
        let strData = [{
            JE_CORE_DATASOURCE_ID: "bQNqVlufB8Yx8OvmHnb",
            parameterStr: params, // 自动处理转义
            limit: ""
        }];
        // 最终发送的请求数据
        let requestData = {"strData":JSON.stringify(strData)};
        //await
        const response =await JE.ajax({
            url: 'je/meta/dataSource/batchExecute',
            params: requestData,
            headers: {}
        });
        if (response.code == 1000 ) {
            // 转换数据格式以匹配表格列配置
            //debugger;
            response.data.DRGZWCQKZCLXL.data.forEach(item => {
                originData.push({
                    zrdw: item.ASSIGN_COMPANY || '暂未指派单位',  // 责任单位
                    type: item.EVENT_TYPE || '未知类型',         // 事件类型
                    total: item.TOTAL || 0,                      // 总数
                    finish: item.FINISH || 0,                     // 已完成
                    processing: item.IN_HANDLE || 0,            // 处理中
                    pending: item.NOT_HANDLE || 0,              // 未处理
                    timeoutResponse: item.TIMEOUT_RESPONSE || 0, // 超时响应
                    timeoutHandle: item.TIMEOUT_HANDLE || 0,     // 超时处理
                    avgResponse: item.AVERAGE_RESPONSE_TIME || '--',  // 平均响应时长
                    avgHandle: item.AVERAGE_HANDLE_TIME || '--',      // 平均处理时长
                    timeoutResponseRate: item.TIMEOUT_RESPONSE_RATE+"%" || '0%', // 超时响应率
                    timeoutHandleRate: item.TIMEOUT_HANDLE_RATE+"%" || '0%',     // 超时处理率
                    finishRate: item.FINISH_RATE+"%" || '0%',           // 完成率
                    reason: item.HANDLE_REASON_TYPE || '无',          // 处理中原因分类
                });
            });
            //渲染更新数据
            gridStore.loadData(originData);
            gridStore.loading = false;
        } else {
            JE.alert(`获取数据失败: ${response.message || '未知错误'}`);
        }
    } catch (error) {
        console.error('请求出错:', error);
        JE.alert(`请求出错: ${error.message}`);
    }
};
const showFuncs = (zrdw,type) =>{
    if ('暂未指派单位' == zrdw) {
        zrdw = '';
    }
    if ('未知类型'==type) {
        type = '';
    }
    //定义参数 开始时间 结束时间 指派单位 事件类型
    const startDates = document.getElementById('startDates').value;//开始时间
    const endDates = document.getElementById('endDates').value;//结束时间
    let querys1 = [
                    {"type":"=","code":"EVENT_TYPE","value":type,"cn":"and"},
                    {"type":"=","code":"ASSIGN_COMPANY","value":zrdw,"cn":"and"},
                    {"type":"between","code":"SY_CREATETIME","value":[startDates,endDates],"cn":"and"}
                ]
    const strList = ['运行管理/手推车', '运行管理/保洁卫生'];
    // 判断 name 是否包含数组中任意一个元素
    const isInclude = strList.some(item1 => type.includes(item1));
    console.log("isInclude:"+isInclude);
    if (isInclude) {
        //跳转到服务事件
        JE.showFunc('DEMO_SERVICE_1',{
            querys:querys1
        })
    } else {//跳转到事件报送
            JE.showFunc('DEMO_MANAGEMENT_1',{
            querys:querys1
        })
    }
}

// 生成表格列
const Vnode = gridColumn.map((item) => {
    return h(Grid.Column, {
        field: item.field,
        title: item.field === 'actionbutton' ? '操作' : item.title,
        minWidth: item.width,
    }, {
        default: ({ row }) => {
            if (item.field === 'actionbutton') {
                return h(item.editType, {
                    onClick: () =>  showFuncs(row.zrdw,row.type),
                    type: 'link'
                }, item.title);
            } else {
                return h('div', {}, row[item.field]);
            }
        }
    });
});

// 构建查询表单
const searchFormNode = h(Row, { gutter: 16 }, [
  h(Col, { span: 6 }, [
        h(Form.Item, { label: '责任单位' }, [
            h(InputSelect.Grid, {
                class: 'zrdw',
                value: searchForm.company,
                onChange: (value) => { searchForm.company = value },
                placeholder: '请选择责任单位',
                readonly: false,
                allowClear: true,
                configInfo: 'JE_RBAC_COMPANY,'+searchForm.company+',COMPANY_NAME,S'
            })
        ])
    ]),
    h(Col, { span: 6 }, [
        h(Form.Item, { label: '事件类型' }, [
            h(InputSelect.Grid, {
                class: 'types',
                value: searchForm.event,
                onChange: (value) => {searchForm.event = value },
                placeholder: '请选择事件类型',
                readonly: false,
                allowClear: true,
                configInfo: 'TCDM_EVENT_TYPE_MANAGE,'+searchForm.event+',TYPE_NAME,S'
            })
        ])
    ]),
  h(Col, { span: 6, style: 'align-items: flex-end;' }, [
    h(Button, {
      type: 'primary',
      onClick: handleSearch,
      style: 'margin-right: 10px;'
    }, '搜 索'),
  ]),
]);

// 构建完整界面
return h('div', {
    style: 'padding: 20px;'
}, [
    h(Form, {
        style: 'margin-bottom: 20px;'
    }, searchFormNode),
    h(Grid, {
        class: 'gridfunc-test',
        store: gridStore,
        align: 'center',
        //pagerConfig: true, //取消分页操作
        height: '500',
    }, Vnode)
]);
最后编辑: 呼丽华  文档更新时间: 2025-06-06 16:20   作者:呼丽华