视频下载

Pai 工具介绍及安装

Pai 工具介绍

pai是一个能让开发进行以下一系列的操作的辅助工具:

  • 快速创建工程项目骨架

  • 根据表结构生成代码

  • 使用Maven进行本地运行和执行单测试

  • 远程构建: 编译 > 打包 > 构建Docker > K8S部署

pai命令

Pai 工具安装

Git提交消息约定

  • [IMP] 提升改善正在开发或者已经实现的功能

  • [FIX] 修正BUG

  • [REF] 重构一个功能,对功能重写

  • [ADD] 添加实现新功能

  • [REM] 删除不需要的文件

创建套件

1. 创建套件

  • 登录 开发者后台
  • 演示套件(sims) cn.flyrise.sims
  • sims > student information management system 学生信息管理系统

2. 后端

  • 创建工程 pai-sim
# 根据骨架创建工程
pai create service -n pai-sims -s cn.flyrise.sims

# 初始化git
cd pai-sims
pai init

# 添加所有文件
pai add .

# 提交初始项目
pai commit -m "[ADD] 创建初始项目"

SQL目录:src/main/resources/meta/sql/VYYYYMMDDNN__[DESC].sql
Nacos配置:src/main/reources/meta/nacos.yml

修改Swagger标题:学生信息管理系统

  • 创建表生成代码

student 学生信息表

字段 类型 描述
name varchar(20) 姓名
age int(11) 年龄
sex char(1) 性别(F - 女 M - 男 O - 其他)
cd pai-sims
pai code -t student
  • 本地运行(pai 或 IDE)
pai run 
  • 国际化

详细说明

文件夹里包含三个属性文件: messages.properties,messages_en_US.properties和messages_zh_CN.properties,
其中 messages.properties 是个默认文件,即使为空也要有,否则MessageSource加会变成[Empty MessageSource]
切记切记 所有文件编码必需是 UTF-8 格式

  • 验证+国际化

VO

/** 姓名 */
@ApiModelProperty("姓名")
@NotBlank
@InvalidCode(value = "5001",  desc = "姓名")
private String name;

/** 年龄 */
@ApiModelProperty("年龄")
@Range(min = 6, max = 100)
@InvalidCode(value = "5002",  desc = "年龄")
private Integer age;

PO
原则上建议继承BaseEntity,如不继承需要配置自动填充注解

Controller
注意修改Swagger描述,原则上Controller不写业务逻辑,统一写到Service层,新增或修改基本上要返回处理完成的VO(实际上是PO在Service中转成VO返回)

@ApiOperation("添加单条记录")
@PostMapping
public Reply<StudentVO> insert(@RequestBody @Valid StudentVO vo) {
    return Reply.success(this.studentService.add(vo));
}

Sevice

@Override
public StudentVO add(StudentVO studentVO){
    StudentPO po = new StudentPO();
    po.setName(studentVO.getName());
    StudentPO exist = selectOnePO(new QueryWrapper<>(po));
    if(exist != null){
        throw new SimsBizException(BusinessErrors.ERR_1001, null);
    }

    studentVO = insertVoReturnVO(studentVO);
    return studentVO;
}

可通过 BusinessErrors.main生成message.properties
通过Swagger 添加全局参数模拟不同语言: Accept-Language en-US header

  • 异常处理

    统一抛出异常BizException的子类

  • 获取当前用户信息

    LoginUser loginUser = SecurityUtils.getLoginUser();

    相关权限及鉴权参考详情

  • 部署运行

# 添加所有文件
pai add .

# 添加新功能模块
pai commit -m "[ADD] 增加学生信息管理功能"

# 推送代码到远程仓库
pai push

# 远程构建并部署到k8s
pai deploy service -n pai-sims

3. 前端

  • 创建工程 pai-sims-ui
# 根据骨架创建工程
pai create front -n pai-sims-ui -s cn.flyrise.sims

# 初始化git
cd pai-dsims-ui
pai init

# 添加所有文件
pai add .

# 提交初始项目
pai commit -m "[ADD] 创建初始项目"

通过 表单建模 工具对表单进行可视化生成代码。

  1. 登录开发者后台,在套件列表中找到工程绑定的套件,点击开发按钮进入开发管理界面。
  2. 选择对应前端工程的表单建模,按步骤创建一个表单
  3. 基于工程后端创建的数据表生成一个表单预览确认后点击导出vue文件。

这个时候在浏览器访问根目录下的文件名已经可以看到刚才生成的表单。
默认首页:http://localhost/sims/
演示表单:http://localhost/sims/student

前端与后端接口进行数据交互。

  1. 新建student.vue文件,把下面的代码复制进去。
  <template>
  <div style="padding: 30px 50px">
    <div style="margin: 30px auto">
      <h3 style="margin-bottom: 30px">学生信息管理</h3>
      <el-button type="primary" @click="addItem" icon="el-icon-plus">新增</el-button>
    </div>
    <el-table :data="list" border v-loading="loading">
      <el-table-column label="编号" prop="id" />
      <el-table-column label="学生姓名" prop="name" />
      <el-table-column label="年龄" prop="age" />
      <el-table-column label="性别">
        <template slot-scope="scope">
          <span v-if="scope.row.sex === 'M'"></span>
          <span v-else-if="scope.row.sex === 'F'"></span>
          <span v-else>其他</span>
        </template>
      </el-table-column>
      <el-table-column label="创建时间" prop="createTime">
        <!-- <template slot-scope="scope">
          <span>{{ $paiui.date.format(scope.row.createTime) }}</span>
        </template> -->
      </el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button type="primary" @click="editItem(scope.row)" icon="el-icon-edit">编辑</el-button>
          <el-button type="danger" @click="delItem(scope.row)" icon="el-icon-delete">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      style="margin-top: 30px"
      :current-page.sync="queryParams.page"
      :page-size.sync="queryParams.size"
      background
      :total="total"
      @current-change="getList"
      @size-change="getList"
      :page-sizes="[5, 10, 20, 50]"
      layout="total, sizes, prev, pager, next, total">
    </el-pagination>
    <el-dialog title="学生信息管理" :visible.sync="dialog">
      <el-row :gutter="15">
        <el-form
          ref="form"
          :model="form"
          :rules="rules"
          size="medium"
          label-width="100px"
          label-position="top"
        >
          <!-- 编辑态 -->
          <template v-if="state !== 'view'">
            <el-col :span="12">
              <el-form-item label="姓名" prop="name">
                <el-input
                  v-model="form.name"
                  placeholder="请输入"
                  :maxlength="50"
                  clearable
                  :style="{ width: '100%' }"
                ></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="年龄" prop="age">
                <el-input
                  v-model="form.age"
                  placeholder="请输入"
                  :maxlength="11"
                  clearable
                  :style="{ width: '100%' }"
                ></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="性别(F-女 M-男 O-其他)" prop="sex">
                <!-- <el-radio-group v-model="form.sex">
                  <el-radio label="M">男</el-radio>
                  <el-radio label="F">女</el-radio>
                  <el-radio label="O">其他</el-radio>
                </el-radio-group> -->
                <el-input
                  v-model="form.sex"
                  placeholder="请输入"
                  clearable
                  :style="{ width: '100%' }"
                ></el-input>
              </el-form-item>
            </el-col>
          </template>
          <!-- 只读态 -->
          <template v-if="state === 'view'">
            <el-col :span="12">
              <el-form-item label="姓名" prop="name">
                <div v-text="form.name"></div>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="年龄" prop="age">
                <div v-text="form.age"></div>
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="性别(F-女 M-男 O-其他)" prop="sex">
                <div v-text="form.sex"></div>
              </el-form-item>
            </el-col>
          </template>
          <el-col :span="24">
            <!-- 操作按钮 -->
            <el-form-item size="large">
              <el-button type="primary" @click="submit">提交</el-button>
              <el-button @click="resetForm">重置</el-button>
            </el-form-item>
          </el-col>
        </el-form>
      </el-row>
    </el-dialog>
  </div>
</template>
<script>
// 导入模板默认的请求方法
import {
  ApiGetTableList,
  ApiAddUser,
  ApiUpdateUser,
  ApiDeleteUser,
  ApiGetData,
} from "@/api/table";
export default {
  components: {},
  props: {
    // 流程的数据
    data: {
      default() {
        return {};
      },
    },
    // 表单状态
    state: {
      default() {
        return "add";
      },
    },
  },
  data() {
    return {
      dialog: false,
      loading: false,
      edit: false,
      list: [],
      total:0,
      queryParams: {
        page: 1,
        size: 5,
      },
      form: {
        id: "",
        name: undefined,
        age: undefined,
        sex: undefined,
      },
      rules: {
        name: [
          {
            required: true,
            message: "请输入",
            trigger: "blur",
          },
        ],
        age: [
          {
            required: true,
            message: "请输入",
            trigger: "blur",
          },
        ],
        sex: [
          {
            required: true,
            message: "请输入",
            trigger: "blur",
          },
        ],
      },
    };
  },
  computed: {},
  watch: {},
  created() {
    // TODO:加载表单
    this.getFormData();
  },
  mounted() {
    this.getList();
  },
  methods: {
    // 获取列表
    getList() {
      let query = {
        ...this.queryParams,
      };
      this.loading = true;
      ApiGetTableList(query).then((res) => {
        this.loading = false;
        res.data && (this.list = res.data.records || []);
        this.total = res.data.total||0
      });
    },
    // 添加学生弹框
    addItem() {
      this.dialog = true;
      this.$nextTick(() => {
        this.resetForm();
      });
      this.edit = false;
    },
    // 删除学生
    delItem(item) {
      this.$confirm("确定要删除选中的数据吗?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        let query = {
          id: item.id,
        };
        ApiDeleteUser(query).then((res) => {
          this.$notify.success(res.msg || "操作成功");
          this.getList();
        });
      });
    },
    // 提交表单
    submit(cmd) {
      this.$refs["form"].validate((valid) => {
        if (!valid) {
          return;
        }
        let data = { ...this.form };
        if (this.edit) {
          ApiUpdateUser(data).then((res) => {
            this.$notify.success(res.msg || "操作成功");
            this.dialog = false;
            this.getList();
          });
        } else {
          ApiAddUser(data).then((res) => {
            this.$notify.success(res.msg || "操作成功");
            this.dialog = false;
            this.getList();
          });
        }
      });
    },
    editItem(item) {
      let query = {
        id: item.id,
      };
      ApiGetData(query).then((res) => {
        this.form = JSON.parse(JSON.stringify(res.data));
        this.edit = true;
        this.dialog = true;
      });
    },
    resetForm() {
      this.$refs["form"].resetFields();
    },
    // 加载表单数据
    getFormData() {
      if (!this.data.id) {
        return;
      }
      // this.$REQUEST({
      //   url: `${this.$BASE_ROUTE}/xxx-api/form/query`,
      //   method: "GET",
      //   params: {
      //     id: this.data.id,
      //   },
      // }).then((res) => {
      //   // TODO:填充表单数据
      //   this.form = res.data
      //   // 返回数据给流程中心
      //   this.$emit("form", this.form)
      // })
      // Demo 填充表单数据
      this.form = {
        id: "123456789",
      };
      // 返回数据给流程中心
      this.$emit("form", this.form);
    },
  },
};
</script>
<style>
</style>

2.把下载的表单文件表单部分复制到student.vue文件替换,可以查看表单的使用。

本地验证没问题后,就可以通过pai工具部署到K8s环境中运行

  • 部署运行
# 添加所有文件
pai add .

# 添加新功能模块
pai commit -m "[ADD] 增加学生信息管理功能"

# 推送代码到远程仓库
pai push

# 远程构建并部署到k8s
pai deploy front -n pai-sims-ui

4. 微应用配置

应用中心 -> 添加版本(0.0.1) -> 添加微应用 [ 学生信息 /sims/student ]

5. 沙箱更新测试

开发 中心 -> 我的套件 -> 沙箱 -> 安装/一键更新

文档更新时间: 2022-11-29 11:59   作者:管理员