UNPKG

sunmao-sdk

Version:

榫卯-开箱即用赋能-sdk

189 lines (176 loc) 5.21 kB
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;