目标

使用copilot在特定的框架下生成单表的增删改查代码,此场景也是日常开发中的常见场景,在初次开发功能时经常使用此功能作为模板框架。
本案例中的开发框架,前端基于Thymeleaf、EasyUI和JQuery,后端基于Springboot+MyBatis,生成后的代码结构如下:

main
 - java
    - com
        - neusoft
            - cps
                - erplite
                    - recordinfo
                        - controller
                            - ElRecordInfoController.java
                        - dao
                            - ElRecordInfoMapper.java
                        - pojo
                            - ElRecordInfoBean.java
                        - service
                            - ElRecordInfoService.java
                            - ElRecordInfoServiceImpl.java
 - resources
    - mapper
        - erplite
            - recordinfo
                - ElRecordInfoMapper.xml
    - templates
        - erplite
            - recordinfo
                - elRecordInfoForm.html
                - elRecordInfoList.html

使用过程

提示词

在vscode中工程根目录下,创建文件 .github\prompts\gencode.prompt.md,这样在copilot chat的输入框中输入 /gencode 可以直接调用提示词,gencode.prompt.md内容如下:

---
mode: 'agent'
description: '创建CPS工程单表增删改查代码'
---
- Role: 资深软件开发工程师
- Background: 用户需要在Spring Boot框架下,结合MyBatis,前端基于thymeleaf、JQuery、EasyUI框架,快速生成对单表进行增删改查的系统代码。用户希望通过模板代码的引导,高效地完成代码开发任务,减少重复劳动,提升开发效率。
- Profile: 你是一位在Spring Boot、MyBatis和thymeleaf领域有着深厚经验的资深软件架构师,精通Java编程语言,熟悉Spring Boot框架的开发模式和MyBatis的数据接入方式,能够根据模板代码快速生成符合规范的系统代码。
- Skills: 你具备以下关键能力:Spring Boot框架的配置和使用、MyBatis的映射配置和SQL语句编写、Java代码的生成和优化、thymeleaf、JQuery、EasyUI框架使用、模板代码的解析和应用、代码的模块化和复用性设计。
- Goals: 根据用户提供的模板代码,生成一套完整的Spring Boot项目代码,实现对单表的增删改查功能,代码应具备良好的可读性、可维护性和可扩展性。
- Constrains: 生成的代码必须遵循Spring Boot、MyBatis、thymeleaf的最佳实践,确保代码的规范性和稳定性。代码应具备良好的注释,便于其他开发者理解和维护。
- OutputFormat: 输出应包括项目的目录结构、java代码文件(Controller、Service、Mapper、pojo)、MyBatis的映射文件、基于thymeleaf、JQuery、EasyUI的前端html代码。
- Workflow:
  1. 解析用户提供的模板代码,明确单表的结构和业务需求。
  2. 根据模板代码生成Spring Boot项目的目录结构
  3. 生成实体类(Pojo)、数据访问对象(Mapper)、服务层(Service)和控制器层(Controller)的代码。
  4. 编写MyBatis的映射文件和SQL语句,实现对单表的增删改查功能。
  5. 生成基于thymeleaf的前端html代码,列表页面List.html和编辑页面Form.html。
- Examples:
  - 例子1:模板代码为学生信息表(EL_STUDENT_INFO),建表sql为:
    ```sql
    -- Create table
    create table EL_STUDENT_INFO
    (
      id          VARCHAR2(36) not null,
      student_no  VARCHAR2(30) not null,
      name        VARCHAR2(50) not null,
      age         NUMBER(3),
      gender      VARCHAR2(10),
      class_name  VARCHAR2(50),
      create_by   VARCHAR2(50),
      create_time DATE default SYSDATE,
      update_by   VARCHAR2(50),
      update_time DATE default SYSDATE
    );
    -- Add comments to the table 
    comment on table EL_STUDENT_INFO
      is '学生信息表';
    -- Add comments to the columns 
    comment on column EL_STUDENT_INFO.student_no
      is '学号';
    comment on column EL_STUDENT_INFO.name
      is '姓名';
    comment on column EL_STUDENT_INFO.age
      is '年龄';
    comment on column EL_STUDENT_INFO.gender
      is '性别';
    comment on column EL_STUDENT_INFO.class_name
      is '班级';
    -- Create/Recreate indexes 
    create unique index IDX_EL_STUDENT_INFO_NO on   EL_STUDENT_INFO (STUDENT_NO);
    ```
    - 代码的目录及文件包括,其中moduleName为动态制定的模块名:
    ```
    main
     - java
        - com
            - neusoft
                - cps
                    - {moduleName}
                        - student
                            - controller
                                - ElStudentInfoController.java
                            - dao
                                - ElStudentInfoMapper.java
                            - pojo
                                - ElStudentInfoBean.java
                            - service
                                - ElStudentInfoService.java
                                - ElStudentInfoServiceImpl.java
     - resources
        - mapper
            - {moduleName}
                - student
                    - ElStudentInfoMapper.xml
        - templates
            - {moduleName}
                - student
                    - elStudentInfoForm.html
                    - elStudentInfoList.html
    ```
    - 生成的代码应包括:
        - Controller类:ElStudentInfoController.java
        ```java
        package com.neusoft.cps.{moduleName}.student.controller;

        import com.neusoft.cps.student.pojo.ElStudentInfoBean;
        import com.neusoft.cps.student.service.ElStudentInfoService;
        import com.neusoft.cps.common.controller.BaseController;
        import com.neusoft.cps.common.page.PageInfo;
        import com.neusoft.cps.common.pojo.Result;
        import com.neusoft.cps.common.tools.CameHumpUtils;
        import com.neusoft.cps.common.tools.ServletUtil;
        import lombok.extern.slf4j.Slf4j;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.stereotype.Controller;
        import org.springframework.ui.Model;
        import org.springframework.web.bind.annotation.*;

        import javax.servlet.http.HttpServletRequest;
        import java.util.List;
        import java.util.Map;

        /**
         * 学生信息表
         *
         * @author dai.wl
         * @date 2025-09-10 17:33:07
         */
        @Slf4j
        @Controller
        @RequestMapping("/student/elStudentInfo")
        public class ElStudentInfoController extends BaseController {
        
            @Autowired
            private ElStudentInfoService elStudentInfoService;

            /**
             * 列表页面
             * @param model
             * @return
             */
            @RequestMapping("/list")
            public String listPage(Model model) {
                return "student/elStudentInfoList";
            }

            /**
             * 列表页面数据表格
             * @param page
             * @param rows
             * @param sort
             * @param order
             * @param request
             * @return
             */
            @PostMapping(value = "/getDataList")
            @ResponseBody
            public Object getDataList(Integer page, Integer rows, String sort, String order,        HttpServletRequest request) {
                PageInfo<ElStudentInfoBean> pageInfo = new PageInfo<>(page, rows, CameHumpUtils.        camelToUnderline(sort), order);
                Map<String, Object> condition = ServletUtil.getParameters(request);
                List<ElStudentInfoBean> dataList = elStudentInfoService.getDataList(pageInfo,condition);
                pageInfo.setPageResult(dataList);
                return pageInfo;
            }

            /**
             * 表单页面(新增)
             * @param model
             * @return
             */
            @RequestMapping("/addForm")
            public String addPage(Model model) {
                model.addAttribute("bean",new ElStudentInfoBean());
                //标识为新增
                model.addAttribute("isUpdate","0");
                return "student/elStudentInfoForm";
            }

            /**
             * 表单页面(修改)
             * @param model
             * @param id
             * @return
             */
            @RequestMapping("/editForm/{id}")
            public String editPage(Model model,@PathVariable String id) {
                model.addAttribute("bean",elStudentInfoService.getBeanById(id));
                //标识为更新
                model.addAttribute("isUpdate","1");
                return "student/elStudentInfoForm";
            }

            /**
             * 保存功能
             * @param elStudentInfoBean 实体bean
             * @param isUpdate 0新增(数据库新增) 1修改(数据库更新)
             * @return
             */
            @PostMapping(value = "/save")
            @ResponseBody
            public Object save(ElStudentInfoBean elStudentInfoBean,String isUpdate) {
                Result result=new Result();
                try {
                    elStudentInfoService.save(elStudentInfoBean, isUpdate);
                    result.setSuccess();
                } catch (Exception e) {
                    log.error("异常原因:", e);
                    result.setFailure();
                    result.setMsg(e.getMessage());
                }
                return result;
            }

            /**
             * 删除选中记录
             * @param id 主键
             * @return
             */
            @PostMapping(value = "/deleteSelect")
            @ResponseBody
            public Object deleteSelect(String id) {
                Result result=new Result();
                try {
                        elStudentInfoService.deleteSelect(id);
                    result.setSuccess();
                } catch (Exception e) {
                    log.error("异常原因", e);
                    result.setFailure();
                    result.setMsg(e.getMessage());
                }
                return result;
            }

        }
        ```
      - dao接口:ElStudentInfoMapper.java
      ```java
        package com.neusoft.cps.{moduleName}.student.dao;

        import com.neusoft.cps.{moduleName}.student.pojo.ElStudentInfoBean;
        import com.neusoft.cps.common.mapper.BaseMapper;
        import com.neusoft.cps.common.page.PageInfo;
        import org.apache.ibatis.annotations.Param;

        import java.util.List;
        import java.util.Map;

        /**
         * 学生信息表
         *
         * @author dai.wl
         * @date 2025-09-10 17:33:07
         */
        public interface ElStudentInfoMapper extends BaseMapper<ElStudentInfoBean> {
            List<ElStudentInfoBean> getDataList(@Param("pageInfo") PageInfo pageInfo, @Param        ("condition") Map<String,Object> condition);
        }
      ```
      - pojo类:ElStudentInfoBean.java
      ```java
        package com.neusoft.cps.{moduleName}.student.pojo;

        import lombok.Data;
        import lombok.ToString;
        import org.apache.ibatis.type.JdbcType;
        import org.springframework.format.annotation.DateTimeFormat;
        import tk.mybatis.mapper.annotation.ColumnType;

        import javax.persistence.Column;
        import javax.persistence.Entity;
        import javax.persistence.Id;
        import javax.persistence.Table;
        import java.io.Serializable;
        import java.util.Date;

        /**
         * 学生信息表
         *
         * @author dai.wl
         * @date 2025-09-10 17:33:07
         */
        @Entity
        @Table( name = "EL_STUDENT_INFO" )
        @Data
        public class ElStudentInfoBean implements Serializable{
        	private static final long serialVersionUID = 1L;

        	/**
        	 * 主键ID
        	 */
        	@Id
        	@ColumnType(column ="ID",jdbcType= JdbcType.VARCHAR)
        	private String id;

        	/**
        	 * 学号
        	 */
        	@ColumnType(column ="STUDENT_NO",jdbcType= JdbcType.VARCHAR)
        	private String studentNo;

        	/**
        	 * 姓名
        	 */
        	@ColumnType(column ="NAME",jdbcType= JdbcType.VARCHAR)
        	private String name;

        	/**
        	 * 年龄
        	 */
        	@ColumnType(column ="AGE",jdbcType= JdbcType.NUMERIC)
        	private Integer age;

        	/**
        	 * 性别
        	 */
        	@ColumnType(column ="GENDER",jdbcType= JdbcType.VARCHAR)
        	private String gender;

        	/**
        	 * 班级
        	 */
        	@ColumnType(column ="CLASS_NAME",jdbcType= JdbcType.VARCHAR)
        	private String className;

        	/**
        	 * 创建人
        	 */
        	@ColumnType(column ="CREATE_BY",jdbcType= JdbcType.VARCHAR)
        	private String createBy;

        	/**
        	 * 创建时间
        	 */
        	@ColumnType(column ="CREATE_TIME",jdbcType= JdbcType.DATE)
        	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        	private Date createTime;

        	/**
        	 * 修改人
        	 */
        	@ColumnType(column ="UPDATE_BY",jdbcType= JdbcType.VARCHAR)
        	private String updateBy;

        	/**
        	 * 修改时间
        	 */
        	@ColumnType(column ="UPDATE_TIME",jdbcType= JdbcType.DATE)
        	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        	private Date updateTime;

        }

      ```
      - Service接口:ElStudentInfoService.java
      ```java
        package com.neusoft.cps.{moduleName}.student.service;

        import com.neusoft.cps.{moduleName}.student.pojo.ElStudentInfoBean;
        import com.neusoft.cps.common.page.PageInfo;
        import com.neusoft.cps.common.service.BaseService;

        import java.util.List;
        import java.util.Map;

        /**
         * 学生信息表
         *
         * @author dai.wl
         * @date 2025-09-10 17:33:07
         */
        public interface ElStudentInfoService extends BaseService<ElStudentInfoBean> {
            List<ElStudentInfoBean> getDataList(PageInfo pageInfo, Map<String,Object> condition);
            void save(ElStudentInfoBean elStudentInfoBean, String isUpdate);
            void deleteSelect(String id);
            ElStudentInfoBean getBeanById(String id);
        }

      ```
      - Service实现类:ElStudentInfoServiceImpl.java
      ```java
        package com.neusoft.cps.{moduleName}.student.service;

        import com.github.pagehelper.PageHelper;
        import com.neusoft.cps.{moduleName}.student.dao.ElStudentInfoMapper;
        import com.neusoft.cps.{moduleName}.student.pojo.ElStudentInfoBean;
        import com.neusoft.cps.common.page.PageInfo;
        import com.neusoft.cps.common.service.BaseServiceImpl;
        import lombok.extern.slf4j.Slf4j;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.stereotype.Service;
        
        import java.util.List;
        import java.util.Map;
        
        /**
         * 学生信息表
         *
         * @author dai.wl
         * @date 2025-09-10 17:33:07
         */
        @Slf4j
        @Service
        public class ElStudentInfoServiceImpl extends BaseServiceImpl<ElStudentInfoBean> implements         ElStudentInfoService {
        
            @Autowired
            private ElStudentInfoMapper elStudentInfoMapper;
        
            /**
             * 数据表格
             * @param pageInfo
             * @param condition
             * @return
             */
            @Override
            public List<ElStudentInfoBean> getDataList(PageInfo pageInfo, Map<String,Object> condition){
                PageHelper.startPage(pageInfo);
                return elStudentInfoMapper.getDataList(pageInfo,condition);
            }
        
            /**
             * 根据主键查询
             * @param id id
             * @return
             */
            @Override
            public ElStudentInfoBean getBeanById(String id){
                return elStudentInfoMapper.selectByPrimaryKey(id);
            }
        
            /**
             * 保存功能
             * @param elStudentInfoBean  实体bean
             * @param isUpdate 0新增(数据库新增) 1修改(数据库更新)
             * @return
             */
            @Override
            public void save(ElStudentInfoBean elStudentInfoBean, String isUpdate) {
                //判断页面标识
                if (isUpdate.equals("0")) {
                    elStudentInfoMapper.insertSelective(elStudentInfoBean);
                } else {
                    elStudentInfoMapper.updateByPrimaryKeySelective(elStudentInfoBean);
                }
            }
        
            /**
             * 删除选中记录
             * @param id 主键
             * @return
             */
            @Override
            public void deleteSelect(String id) {
                elStudentInfoMapper.deleteByPrimaryKey(id);
            }
        }
        
      ```
      - Mapper XML文件:ElStudentInfoMapper.xml
      ```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="com.neusoft.cps.student.dao.ElStudentInfoMapper">

        	<resultMap type="com.neusoft.cps.student.pojo.ElStudentInfoBean"        id="elStudentInfoResultMap">
        		<result property="id"  jdbcType="VARCHAR"  column="ID"  />
        		<result property="studentNo"  jdbcType="VARCHAR"  column="STUDENT_NO"  />
        		<result property="name"  jdbcType="VARCHAR"  column="NAME"  />
        		<result property="age"  jdbcType="NUMERIC"  column="AGE"  />
        		<result property="gender"  jdbcType="VARCHAR"  column="GENDER"  />
        		<result property="className"  jdbcType="VARCHAR"  column="CLASS_NAME"  />
        		<result property="createBy"  jdbcType="VARCHAR"  column="CREATE_BY"  />
        		<result property="createTime"  jdbcType="DATE"  column="CREATE_TIME"  />
        		<result property="updateBy"  jdbcType="VARCHAR"  column="UPDATE_BY"  />
        		<result property="updateTime"  jdbcType="DATE"  column="UPDATE_TIME"  />
        	</resultMap>

        	<sql id="baseColumn"> ID, STUDENT_NO, NAME, AGE, GENDER, CLASS_NAME, CREATE_BY,         CREATE_TIME, UPDATE_BY, UPDATE_TIME</sql>

        	<select id="getDataList" resultMap="elStudentInfoResultMap">
        		select <include refid="baseColumn"></include> from EL_STUDENT_INFO
        		<where>
        			<if test="condition.id!= null and condition.id!='' and condition.id!='null' ">
        				<![CDATA[ and ID=#{condition.id} ]]>
        			</if>
        			<if test="condition.studentNo!= null and condition.studentNo!='' and condition.     studentNo!='null' ">
        				<![CDATA[ and STUDENT_NO=#{condition.studentNo} ]]>
        			</if>
        			<if test="condition.name!= null and condition.name!='' and condition.name!='null' ">
        				<![CDATA[ and NAME=#{condition.name} ]]>
        			</if>
        			<if test="condition.age!= null and condition.age!='' and condition.age!='null' ">
        				<![CDATA[ and AGE=#{condition.age} ]]>
        			</if>
        			<if test="condition.gender!= null and condition.gender!='' and condition.       gender!='null' ">
        				<![CDATA[ and GENDER=#{condition.gender} ]]>
        			</if>
        			<if test="condition.className!= null and condition.className!='' and condition.     className!='null' ">
        				<![CDATA[ and CLASS_NAME=#{condition.className} ]]>
        			</if>
        			<if test="condition.createBy!= null and condition.createBy!='' and condition.       createBy!='null' ">
        				<![CDATA[ and CREATE_BY=#{condition.createBy} ]]>
        			</if>
        			<if test="condition.createTime!= null and condition.createTime!='' and condition.       createTime!='null' ">
        				<![CDATA[ and CREATE_TIME=to_date(#{condition.createTime}, 'YYYY-MM-DD      hh24:mi:ss') ]]>
        			</if>
        			<if test="condition.updateBy!= null and condition.updateBy!='' and condition.       updateBy!='null' ">
        				<![CDATA[ and UPDATE_BY=#{condition.updateBy} ]]>
        			</if>
        			<if test="condition.updateTime!= null and condition.updateTime!='' and condition.       updateTime!='null' ">
        				<![CDATA[ and UPDATE_TIME=to_date(#{condition.updateTime}, 'YYYY-MM-DD      hh24:mi:ss') ]]>
        			</if>
        		</where>
        		<if test="pageInfo.sort != null and pageInfo.sort != ''">
        			order by ${pageInfo.sort} ${pageInfo.order}
        		</if>
        		<if test="pageInfo.sort == null or pageInfo.sort == ''">
        			order by create_time desc
        		</if>
        	</select>

        </mapper>
      ```
      - 编辑页面 elStudentInfoForm.html
      ```html
        <html xmlns:th="http://www.thymeleaf.org">
        <head th:include="common :: commonHeader(~{::meta},~{::title},~{::link},~{::script})">
        	<meta charset="utf-8">>
        	<title>表单页面</title>
        	<link rel="stylesheet" type="text/css" th:href="@{/css/common/develop/cps_dev.css}">
        	<script>
        		let ctxPath = "[[@{/}]]";

        		$(function() {
        		});

        		function submitForm() {
        			let parmFilter = $("#dataForm").serializeObject();
        			if ($("#dataForm").form('enableValidation').form('validate')) {
        				loading();
        				$.ajax({
        					type: "POST",
        					url : ctxPath + "student/elStudentInfo/save",
        					data: parmFilter,
        					success: function(resJson) {
        						loadEnd();
        						if(resJson.code == 0) {
        							$.messager.alert('系统提示','保存成功','info',function(){
        								parent.$('#divDialog').window({
        									onClose:function(){
        										parent.searchFun();
        									}
        								}).window('close');
        							});
        						} else {
        							$.messager.alert('系统提示',resJson.msg,'error');
        						}

        					}
        				});
        			}
        		}

        		function cancel() {
        			parent.$('#divDialog').window().window('close');
        		}
        	</script>
        </head>

        <body style="background: #fff;">

        	<div class="pagebox" style="width: 650px;">

        		<div class="cbox">

        			<div class="easyui-panel" style="padding: 15px; width: 100%;">
        				<form id="dataForm" class="easyui-form" method="post"       data-options="novalidate:true">
        					<input type="hidden" id="isUpdate" name="isUpdate" th:value="${isUpdate}">
        					<div style="width: 600px;">
        							<ul class="flist">
        							< style="width: 46%"><input class="easyui-textbox" name="id"    id="id" th:value="${bean.id}" data-options="label:'主键ID:',  labelAlign: 'right', prompt:'请录入主键ID'" style="width: 95%;"></       li>
        							<li style="width: 46%"><input class="easyui-textbox"        name="studentNo" id="studentNo" th:value="${bean.studentNo}"    data-options="label:'学号:',labelAlign: 'right', prompt:'请录入学号      '" style="width: 95%;"></li>
        							</ul>
        							<ul class="flist">
        							<li style="width: 46%"><input class="easyui-textbox" name="name"        id="name" th:value="${bean.name}" data-options="label:'姓名:',  labelAlign: 'right', prompt:'请录入姓名'" style="width: 95%;"></li>
        							<li style="width: 46%"><input class="easyui-textbox" name="age"         id="age" th:value="${bean.age}" data-options="label:'年龄:',        labelAlign: 'right', prompt:'请录入年龄'" style="width: 95%;"></li>
        							</ul>
        							<ul class="flist">
        							<li style="width: 46%"><input class="easyui-textbox" name="gender"      id="gender" th:value="${bean.gender}" data-options="label:'性别:',      labelAlign: 'right', prompt:'请录入性别'" style="width: 95%;"></li>
        							<li style="width: 46%"><input class="easyui-textbox"        name="className" id="className" th:value="${bean.className}"    data-options="label:'班级:',labelAlign: 'right', prompt:'请录入班级      '" style="width: 95%;"></li>
        							</ul>
        							<ul class="flist">
        							<li style="width: 46%"><input class="easyui-textbox"        name="createBy" id="createBy" th:value="${bean.createBy}"   data-options="label:'创建人:',labelAlign: 'right', prompt:'请录入创建        人'" style="width: 95%;"></li>
        							<li style="width: 46%"><input class="easyui-datetimebox"        name="createTime" id="createTime" th:value="${bean.createTime}"     data-options="label:'创建时间:',labelAlign: 'right', prompt:'请录入创    建时间'" style="width: 95%;"></li>
        							</ul>
        							<ul class="flist">
        							<li style="width: 46%"><input class="easyui-textbox"        name="updateBy" id="updateBy" th:value="${bean.updateBy}"   data-options="label:'修改人:',labelAlign: 'right', prompt:'请录入修改        人'" style="width: 95%;"></li>
        							<li style="width: 46%"><input class="easyui-datetimebox"        name="updateTime" id="updateTime" th:value="${bean.updateTime}"     data-options="label:'修改时间:',labelAlign: 'right', prompt:'请录入修    改时间'" style="width: 95%;"></li>
        							</ul>
        					</div>
        				</form>
        			</div>
        		</div>

        		<div class="cbox"
        			 style="padding: 5px 0 5px 0; position: fixed; bottom: 0px; left: 0px; width: 100%;         background: #e3e6e8;">
        			<div style="text-align: center;">
        				<a href="javascript:void(0)" class="easyui-linkbutton c1"
        				   onclick="cancel()"
        				   style="width: 80px;">取消</a>
        				<a href="javascript:void(0)" class="easyui-linkbutton c1"
        				   onclick="submitForm()" style="width: 80px">保存</a>
        			</div>
        		</div>

        	</div>
        </body>
        </html>
      ```
      - 列表页面 elStudentInfoList.html
      ```html
        <html xmlns:th="http://www.thymeleaf.org">
        <head th:include="common :: commonHeader(~{::meta},~{::title},~{::link},~{::script})">
            <meta charset="utf-8">>
            <title> 学生信息表列表页面</title>
            <link rel="stylesheet" type="text/css" th:href="@{/css/common/develop/cps_dev.css}">
            <script type="text/javascript">
                let ctxPath = "[[@{/}]]";
                $(function(){
                    $('#dataTable').datagrid({
                        url:ctxPath + 'student/elStudentInfo/getDataList',
                        queryParams: $("#searchForm").serializeObject(),
                        fit: true,
                        striped: true,
                        rownumbers: true,
                        border: false,
                        pagination: true,
                        singleSelect: true,
                        nowrap: true, // false:内容自动折行显示
                        pageSize: 20,
                        pageList: [10, 20, 50, 100, 200],
                        columns: [
                            // 这里注意格式,要有换行,这个注释要保留
                            [
                                {field: '', width: 100, align: 'center', checkbox: true},
                                {title: '主键ID', field: 'id', width: "20%", align: 'left',halign:      'center'},
                                {title: '学号', field: 'studentNo', width: "20%", align: 'left',halign:         'center'},
                                {title: '姓名', field: 'name', width: "20%", align: 'left',halign:      'center'},
                                {title: '年龄', field: 'age', width: "20%", align: 'left',halign:       'center'},
                                {title: '性别', field: 'gender', width: "20%", align: 'left',halign:        'center'},
                                {title: '班级', field: 'className', width: "20%", align: 'left',halign:         'center'},
                                {title: '创建人', field: 'createBy', width: "20%", align: 'left',       halign: 'center'},
                                {title: '创建时间', field: 'createTime', width: "20%", align: 'left',       halign: 'center'},
                                {title: '修改人', field: 'updateBy', width: "20%", align: 'left',       halign: 'center'},
                                {title: '修改时间', field: 'updateTime', width: "20%", align: 'left',       halign: 'center'},
                            ]
                        ],
                        toolbar: [{
                            text: '新增',
                            iconCls: 'icon-tianjia',
                            handler: function() {
                                add();
                            }
                        }, '-', {
                            text: '修改',
                            iconCls: 'icon-bianji',
                            handler: function() {
                                edit();
                            }
                        }, '-', {
                            text: '删除',
                            iconCls: 'iconCls-bin',
                            handler: function() {
                                del();
                            }
                        }]
                    }).datagrid("initToolbarBtnRole");//按钮权限;
                });

                //查询
                function searchFun() {
                    if ($("#searchForm").form('enableValidation').form('validate')) {
                        var parmFilter = $("#searchForm").serializeObject();
                        $('#dataTable').datagrid('load', parmFilter);
                    }
                }

                //重置按钮
                function cleanFun() {
                    $('#searchForm').form('clear');
                }

                function showMore(){
                    $("#showMore").hide();
                    $("#hideMore").show();
                    $(".more").css("display","block");
                    $('#reportPanel').layout('panel', 'north').panel('resize',{height:210});
                    $.parser.parse();
                }

                function hideMore(){
                    $("#showMore").show();
                    $("#hideMore").hide();
                    $(".more").css("display","none");
                    $('#reportPanel').layout('panel', 'north').panel('resize',{height:125});
                    $.parser.parse();
                }

                function add() {
                    $('#iframeDialogSelect').attr("src", ctxPath + "student/elStudentInfo/addForm");
                    $('#divDialog').window('open');
                }

                function edit() {
                    let selectedRow = $('#dataTable').datagrid("getSelected");
                    if(selectedRow == null) {
                        $.messager.alert('系统提示',"请选择数据",'error');
                        return;
                    }
                    $('#iframeDialogSelect').attr("src", ctxPath + "student/elStudentInfo/editForm/" +          selectedRow.id);
                    $('#divDialog').window('open');
                }

                function del() {
                    let selectedRow = $('#dataTable').datagrid("getSelected");
                    if(selectedRow == null) {
                        $.messager.alert('系统提示',"请选择数据",'error');
                        return;
                    }
                    $.messager.confirm("确认", "请确认将此记录删除?", function(r) {
                        if (r) {
                            loading();
                            $.ajax({
                                type: "POST",
                                url: ctxPath + "student/elStudentInfo/deleteSelect",
                                data: {id:selectedRow.id},
                                success: function(resJson) {
                                    loadEnd();
                                    if(resJson.code == 0) {
                                        $.messager.alert('系统提示','删除成功','info',function(){
                                            searchFun();
                                        });
                                    } else {
                                        $.messager.alert('系统提示',resJson.msg,'error');
                                    }

                                }
                            });
                        }
                    });
                }
            </script>
        </head>
        <body>
        <div class="easyui-layout" data-options="fit:true" id="reportPanel">
            <div data-options="region:'north'" style="height: 125px;" id="criteria">
                <form class="form-horizontal" role="form" id="searchForm"       data-options="novalidate:true">
                    <div class="easyui-panel" style="padding: 10px; width: 100%;"  id="asd">
                        <div id="tb">
                            <ul class="flist">
                                <li style="width: 32%"><input class="easyui-textbox" name="id" id="id"      data-options="label:'主键ID:',labelAlign: 'right', prompt:'请录入主键       ID'" style="width: 95%;"></li>
                                <li style="width: 32%"><input class="easyui-textbox" name="studentNo"       id="studentNo" data-options="label:'学号:',labelAlign: 'right', prompt:'    请录入学号'" style="width: 95%;"></li>
                                <li style="width: 32%"><input class="easyui-textbox" name="name"        id="name" data-options="label:'姓名:',labelAlign: 'right', prompt:'请录     入姓名'" style="width: 95%;"></li>
                            </ul>
                            <ul class="flist">
                                <li style="width: 32%"><input class="easyui-textbox" name="age"         id="age" data-options="label:'年龄:',labelAlign: 'right', prompt:'请录入        年龄'" style="width: 95%;"></li>
                                <li style="width: 32%"><input class="easyui-textbox" name="gender"      id="gender" data-options="label:'性别:',labelAlign: 'right', prompt:'请     录入性别'" style="width: 95%;"></li>
                                <li style="width: 32%"><input class="easyui-textbox" name="className"       id="className" data-options="label:'班级:',labelAlign: 'right', prompt:'    请录入班级'" style="width: 95%;"></li>
                            </ul>
                            <ul class="flist">
                                <li style="width: 32%"><input class="easyui-textbox" name="createBy"        id="createBy" data-options="label:'创建人:',labelAlign: 'right',    prompt:'请录入创建人'" style="width: 95%;"></li>
                                <li style="width: 32%"><input class="easyui-datetimebox"        name="createTime" id="createTime" data-options="label:'创建时间:',  labelAlign: 'right', prompt:'请录入创建时间'" style="width: 95%;"></li>
                                <li style="width: 32%"><input class="easyui-textbox" name="updateBy"        id="updateBy" data-options="label:'修改人:',labelAlign: 'right',    prompt:'请录入修改人'" style="width: 95%;"></li>
                            </ul>
                            <ul class="flist">
                                <li style="width: 32%"><input class="easyui-datetimebox"        name="updateTime" id="updateTime" data-options="label:'修改时间:',  labelAlign: 'right', prompt:'请录入修改时间'" style="width: 95%;"></li>
                                    <li style="width: 32%">
                                        <a href="#" class="easyui-linkbutton c1" onclick="searchFun()">     查询</a>
                                        <a href="#" class="easyui-linkbutton c1" onclick="cleanFun()"       data-options="iconCls:'icon-shuaxin'">重置</a>
                                        <a href="#" class="easyui-linkbutton listmore c1"       onclick="showMore()" id="showMore"      data-options="iconCls:'icon-androidmorevertical'">更多</a>
                                        <a href="#" class="easyui-linkbutton listmore c1"       style="display:none;" onclick="hideMore()" id="hideMore"    data-options="iconCls:'icon-androidmorevertical'">收起</a>
                                    </li>
                            </ul>
                        </div>
                    </div>
                </form>
            </div>
            <div data-options="region:'center'" id="datagrid">
                <table id="dataTable" class="easyui-datagrid" title="数据列表">
                </table>
            </div>
        </div>

        <div id="divDialog" class="easyui-window"
             data-options="closed:true,closable:true,collapsible:false,minimizable:false,       maximizable:false,modal:true,title:'新增信息'"
             style="width: 700px; height: 400px;">
            < id="iframeDialogSelect" frameborder="0" scrolling="yes"	width="100%" height="98%"></        iframe>
        </div>

        </body>
        </html>
      ```
- Initialization: 如果已接收到用户提供的信息,立即开始生成目录和代码文件,如果用户未提供信息,提示用户需要提供建表sql语句以及moduleName,提示信息:"1.请提供建表sql语句,以参考文件形式 2.请提供moduleName,以moduleName=xxx形式"。

运行过程

输入信息

本案例中使用ClaudeSonnet4模型,根据提示词输入moduleName和建表sql语句
在这里插入图片描述
其中建表sql语句为oracle常规建表sql,内容如下:

-- Create table
create table EL_RECORD_INFO
(
  id                       VARCHAR2(32) not null,
  business_no              VARCHAR2(50),
  project_no               VARCHAR2(20),
  customer_no              VARCHAR2(20),
  customer_name            VARCHAR2(500),
  account_composition      VARCHAR2(500),
  amount                   NUMBER,
  record_type              VARCHAR2(2),
  accounting_period        DATE,
  company_segment          VARCHAR2(10),
  currency                 VARCHAR2(20),
  cash_flow_code           VARCHAR2(10),
  cash_flow_name           VARCHAR2(500),
  journal_head_description VARCHAR2(240),
  status                   VARCHAR2(1),
  create_by                VARCHAR2(32),
  create_time              DATE,
  update_by                VARCHAR2(32),
  update_time              DATE
);
-- Add comments to the table 
comment on table EL_RECORD_INFO
  is '凭证信息表';
-- Add comments to the columns 
comment on column EL_RECORD_INFO.id
  is '主键ID';
comment on column EL_RECORD_INFO.business_no
  is '业务编号';
comment on column EL_RECORD_INFO.project_no
  is '项目号';
comment on column EL_RECORD_INFO.customer_no
  is '客户号';
comment on column EL_RECORD_INFO.customer_name
  is '客户名称';
comment on column EL_RECORD_INFO.account_composition
  is '账户组合';
comment on column EL_RECORD_INFO.amount
  is '金额';
comment on column EL_RECORD_INFO.record_type
  is '凭证类型:DR-借方,CR-贷方';
comment on column EL_RECORD_INFO.accounting_period
  is '会计期';
comment on column EL_RECORD_INFO.company_segment
  is '公司段';
comment on column EL_RECORD_INFO.currency
  is '币种';
comment on column EL_RECORD_INFO.cash_flow_code
  is '现金流代码';
comment on column EL_RECORD_INFO.cash_flow_name
  is '现金流名称';
comment on column EL_RECORD_INFO.journal_head_description
  is '日记账头描述';
comment on column EL_RECORD_INFO.status
  is '状态:0-未过账,1-已过账';
comment on column EL_RECORD_INFO.create_by
  is '创建人';
comment on column EL_RECORD_INFO.create_time
  is '创建时间';
comment on column EL_RECORD_INFO.update_by
  is '更新人';
comment on column EL_RECORD_INFO.update_time
  is '更新时间';
-- Create/Recreate primary, unique and foreign key constraints 
alter table EL_RECORD_INFO
  add constraint PK_RECORD_INFO primary key (ID);

输入信息

在vscode中,copilot chat能够在工程目录中生成文件,具体输入如下:

Perfect! I have both the SQL table definition for EL_RECORD_INFO and the module name erplite. Let me generate a complete Spring Boot CRUD code structure following the template instructions.

Starting (2/7) Generate entity/model class

Now I'll create the complete directory structure and generate all the necessary files based on the EL_RECORD_INFO table and the erplite module name.

First, let me create the directory structure:

Created controller

Created dao

Created pojo

Created service

Created recordinfo

Created recordinfo

Now, let me generate the entity/model class:

Created ElRecordInfoBean.java

The errors are expected since this is just a code generation task without the actual project dependencies. Let me continue with the DAO interface:

Starting (3/7) Generate DAO/Repository layer

Created ElRecordInfoMapper.java

Now let me create the Service interface:

Starting (4/7) Generate service layer

Created ElRecordInfoService.java

Now let me create the Service implementation:

Created ElRecordInfoServiceImpl.java

Now let me create the Controller:

Starting (5/7) Generate controller/API layer

Created ElRecordInfoController.java

Now let me create the MyBatis mapper XML file:

Starting (6/7) Generate MyBatis mapper XML

Created ElRecordInfoMapper.xml

Now let me create the HTML templates. First, the form page:

Starting (7/7) Generate frontend templates

Created elRecordInfoForm.html

Now let me create the list page:

Created elRecordInfoList.html

Completed (7/7) Generate frontend templates

Perfect! I have successfully generated a complete Spring Boot CRUD code structure for the EL_RECORD_INFO table with the module name erplite. Here's a summary of what was created:

Generated Directory Structure:
main
 - java
    - com
        - neusoft
            - cps
                - erplite
                    - recordinfo
                        - controller
                            - ElRecordInfoController.java
                        - dao
                            - ElRecordInfoMapper.java
                        - pojo
                            - ElRecordInfoBean.java
                        - service
                            - ElRecordInfoService.java
                            - ElRecordInfoServiceImpl.java
 - resources
    - mapper
        - erplite
            - recordinfo
                - ElRecordInfoMapper.xml
    - templates
        - erplite
            - recordinfo
                - elRecordInfoForm.html
                - elRecordInfoList.html


Generated Files Include:
1.Entity Class (ElRecordInfoBean.java):
Complete POJO with all fields from the EL_RECORD_INFO table
Proper JPA annotations and MyBatis column mappings
Lombok annotations for getters/setters
Proper data types (BigDecimal for amount, Date for date fields)

2.DAO Interface (ElRecordInfoMapper.java):
Extends BaseMapper for common CRUD operations
Custom method for paginated data retrieval

3.Service Layer:
Interface (ElRecordInfoService.java) with business methods
Implementation (ElRecordInfoServiceImpl.java) with full CRUD operations
PageHelper integration for pagination

4.Controller (ElRecordInfoController.java):
REST endpoints for list, add, edit, save, and delete operations
Proper request mappings for the erplite module
JSON response handling with Result wrapper

5.MyBatis Mapper XML (ElRecordInfoMapper.xml):
Complete result map for all table columns
Dynamic SQL query with conditional filtering
Proper Oracle SQL syntax with date handling

6.Frontend Templates:
List Page (elRecordInfoList.html): EasyUI datagrid with search functionality, toolbar buttons, and proper column formatting
Form Page (elRecordInfoForm.html): Complete form with all fields, proper input types (numberbox for amount, combobox for dropdown fields, datebox for dates)

Key Features:
Complete CRUD Operations: Create, Read, Update, Delete
Pagination: Integrated with PageHelper
Search Functionality: Dynamic filtering on multiple fields
Proper Data Types: BigDecimal for monetary amounts, proper date handling
Dropdown Lists: For record type (DR/CR) and status (0/1)
Validation: Form validation and error handling
Responsive UI: EasyUI-based interface with proper styling
Oracle Database: Optimized SQL queries for Oracle with proper date functions

The generated code follows the Spring Boot + MyBatis + Thymeleaf + EasyUI architecture as specified in the template, providing a complete solution for managing voucher/record information in an ERP system.

生成代码如下详见绑定资源

总结

  1. 生成代码放入工程中能够正常启动操作,大模型的理解需求与实现编码的能力超出预期。
  2. 虽然结果代码能够正常使用,但原生成功能采用Velocity模板只需要几秒钟,使用大模型则需要几分钟,显然性价比非常低,同时开发复杂提示词消耗时间也较长。
  3. 使用大模型编程,可能采用类似零样本提示这种简单提示的实际价值更高,通过不断迭代的方式或者人工修改的方式,更适合现阶段的开发任务。
  4. 大模型的使用通常有额度限制,使用大模型开发一些工具来简化问题,而不是直接实现需求,可能更适合。例如需要批量生成一些SQL,不是让大模型直接处理输出sql,而是根据业务逻辑让大模型开发一个批量生成sql的工具,运行工具来实现生成批量SQL。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐