阿里低代码插件扩展(多页面管理插件)

在阿里低代码DEMO上扩展多页面管理插件

效果如下: 能够进行页面的添加、编辑和删除
在这里插入图片描述

页面结构是根据当前选择的系统查询并处理的,使用了消息订阅与发布pubsub 来监听系统的改变。
系统管理请看这一篇: https://blog.csdn.net/qq_45868390/article/details/125539342

(1)新建一个react文件

import React, { Component } from 'react'
import { Nav, Button, Dialog, Message } from '@alifd/next';
const { Item, SubNav } = Nav;

import { nanoid } from "nanoid";

import {
  project,
  config,
} from '@alilc/lowcode-engine';
// 网络请求
import { getPage, addPage, updatePage, delPage } from 'src/network/data'

import PMForm from './child-components/PM-form';

import { delPropInObject, getEmptySchema, getPackages } from 'src/universal/utils'
import _, { find } from 'lodash';

import PubSub from 'pubsub-js'

import './index.scss'

export default class PageManage extends Component {

  token = null
  token1 = null
  state = {
    isNoSystem: false, // 是否没有选择系统
    isDisabledAddBtn: false, // 是否禁用添加按钮
    isDisabledDelBtn: true,
    currentPageId: undefined, // 当前选中的page的id
    currentPagePId: 0, // 当前选中的page的pid,默认为根节点 0
    page: [], // 页面列表(处理过层级结构后后)
    originPage: [], // 页面列表,未处理层级结构
    currentSchema: null, // 当前刚打开的schema

    isShowDialog: false, // 是否显示添加页面弹框
    footerActions: [], // 消除页面自带默认按钮
    formData: {}, // 当前的页面数据
    isAdd: undefined, // 是否为新增页面
  }
  componentDidMount() {
    console.log(process.env.NODE_ENV, 'NODE_ENV');

    console.log(process.env, 'NODE_ENV');
    // 判断当前是否已经全局选择了系统
    // 若选择,直接拿页面数据,
    // 若不做该处的处理,在关闭插件面板,或者固定左侧面板时,状态会刷新,页面会丢失
    this.judgeIsChooseSystem()

    // 订阅系统变化消息
    this.token = PubSub.subscribe('currentSystem', (_: any, data: any) => {
      console.log("当前的系统是", data);
      console.log(process.env.NODE_ENV, 'NODE_ENV', process.env.REACT_APP_ENV);
      this.setState({
        isNoSystem: false,
        currentPageId: undefined,
        currentPagePId: 0,
        currentSchema: null
      })

      // 查询接口
      // 拿到该系统对应的page数据处理后赋值给state
      this.getPageAndSchemaData()


    })
    // 订阅页面修改消息
    this.token1 = PubSub.subscribe('updatePage', (_: any) => {
      this.getPageAndSchemaData()
      // 注意要重新设置当前的schema,否则切换时仍然会弹出修改提示
      this.setState({
        currentSchema: project.exportSchema().componentsTree[0],
      })
    })

    // 默认第一次加载选择第一个页面
    setTimeout(()=>{
      //  this.clickFirstNodeAfterFirstLoadedOrDel()
    },200)
   
  }
  componentWillUnmount() {
    PubSub.unsubscribe(this.token)
    PubSub.unsubscribe(this.token1)

  }
  // 判断是否选择了系统
  judgeIsChooseSystem = () => {
    let currentSystem = config.get('currentSystem')
    if (currentSystem !== undefined) {
      this.setState({
        isNoSystem: false
      })
      this.getPageAndSchemaData()
    } else {
      this.setState({
        isNoSystem: true
      })
    }
    console.log(currentSystem, 'config');
  }
  // 查询系统对应的页面
  getPageAndSchemaData = () => {
    // 网络请求
    let params = {
      page: 1,
      pageNum: 10,
      param: {
        system_id: config.get('currentSystem').systemId
      }

    }
    getPage(params).then(res => {
      res.data.list.reverse()
      // console.log("查询的页面", res.data.list.reverse());
      this.setState({
        originPage: JSON.parse(JSON.stringify(res.data.list))
      })
      this.dealData(JSON.parse(JSON.stringify(res.data.list)))
    }).catch(err => {

    })

  }
  // 处理数据
  dealData = (data: Array<object>) => {
    console.log("传入的", data);
    // let newData: Array<object> = []
    data.forEach((item: any) => {
      let children: Array<object> = []
      item.key = item.row_id
      data.forEach((c: any) => {
        if (item.row_id == c.parent_id) {
          children.push(c)
          // 把找到的添加给children,同时要删除该项
          let index = data.findIndex((d: any) => {
            return c.row_id === d.row_id
          })

          data.splice(index, 1)
        }
      })
      if (children.length > 0) {
        item['children'] = children
      }

      // newData.push(item)
    })
    console.log("处理过后的页面结构", data);
    if (data.length == 0) this.setState({ isDisabledDelBtn: true })
    this.setState({
      page: data
    })
  }
  // 切换页面
  handleSelect = async (selectedKeys: any, item: any) => {
    // const packages = await getPackages()
    // console.log(packages, '..');

    // let currentSchema = delPropInObject(project.exportSchema().componentsTree[0],'docId') 
    // 判断页面是否修改
    this.pageSchemaChangeWillTip(item).then(res => {
      // 改变
      // console.log('res', res);
      // 调用接口修改
      this.handleUpdatePage().then(res => {
        Message.success('保存成功!')
        console.log(res, '修改成功!');
        this.switchPageSchema(item)
        this.getPageAndSchemaData()
        this.setState({
          currentPageId: item.props.row_id,
          currentPagePId: item.props.parent_id == 0 ? item.props.row_id : item.props.parent_id,
          isDisabledDelBtn: false, // 解禁删除按钮
        })
        // config.set('currentPageId',item.props.row_id)
      }).catch(err => {
        Message.error('修改失败!')

      })


    }).catch(err => {
      this.switchPageSchema(item)
      // 没改变
      this.setState({
        currentPageId: item.props.row_id,
        currentPagePId: item.props.parent_id == 0 ? item.props.row_id : item.props.parent_id,
        isDisabledDelBtn: false, // 解禁删除按钮
      })
    })

    // 设置当前页面的id
    config.set('currentPageId', item.props.row_id)

    // 处理
  };
  // 切换不同的页面schema
  switchPageSchema = (page: any) => {

    project.removeDocument(project.currentDocument as any)

    let info = this.state.originPage.find((item: any) => {
      return item.row_id === page.props.row_id
    }) as any
    // console.log(info,'查到的');

    project.openDocument(JSON.parse(info.schema_info).schema)
    // 保存当前打开的schema
    // 需要使用低代码的api进行导出,在加载schema时,会给组件加上docId等属性
    // 若不使用api,会导致判断是否修改出问题,一直是已修改状态
    this.setState({
      currentSchema: project.exportSchema().componentsTree[0],
      formData: {
        name: page.props.name,
        parent_id: page.props.parent_id,
        icon: page.props.icon_
      }
    })
  }
  // 对比页面内容是否改变并提示是否保存
  pageSchemaChangeWillTip = (item: any) => {
    let currentSchema = project.exportSchema().componentsTree[0]
    console.log("当前的schema", currentSchema);
    console.log("原来的schema", this.state.currentSchema);
    // 使用lodash工具类
    // let isSame = _.isEqual(currentSchema, this.state.currentSchema)
    let isSame = JSON.stringify(currentSchema) == JSON.stringify(this.state.currentSchema)
    console.log('是否一样', isSame);


    return new Promise((resolve, reject) => {
      // 切换页面前判断是否已经选择了某个页面
      // 若选了,且改变内容了,切换给提示
      // 若没有选择任何的页面,则直接打开schema
      if (this.state.currentPageId !== undefined && !isSame) {
        Dialog.confirm({
          v2: true,
          title: "温馨提示",
          className: 'is-save-schame',
          content: '内容已修改,是否要保存该页面?',
          onOk: () => {
            // 调用保存接口

            // 删除当前的文档
            // 再根据schema加载新的文档
            resolve(true)
            // this.switchPageSchema(item)
          },
          onCancel: () => {
            // this.switchPageSchema(item)
            console.log('不保存!');
            reject(false)

          },
          onClose: () => {
            // this.switchPageSchema(item)
            reject(false)
            console.log('不保存!');
          }
        })
      } else {
        reject(false)
        // this.switchPageSchema(item)
      }
    })

  }
  // 显示添加页面
  handleShowAddPage = async () => {
    // let news = await getEmptySchema()
    // console.log('新的schema', news);
    this.setState({
      isShowDialog: true,
      isAdd: true
    })

  }
  // 添加新页面
  handleAddPage = async (data: object) => {
    const { componentsMap, componentsTree } = await getEmptySchema()
    let params = {
      ...data,
      system_id: config.get('currentSystem').systemId,
      schema_info: JSON.stringify({
        componentsMap: componentsMap,
        schema: componentsTree[0]
      })
    }

    addPage(params).then(res => {
      console.log(res, '添加成功!');
      this.getPageAndSchemaData()
      // 强制渲染组件
      // this.forceUpdate();
      Message.success("添加成功!");
      this.setState({ isShowDialog: false })
    }).catch(err => {
      Message.error(err);
    })
  }
  // 显示修改页面
  handleModifyPage = () => {
    this.setState({
      isShowDialog: true,
      isAdd: false
    })
  }
  // 删除页面
  handleDelPage = () => {
    Dialog.confirm({
      v2: true,
      title: "温馨提示",
      className: 'del-page',
      content: '确定要删除该页面?',
      onOk: () => {
        // 调用保存接口

        // 删除当前的文档
        // 再根据schema加载新的文档
        let params = {
          row_id: this.state.currentPageId
        }
        delPage(params).then(res => {
          Message.success("删除成功!");
          this.getPageAndSchemaData()
          // 强制渲染组件
          // this.forceUpdate();
          this.setState({
            currentPageId: undefined,
            currentPagePId: 0,
            isDisabledDelBtn: true, // 禁用删除按钮
          })
          this.clickFirstNodeAfterFirstLoadedOrDel()
        }).catch(err => {
          Message.error(err);
        })
      },
      onCancel: () => {
        console.log('不保存!');

      },
      onClose: () => {
        console.log('不保存!');
      }
    })

  }
  // 封装修改页面内容 返回promise
  handleUpdatePage = (data: object = {}) => {
    const { componentsMap, componentsTree } = project.exportSchema()
    let schema = {
      componentsMap: componentsMap,
      schema: componentsTree[0]
    }
    let params = {
      data: {
        ...data,
        schema_info: JSON.stringify(schema)
      },
      row_id: this.state.currentPageId
    }
    return updatePage(params)
  }
  // 修改页面
  handleUpdatePageInfo = (data: object) => {

    this.handleUpdatePage(data).then(res => {
      console.log(res, '修改成功!');
      this.getPageAndSchemaData()
      // 强制渲染组件
      // this.forceUpdate();
      Message.success("修改成功!");
      this.setState({ isShowDialog: false })
    }).catch(err => {
      Message.error(err);
    })
  }
  // 关闭弹框
  onClose = (e: any) => {
    console.log(e);
    this.setState({ isShowDialog: false })
  };
  // 刪除节点后默认选中第一个
  clickFirstNodeAfterFirstLoadedOrDel = () => {
    let elementNode = document.getElementsByClassName('next-nav-item')
    console.log(elementNode, '节点');

    elementNode[0].click()

  }
  render() {
    const { page, formData, isAdd, currentPagePId, isDisabledAddBtn, isDisabledDelBtn, isNoSystem, footerActions, isShowDialog } = this.state
    // const pageCopy = JSON.parse(JSON.stringify(page))
    return (
      <div className="page-manage">
        {
          isNoSystem ? (
            <div className="no-system">
              <p >请先选择系统!</p>
            </div>
          ) : null
        }

        <div className="operation-page" style={{ display: isNoSystem ? 'none' : 'flex' }}>
          <Button className='btn' type="secondary" onClick={this.handleShowAddPage} disabled={isDisabledAddBtn}>添加页面</Button>
          <Button className='btn' type="secondary" onClick={this.handleModifyPage} disabled={isDisabledDelBtn}>编辑页面</Button>
          <Button className='btn' type="secondary" onClick={this.handleDelPage} disabled={isDisabledDelBtn}>删除页面</Button>
        </div>
        <Nav type='line' mode='inline' onSelect={this.handleSelect} defaultOpenAll>
          {/* <SubNav label={page.name}> */}
          {
            page.map((page: any) => {
              if (page.children && page.children.length !== 0) {
                return (
                  <SubNav icon={page.icon} label={page.name} key={page.key}>
                    {
                      page.children.map((c: any) =>
                        // Item本身就有 icon属性,需要再声明一个自定义的
                        // 才能在之后拿到该属性
                        <Item
                          icon={c.icon}
                          icon_={c.icon}
                          row_id={c.row_id}
                          parent_id={c.parent_id}
                          name={c.name}
                          key={c.key}
                        >
                          {c.name}
                        </Item>)
                    }

                  </SubNav>
                )

              } else {
                return (
                  <Item
                    icon={page.icon}
                    icon_={page.icon}
                    row_id={page.row_id}
                    parent_id={page.parent_id}
                    name={page.name}
                    key={page.key}
                  >
                    {page.name}
                  </Item>
                )
              }

            })
          }
          {/* </SubNav> */}



        </Nav>

        {/* 添加页面弹框 */}
        <Dialog
          className='page-manage-dialog'
          v2
          title={this.state.isAdd ? "添加页面" : "编辑页面"}
          visible={isShowDialog}
          onClose={this.onClose}
          footerActions={footerActions}
        >
          <div className="page-content">
            <PMForm
              pageData={page}
              pId={currentPagePId}
              handleAddPage={this.handleAddPage}
              handleUpdatePageInfo={this.handleUpdatePageInfo}
              onCancel={this.onClose}
              formData={formData}
              isAdd={isAdd}
            />
          </div>
        </Dialog>
      </div>
    )
  }
}


(2)在plugin.tsx文件进行插件的注册。值得注意的是配置项中有个index,内置插件默认都是0,-1就可以排序在最上面,具体看个人需求。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
你好!关于阿里代码件不生效的问题,我可以给你一些建议来解决。 首先,确保你已经正确安装了阿里代码件,并且在你的开发环境中启用了它。你可以在编辑器的管理扩展商店中查找并安装阿里代码件。 如果件已正确安装并启用,但仍然不生效,你可以尝试以下方法: 1. 检查件配置:确认件的配置是否正确,例如是否启用了规范化检查、代码格式化等功能。有些件可能需要手动配置才能生效。 2. 检查文件类型:确保件适用于你正在编辑的文件类型。有些件只支持特定的文件类型,如果你在一个不受支持的文件中使用件,它可能不会生效。 3. 检查件版本:确保你使用的是最新版本的件。有时旧版本的件可能存在问题或不兼容最新的开发环境。 4. 重启编辑器:有时候件需要在编辑器重新启动后才能生效。尝试关闭编辑器并重新打开,然后再次检查件是否工作。 5. 查看件文档或支持资源:搜索阿里代码件的官方文档或支持资源,看看是否有相关的故障排除指南或常见问题解答。这些资源可能提供了解决你问题的更具体的方法。 如果以上方法仍然无法解决问题,你可以尝试卸载并重新安装件,或者考虑使用其他类似的代码规范件。另外,你也可以在开发社区或论坛上寻求帮助,向其他开发者咨询他们是否遇到过类似的问题,并了解他们是如何解决的。 希望以上建议能对你有所帮助!如果你还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值