门户中用自定义界面和搜索交互案例
介绍
用户在门户展板中想要显示一个自定义的统计,显示后台返回的数据,并且与顶部的搜索交互
效果

实现步骤
- 搜索条代码
const {h} = JE.useVue();
const {Button,DatePicker,Input,Panel,Select,Form,InputSelect} = JE.useUi();
const {container,$portal,refreshParams} = EventOptions;
const todayDate = JE.dateFormat(new Date(),'YYYY-MM-DD');
// 1. 确定基准日期(不传则用当前系统时间)
const baseDate = new Date();
const oneMonthAgo = new Date(baseDate);
// 2. 核心:减1个月 + 处理31日跨月的边界问题(如3月31日→2月最后一天)
const originalDay = baseDate.getDate(); // 基准日期的“日”(如31、28)
oneMonthAgo.setMonth(baseDate.getMonth() - 1);
// 若跨月后日期异常(如2月没有31日),自动修正为上月最后一天
if (oneMonthAgo.getDate() !== originalDay) {
oneMonthAgo.setDate(0); // setDate(0) = 上个月最后一天
}
// 3. 格式化为 YYYY-MM-DD 字符串(控件要求的格式)
const year = oneMonthAgo.getFullYear();
const month = String(oneMonthAgo.getMonth() + 1).padStart(2, '0'); // 月份+1,补0
const day = String(oneMonthAgo.getDate()).padStart(2, '0'); // 日期补0
const formData = {
CGBM: 'T2101,T2201,T2301,T2401',
KSSJ: year + '-' + month + '-' + day,
JSSJ: todayDate,
SJLD: "DAY"
};
const onButtonClick = ()=>{
// 获取筛选参数
const params = {
KSSJ: formData.KSSJ,
JSSJ: formData.JSSJ
};
$portal.getPortalItem('SBQK').refresh(params);//刷新面板
};
// 渲染 UI
const node = h('div', { style: { display: 'flex', gap: '10px', alignItems: 'center' } }, [
h('span', '储罐编码:'),
h(InputSelect.Grid,{
name: 'CGBM',
value: formData.CGBM,
configInfo:'SAFETY_MAINDATA_CGXX,CGBM,CGXX_CODE,M',
'onUpdate:value': function (val) {
formData.CGBM= val;
},
getPopupContainer:() => document.body,
style:{width:'240px'}
}),
h('span', '开始时间:'),
h(DatePicker,{
value: formData.KSSJ,
'onUpdate:value': function (val) {
formData.KSSJ= val;
},
getPopupContainer:() => document.body,
style:{width:'200px'},
id:'startdates'
}),
h('span', '结束时间:'),
h(DatePicker,{
value: formData.JSSJ,
'onUpdate:value': function (val) {
formData.JSSJ= val;
},
getPopupContainer:() => document.body,
style:{width:'200px'},
id:'enddates'
}),
h('span', '数据粒度:'),
h(Select,{
name: 'SJLD',
value: formData.SJLD,
configInfo: 'HG_SJLD,SJLD,code,S',
'onUpdate:value': function (val) {
formData.SJLD= val;
},
getPopupContainer:() => document.body,
style:{width:'200px'}
}),
// 检索按钮
h(Button,{
type:"primary",
onClick:()=>{
if(formData.KSSJ && formData.JSSJ && formData.SJLD){
onButtonClick();
}else {
JE.alert('开始时间、结束时间、数据粒度不能为空!');
}
},style: { marginLeft: '10px' , width: '100px'}},
'查询')
]);
return node;- 统计面板代码
const { h, ref, watch } = JE.useVue();
// 获取事件参数
let { refreshParams, $portal, container } = EventOptions;
if (container) {
if(container.children.length > 0) {container.children[0].remove();}
}
const todayDate = JE.dateFormat(new Date(), 'YYYY-MM-DD');
// 基准日期处理
const baseDate = new Date();
const oneMonthAgo = new Date(baseDate);
oneMonthAgo.setMonth(baseDate.getMonth() - 1);
if (oneMonthAgo.getDate() !== baseDate.getDate()) {
oneMonthAgo.setDate(0); // 处理31日跨月问题
}
// 初始化时间范围
let startTime = ref(refreshParams?.KSSJ || `${oneMonthAgo.getFullYear()}-${String(oneMonthAgo.getMonth() + 1).padStart(2, '0')}-${String(oneMonthAgo.getDate()).padStart(2, '0')}`);
let endTime = ref(refreshParams?.JSSJ || todayDate);
// 数据模型
let innerGs = ref(0);
let outerGs = ref(0);
let innerSl = ref(0);
let outerSl = ref(0);
let innerJz = ref(0);
let outerJz = ref(0);
// 数据获取函数
const res = JE.syncAjax({
url: '/je/common/script/sql/select',
params: {
templateCode: 'comprehensiveStatistics',
projectCode: 'safety',
KSSJ: startTime.value,
JSSJ: endTime.value
},
headers: { pd: 'safety' }
});
if (res.data?.length > 0) {
innerGs.value = res.data[0].INNER_GS ? res.data[0].INNER_GS : 0;
outerGs.value = res.data[0].OUTER_GS ? res.data[0].OUTER_GS : 0;
innerSl.value = res.data[0].INNER_SL ? res.data[0].INNER_SL : 0;
outerSl.value = res.data[0].OUTER_SL ? res.data[0].OUTER_SL : 0;
innerJz.value = res.data[0].INNER_JZ ? res.data[0].INNER_JZ : 0;
outerJz.value = res.data[0].OUTER_JZ ? res.data[0].OUTER_JZ : 0;
}
// 统计卡片配置
const statsCards = [
{
inputValue: innerGs.value + '票/次',
inputTitle: '进仓',
outValue: outerGs.value + '票/次',
outTitle: '出仓',
icon: 'fal fa-ballot',
backgroundimage: '/micro/boards/img/process.06a4ca5e.png'
},
{
inputValue: innerSl.value + '万吨',
inputTitle: '进仓',
outValue: outerSl.value + '万吨',
outTitle: '出仓',
icon: 'fal fa-cubes',
backgroundimage: '/micro/boards/img/annual.45b842b6.png'
},
{
inputValue: innerJz.value + '万美元',
inputTitle: '进仓',
outValue: outerJz.value + '万美元',
outTitle: '出仓',
icon: 'fal fa-money-check-dollar',
backgroundimage: '/micro/boards/img/evection.d043cbf8.png'
}
];
// 格式化工具函数
const formatValue = (value) => {
const match = value.match(/(\d+\.?\d*)(.*)/);
return {
number: match?.[1] || value,
unit: match?.[2] || ''
};
};
// 卡片渲染
const cards = statsCards.map(card => {
const inputFormatted = formatValue(card.inputValue);
const outFormatted = formatValue(card.outValue);
return h('div', {
style: {
padding: '20px',
borderRadius: '10px',
flex: '1',
margin: '0 10px',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
backgroundImage: `url(${card.backgroundimage})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
position: 'relative'
}
}, [
h('div', {
style: {
position: 'relative',
zIndex: 1,
padding: '13px 20px 13px 50px',
borderRadius: '8px',
color: 'white',
display: 'flex',
flexDirection: 'column',
gap: '6px'
}
}, [
// 进仓部分
h('div', {
style: {
display: 'flex',
alignItems: 'baseline',
gap: '8px'
}
}, [
h('span', {
style: { fontSize: '32px', fontWeight: 500}
}, inputFormatted.number),
h('span', {
style: { fontSize: '14px', whiteSpace: 'nowrap'}
}, inputFormatted.unit)
]),
h('div', { style: { fontSize: '14px' } }, card.inputTitle),
// 出仓部分
h('div', {
style: {
display: 'flex',
alignItems: 'baseline',
gap: '8px'
}
}, [
h('span', {
style: { fontSize: '32px', fontWeight: 500 }
}, outFormatted.number),
h('span', {
style: { fontSize: '14px' ,whiteSpace: 'nowrap'}
}, outFormatted.unit)
]),
h('div', { style: { fontSize: '14px' } }, card.outTitle)
]),
h('i', {
style: {
fontSize: '58px',
color: 'white',
zIndex: 2,
// padding: '40px 50px 40px 20px'
},
class: card.icon
})
]);
});
const node = h('div', {
style: {
display: 'flex',
justifyContent: 'space-between',
marginTop: '20px'
}
}, cards);
const app = JE.useVue().createApp({
render() {
return node;
}
});
app.mount(container);
最后编辑: 呼丽华 文档更新时间: 2025-12-11 14:13 作者:呼丽华