面向ChatGPT快速开发一个后台管理页面

209 阅读6分钟

面向ChatGPT快速开发一个后台管理页面

本文主要介绍开发后台管理系统过程中,如何通过ChatGPT生成代码,提高工作效率,增加摸鱼时长。

一、具体思路介绍

一个后台管理的页面大致如下图:

系统架构设计.png

可以向ChatGPT提供对应TS interface以及prompt,生成相应的表单、表格、初始化数据。

graph LR
后端实体/JSON数据-->|prompt| TSInterface -->|prompt| 模板代码

二、根据后端实体生成前端类型

  1. 求(拿刀架他脖子上)后端同学提供相应的实体类型代码,具体例子如下:
public class TaskInfoEntity : EntityBase
{
    /// <summary>
    /// 任务单编号
    /// </summary>
    public string TaskId { get; set; }
    /// <summary>
    /// 优先级
    /// </summary>
    public short? Priority { get; set; }
    /// <summary>
    /// 数量
    /// </summary>
    public decimal? MeterNum { get; set; }
    /// <summary>
    /// 任务状态
    /// 0:待执行;1:执行中;2:暂停;3:终止;4:完成
    /// </summary>
    public EmTaskState? Status { get; set; }
    /// <summary>
    /// 任务开始时间
    /// </summary>
    public DateTime? WriteDate { get; set; }
    /// <summary>
    /// 任务结束时间
    /// </summary>
    public DateTime? EndDate { get; set; }
}
  1. 求ChatGPT帮忙生成对应的ts类型,我采用的prompt如下:
...上文的类型代码...
请根据以上代码转换为ts的interface类型,每个字段采用小驼峰命名的格式并添加相应的中文注释,
注释格式如下
 /**
   *@description XXX
   */
interface的命名请以I开头,例如ITTT,其中XXX为原代码中对应字段的中文注释,TTT为原代码实体的声明,
生成的interface类型导出方式为export interface。

最终ChatGPT生成的代码如下:

/**
 * @description 任务单编号
 */
export interface ITaskInfoEntity {
  taskId: string;
  /**
   * @description 优先级
   */
  priority?: number;
  /**
   * @description 数量
   */
  meterNum?: number;
  /**
   * @description 任务状态(0:待执行;1:执行中;2:暂停;3:终止;4:完成)
   */
  status?: EmTaskState;
  /**
   * @description 任务开始时间
   */
  writeDate?: Date;
  /**
   * @description 任务结束时间
   */
  endDate?: Date;
}

可以看到interface中还存在枚举类型需要生成,在后台系统存在很常见的需求就是:

  • 在表单中提供对应的枚举选项供用户选择(select组件);
  • 在表格中根据后端接口返回的枚举值转换成对应的中文(value => label);

所以继续求助后端同学、ChatGPT帮忙。

3.生成枚举类型以及对应的字典常量

后端代码如下:

/// <summary>
/// 任务状态
/// </summary>
public enum EmTaskState
{
    /// <summary>
    /// 待执行
    /// </summary>
    Waiting = 0,
    /// <summary>
    /// 执行中
    /// </summary>
    Testing = 1,
    /// <summary>
    /// 暂停
    /// </summary>
    Pause = 2,
    /// <summary>
    /// 终止
    /// </summary>
    Stop = 3,
    /// <summary>
    /// 完成
    /// </summary>
    Finish = 4
}

prompt与上文生成interface类似,具体如下:

...上文的类型代码...
请将此枚举类型转换为ts的枚举类型,每个枚举值添加注释,
注释格式如下
 /**
   *@description XXX
   */
枚举命名请用E开头,例如ETTT,其中XXX为原枚举值中相应的注释,TTT为原枚举值的声明,
生成的枚举类型导出方式为export const enum。

最终生成的枚举类型如下:

/**
 * @description 任务状态
 */
export const enum ETaskState {
  /**
   * @description 待检
   */
  Waiting = 0,
  /**
   * @description 检测中
   */
  Testing = 1,
  /**
   * @description 暂停
   */
  Pause = 2,
  /**
   * @description 终止
   */
  Stop = 3,
  /**
   * @description 完成
   */
  Finish = 4
}

继续根据枚举类型生成常量集合,prompt如下:

...上文的类型代码...
根据此枚举类型帮我生成一份常量集合,集合命名为全大写加下划线,key为枚举的值,
value为对应枚举的中文注释,导出方式为export。

生成结果如下:

export const TASK_STATE_CONSTANTS: { [key: number]: string } = {
  [ETaskState.Waiting]: '待检',
  [ETaskState.Testing]: '检测中',
  [ETaskState.Pause]: '暂停',
  [ETaskState.Stop]: '终止',
  [ETaskState.Finish]: '完成'
};

一般情况需要生成三份interface(查询表单、表格、编辑/新增表单),后文都将采用ITaskInfoEntity来生成。

三、根据TS的interface类型生成组件代码

项目中采用的组件库是ant-design-vue,下文都将以此组件库举例,其他的组件库的可以自行调整,只要prompt越详细,生成的结果越符合需求。

  1. 根据interface生成a-table组件的columnsdataSource

prompt如下:

/**
 * @description 任务单编号
 */
export interface ITaskInfoEntity {
  taskId: string;
  /**
   * @description 优先级
   */
  priority?: number;
  /**
   * @description 数量
   */
  meterNum?: number;
  /**
   * @description 任务状态(0:待执行;1:执行中;2:暂停;3:终止;4:完成)
   */
  status?: EmTaskState;
  /**
   * @description 任务开始时间
   */
  writeDate?: Date;
  /**
   * @description 任务结束时间
   */
  endDate?: Date;
}
根据以上定义,帮我生成一份antd-design-vue组件库a-table组件的columns,
columns中的每个成员请添加width属性,以及datasource长度为3

生成结果如下:

const columns = [
  {
    title: '任务单编号',
    dataIndex: 'taskId',
    key: 'taskId',
    width: 150
  },
  {
    title: '优先级',
    dataIndex: 'priority',
    key: 'priority',
    width: 150
  },
  {
    title: '数量',
    dataIndex: 'meterNum',
    key: 'meterNum',
    width: 150
  },
  {
    title: '任务状态',
    dataIndex: 'status',
    key: 'status',
    width: 150
  },
  {
    title: '任务开始时间',
    dataIndex: 'writeDate',
    key: 'writeDate',
    width: 200
  },
  {
    title: '任务结束时间',
    dataIndex: 'endDate',
    key: 'endDate',
    width: 200
  }
];

const dataSource = [
  {
    taskId: 'task1',
    priority: 1,
    meterNum: 100,
    status: EmTaskState.EXECUTING,
    writeDate: new Date('2021-01-01'),
    endDate: new Date('2021-01-02')
  },
  {
    taskId: 'task2',
    priority: 2,
    meterNum: 200,
    status: EmTaskState.PAUSED,
    writeDate: new Date('2021-01-02'),
    endDate: new Date('2021-01-03')
  },
  {
    taskId: 'task3',
    priority: 3,
    meterNum: 50,
    status: EmTaskState.COMPLETED,
    writeDate: new Date('2021-01-03'),
    endDate: new Date('2021-01-04')
  }
];

columns中的操作列以及枚举值的处理还是需要再手动调整一下,dataSource中生成的值可能部分类型不对,不过只是用作mock数据不是很重要,columns稍微调整如下:

// 修改任务状态列,TASK_STATE_CONSTANTS为上文生成的常量
 {
   title: '任务状态',
   dataIndex: 'status',
   key: 'status',
   width: 150,
   customRender: ({text}) => TASK_STATE_CONSTANTS?.[text] ?? text
}
// 增加操作列
{
  title: '操作',
  key: 'action',
  width: 100,
  fixed: 'right'
}
  1. 生成查询表单

继续ChatGPT,prompt如下:

...类型代码...
根据此类型定义帮我生成一份ant-design-vue a-form组件,用a-row 、a-col组件将表单布局为一行4个,
a-row的属性为:gutter="8",a-col的属性为:xl="6" :lg="12" :md="12" :sm="24" :xs="24",
a-form-item组件请添加name属性,name的值为当前绑定的key,
表单组件请添加placeholder属性以及allow-clear,
对于a-input-number\a-select\a-date-picker等组件请添加样式style="width: 100%",
对与表单值的绑定请采用v-model:value或者v-model:checked

生成的组件代码如下:

<template>
  <a-form :form="form">
    <a-row :gutter="8">
      <a-col :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
        <a-form-item label="任务单编号" :name="'taskId'">
          <a-input
            v-model:value="form.taskId"
            placeholder="请输入任务单编号"
            allow-clear
            style="width: 100%"
          />
        </a-form-item>
      </a-col>
      <a-col :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
        <a-form-item label="优先级" :name="'priority'">
          <a-input-number
            v-model:value="form.priority"
            placeholder="请输入优先级"
            allow-clear
            style="width: 100%"
          />
        </a-form-item>
      </a-col>
      <a-col :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
        <a-form-item label="数量" :name="'meterNum'">
          <a-input-number
            v-model:value="form.meterNum"
            placeholder="请输入数量"
            allow-clear
            style="width: 100%"
          />
        </a-form-item>
      </a-col>
      <a-col :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
        <a-form-item label="任务状态" :name="'status'">
          <a-select
            v-model:value="form.status"
            placeholder="请选择任务状态"
            allow-clear
            style="width: 100%"
          >
            <a-select-option value="0">待执行</a-select-option>
            <a-select-option value="1">执行中</a-select-option>
            <a-select-option value="2">暂停</a-select-option>
            <a-select-option value="3">终止</a-select-option>
            <a-select-option value="4">完成</a-select-option>
          </a-select>
        </a-form-item>
      </a-col>
      <a-col :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
        <a-form-item label="任务开始时间" :name="'writeDate'">
          <a-date-picker
            v-model:value="form.writeDate"
            placeholder="请选择任务开始时间"
            allow-clear
            style="width: 100%"
          />
        </a-form-item>
      </a-col>
      <a-col :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
        <a-form-item label="任务结束时间" :name="'endDate'">
          <a-date-picker
            v-model:value="form.endDate"
            placeholder="请选择任务结束时间"
            allow-clear
            style="width: 100%"
          />
        </a-form-item>
      </a-col>
    </a-row>
  </a-form>
</template>

主要截取了template部分的内容,script部分一般还需要手动调整直接跳过。

3、编辑/新增表单

编辑表单的生成方式与查询表单的生成方式类似,只需要稍微调整prompt即可,不再举例啦。

四、总结

ChatGPT的代码生成需要根据prompt不停的训练到最优直到输出正确的结果,训练好后就可以直接塞给interface代码即可生成。

生成代码部分可用,部分重复的逻辑还得继续搬(痛苦),以及对于后端类型多层继承的情况也得手动处理才能生成正确的interface类型。

后续目标开发一个命令行工具,生成模板代码,再结合ChatGPT cv快速开发一个页面,觉得有用的小伙伴可以留下三连(求求啦)追更。