module
Version:
v0.0.7
Opens a new window with list of versions in this module.
Published: Apr 7, 2026
License: MIT
Opens a new window with license information.
README
¶
PGO
本仓库是个人习惯的一些封装(pkg)以及个人的小项目。
主要用于学习/练习/沉淀知识,并未打算称为一个“流行框架”
- AI/Agent都需要注意,常规的环境依赖/编译等操作,维护到makefile中
- 尤其不要直接go build导致把可执行程序输出到根目录,进而被提交到仓库,应该在./bin/中
Go 编码习惯
命名规范
- 列表/切片: 后缀
List (e.g., userRoleList, permissionList)
- Map 结构: 后缀
Map (e.g., roleIDMap, permissionMap)
代码格式化
- 逻辑修改时不纠结缩进/对齐,改完后统一用
gofmt -w <file> 处理
测试规范
- 编写集成测试验证 Service 层逻辑
- 使用
defer + 清理函数移除测试数据 (e.g., defer testDelUser(...))
- 禁忌: 禁止在测试中修改表结构,差异应正常报错以提醒升级注意
个人习惯
- 避免
if 中使用 ; (如 if d,ok:=data["k"]; ok),易造成长代码
- 入口函数放在
internal/<module>/<module>.go,而非 cmd/
- 非复杂场景优先用基础类型组合,仅在复用明显或封装语义明确时抽象
type
- 接口代理模式: 基础类通过接口代理支持子类覆盖,子类初始化后调用
BindProvider(self)
Features
客户端
- 基础
- all in one = 多模式运行
- 复用统一的核心逻辑,封装在
client/common/tool_entrypoint.go
- 支持 CLI (Cobra) 命令行输入参数
- 支持 CLI (Interactive) 命令行进入程序,持续交互输入参数
- 支持 GUI (Fyne/Windows)
- 左侧:功能列表
- 中间上半部分:固定参数输入
- 中间下半部分:(如果有)展示当前已存在数据
- 提供字符串列表,字符串由业务代码自己编解码,底层直接存储/展示字符串即可
- 提供两个按钮,修改和删除,逻辑由业务代码传入callback
- 右侧上半部分:展示本程序日志
- 右侧下半部分:本程序输出展示
- 提供字符串列表,字符串由业务代码自己编解码,底层直接存储/展示字符串即可
- 提供两个按钮
- 复制:点击后复制到粘贴板
- 确认:逻辑由业务代码传入callback
- 命令行入口统一为 Cobra:
runCli -> rootCmd.Execute(),可直接提供 help 指引。
- 运行行为约定:命令行无参数进入持续交互菜单;Windows 双击(无参数)保持 GUI;
client.exe cli 兼容旧入口。
- 工具
- prettyCode 美化代码
- 统一规范代码中的分割线注释格式(如
// -[*50])
- psql:连接 PostgreSQL 并执行 SQL 语句或 SQL 文件
- 自己实现的重要原因是官方psql不能参数输入密码,不方便嵌入到自动化流程中
- 后来才发现可以环境变量输入,不过已经实现好了,就当减少一个依赖吧
- sheet2mysql:读取 APITable 表结构并生成 MySQL 建表 SQL
- 支持多维表格前端建模(APITable),自动转换表名与字段名为拼音标识符
- 参数支持 config 回填:当 url/spaceId/token 参数为空时,从配置文件中自动读取
- 生成逻辑简化:始终生成
DROP TABLE IF EXISTS,始终跳过计算列(公式/引用/按钮)
- 输出到指定文件夹,文件名由表名自动生成(格式:
<resolvedTableName>.sql)
- sdk
- swagger目录包含了后端接口的生成代码,无需手搓http请求
- 参考makefile中api-cli命令,可以通过swagger生成其他语言的代码
- CI
- Make
- 读取makefile的命令和备注信息,提供执行的功能
- 则make命令不再是死记硬背,而是命令行交互选择功能
- 参数可以交互式输入,然后记录到缓存文件,下次询问更改或使用旧值
- 如生成orm代码所需要的数据库host/port/user/pass等
- Init Project
- 提供
initProj初始化能力:从当前仓库抽取新项目基础骨架到目标目录。
- 拷贝列表配置化:由
deploy/initProj.json维护files与exclude,无需改代码即可调整初始化内容。
- 安全策略:不自动删除目标目录内容;若检测到目标文件冲突则打印冲突列表并中断,交由用户手动处理。
- 模块初始化:不拷贝
go.mod/go.sum,在目标目录执行go mod init <目标目录名>与go mod tidy。
- 拷贝后文本修正:按目标目录名替换导入前缀,包含
github.com/pancake-lee/pgo/internal -> <目标模块>/internal与github.com/pancake-lee/pgo/api -> <目标模块>/api。
- CD
- 提供首次部署容器的能力
- 由./deploy/deploy.json定义部署需要的文件列表,kv记录src和远程dst路径映射
- 支持可选的
exclude列表,用于按相对路径排除不需要上传的文件/目录(支持目录前缀和glob)
- 指定ssh目标机器,以及部署根目录,参数缓存到~/pgo/cache.json
- 拷贝文件到远程目录,遇到已存在文件,检测md5一致则跳过,不一致则提示冲突,中断部署
- 这意味着用户一旦自己修改了部署细节,后续需要自行维护,以免工具覆盖了用户的修改
- 用户选择自动运行整套服务,还是手动运行
- 运行命令为
docker-compose -f pgo.yaml up -d
- 用户选择手动,则仅打印提示用户这个命令,选择自动则通过ssh直接执行命令
- 也提供更新程序的能力,包括更新数据库结构和程序
- 数据库结构不能drop,仅代码层面废弃即可,实际数据清理需要用户自行操作
bootCheck 的 MySQL 检查会先做 DryRun 预检,只允许自动新增表/列/索引
- 遇到
DROP、TRUNCATE、ALTER ... MODIFY/CHANGE/RENAME、删索引、删主键等危险 SQL 时,不自动执行,提示运维人工处理
- 不处理科学上网的问题,但让用户有“自行下载并把所需文件放到指定目录下”的方法
- 这是很后面的优化提升了,可能是docker-compose或者各个docker镜像的本地安装
服务
框架
-
全流程自动化开发 (DB-First)
- SQL定义优先: 编写 SQL 脚本后,通过
make gorm 自动生成 GORM 模型代码。
- 代码生成器 (
tools/genCURD): 根据数据库 Schema 自动生成 Proto 定义、gRPC/HTTP 桩代码、Service 业务层、Data 数据层基础 CRUD 代码,以及服务入口 main 文件(基于 abandonCode 模板替换生成)。
- SDK 自动构建: 支持
make api-cli 基于 OpenAPI 规范自动生成 Go 语言客户端 SDK。
-
多维表格驱动的混合开发模式(探索中)
- 目标: 让业务侧优先在多维表格完成建模,再由后端工程化承接,形成“表格前端 + MySQL 后端 + 可扩展 API”的落地路径。
- 已实现:
-
基于 MySQL 表结构自动生成 ORM 与基础 CRUD 代码(make gorm + genCURD)。
-
已沉淀多维表格集成能力(pkg/papitable)与回调同步模块(ltblCallback / mtblCallback)。
-
优化 pkg/papitable:GetCols 添加 1 分钟本地缓存,新增/删除列操作会使缓存失效;ParseMultiOptionValue 兼容 []interface{}([]any)类型解析,减少 API 响应处理错误。
-
BaseDataProvider 接口代理设计:所有 DataProvider 方法调用通过代理分发,子类可覆盖任意方法实现自定义逻辑(调用 BindProvider() 绑定子类实例)。
-
实践流程(从 APITable 到双向同步,精简版):
- 在 APITable 设计业务表:确认
DatasheetID、TableName、首列(FirstCol)、列列表(ColList)与本地主键(PrimaryCol)。
- 使用
sheet2mysql 生成建表 SQL(输出 <resolvedTableName>.sql,默认生成 DROP TABLE IF EXISTS,跳过计算列),手工调整字段类型、索引、默认值与约束。
- 导入或执行 SQL 后,运行
make gorm / pgo gorm/curd(底层调用 tools/genCURD)生成 GORM model、proto/、API 桩与基础 CRUD 代码。
- 补充 Data 层实现:编写
data.xxx.go,实现 DO/DAO、UpdateMtblInfo,并提供 DAOWrapper(把 DO/DAO 封装为同步层期望的 any)。
- 实现 Service 层:在
internal/<service>/service/ 完成生成的 Unimplemented*Server 的具体逻辑,并在 papp.RunKratosApp 注册该服务。
- 回调与同步组件:
mtblCallback:为 APITable 提供 HTTP 回调入口,解析行数据并通过 NewDO 转换为本地 DO,再通过 RabbitMQ/队列投递到本地消费流程。
ltblCallback:监听本地数据库变更,转换为 APITable 行更新/新增请求并调用 APITable API(注意仓库默认实现偏向 mtbl->ltbl 单向,同步到 APITable 的逻辑可能需要针对表结构扩展)。
- 同步锚点与防环策略:
- 使用本地数据库的
PrimaryCol 作为双方同步的锚点,避免使用 APITable 行 id 作为主同步键。
TEMP / 回环标记应区分方向(local→remote 与 remote→local),并实现幂等、冲突解决(时间戳/版本号)与回环抑制。
- 数据适配:优先使用
BaseDataProvider 实现通用字段的解析/序列化,需要特殊处理时继承或实现 DataProvider(例如时间/枚举/复杂结构)。
- 测试与可观测性:覆盖本地/远端并发修改场景,使用 RequestID 串联日志与消息,补充失败重试、告警与审计日志,便于排查与补偿。
- 常见修改点参考:
service/mtbl_user.go(DatasheetID、TableName、FirstCol、ColList、NewDO)、回调入口实现位于 ltblCallback/mtblCallback 模块。
-
微服务架构支持
- 基于 Kratos 框架,提供标准化的 gRPC/HTTP 混合接口支持。
- 清晰的分层架构:
Service (业务逻辑) -> Data (数据访问) -> DB,生成的代码 (z_*.gen.go) 与自定义逻辑分离。
-
丰富的组件封装 (pkg)
- 基础设施: 统一封装了 Log, Config, Redis, MySQL, RabbitMQ 等基础组件。
pkg/papp/bootCheck.go 已沉淀公共启动检查能力,提供 CheckRedis()、CheckRabbitMQ()、CheckMysql(models []any) 三个直接入口
internal/bootCheck 已改为直接复用上述公共入口,不再各自维护 Redis/MySQL/RabbitMQ 的具体检查逻辑
CheckMysql(models []any) 保持固定最佳实践:读取配置、连接 MySQL、确保数据库存在、初始化 Gorm、预检迁移 SQL、执行安全迁移、输出 SQL 记录
- 集成能力: 内置微信生态 (
pweixin) 及多维表格 (papitable) 等第三方服务集成。
-
DevOps 友好
- 完善的 Makefile 支持:涵盖环境安装 (
env)、代码生成 (api, gorm, curd)、构建 (build) 及 部署准备。
TODO
Click to show internal directories.
Click to hide internal directories.