带你一步步实现低代码开发平台——基于配置信息生成库表和代码

背景

通过前面的步骤,我们完成了实体的配置,主要包括实体、实体模型、视图,接下来的工作主要是三项,一是生成数据库表,二是生成前后端源码,三是配置权限项(菜单及按钮),完成这几步工作后,配置的功能就能运转起来了,下面继续以接口平台模块中的应用这个实体为例来具体说说。

生成库表

不少低代码平台,都是先通过数据库模型开发工具,如PowerDesigner,设计数据库表,然后生成库表,平台再连接数据库,进行逆向工程,生成源码。这种方式,还是需要开发人员去了解库表设计工具的使用,以及数据库相应的知识,如不同种类的数据库,字符串、整形、日期各有不同。这种模式本质上还是传统意义上的数据驱动。
我设计的这套低代码平台,是先设计模型,然后由平台根据模型配置来自动创建库表,开发人员只需要在平台内做配置就可以了。这种模式相当于模型驱动,开发人员不再需要关注数据库的类型和细节了,平台已经接管了。

通过菜单进入实体管理列表,勾选要生成库表的一个或多个实体,然后点击“生成库表”按钮,系统会根据模型配置信息,自动生成数据库表创建语句,并连接数据库创建。

image.png

image.png

生成代码

同生成库表操作类似,通过菜单进入实体管理列表,勾选要生成库表的一个或多个实体,然后点击“生成代码”按钮,系统会根据实体配置信息,自动生成源码,包括后端的实体类、DAO层的Mapper接口及xml配置文件、服务层(接口及实现类)、控制器层、视图对象类,以及前端的视图(列表、新增、修改、查看、参照以及可能的树、树表等,取决于视图配置环节的设置)。
image.png

前端:将view目录下的vue视图文件,拷贝到前端src\modules\cip\view目录下
后端:其他目录下文件,拷贝到后端manage项目下

实体类

package tech.abc.platform.cip.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import tech.abc.platform.common.base.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;

/**
 * 应用 实体类
 *
 * @author wqliu
 * @date 2023-05-02
 *
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("cip_app")
public class App extends BaseEntity {
    
    

    /**
     * 名称
     */
    @TableField("name")
    private String name;

    /**
     * 编码
     */
    @TableField("code")
    private String code;

    /**
     * 密钥
     */
    @TableField("secret_key")
    private String secretKey;

    /**
     * 对接模式
     */
    @TableField("integration_model")
    private String integrationModel;

    /**
     * 状态
     */
    @TableField("status")
    private String status;

    /**
     * 排序
     */
    @TableField("order_no")
    private String orderNo;

}

Mapper接口

package tech.abc.platform.cip.mapper;

import tech.abc.platform.cip.entity.App;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;


/**
 * 应用 Mapper 接口
 *
 * @author wqliu
 * @date 2023-05-02
 */
public interface AppMapper extends BaseMapper<App> {
    
    

}


Mapper XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.abc.platform.cip.mapper.AppMapper">

</mapper>

服务接口类

package tech.abc.platform.cip.service;

import tech.abc.platform.cip.entity.App;
import tech.abc.platform.common.base.BaseService;
import java.util.List;
import java.util.Map;

/**
 * 应用 服务接口类
 *
 * @author wqliu
 * @date 2023-05-27
 */
public interface AppService extends BaseService<App> {
    
    

   /**
   * 获取标识与名称的Map集合
   *
   * @param idList 标识列表
   * @return 集合
   */
   Map<String,String> getNameMap(List<String> idList);
}


服务实现类

package tech.abc.platform.cip.service.impl;

import tech.abc.platform.cip.entity.App;
import tech.abc.platform.cip.mapper.AppMapper;
import tech.abc.platform.cip.service.AppService;
import tech.abc.platform.common.base.BaseServiceImpl;
import org.springframework.stereotype.Service;
import tech.abc.platform.common.exception.CommonException;
import tech.abc.platform.common.exception.CustomException;
import java.math.BigDecimal;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
/**
* 应用 服务实现类
*
* @author wqliu
* @date 2023-05-27
*/
@Service
@Slf4j
public class AppServiceImpl extends BaseServiceImpl<AppMapper, App> implements AppService {
    
    
    @Override
    public App init() {
    
    
        App entity=new App();
        //默认值处理
        entity.setIntegrationModel("CLIENT");
        entity.setStatus("NORMAL");
        return entity;
    }

    @Override
    public void beforeAdd(App entity) {
    
    
        //唯一性验证
        //验证 名称 全局唯一
        if (StringUtils.isNotBlank(entity.getName())) {
    
    
            long countName = this.lambdaQuery().eq(App::getName, entity.getName()).count();
            if (countName > 0) {
    
    
                throw new CustomException(CommonException.PROPERTY_EXIST,"【名称】");
            }
        }
        //验证 编码 全局唯一
        if (StringUtils.isNotBlank(entity.getCode())) {
    
    
            long countCode = this.lambdaQuery().eq(App::getCode, entity.getCode()).count();
            if (countCode > 0) {
    
    
                throw new CustomException(CommonException.PROPERTY_EXIST,"【编码】");
            }
        }
    }

    @Override
    public void beforeModify(App entity) {
    
    
        //唯一性验证
        //验证 名称 全局唯一
        if (StringUtils.isNotBlank(entity.getName())) {
    
    
            long countName = this.lambdaQuery().eq(App::getName, entity.getName())
                .ne(App::getId, entity.getId()).count();
            if (countName > 0) {
    
    
                throw new CustomException(CommonException.PROPERTY_EXIST,"【名称】");
            }
        }
        //验证 编码 全局唯一
        if (StringUtils.isNotBlank(entity.getCode())) {
    
    
            long countCode = this.lambdaQuery().eq(App::getCode, entity.getCode())
                .ne(App::getId, entity.getId()).count();
            if (countCode > 0) {
    
    
                throw new CustomException(CommonException.PROPERTY_EXIST,"【编码】");
            }
        }
    }

    @Override
    public Map<String, String> getNameMap(List<String> idList) {
    
    
        Map<String, String> result = new HashMap<>(5);
        if (CollectionUtils.isNotEmpty(idList)) {
    
    
            List<App> list = this.lambdaQuery().in(App::getId, idList).list();
            if (CollectionUtils.isNotEmpty(list)) {
    
    
                list.stream().forEach(x -> {
    
    
                    result.put(x.getId(), x.getName());
                });
            }
        }
        return result;
    }

    @Override
    protected void copyPropertyHandle(App entity, String... value) {
    
    
        // 主属性后附加“副本”用于区分
        entity.setName (entity.getName() + " 副本");
    }

}


控制器类

package tech.abc.platform.cip.controller;


import org.springframework.web.bind.annotation.RestController;
import tech.abc.platform.common.base.BaseController;
import org.springframework.web.bind.annotation.RequestMapping;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import tech.abc.platform.common.annotation.SystemLog;
import tech.abc.platform.common.query.QueryGenerator;
import tech.abc.platform.common.utils.ResultUtil;
import tech.abc.platform.common.vo.PageInfo;
import tech.abc.platform.common.vo.Result;
import tech.abc.platform.common.vo.SortInfo;
import tech.abc.platform.cip.entity.App;
import tech.abc.platform.cip.service.AppService;
import tech.abc.platform.cip.vo.AppVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* 应用 前端控制器类
*
* @author wqliu
* @date 2023-05-27
*/
@RestController
@RequestMapping("/cip/app")
@Slf4j
public class AppController extends BaseController {
    
    
    @Autowired
    private AppService appService;

    //region 基本操作
    /**
    * 初始化
    */
    @GetMapping("/init")
    public ResponseEntity<Result> init() {
    
    
        App entity=appService.init();
        AppVO vo = convert2VO(entity);
        return ResultUtil.success(vo);
    }

    /**
    * 新增
    */
    @PostMapping("/")
    @SystemLog(value = "应用-新增")
    @PreAuthorize("hasPermission(null,'cip:app:add')")
    public ResponseEntity<Result> add(@Validated @RequestBody AppVO vo) {
    
    
        App entity=convert2Entity(vo);
        appService.add(entity);
        AppVO newVO = convert2VO(entity);
        return ResultUtil.success(newVO);
    }

    /**
    * 修改
    */
    @PutMapping("/")
    @SystemLog(value = "应用-修改")
    @PreAuthorize("hasPermission(null,'cip:app:modify')")
    public ResponseEntity<Result> modify(@Validated @RequestBody AppVO vo) {
    
    
        App entity=convert2Entity(vo);
        appService.modify(entity);
        AppVO newVO = convert2VO(entity);
        return ResultUtil.success(newVO);
    }

    /**
    * 删除数据,单条数据标识,或多条数据标识用逗号间隔拼成的字符串
    */
    @DeleteMapping("/{id}")
    @SystemLog(value = "应用-删除")
    @PreAuthorize("hasPermission(null,'cip:app:remove')")
    public ResponseEntity<Result> remove(@PathVariable("id") String id) {
    
    
        appService.remove(id);
        return ResultUtil.success();
    }

    /**
    * 分页
    */
    @GetMapping("/page")
    @SystemLog(value = "应用-分页")
    @PreAuthorize("hasPermission(null,'cip:app:query')")
    public ResponseEntity<Result> page(AppVO queryVO, PageInfo pageInfo, SortInfo sortInfo) {
    
    
        //构造分页对象
        IPage<App> page = new Page<App>(pageInfo.getPageNum(), pageInfo.getPageSize());


        //构造查询条件
        QueryWrapper<App> queryWrapper = QueryGenerator.generateQueryWrapper(App.class,queryVO,sortInfo);

        //查询数据
        appService.page(page, queryWrapper);
        //转换vo
        IPage<AppVO> pageVO = mapperFacade.map(page, IPage.class);
        List<AppVO>  appVOList=convert2VO(page.getRecords());
        pageVO.setRecords(appVOList);
        return ResultUtil.success(pageVO);
    }


    /**
    * 列表
    */
    @GetMapping("/list")
    @SystemLog(value = "应用-列表")
    @PreAuthorize("hasPermission(null,'cip:app:query')")
    public ResponseEntity<Result> list(AppVO queryVO, SortInfo sortInfo) {
    
    
        //构造查询条件
        QueryWrapper<App> queryWrapper = QueryGenerator.generateQueryWrapper(App.class, queryVO,sortInfo);
        List<App> list= appService.list(queryWrapper);
        //转换vo
        List<AppVO>  appVOList=convert2VO(list);
        return ResultUtil.success(appVOList);
    }

    /**
    * 获取单条数据
    */
    @GetMapping("/{id}")
    @SystemLog(value = "应用-详情")
    @PreAuthorize("hasPermission(null,'cip:app:view')")
    public ResponseEntity<Result> get(@PathVariable("id") String id) {
    
    
        App entity = appService.query(id);
        AppVO vo = convert2VO(entity);
        return ResultUtil.success(vo);
    }

    /**
    * 复制新增数据,单条数据标识,或多条数据标识用逗号间隔拼成的字符串
    */
    @PostMapping("/{id}")
    @SystemLog(value = "应用-复制新增")
    @PreAuthorize("hasPermission(null,'cip:app:addByCopy')")
    public ResponseEntity<Result> addByCopy(@PathVariable("id") String id) {
    
    
        appService.addByCopy(id);
        return ResultUtil.success();
    }



    //endregion

    //region 扩展操作

    //endregion

    //region 辅助操作

    /**
    * 将单条实体转换为视图对象
    *
    * @param entity 实体
    * @return {@link EntityVO} 视图对象
    */
    private AppVO convert2VO(App entity){
    
    
        AppVO vo=mapperFacade.map(entity,AppVO.class);
        vo.setIntegrationModelName(dictionaryUtil.getNameByCode("IntegrationModel", entity.getIntegrationModel()));
        vo.setStatusName(dictionaryUtil.getNameByCode("Status", entity.getStatus()));
        return vo;
    }

    /**
    * 将实体列表转换为视图对象列表
    *
    * @param entityList 实体列表
    * @return {@link List}<{@link EntityVO}> 视图对象列表
    */
    private List<AppVO> convert2VO(List<App> entityList) {
    
    
        List<AppVO> voList = new ArrayList<>(entityList.size());

        entityList.stream().forEach(x -> {
    
    
            AppVO vo = convert2VO(x);
            voList.add(vo);
        });
        return voList;
    }


    private App convert2Entity(AppVO vo){
    
    
        App entity=mapperFacade.map(vo,App.class);
        return entity;
    }

    //endregion
 }

视图对象类

package tech.abc.platform.cip.vo;


import tech.abc.platform.common.base.BaseVO;
import java.time.LocalDateTime;
import javax.validation.constraints.NotBlank;
import java.math.BigDecimal;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

/**
* 应用 视图对象类
*
* @author wqliu
* @date 2023-05-02
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class AppVO extends BaseVO {
    
    
    /**
    * 名称
    */
    @NotBlank(message = "【名称】不能为空")
    private String name;

    /**
    * 编码
    */
    @NotBlank(message = "【编码】不能为空")
    private String code;

    /**
    * 密钥
    */
    @NotBlank(message = "【密钥】不能为空")
    private String secretKey;

    /**
    * 对接模式
    */
    @NotBlank(message = "【对接模式】不能为空")
    private String integrationModel;

    /**
    * 状态
    */
    @NotBlank(message = "【状态】不能为空")
    private String status;

    /**
    * 排序
    */
    private String orderNo;


    /********字典类*****/
    /**
    * 对接模式
    */
    private String integrationModelName;
    /**
    * 状态
    */
    private String statusName;

    /********实体类*****/

    /********范围查询*****/

    /********自定义扩展*****/

    /********子对象*****/




}

列表视图

<template>
  <ContentWrap>
    <CollapseTab>
      <el-form :inline="true" :model="queryCondition" label-width="120px" @keyup.enter="query">
        <!--查询条件区 -->
        <el-form-item label="名称">
          <QueryText v-model="queryCondition.name" type="LK" />
        </el-form-item>
        <el-form-item label="编码">
          <QueryText v-model="queryCondition.code" type="LK" />
        </el-form-item>
        <el-form-item label="状态">
          <dictionary-select v-model="queryCondition.status" code="Status" multiple />
        </el-form-item>
        <el-form-item style="float: right">
          <QueryButton :page-code="pageCode" />
        </el-form-item>
        <div class="clearfix"></div>
      </el-form>
    </CollapseTab>
    <div class="mb-10px mt-10px">
      <el-button type="primary" icon="refresh" @click="refresh">刷新</el-button>
      <el-button v-permission="pageCode + 'add'" type="primary" icon="plus" @click="add"
        >新增</el-button
      >
      <el-button
        v-permission="pageCode + 'remove'"
        type="primary"
        icon="delete"
        @click="batchRemove"
        >删除</el-button
      >
      <el-button
        v-permission="pageCode + 'addByCopy'"
        type="primary"
        icon="CopyDocument"
        @click="addByCopy"
        >复制新增</el-button
      >
    </div>

    <el-card style="width: 100%">
      <div style="float: right; margin-top: 0; margin-bottom: 10px">
        <ColumnsController :value="columnList" :tableKey="tableKey" />
      </div>

      <el-table
        v-loading="loading"
        :data="tableData"
        style="width: 100%"
        highlight-current-row
        border
        @sort-change="sortChange"
        @current-change="rowChange"
        @selection-change="selectionChange"
        @row-dblclick="rowDoubleClick"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column
          v-for="(item, index) in showCols"
          :key="index"
          :label="item.label"
          :prop="item.prop"
          :show-overflow-tooltip="item.showOverflowTooltip"
          :width="item.width"
          :formatter="item.formatFunc"
          :sortable="item.sortable"
        />
        <el-table-column fixed="right" label="操作" width="320">
          <template #default="scope">
            <el-button
              v-permission="pageCode + 'configApiPermission'"
              type="primary"
              @click="configApiPermission(scope.row)"
              >API权限</el-button
            >
            <el-button
              v-permission="pageCode + 'configMessagePermission'"
              type="primary"
              @click="configMessagePermission(scope.row)"
              >消息权限</el-button
            >
            <el-dropdown class="ml-10px">
              <el-button type="primary">
                更多
                <el-icon class="el-icon--right"><arrow-down /></el-icon>
              </el-button>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item>
                    <el-button text v-permission="pageCode + 'modify'" @click="modify(scope.row)"
                      >修改</el-button
                    >
                  </el-dropdown-item>
                  <el-dropdown-item>
                    <el-button text v-permission="pageCode + 'remove'" @click="remove(scope.row)"
                      >删除</el-button
                    >
                  </el-dropdown-item>
                  <el-dropdown-item>
                    <el-button text v-permission="pageCode + 'enable'" @click="enable(scope.row)"
                      >启用</el-button
                    >
                  </el-dropdown-item>
                  <el-dropdown-item>
                    <el-button text v-permission="pageCode + 'disable'" @click="disable(scope.row)"
                      >停用</el-button
                    >
                  </el-dropdown-item>
                  <el-dropdown-item>
                    <el-button
                      text
                      v-permission="pageCode + 'resetSecretKey'"
                      @click="resetSecretKey(scope.row)"
                      >重置密钥</el-button
                    >
                  </el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </template>
        </el-table-column>
      </el-table>
      <ListPager
        :page-num="pageInfo.pageNum"
        :page-size="pageInfo.pageSize"
        :page-total="pageTotal"
      />
    </el-card>

    <AddPage ref="addPage" @refresh="refresh" />
    <ModifyPage ref="modifyPage" @refresh="refresh" />
    <ViewPage ref="viewPage" />
    <ApiServicePermission ref="apiServicePermission" />
    <MessagePermission ref="messagePermission" />
  </ContentWrap>
</template>

<script lang="ts">
import { listMixin } from '@/mixin/listMixin.js'
import ApiServicePermission from './apiServicePermission.vue'
import MessagePermission from './messagePermission.vue'
import AddPage from './add.vue'
import ModifyPage from './modify.vue'
import ViewPage from './view.vue'
const MODULE_CODE = 'cip'
const ENTITY_TYPE = 'app'
export default {
  name: ENTITY_TYPE,
  components: {
    AddPage,
    ModifyPage,
    ViewPage,
    ApiServicePermission,
    MessagePermission
  },
  mixins: [listMixin],
  data() {
    return {
      entityType: ENTITY_TYPE,
      moduleCode: MODULE_CODE,
      // eslint-disable-next-line no-eval
      api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
      pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
      columnList: [
        {
          prop: 'name',
          label: '名称',
          show: true,
          showOverflowTooltip: true,

          sortable: true
        },
        {
          prop: 'code',
          label: '编码',
          show: true,
          showOverflowTooltip: true,
          width: '120',
          sortable: true
        },
        {
          prop: 'secretKey',
          label: '密钥',
          show: true,
          showOverflowTooltip: true,
          width: '120',
          sortable: true
        },
        {
          prop: 'integrationModelName',
          label: '对接模式',
          show: true,
          showOverflowTooltip: true,
          width: '120'
        },
        {
          prop: 'statusName',
          label: '状态',
          show: true,
          showOverflowTooltip: true,
          width: '120'
        },
        {
          prop: 'orderNo',
          label: '排序',
          show: true,
          showOverflowTooltip: true,
          width: '120',
          sortable: true
        }
      ],
      queryCondition: {
        //默认值处理
        status: ''
      }
    }
  },

  methods: {
    configApiPermission(row) {
      this.$refs.apiServicePermission.init({ id: row.id })
    },
    configMessagePermission(row) {
      this.$refs.messagePermission.init({ id: row.id })
    },

    resetSecretKey(row) {
      this.$confirm('是否重置密钥?', '确认', {
        type: 'warning'
      })
        .then(() => {
          this.api.resetSecret(row.id).then(() => {
            this.refresh()
          })
        })
        .catch(() => {
          this.$message.info('已取消')
        })
    }
  }
}
</script>

新增视图

<template>
  <Dialog title="新增" v-model="visible" width="500px">
    <el-form
      ref="form"
      :model="entityData"
      :rules="rules"
      label-width="120px"
      label-position="right"
      style="width: 90%; margin: 0 auto"
    >
      <!--表单区域 -->
      <el-form-item label="名称" prop="name">
        <el-input v-model="entityData.name" />
      </el-form-item>
      <el-form-item label="编码" prop="code">
        <el-input v-model="entityData.code" />
      </el-form-item>
      <el-form-item label="密钥" prop="secretKey">
        <el-input v-model="entityData.secretKey" type="textarea" rows="4" />
      </el-form-item>
      <el-form-item label="对接模式" prop="integrationModel">
        <dictionary-radio-group v-model="entityData.integrationModel" code="IntegrationModel" />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <dictionary-radio-group v-model="entityData.status" code="Status" />
      </el-form-item>
      <el-form-item label="排序" prop="orderNo">
        <el-input v-model="entityData.orderNo" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button type="primary" @click="save" v-permission="pageCode + 'add'">保存</el-button>
      <el-button @click="close">关闭</el-button>
    </template>
  </Dialog>
</template>

<script>
import { addMixin } from '@/mixin/addMixin.js'
const MODULE_CODE = 'cip'
const ENTITY_TYPE = 'app'
export default {
  name: ENTITY_TYPE + '-add',
  components: {},
  mixins: [addMixin],
  data() {
    return {
      entityType: ENTITY_TYPE,
      moduleCode: MODULE_CODE,
      // eslint-disable-next-line no-eval
      api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
      pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
      entityData: {},
      rules: {
        //前端验证规则
        name: [{ required: true, message: '【名称】不能为空', trigger: 'blur' }],
        code: [{ required: true, message: '【编码】不能为空', trigger: 'blur' }],
        secretKey: [{ required: true, message: '【密钥】不能为空', trigger: 'blur' }],
        integrationModel: [{ required: true, message: '【对接模式】不能为空', trigger: 'blur' }],
        status: [{ required: true, message: '【状态】不能为空', trigger: 'blur' }]
      }
    }
  },
  methods: {}
}
</script>

<style></style>

修改视图

<template>
  <Dialog title="修改" v-model="visible" width="500px">
    <el-form
      ref="form"
      :model="entityData"
      :rules="rules"
      label-width="120px"
      label-position="right"
      style="width: 90%; margin: 0 auto"
    >
      <!--表单区域 -->
      <el-form-item label="名称" prop="name">
        <el-input v-model="entityData.name" />
      </el-form-item>
      <el-form-item label="编码" prop="code">
        <el-input v-model="entityData.code" />
      </el-form-item>
      <el-form-item label="密钥" prop="secretKey">
        <el-input v-model="entityData.secretKey" type="textarea" rows="4" />
      </el-form-item>
      <el-form-item label="对接模式" prop="integrationModel">
        <dictionary-radio-group v-model="entityData.integrationModel" code="IntegrationModel" />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <dictionary-radio-group v-model="entityData.status" code="Status" />
      </el-form-item>
      <el-form-item label="排序" prop="orderNo">
        <el-input v-model="entityData.orderNo" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button type="primary" @click="save" v-permission="pageCode + 'modify'">保存</el-button>
      <el-button @click="close">关闭</el-button>
    </template>
  </Dialog>
</template>

<script>
import { modifyMixin } from '@/mixin/modifyMixin.js'
const MODULE_CODE = 'cip'
const ENTITY_TYPE = 'app'
export default {
  name: ENTITY_TYPE + '-modify',
  components: {},
  mixins: [modifyMixin],
  data() {
    return {
      entityType: ENTITY_TYPE,
      moduleCode: MODULE_CODE,
      // eslint-disable-next-line no-eval
      api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
      pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
      entityData: {},
      rules: {
        //前端验证规则
        name: [{ required: true, message: '【名称】不能为空', trigger: 'blur' }],
        code: [{ required: true, message: '【编码】不能为空', trigger: 'blur' }],
        secretKey: [{ required: true, message: '【密钥】不能为空', trigger: 'blur' }],
        integrationModel: [{ required: true, message: '【对接模式】不能为空', trigger: 'blur' }],
        status: [{ required: true, message: '【状态】不能为空', trigger: 'blur' }]
      }
    }
  },
  methods: {}
}
</script>

<style></style>

查看视图

<template>
  <Dialog title="查看" v-model="visible" width="500px">
    <el-form
      ref="form"
      :model="entityData"
      label-width="120px"
      label-position="right"
      style="width: 90%; margin: 0 auto"
    >
      <!--表单区域 -->
      <el-form-item label="名称" prop="name">
        <el-input v-model="entityData.name" />
      </el-form-item>
      <el-form-item label="编码" prop="code">
        <el-input v-model="entityData.code" />
      </el-form-item>
      <el-form-item label="密钥" prop="secretKey">
        <el-input v-model="entityData.secretKey" type="textarea" rows="4" />
      </el-form-item>
      <el-form-item label="对接模式" prop="integrationModel">
        <dictionary-radio-group v-model="entityData.integrationModel" code="IntegrationModel" />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <dictionary-radio-group v-model="entityData.status" code="Status" />
      </el-form-item>
      <el-form-item label="排序" prop="orderNo">
        <el-input v-model="entityData.orderNo" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="close">关闭</el-button>
    </template>
  </Dialog>
</template>

<script>
import { viewMixin } from '@/mixin/viewMixin.js'
const MODULE_CODE = 'cip'
const ENTITY_TYPE = 'app'
export default {
  name: ENTITY_TYPE + '-view',
  components: {},
  mixins: [viewMixin],
  data() {
    return {
      entityType: ENTITY_TYPE,
      moduleCode: MODULE_CODE,
      // eslint-disable-next-line no-eval
      api: eval('this.$api.' + MODULE_CODE + '.' + ENTITY_TYPE),
      pageCode: MODULE_CODE + ':' + ENTITY_TYPE + ':',
      entityData: {}
    }
  },
  methods: {}
}
</script>

<style></style>

平台根据配置实现的是一些模式化的工作,还是需要开发人员根据业务需求进行一些调整工作,主要在后端方面,例如,编写启动、停用和重设密钥的服务。

低代码并不意味无代码,配置人员和开发人员需要协作才能发挥最大的作用。

配置权限项

使用系统管理模块下的权限项管理功能,配置模块、菜单和按钮
image.png

image.png
按钮可以找个类似的,通过复制新增功能快速创建。
image.png

运行效果

菜单、列表页面
image.png
修改视图
image.png

至此,平台低代码整体配置流程介绍完毕,下篇我们介绍下平台如何通过优化来提升配置效率。

开发平台资料

平台名称:一二三开发平台
简介: 企业级通用开发平台
设计资料:csdn专栏
开源地址:Gitee
开源协议:MIT
欢迎收藏、点赞、评论,你的支持是我前行的动力。

猜你喜欢

转载自blog.csdn.net/seawaving/article/details/130903885
今日推荐