Skip to content

4.5 门户管理

用户成功登录默认进入“门户”界面,用户也可以通过左侧功能导航栏切换功能。门户 分个人与单位两个维度展示,个人或单位下都展示了工作台和动态两个固定模块。工作台页 面展示了快捷操作、事项提醒、常用、数据核信息等。

门户管理实现的功能包括对门户界面的个性化设置,如通过驻留的方式将应用、视图、模板等固定在个人或单位下,以及对门户封面进行编辑,提升用户的个性化体验。同时,门户管理还涉及工作台的设置与使用,工作台作为用户自定义的工作主界面,包含快捷操作、事项提醒、常用模块和数据展示等功能,用户可通过快捷操作进行申请存储、设立部门等操作,事项提醒则涵盖集群未读、单位待办等信息,常用模块支持用户根据自身需求进行个性化设置,数据展示则呈现用户已加入的数据核的使用状态。

门户管理还涵盖了动态功能,用户可以查看所加入单位、部门、集群和群组发布的动态,并进行转发、点赞、评论等操作,同时支持发布个人动态和群动态,促进了平台内信息的交流与共享。沟通方面,用户可在沟通界面与好友、单位、群组、集群开展实时聊天,并在聊天过程中进行文件传输、发布动态等操作,且沟通记录会保存至存储资源中,方便用户随时查看和管理。

HomeNavTemplate组件

界面包含两个导航项,分别是“工作台”和“动态”,每个导航项包含名称、类型、背景图片URL和组件。以下代码为导航模板的关键组件HomeNavTemplate组件的定义,该组件用于用于在主页上展示多个标签页,每个标签页可以展示不同的内容

const HomeNavTemplate: React.FC = () => {
  const [headData, setHeadData] = useState<any>([]);
  const [loading, setLoading] = useState(false);
  const [activeNav, setActiveNav] = useState<any>();
  useEffect(() => {
    initPage();
    orgCtrl.home.current.cacheObj.subscribe('homeConfig', async (res) => {
      initPage(res);
    });
  }, []);

  const initPage = async (_homeConfig?: model.HomeConfig) => {
    let res: any[] = [];
    if (_homeConfig) {
      res = await orgCtrl.home.getTops(_homeConfig);
    }
    setHeadData([...getTabItems(allPages), ...res]);
    setLoading(true);
  };

  const getTabItems = (page: any = headData) => {
    return page.map((it: any) => {
      return {
        ...it,
        children:
          it.type == '5' || it.type == '6'
            ? it.component
            : React.createElement(it.component, {
                onChange: () => {
                  initPage();
                },
              }),
      };
    });
  };

  const renderApp = (entity: any) => {
    const typeName = entity.metadata?.typeName;
    let data = <></>;
    switch (typeName) {
      case '应用':
        data = <AssetModule key={entity.key} selectXApp={entity}></AssetModule>;
        break;
      case '商城模板':
        data = <MallTemplate current={entity as IMallTemplate} />;
        break;
      case '视图':
        if (entity.groupTags.includes('图表视图')) {
          data = <DashboardTemplateHomeView current={entity as any} />;
          break;
        } else if (entity instanceof TotalView) {
          data = (
            <LedgerForm
              isFull={false}
              current={entity as IView}
              form={entity.metadata as any}
              directory={entity.directory}
            />
          );
        } else {
          data = (
            <FormView
              form={entity.metadata}
              directory={entity.directory}
              isMemberView={false}
            />
          );
        }
        break;
      case '目录':
        data = <Directory root={entity} />;
        break;
    }
    return data;
  };

  const onTagClick = (item: any, index: number) => {
    const typeName = item.metadata?.typeName;
    if (typeName) {
      let data = renderApp(item);
      headData[index] = item;
      setHeadData(headData);
      setActiveNav({
        name: item.name,
        children: data,
        id: item.metadata.id,
      });
    } else {
      setActiveNav(item);
    }
  };

  return loading ? (
    <div className={cls.homeNavTemplate}>
      <Space size={8} className={cls.homeNavTag}>
        {headData.map((item: NavigationItem, index: number) => {
          const props =
            (!activeNav && index === 0) || item.name === activeNav?.name
              ? { color: '#366EF4' }
              : {};
          return (
            <Tag key={item.name} {...props} onClick={onTagClick.bind(this, item, index)}>
              {item.name}
            </Tag>
          );
        })}
      </Space>
      <div>{activeNav?.children || headData[0]?.children}</div>
    </div>
  ) : (
    <></>
  );
};

export default HomeNavTemplate;

该组件的主要功能为

(1)初始化页面数据:在组件挂载时,通过useEffect钩子调用initPage函数初始化页面数据。initPage函数从配置中获取顶部数据,并更新组件的状态。

(2)处理标签点击事件:当用户点击标签时,onTagClick函数会被调用。该函数根据点击的标签更新激活的导航项,并渲染相应的组件。

(3)渲染标签和内容:组件返回一个包含标签和内容的div。根据loading状态决定是否渲染。如果loading为true,则渲染标签和内容;否则,不渲染。

(4)渲染不同的组件:根据实体类型,renderApp函数会渲染不同的组件。例如,如果实体类型是“应用”,则渲染AssetModule组件;如果实体类型是“商城模板”,则渲染MallTemplate组件;如果实体类型是“视图”,则根据视图类型渲染DashboardTemplateHomeView、LedgerForm或FormView组件;如果实体类型是“目录”,则渲染Directory组件。

(5)处理homeConfig的变化:通过订阅homeConfig的变化,当homeConfig发生变化时,initPage函数会被调用,更新页面数据。

(6)处理导航项:getTabItems函数处理导航项,根据类型决定是否渲染组件。如果类型是5或6,则直接渲染组件;否则,使用React.createElement创建组件。

WorkBenchView组件(工作台组件)

const WorkBenchView: React.FC = () => {
  return (
    <div className="workbench-content">
      <Banner space={orgCtrl.home.current}></Banner>
      <RenderOperate />
      {!orgCtrl.home.isUser && <MatterInfo company={orgCtrl.home.current as ICompany} />}
      <ContentCard space={orgCtrl.home.current} />
      {orgCtrl.home.current.hasDataAuth() && <DataInfo space={orgCtrl.home.current} />}
      <div className="cardGroup">
        <div className={cls['flex-space']}></div>
      </div>
    </div>
  );
};

WorkBenchView组件是一个工作台视图组件,用于在主页上展示工作台的内容。以下是该组件的主要作用:

(1)展示横幅:通过<Banner space={orgCtrl.home.current}></Banner>组件,主要功能是显示一个带有默认图片的横幅(Banner)。 (2)快捷操作渲染:通过<RenderOperate />组件,展示操作渲染的内容,该组件用于渲染一组快捷操作按钮。这些按钮允许用户快速执行某些命令。

(3)展示 MatterInfo:如果当前用户不是系统用户,则通过<MatterInfo company={orgCtrl.home.current as ICompany}/>组件,展示当前公司的信息。组件的主要功能是显示不同类型的事项(如集群未读、单位待办、单位提醒和单位任务)的列表,并允许用户点击这些事项以查看详细信息。

(4)展示内容卡片:通过<ContentCard space={orgCtrl.home.current} />组件,展示当前空间的内容卡片。

(5)展示 DataInfo:如果当前空间有数据权限,则通过<DataInfo space={orgCtrl.home.current} />组件,展示当前空间的数据信息,包括存储大小、关系数量、数据集数量、对象数量和文件数量等。

(6)布局:通过<divclassName="cardGroup"><divclassName={cls['flex-space']}></div>组件,进行布局。

Activate组件(动态组件)

const ActivityIndex: React.FC = () => {
  const groupActivity = new GroupActivity(
    orgCtrl.user,
    orgCtrl.home.current.activitys,
    true,
  );
  return <GroupActivityItem activity={groupActivity} />;
};
export default ActivityIndex;

ActivityIndex组件的主要功能是展示组活动的列表。该组件的主要功能为: (1)创建组活动实例:通过new GroupActivity(orgCtrl.user, orgCtrl.home.current.activitys, true)创建一个GroupActivity实例。这个实例包含了用户信息、当前活动的数据和某个布尔值。

(2)渲染组活动列表:通过<GroupActivityItem activity={groupActivity} />将GroupActivity实例传递给GroupActivityItem组件,用于展示组活动的列表。

Board模块(展示页面)

const Board: React.FC<IProps> = ({ pages }) => {
  console.log('pages', pages);

  return (
    <div className={cls['board']}>
      <div className="cardGroup" style={{ padding: '12px', marginLeft: '8px' }}>
        <div className={cls['select-space']} style={{}}>
          <div className={cls['selectspan']}>
            <EntityIcon entityId={pages?.metadata.belongId} size={30} />
            <div style={{ fontSize: 20, color: '#15181D' }}>{pages?.metadata.name}</div>
          </div>
          <div>
            <Tag color="processing">{pages?.directory.belong.name}</Tag>
          </div>
          <div style={{ cursor: 'default', color: 'rgba(54, 110, 244, 1)' }}>
            数据切换
          </div>
          <RightOutlined />
        </div>
      </div>
      <Row gutter={16}>
        <Col span={24}>
          <Card className={cls['board-info']}>
            <div className={cls['board-title']}>资产价值统计</div>
            <Row gutter={16} className={cls['board-content']}>
              <Col
                className="gutter-row"
                span={8}
                style={{
                  display: 'flex',
                  justifyContent: 'space-between',
                }}>
                <div className={cls['board-item']}>
                  <span className={cls['board-item-remark']}>净值</span>
                  <div>
                    <span className={cls['board-price']}>54,759.0</span>
                    <span>万</span>
                  </div>
                </div>
                <Divider type="vertical" />
              </Col>
              <Col
                className="gutter-row"
                span={8}
                style={{
                  display: 'flex',
                  justifyContent: 'space-between',
                }}>
                <div className={cls['board-item']}>
                  <span className={cls['board-item-remark']}>原值</span>
                  <div>
                    <span className={cls['board-price']}>128,239.1</span>
                    <span>万</span>
                  </div>
                </div>
                <Divider type="vertical" />
              </Col>
              <Col className="gutter-row" span={8}>
                <div className={cls['board-item']}>
                  <span className={cls['board-item-remark']}>数量</span>
                  <div>
                    <span className={cls['board-price']}>82,454</span>
                    <span></span>
                  </div>
                </div>
              </Col>
            </Row>
          </Card>
        </Col>
      </Row>
      <Row gutter={16}>
        <Col className="gutter-row" span={8}>
          <Card>
            <Ring />
          </Card>
        </Col>
        <Col className="gutter-row" span={16}>
          <Card>
            <Bar />
          </Card>
        </Col>
      </Row>
      <Row gutter={16} className={cls['card-height-30']}>
        <Col className="gutter-row" span={8}>
          <Card>
            <Pie />
          </Card>
        </Col>
        <Col className="gutter-row" span={16}>
          <Card>
            <Line />
          </Card>
        </Col>
      </Row>
    </div>
  );
};

该组件Board主要用于展示页面模板(pages)的信息,包括页面的元数据、资产价值统计、以及一些图表(饼图、折线图、柱状图和环形图)。具体功能如下:

(1)页面元数据展示: 使用EntityIcon组件显示页面模板的图标。显示页面模板的名称和所属目录。

(2)资产价值统计: 展示页面的净值、原值和数量,使用StatisticCard组件进行展示。

(3)图表展示: 使用Pie、Line、Bar、Ring组件分别展示饼图、折线图、柱状图和环形图。

(4)样式管理: 使用CSS模块cls进行样式管理,确保组件的样式不会影响到其他组件。

(5)响应式布局: 使用Row和Col组件进行响应式布局,确保组件在不同屏幕尺寸下都能正常显示。

(6)数据切换: 提供一个“数据切换”按钮,用于切换数据源。

云原生应用研究院版权所有