代码生成器(beta版)

一、导入数据表

  1. 登录至pai开发平台 -> 套件 -> 数据库管理 -> 生成表结构 -> 勾选需要生成的数据表(注:只需要表结构,不需要数据)
  2. 访问代码生成器 -> 导入 -> 选择pai开发平台导出的数据库文件 -> 上传 -> 完成导入
  3. 数据表增减字段,改动过多时,可删除原表进行重新导入;改动较小时,为保持原有配置,可自己编写alter table xxx等语句进行导入,之后便可以进行数据表同步

二、数据属性说明

2.1 基本信息

序号 属性 说明
1 表名称 po对象@ TableName注解
2 表描述 数据表描述
3 实体类名称 po、vo、service、controller、mapper等名称前缀
4 作者 此处填写自己的码名
5 备注 备注

2.2 字段信息

序号 属性 说明 备注
1 字段列名 对应的数据库字段名称
2 字段描述 vo对象@ ApiModelProperty、I18N文件对应值
3 物理类型 对应的数据库字段类型 vo对象会根据此属性进行长度限制操作
4 Java类型 对应的Java类型 Integer、Long、String、Date、BigDecimal
5 Java属性 vo、po、mapper.xml等生成属性名称
6 插入 勾上则会在新增显示
7 编辑 勾上则会在新增页面显示 增、改目的使用add.vue,查看使用view.vue。 后续增加只读查看页面
8 列表 勾上则会在列表字段显示
9 查询 勾上则会在列表查询处显示
10 查询方式 查询字段对应的查询方式 目前仅生成=、Between,后续再决定是否放开其他
11 必填 勾上则在vo以及前端添加必填校验
12 显示类型 即控件类型 文本框、文本域、下拉框、单选框、复选框、流水号、富文本、上传控件、日期控件、企业选择器、园区选择器、部门选择器 、人员选择器。目前前端并未完全标准化
13 字典类型 当显示类型为单行框、复选框及下拉框时,需填写对应的数据字典标识;同时如果字典在其他套件,需要对应修改控件及ServiceImpl.setup方法中对应的套件名称

2.3 生成信息

序号 属性 说明
1 生成模板 支持单表、主子表(增删改查)
2 生成包路径 后端生成文件的包名前缀,如租赁意向:cn.flyrise.pai.business.lease.intention。如存在主子表关系,子表使用主表设置的包路径
3 生成模块名 对应套件后半部分,如cn.flyrise.business,则此处只需要填写business即可
4 生成业务名 对应业务名称,如租赁则为:lease,租赁意向则为:lease.intention。子表只需填写自身业务即可,如房间子表:room
5 生成功能名 Java类注释、swagger显示模块名称
6 validCode起始值 中台建议由3000起步,请根据项目已使用的code进行赋值
7 主子表关联信息
关联子表 选择相应的子表
子表关联的外键名 选择子表关联主表外键

三、使用方法

  1. 点击生成代码,下载一个以zip结尾的压缩包,进行解压缩

  2. main、test文件夹为后端工程专用,复制到java后端工程src下

  3. feign文件夹(生成条件查看特性4.1 name字段说明),将其下的文件夹复制至对应业务内部调用库的src下

  4. web文件夹为前端工程专用,复制其下的api及pages文件夹至前端工程根目录

  5. 启动后端

  6. 前端部分控件需要安装依赖,请根据 https://pai.flyrise.cn/pai-sp-ui/#/docs/Install 指引进行安装

  7. 前端修改nuxt.config.js,找到 LOCAL_PROXY_OPTIONS,进行修改,目的是让前端工程访问自身后端:

    1. 修改前
    const LOCAL_PROXY_OPTIONS = {
      enable: false, // 是否启用
      target: 'http://127.0.0.1:8080',
      proxies: [
        // {
        //   path: 'template-api', // 替换成业务后端api
        // },
        // {
        //   path: 'test-api',
        //   target: 'http://127.0.0.1:8888'
        // }
      ]
    }
        修改后
    const LOCAL_PROXY_OPTIONS = {
      enable: true, // 是否启用
      target: 'http://10.62.19.xx:8080',  //后端地址
      proxies: [
        {
          path: 'business-api', // 替换成业务后端api
        },
        // {
        //   path: 'test-api',
        //   target: 'http://127.0.0.1:8888'
        // }
      ]
    }
  8. 启动前端

四、特性

4.1 字段

4.1.1 name

当单表或主表包含`name`字段时,会将此模块当成字典类型处理,额外添加以下功能:
  1. service添加以下方法

        /**
       * 获取对象名称
       *
       * @param id 主键
       * @return 名称
       */
      String getName(String id);
    
      /**
       * 获取对象id、名称集合
       *
       * @param ids 主键集合
       * @return 主键、名称集合
       */
      Map<String, String> getNames(Collection<String> ids);
    
      /**
       * 获取对象id、名称集合。用于下拉选择器
       *
       * @param query 查询对象
       * @return 主键、名称集合
       */
      Page<VO> selector(QueryVO query);
  2. controller添加如下方法:

        @ApiOperation("分页查询主键、名称集合")
      ~~@PostMapping("selector")~~
      @PostMapping("dict")
      public Reply<Page<VO>> dict(@Valid @RequestBody QueryVO query) {
        return Reply.success(this.${className}Service.selector(query));
      }
  3. 额外添加内部Controller类,用于依赖模块的保存验证等

    @RestController
    @RequestMapping("/${api.version}/xxx/inner")
    public class InnerController {
    
      @Resource
      private IService Service;
    
      @ApiOperation("获取名称")
      @GetMapping("name/{id}")
      @ApiResponses({
        @ApiResponse(code = 1006, message = "id不能为空"),
      })
      @ApiImplicitParams({
        @ApiImplicitParam(name = "${table.getPkName()}" , value = "${functionName}主键", dataTypeClass = String.class, required = true)
      })
      @Inner
      public Reply<String> getName(@PathVariable("id") String id) {
        return Reply.success(this.${className}Service.getName(id));
      }
    
      @ApiOperation("获取主键、名称集合")
      @PostMapping("names")
      @Inner
      public Reply<Map<String, String>> getNames(@RequestBody Collection<String> ids) {
        return Reply.success(this.${className}Service.getNames(ids));
      }
    
    }
  4. 额外添加feign调用类:

    @FeignClient(
            name = "pai-xxx",
            contextId = "xxxApi",
            path = "${api.service.xxx.path:}/${api.service.xxx.version:v1}/xxx/inner",
            fallbackFactory = RemoteFallbackFactory.class
    )
    public interface IService {
    
      @ApiOperation("获取租赁意向名称")
      @GetMapping("name/{id}")
      Reply<String> getName(@PathVariable("id") String id, @RequestHeader(FROM) String from);
    
      @ApiOperation("获取租赁意向主键、名称集合")
      @PostMapping("name")
      Reply<Map<String, String>> getNames(@RequestBody Collection<String> ids,
              @RequestHeader(FROM) String from);
    
    }
    public class RemoteLeaseFactory implements FallbackFactory<IService> {
    
      @Override
      public IService create(Throwable throwable) {
        return new IService() {
          @Override
          public Reply<String> getName(String id, String from) {
            return fail();
          }
    
          @Override
          public Reply<Map<String, String>> getNames(Collection<String> ids, String from) {
            return fail();
          }
        };
      }
    
      private <T> Reply<T> fail() {
        return Reply.fail("405" , "租赁意向服务异常,请稍后重试");
      }
    }

4.1.2 字段名称对应默认生成控件

  1. enterprise_id、consumer_id :企业选择器。规范推荐使用enterprise_id,更能体现是由企业档案而来
  2. park_id:园区选择器
  3. dept_id:部门选择器
  4. create_by、update_by:人员选择器
  5. annex、或以file结尾:上传控件
  6. room_id:房源选择器
  7. 以_id结尾:下拉框

五、注意事项

  1. java代码import部分会引入未使用的类,请格式化所有java代码

  2. vo字段验证:长度验证是根据数据字段类型进行判断,如status等表示状态的,1-10范围内基本已满足,但生成器目前尚未做此判断,所以需要自行进行调整:

        @ApiModelProperty(value = "状态", hidden = true)
      @Min(0)
      @Max(999999999)
      @InvalidCode(value = "3022", desc = "状态", message = "{status}")
      private Long status;
  1. 企业、园区、部门、员工、字典等参照项显示值,如需持久化到数据表中,需要在ServiceImpl.setup方法中自行赋值:

    private LeaseIntentionPO setup(LeaseIntentionVO vo) {
    
    }
  1. 子表保存验证:不同于主表验证,其是批量形式,目前还没能找齐获取集合进行验证的接口,暂时需要自行编写验证代码。在子表ServiceImpl类中搜索TODO查找相应位置,如下:

            List<LeaseIntentionRoomPO> items = list.stream().map(
            item -> {
              // TODO 子表验证保存
              LeaseIntentionRoomPO po = ConvertUtil.transfor(item, LeaseIntentionRoomPO.class);
              po.setIntentionId(mainId);
              return po;
            }).collect(toList());
        this.saveOrUpdateBatch(items);
        return ConvertUtil.transforList(items, LeaseIntentionRoomVO.class);
  1. 前端验证:接口访问失败处理、提交失败处理、表单验证未通过处理、子表操作等个性化处理需自行处理。搜索TODO查找相应位置

    this.$refs.ruleForm.validate(valid => {
      if (valid) {
        this.fullLoading = true
        let apiMethod = this.isAdd ? LeaseIntentionApi.add : LeaseIntentionApi.update;
        apiMethod(this.form).then((res) => {
          this.fullLoading = false
          if (res.success) {
            this.back()
          }
        })
          .catch((errorRes) => {
          this.fullLoading = false
          // TODO 提交失败处理
        });
      } else {
        // TODO 表单验证未通过处理
      }
    })
  1. 主子表生成代码方式:无需勾选子表,只对主表进行生成代码操作即可,生成器会根据主表的关联关系自动生成子表对应的代码

  2. i18n文件

    1. 为避免覆盖原messages.properties文件,将生成{业务名}.messages.properties文件,复制内容至messages.properties文件即可
    2. 不同的表难免存在同名称的列,需要手动确认
  3. 问题:目前前端控件标准化程度不完整,如遇到控件不存在而报错的,请在部门群内询问解决

此版本为beta版,并非稳定版本,请做好心理预期。使用过程中有任何问题、任何改进意见都可以进行讨论,让我们一起完善此工具,减少重复性工作,专注于业务开发。

文档更新时间: 2022-02-24 19:59   作者:陆鸿睿