Mall4j
gz-yami/mall4j
Mall4j 开源版现有功能副驾驶:本地启动、mall4v/mall4m/mall4uni、商品/SKU、购物车、下单支付、订单发货、会员、运费、权限、部署排查。适用于下载 mall4j / yami-shop 后按现有功能使用或二次开发;不要编造开源版没有的能力。
为 mfish-nocode-pro 项目生成标准增删改查(CRUD)代码,包括 Entity、Req、Mapper、Service、ServiceImpl、Controller 六层结构。当用户说"帮我生成增删改查"、"新增一个模块"、"生成CRUD代码"时使用此 skill。
$ npx skills add mfish-qf/mfish-nocode --skill crud-generator -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install mfish-qf/mfish-nocode crud-generator --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/mfish-qf/mfish-nocode.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.codex/skills/crud-generator .claude/skills/crud-generator && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "crud-generator" agent skill from https://github.com/mfish-qf/mfish-nocode/tree/main/.codex/skills/crud-generator into .claude/skills/crud-generator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "crud-generator", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/mfish-qf/mfish-nocode/tree/main/.codex/skills/crud-generatorType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add mfish-qf/mfish-nocode --skill crud-generator -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install mfish-qf/mfish-nocode crud-generator --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mfish-qf/mfish-nocode.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.codex/skills/crud-generator .agents/skills/crud-generator && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "crud-generator" agent skill from https://github.com/mfish-qf/mfish-nocode/tree/main/.codex/skills/crud-generator into .agents/skills/crud-generator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "crud-generator", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mfish-qf/mfish-nocode --skill crud-generator -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install mfish-qf/mfish-nocode crud-generator --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mfish-qf/mfish-nocode.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.codex/skills/crud-generator .cursor/skills/crud-generator && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "crud-generator" agent skill from https://github.com/mfish-qf/mfish-nocode/tree/main/.codex/skills/crud-generator into .cursor/skills/crud-generator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "crud-generator", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/mfish-qf/mfish-nocode.git --path .codex/skills/crud-generator--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add mfish-qf/mfish-nocode --skill crud-generator -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install mfish-qf/mfish-nocode crud-generator --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mfish-qf/mfish-nocode.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.codex/skills/crud-generator .gemini/skills/crud-generator && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "crud-generator" agent skill from https://github.com/mfish-qf/mfish-nocode/tree/main/.codex/skills/crud-generator into .gemini/skills/crud-generator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "crud-generator", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install mfish-qf/mfish-nocode crud-generatorInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add mfish-qf/mfish-nocode --skill crud-generator -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/mfish-qf/mfish-nocode.git skills-src && mkdir -p .github/skills && cp -r skills-src/.codex/skills/crud-generator .github/skills/crud-generator && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "crud-generator" agent skill from https://github.com/mfish-qf/mfish-nocode/tree/main/.codex/skills/crud-generator into .github/skills/crud-generator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "crud-generator", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mfish-qf/mfish-nocode --skill crud-generator -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install mfish-qf/mfish-nocode crud-generator --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mfish-qf/mfish-nocode.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.codex/skills/crud-generator .opencode/skills/crud-generator && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "crud-generator" agent skill from https://github.com/mfish-qf/mfish-nocode/tree/main/.codex/skills/crud-generator into .opencode/skills/crud-generator/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "crud-generator", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
crud-generator为 mfish-nocode-pro 项目生成标准增删改查(CRUD)代码,包括 Entity、Req、Mapper、Service、ServiceImpl、Controller 六层结构。当用户说"帮我生成增删改查"、"新增一个模块"、"生成CRUD代码"时使用此 skill。
Crud Generator is an agent skill from mfish-qf/mfish-nocode. 为 mfish-nocode-pro 项目生成标准增删改查(CRUD)代码,包括 Entity、Req、Mapper、Service、ServiceImpl、Controller 六层结构。当用户说"帮我生成增删改查"、"新增一个模块"、"生成CRUD代码"时使用此 skill。
Its SKILL.md is about 4.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Backend & APIs. It works with Spring Boot. The repository describes itself as: 摸鱼低代码平台,是一款致力于让开发像摸鱼一样轻松的低代码/无代码平台。首创微服务单体服务一体化架构。基于SpringBoot4、Spring Ai、Vue3等最新前后端技术栈。已用于多个成熟项目,学习和实战两不误。我们希望打破技术门槛,让程序员和非程序员都能快速构建业务系统,提升效率,释放创造力。 The licence is Apache-2.0.
6 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 664fc6b. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are java and xml).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Crud Generator loads about 4.6k tokens when it runs. Until then it costs about 39 tokens; SKILL.md has 379 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from mfish-qf/mfish-nocode at commit 664fc6b, republished under its Apache-2.0 licence (© mfish-qf). 379 words, ~4,601 tokens.
.claude/skills/crud-generator/SKILL.md (or your agent's skills folder).mf-api/mf-xxx-api/
└── src/main/java/cn/com/mfish/xxx/api/entity/ # API 层实体(跨服务共享)
mf-business/mf-xxx/
└── src/main/java/cn/com/mfish/xxx/
├── controller/ # Controller 层
├── entity/ # 业务实体
├── mapper/ # Mapper 接口
├── req/ # 请求参数类
└── service/
├── XxxService.java
└── impl/XxxServiceImpl.javaBaseMapper<T>、ServiceImpl<M,T>、IService<T>)PageHelper.startPage(pageNum, pageSize))@RequiresPermissions("模块:功能:操作")(insert/update/delete/query/export)@Log(title = "xxx-操作", operateType = OperateType.INSERT/UPDATE/DELETE)Result<T>、Result<PageResult<T>>、Result<Boolean>@Tag、@Operation、@Parameter@TableId(type = IdType.ASSIGN_UUID);数值自增 → @TableId(type = IdType.AUTO)BaseEntity<T>(含 id、createBy、createTime、updateBy、updateTime),T 与 ID 类型一致ExcelUtils.write(fileName, list)(来自 cn.com.mfish.common.core.utils.excel.ExcelUtils)StringUtils.isEmpty()(来自 cn.com.mfish.common.core.utils.StringUtils)@Schema 注解(类级和字段级)询问用户(如未提供):
sys:order)cn.com.mfish.sys)按以下顺序生成,文件路径基于 mf-business/mf-xxx/src/main/java/ 目录。
package {包路径}.entity;
import cn.com.mfish.common.core.entity.BaseEntity;
import cn.idev.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
// 有 Date 类型字段时引入:
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
// 有 BigDecimal 类型字段时引入:
import java.math.BigDecimal;
/**
* @description: {中文名称}
* @author: mfish
* @date: {当前日期}
* @version: V2.4.1
*/
@Data
@TableName("{表名}")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "{表名}对象 {中文名称}")
public class {类名} extends BaseEntity<String> {
// String UUID 主键:
@ExcelProperty("唯一ID")
@Schema(description = "唯一ID")
@TableId(type = IdType.ASSIGN_UUID)
@Accessors(chain = true)
private String id;
// 数值自增主键(替换上面的 id 声明):
// @TableId(type = IdType.AUTO)
// @Accessors(chain = true)
// private Integer id;
// 普通字段:
@ExcelProperty("{字段注释}")
@Schema(description = "{字段注释}")
private {类型} {字段名};
// 日期字段(DATE 类型):
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@ExcelProperty("{字段注释}")
@Schema(description = "{字段注释}")
private Date {字段名};
// 日期时间字段(DATETIME 类型):
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ExcelProperty("{字段注释}")
@Schema(description = "{字段注释}")
private Date {字段名};
}package {包路径}.req;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
// 有 Date 类型搜索字段时引入:
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @description: {中文名称}
* @author: mfish
* @date: {当前日期}
* @version: V2.4.1
*/
@Data
@Accessors(chain = true)
@Schema(description = "{中文名称}请求参数")
public class Req{类名} {
// 普通搜索字段:
@Schema(description = "{字段注释}")
private {类型} {字段名};
// DATE 类型搜索字段:
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@Schema(description = "{字段注释}")
private Date {字段名};
// DATETIME 类型搜索字段:
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "{字段注释}")
private Date {字段名};
}package {包路径}.mapper;
import {包路径}.entity.{类名};
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @description: {中文名称}
* @author: mfish
* @date: {当前日期}
* @version: V2.4.1
*/
public interface {类名}Mapper extends BaseMapper<{类名}> {
// 如有复杂查询,声明自定义方法,并对应 XML
}对应 XML 文件(resources/mapper/{类名}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="{包路径}.mapper.{类名}Mapper">
</mapper>package {包路径}.service;
import cn.com.mfish.common.core.web.PageResult;
import cn.com.mfish.common.core.web.ReqPage;
import cn.com.mfish.common.core.web.Result;
import {包路径}.entity.{类名};
import {包路径}.req.Req{类名};
import com.baomidou.mybatisplus.extension.service.IService;
import java.io.IOException;
/**
* @description: {中文名称}
* @author: mfish
* @date: {当前日期}
* @version: V2.4.1
*/
public interface {类名}Service extends IService<{类名}> {
/** 分页列表查询 */
Result<PageResult<{类名}>> queryPageList(Req{类名} req{类名}, ReqPage reqPage);
/** 添加 */
Result<{类名}> add({类名} {变量名});
/** 编辑 */
Result<{类名}> edit({类名} {变量名});
/** 通过id删除 */
Result<Boolean> delete(String id);
/** 批量删除(ids 逗号分隔) */
Result<Boolean> deleteBatch(String ids);
/** 通过id查询 */
Result<{类名}> queryById(String id);
/** 导出 */
void export(Req{类名} req{类名}, ReqPage reqPage) throws IOException;
}若 ID 为数值型(如
Integer),将String id改为对应类型。
package {包路径}.service.impl;
import cn.com.mfish.common.core.utils.StringUtils;
import cn.com.mfish.common.core.utils.excel.ExcelUtils;
import cn.com.mfish.common.core.web.PageResult;
import cn.com.mfish.common.core.web.ReqPage;
import cn.com.mfish.common.core.web.Result;
import {包路径}.entity.{类名};
import {包路径}.mapper.{类名}Mapper;
import {包路径}.req.Req{类名};
import {包路径}.service.{类名}Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* @description: {中文名称}
* @author: mfish
* @date: {当前日期}
* @version: V2.4.1
*/
@Service
public class {类名}ServiceImpl extends ServiceImpl<{类名}Mapper, {类名}> implements {类名}Service {
@Override
public Result<PageResult<{类名}>> queryPageList(Req{类名} req{类名}, ReqPage reqPage) {
return Result.ok(new PageResult<>(queryList(req{类名}, reqPage)), "{中文名称}-查询成功!");
}
private List<{类名}> queryList(Req{类名} req{类名}, ReqPage reqPage) {
PageHelper.startPage(reqPage.getPageNum(), reqPage.getPageSize());
LambdaQueryWrapper<{类名}> lambdaQueryWrapper = new LambdaQueryWrapper<{类名}>()
// String 类型字段用 StringUtils.isEmpty 判断:
.like(!StringUtils.isEmpty(req{类名}.get{字段}()), {类名}::get{字段}, req{类名}.get{字段}())
// 非 String 类型字段用 null != xxx 判断:
.eq(null != req{类名}.get{字段}(), {类名}::get{字段}, req{类名}.get{字段}());
return list(lambdaQueryWrapper);
}
@Override
public Result<{类名}> add({类名} {变量名}) {
if (save({变量名})) {
return Result.ok({变量名}, "{中文名称}-添加成功!");
}
return Result.fail({变量名}, "错误:{中文名称}-添加失败!");
}
@Override
public Result<{类名}> edit({类名} {变量名}) {
if (updateById({变量名})) {
return Result.ok({变量名}, "{中文名称}-编辑成功!");
}
return Result.fail({变量名}, "错误:{中文名称}-编辑失败!");
}
@Override
public Result<Boolean> delete(String id) {
if (removeById(id)) {
return Result.ok(true, "{中文名称}-删除成功!");
}
return Result.fail(false, "错误:{中文名称}-删除失败!");
}
@Override
public Result<Boolean> deleteBatch(String ids) {
if (removeByIds(Arrays.asList(ids.split(",")))) {
return Result.ok(true, "{中文名称}-批量删除成功!");
}
return Result.fail(false, "错误:{中文名称}-批量删除失败!");
}
@Override
public Result<{类名}> queryById(String id) {
{类名} {变量名} = getById(id);
return Result.ok({变量名}, "{中文名称}-查询成功!");
}
@Override
public void export(Req{类名} req{类名}, ReqPage reqPage) throws IOException {
// swagger 调用有问题,使用 postman 测试
ExcelUtils.write("{中文名称}_" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()), queryList(req{类名}, reqPage));
}
}搜索条件 LambdaQueryWrapper 规则:
String 类型字段 → .like(!StringUtils.isEmpty(req.getXxx()), Entity::getXxx, req.getXxx())(模糊) 或 .eq(!StringUtils.isEmpty(req.getXxx()), Entity::getXxx, req.getXxx())(精确)String 类型字段 → .eq(null != req.getXxx(), Entity::getXxx, req.getXxx())package {包路径}.controller;
import cn.com.mfish.common.core.enums.OperateType;
import cn.com.mfish.common.core.web.PageResult;
import cn.com.mfish.common.core.web.ReqPage;
import cn.com.mfish.common.core.web.Result;
import cn.com.mfish.common.log.annotation.Log;
import cn.com.mfish.common.oauth.annotation.RequiresPermissions;
import {包路径}.entity.{类名};
import {包路径}.req.Req{类名};
import {包路径}.service.{类名}Service;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
/**
* @description: {中文名称}
* @author: mfish
* @date: {当前日期}
* @version: V2.4.1
*/
@Slf4j
@Tag(name = "{中文名称}")
@RestController
@RequestMapping("/{变量名}")
public class {类名}Controller {
@Resource
private {类名}Service {变量名}Service;
/**
* 分页列表查询
*/
@Operation(summary = "{中文名称}-分页列表查询", description = "{中文名称}-分页列表查询")
@GetMapping
@RequiresPermissions("{权限前缀}:query")
// 需要数据权限时加:@DataScope(table = "{表名}", type = DataScopeType.Tenant)
public Result<PageResult<{类名}>> queryPageList(Req{类名} req{类名}, ReqPage reqPage) {
return {变量名}Service.queryPageList(req{类名}, reqPage);
}
/**
* 添加
*/
@Log(title = "{中文名称}-添加", operateType = OperateType.INSERT)
@Operation(summary = "{中文名称}-添加")
@PostMapping
@RequiresPermissions("{权限前缀}:insert")
public Result<{类名}> add(@RequestBody {类名} {变量名}) {
return {变量名}Service.add({变量名});
}
/**
* 编辑
*/
@Log(title = "{中文名称}-编辑", operateType = OperateType.UPDATE)
@Operation(summary = "{中文名称}-编辑")
@PutMapping
@RequiresPermissions("{权限前缀}:update")
public Result<{类名}> edit(@RequestBody {类名} {变量名}) {
return {变量名}Service.edit({变量名});
}
/**
* 通过id删除
*/
@Log(title = "{中文名称}-通过id删除", operateType = OperateType.DELETE)
@Operation(summary = "{中文名称}-通过id删除")
@DeleteMapping("/{id}")
@RequiresPermissions("{权限前缀}:delete")
public Result<Boolean> delete(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) {
return {变量名}Service.delete(id);
}
/**
* 批量删除
*/
@Log(title = "{中文名称}-批量删除", operateType = OperateType.DELETE)
@Operation(summary = "{中文名称}-批量删除")
@DeleteMapping("/batch/{ids}")
@RequiresPermissions("{权限前缀}:delete")
public Result<Boolean> deleteBatch(@Parameter(name = "ids", description = "唯一性ID") @PathVariable String ids) {
return {变量名}Service.deleteBatch(ids);
}
/**
* 通过id查询
*/
@Operation(summary = "{中文名称}-通过id查询")
@GetMapping("/{id}")
@RequiresPermissions("{权限前缀}:query")
// 需要数据权限时加:@DataScope(table = "{表名}", type = DataScopeType.Tenant)
public Result<{类名}> queryById(@Parameter(name = "id", description = "唯一性ID") @PathVariable String id) {
return {变量名}Service.queryById(id);
}
/**
* 导出
*/
@Operation(summary = "导出{中文名称}", description = "导出{中文名称}")
@GetMapping("/export")
@RequiresPermissions("{权限前缀}:export")
public void export(Req{类名} req{类名}, ReqPage reqPage) throws IOException {
{变量名}Service.export(req{类名}, reqPage);
}
}Controller 核心原则:Controller 只做路由转发,所有业务逻辑在 Service 中实现,Controller 方法体直接
return xxxService.方法()。
| 占位符 | 说明 | 示例 |
|---|---|---|
{类名} | PascalCase 类名 | SysOrder |
{变量名} | camelCase 变量名(也用作 @RequestMapping 路径) | sysOrder |
{表名} | 数据库表名(下划线) | sys_order |
{权限前缀} | 权限标识符({apiPrefix}:{变量名}) | sys:sysOrder |
{包路径} | Java 包名 | cn.com.mfish.sys |
return xxxService.方法() 即可,业务实现全在 ServiceImplverifyXxx() 私有方法,并在 add/edit 中调用@Transactional 处理级联操作resources/mapper/ 下创建对应 XML 文件mf-business/mf-xxx 子模块mf-api/mf-xxx-api 模块delFlag 字段,删除时 updateById(new Xxx().setId(id).setDelFlag(1)),查询时 .eq(Xxx::getDelFlag, 0)tenantId 字段,Controller 的写操作加 @DataScope(table="表名", type=DataScopeType.Tenant) 注解,Service 中用 AuthInfoUtils.getCurrentTenantId() 写入,修改时 setTenantId(null) 避免覆盖BaseEntity<Integer>,@TableId(type = IdType.AUTO),Service/Controller 中 id 参数类型相应改为 Integer@Schema 注解,包括:@Schema(description = "描述信息", name = "类名")@Schema(description = "字段描述")MyRuntimeException 处理import cn.com.mfish.common.core.exception.MyRuntimeException;// 数据不存在校验
if (entity == null) {
throw new MyRuntimeException("错误:记录不存在!");
}
// 重复性校验
if (baseMapper.exists(new LambdaQueryWrapper<Entity>()
.eq(Entity::getField, value))) {
throw new MyRuntimeException("错误:已存在,不能重复提交!");
}
// 状态校验
if (!"active".equals(entity.getStatus())) {
throw new MyRuntimeException("错误:记录状态不正确!");
}"错误:" 开头,便于前端统一处理和识别RuntimeException 或其他自定义异常return Result.fail(false, "错误:配置不正确," + e.getMessage()); ❌return Result.fail(false, "错误:配置不正确,请检查配置是否完整且符合规范"); ✅log.error() 记录到日志文件中,便于开发人员排查try {
// 业务逻辑
someOperation();
} catch (Exception e) {
// 详细异常信息记录到日志
log.error("操作失败:{}", e.getMessage(), e);
// 返回给前端的是友好的提示信息
return Result.fail(false, "错误:操作失败,请检查配置是否正确");
}数据权限通过 @DataScope / @DataScopes 注解在 Controller 查询方法 上声明,框架自动在 SQL 中追加过滤条件。
重要约束
- 注解只能用于查询方法,不能用于新增/修改/删除
- 注解加在 Controller 层,不在 Service 层
- 表中须有对应的权限字段:租户
tenant_id、用户user_id、角色role_id、组织org_id
| 类型 | 说明 | 表中需要字段 |
|---|---|---|
DataScopeType.Tenant | 按当前租户过滤 | tenant_id |
DataScopeType.User | 按当前用户过滤 | user_id |
DataScopeType.Role | 按当前角色过滤 | role_id |
DataScopeType.Org | 按当前组织及下级过滤 | org_id |
DataScopeType.None | 不过滤(默认) | — |
1. 单表租户过滤(最常用)
@GetMapping
@RequiresPermissions("{权限前缀}:query")
@DataScope(table = "{表名}", type = DataScopeType.Tenant)
public Result<PageResult<{类名}>> queryPageList(Req{类名} req, ReqPage reqPage) { ... }2. 单表组织过滤
@DataScope(table = "{表名}", type = DataScopeType.Org)3. 固定角色值过滤(指定具体角色编码)
@DataScope(table = "{表名}", type = DataScopeType.Role, values = {"manage", "superAdmin"})4. 排除公开数据(满足排除条件的记录不被过滤,始终可查)
@DataScope(table = "{表名}", type = DataScopeType.Tenant, excludes = "is_public=1")5. 忽略条件(优先级最高,满足时其他权限条件全部失效)
// 变量值从 ServletRequest.getParameter 中取,为空时不使用忽略条件
@DataScope(table = "{表名}", ignores = "share_token=#{_shareToken} and share_end_time>=now()")6. 多表组合权限(使用 @DataScopes)
import cn.com.mfish.common.oauth.annotation.DataScopes;
@DataScopes({
@DataScope(table = "{主表名}", type = DataScopeType.Tenant),
@DataScope(table = "{关联表名}", type = DataScopeType.Tenant, excludes = "is_public=1")
})7. 租户 + 角色组合过滤
@DataScopes({
@DataScope(table = "{表名}", type = DataScopeType.Tenant),
@DataScope(table = "{表名}", type = DataScopeType.Role, values = {"manage", "superAdmin"})
})import cn.com.mfish.common.oauth.annotation.DataScope;
import cn.com.mfish.common.oauth.annotation.DataScopes; // 多条件时引入
import cn.com.mfish.common.oauth.common.DataScopeType;© mfish-qf, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .codex/skills/crud-generator of mfish-qf/mfish-nocode.
Open the folder on GitHubat commit 664fc6b
Crud Generator next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Crud Generator this skillmfish-qf/mfish-nocode | 747 | — | ~4.6k | Automated safety check: Pass | Apache-2.0 | |
| Mall4jgz-yami/mall4j | 5.3k | — | ~640 | Automated safety check: Notes | AGPL-3.0 | |
| Spring Bootpiomin/claude-ai-spring-boot | 1.3k | — | ~2k | Automated safety check: Pass | Apache-2.0 | |
| Dr Jskilljdubois/dr-jskill | 342 | — | ~4.6k | Automated safety check: Notes | Apache-2.0 | |
| Gsgo-spring/go-spring | 1.8k | — | ~1.1k | Automated safety check: Pass | Apache-2.0 | |
| WxJava Integration Guidebinarywang/WxJava | 33k | — | ~123 | Automated safety check: Pass | Apache-2.0 |
gz-yami/mall4j
Mall4j 开源版现有功能副驾驶:本地启动、mall4v/mall4m/mall4uni、商品/SKU、购物车、下单支付、订单发货、会员、运费、权限、部署排查。适用于下载 mall4j / yami-shop 后按现有功能使用或二次开发;不要编造开源版没有的能力。
piomin/claude-ai-spring-boot
Spring Boot 3.x development - REST APIs, JPA, Security, Testing, and Cloud-native patterns.
jdubois/dr-jskill
Creates Java + Spring Boot projects: Web applications, full-stack apps with Vue.js or Angular or React or vanilla JS, PostgreSQL, REST APIs, and Docker.
go-spring/go-spring
Go-Spring 项目研发托管入口:一句话诉求经 规划(Plan)→ 执行(Execute)→ 交付(Settle)循环,从工具集(起骨架/加接口/重生成/接组件/补测试)中选取组合并落地。在 Go-Spring 项目中开展任一研发任务时触发;由 Plan 判定是否接管,超范围时放手。
binarywang/WxJava
Plans a WxJava setup for Java, Spring Boot or Solon projects that call WeChat services, from module and BOM choice to config and a minimal working call.
apache/grails-core
Guides building Grails web applications and REST APIs with GORM, controllers, services, views, plugins and Spock and Geb testing.
mfish-qf/mfish-nocode
为 mfish-nocode-pro 项目前端(Vue3 + TypeScript)生成标准增删改查页面代码,包括 Model、API、data、index.vue、Modal、ViewModal 六个文件。当用户说"帮我生成前端增删改查"、"新增前端页面"、"生成前端CRUD"时使用此 skill。
mfish-qf/mfish-nocode
为 mfish-nocode-pro 项目集成 Flowable 工作流审批能力,包括注册 FlowKey、实体审批状态字段、Service 启动/撤回流程、Controller 审批回调接口、Feign 回调接口注册五个步骤的完整代码模板。当用户说"带工作流审批"、"发布审核流程"、"集成工作流"、"审批回调"时使用此 skill。
Works with
Categories
为 mfish-nocode-pro 项目生成标准增删改查(CRUD)代码,包括 Entity、Req、Mapper、Service、ServiceImpl、Controller 六层结构。当用户说"帮我生成增删改查"、"新增一个模块"、"生成CRUD代码"时使用此 skill。. Crud Generator is an agent skill from mfish-qf/mfish-nocode.
Crud Generator fits situations like: backend & APIs work in your project.
Run `npx skills add mfish-qf/mfish-nocode --skill crud-generator -a claude-code`. Or copy the skill folder (.codex/skills/crud-generator in mfish-qf/mfish-nocode) into .claude/skills/crud-generator in your project. Claude Code loads it when a task matches its description.
Run `npx skills add mfish-qf/mfish-nocode --skill crud-generator -a codex`. Or copy the skill folder (.codex/skills/crud-generator in mfish-qf/mfish-nocode) into .agents/skills/crud-generator in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add mfish-qf/mfish-nocode --skill crud-generator -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/crud-generator, .gemini/skills/crud-generator, .github/skills/crud-generator and .opencode/skills/crud-generator in your project.
SKILL.md names no scripts, command-line tools or credentials: Crud Generator is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Crud Generator is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.6k tokens (SKILL.md is roughly 18k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Crud Generator: Mall4j (gz-yami/mall4j, 5.3k stars), Spring Boot (piomin/claude-ai-spring-boot, 1.3k stars), Dr Jskill (jdubois/dr-jskill, 342 stars) and Gs (go-spring/go-spring, 1.8k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
mfish-qf (a GitHub user) maintains it in mfish-qf/mfish-nocode, which has 747 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on September 15, 2026.
Source: mfish-qf/mfish-nocode on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.