sunmao-sdk
Version:
榫卯-开箱即用赋能-sdk
189 lines (176 loc) • 5.21 kB
JSX
import React, { useRef, useState, useEffect } from "react";
import { Spin } from "antd";
import { isArray, isString } from "lodash";
import CpBase from "./CpBase";
import { handleAppParams, postNew } from "./../net/request";
import * as commonUtils from "./../utils/commonUtils";
import { CP } from "..";
import "./index.css";
const displayName = "CpComposite";
const CpComposite = props => {
const {
schema,
defaultSchemaMap,
initData,
refreshSchema,
name,
title,
api = {},
filterParams,
widgets,
...otherProps
} = props;
const { url, okPath = "data", table } = schema;
const requestFunc = CP.getCPInfo().requestFunc || postNew;
const [loading, setLoading] = useState(false);
// 首次渲染不因 initData 请求
const hasPageSchema = useRef(false);
// 用于上下文传递, 作为子页面的initData
const [pageData, setPageData] = useState(null);
// 页面级接口请求入参 事件回调需要useRef
const searchParams = useRef({});
// 赋值页面上下文数据 initData变更需刷新页面
useEffect(() => {
// 此处有待调优
if (hasPageSchema.current) {
onSdkSearch(initData);
} else {
// 页面首次渲染
onSdkSearch(initData);
}
}, [initData]);
/**
* 必备函数
* 表格请求函数
* 暂支持post请求,因get用长度限制,避免过多参数
* @param params 搜索项信息
*/
const onSdkSearch = params => {
const _params = {
...searchParams.current, // 已有页面信息
...params // 新入参信息,常见为:覆盖已有页面信息
};
// 是否有 请求配置
if (url) {
setLoading(true);
requestFunc(
commonUtils.getUrl(url),
handleAppParams(_params, filterParams),
okPath
)
.then(({ data, exactData, ...other }) => {
if (!data) {
throw new Error(
"请求错误,自行处理,该请求可自行设计,只要返回正确数据格式即可!"
);
} else {
// 将页面数据作为 子页面的initData
let resData = exactData || data;
// 当返回数据是数组时, 嵌套一层
const extInitData =
isArray(resData) || isString(resData)
? { data: resData }
: resData;
// 将页面数据作为 子页面的initData
setSearchParams({ ..._params, ...extInitData });
}
})
.catch(err => {
console.error("err", err, displayName);
})
.finally(() => {
setLoading(false);
});
} else {
// 无请求配置, 直接设置页面级上下文数据
setSearchParams(_params);
}
};
/**
* 设置页面级上下文数据
* @param {页面级入参} params
*/
const setSearchParams = params => {
// 同步事件params
searchParams.current = params;
// 刷新所有子页面
setPageData(params);
};
/**
* 获取自组件的分子、分母
* @param {分数字符串} fraction
* @returns 默认 [1,1]即100%宽度
*/
const getFraction = fraction => {
try {
return fraction.split("-").map(s => parseInt(s));
} catch {
return [1, 1];
}
};
/**
* 通过分子分母计算出宽度
* @param {分子} fenZi
* @param {分母} fenMu
* @returns 返回组件宽度
*/
const getWidth = (fenZi, fenMu) => {
return `calc(100%*${fenZi / fenMu} - ${fenMu - fenZi}*20px/${fenMu})`;
};
const childRender = renderInfo => {
const {
pageType,
name,
title,
key,
sdkRender,
fraction,
height
} = renderInfo;
// 模块name 支持 不展示模块标题
const pageTitle = title === "null-Title" ? "" : title || name;
// 用于计算宽度。 默认100% 1/1
const [fenZi, fenMu] = getFraction(fraction);
// 通过分子分母计算出宽度
const width = getWidth(fenZi, fenMu);
// 获取自定义渲染函数
const renderFunc = commonUtils.getFunc(sdkRender, api);
return (
<div
style={{
width, // 通过fraction占比设置
height: height || "auto", // 输入框设置,设置出错不兼容
overflow: "scroll"
}}
>
{pageType === "sunmao_composite" || pageType === "sunmao_tabs" ? (
<div>暂不支持嵌套复杂详情页,请重新配置该部分实现</div>
) : renderFunc ? (
renderFunc(renderInfo, pageData)
) : (
<CpBase
flag={key}
initData={pageData}
api={api}
widgets={widgets}
defaultSchemaMap={defaultSchemaMap}
title={pageTitle}
filterParams={filterParams}
tableProps={{ title: pageTitle }}
{...otherProps}
/>
)}
</div>
);
};
return !!pageData ? (
<Spin spinning={loading}>
<div className="sunmao_composite">
{table.columnItems.map(childRender)}
</div>
</Spin>
) : (
<div>页面构建中...</div>
);
};
export default CpComposite;