Take you step by step to realize the low-code development platform - generate library tables and codes based on configuration information

background

Through the previous steps, we have completed the configuration of entities, mainly including entities, entity models, and views. The next work is mainly three items, one is to generate database tables, the other is to generate front-end and back-end source codes, and the third is to configure permission items (menu and button), after completing these steps, the configuration function will be able to run. Let’s continue to take the application entity in the interface platform module as an example to talk about it specifically.

Generate library table

Many low-code platforms first use database model development tools, such as PowerDesigner, to design database tables, then generate database tables, and then connect the platform to the database for reverse engineering and generate source code. In this way, developers still need to understand the use of library table design tools and the corresponding knowledge of the database, such as different types of databases, strings, integers, and dates are different. This model is essentially data-driven in the traditional sense.
The low-code platform I designed is to design the model first, and then the platform automatically creates library tables according to the model configuration. Developers only need to configure it in the platform. This mode is equivalent to model-driven. Developers no longer need to pay attention to the type and details of the database, and the platform has taken over.

Enter the entity management list through the menu, check one or more entities to generate a database table, and then click the "Generate Library Table" button, the system will automatically generate a database table creation statement according to the model configuration information, and connect to the database creation.

image.png

image.png

generate code

Similar to the operation of generating library tables, enter the entity management list through the menu, check one or more entities to generate library tables, and then click the "Generate Code" button, the system will automatically generate source codes according to the entity configuration information, including back-end entities Class, Mapper interface and xml configuration file of DAO layer, service layer (interface and implementation class), controller layer, view object class, and front-end view (list, add, modify, view, reference and possible tree, tree table, etc., depending on the settings in the view configuration section).
image.png

Front-end: Copy the Vue view files in the view directory to the front-end src\modules\cip\view directory Back-end
: Copy files in other directories to the back-end manage project

Entity class

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 interface

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>

service interface class

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);
}


service implementation class

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() + " 副本");
    }

}


controller class

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
 }

view object class

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;

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

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

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

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




}

list view

<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>

new view

<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>

modify view

<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>

view view

<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>

Does the platform implement some patterned work based on configuration, or does it require developers to make some adjustments based on business needs, mainly in the backend, for example, writing services for starting, stopping, and resetting keys.

Low-code does not mean no-code, and configurators and developers need to collaborate to be most effective.

Configure permission items

Use the permission item management function under the system management module to configure modules, menus and buttons
image.png

image.png
You can find a similar button and quickly create it by copying the new function.
image.png

running result

Menu, List Page
image.png
Modify View
image.png

So far, the overall low-code configuration process of the platform has been introduced. In the next article, we will introduce how the platform improves configuration efficiency through optimization.

Development platform information

Platform name: One Two Three Development Platform
Introduction: Enterprise-level general development platform
Design information: csdn column
Open source address: Gitee
open source protocol: MIT
welcomes favorites, likes, and comments. Your support is the driving force for me to move forward.

Guess you like

Origin blog.csdn.net/seawaving/article/details/130903885