Compare commits

117 Commits

Author SHA1 Message Date
osindex
bf5bcd3eeb Merge f254132e18 into 1688aaf371 2025-09-19 21:00:07 +08:00
osi
f254132e18 🎨 🔥 🚑 集成前端代码的&兼容容器化部署插件的插件改造&提供了一个新的轮播图插件 2025-09-19 20:46:30 +08:00
osi
edb673ee34 🎨 去除mysql硬编码 方便切换pgsql 2025-09-19 19:40:00 +08:00
孟帅
1688aaf371 Merge pull request #192 from entheosl/feature/entheosl-change
修复模版生成model.ts表字段如果有默认值不带引号的问题
2025-09-01 10:47:44 +08:00
lzl
ae540c6bfe 修复模版生成model.ts默认值不带引号 2025-08-18 14:35:59 +08:00
孟帅
9f1c1ce031 Merge pull request #188 from rxrddd/v2.0
fix:处理分页结构体PerPage的json别名pageSize 无法被验证导致 pageSize传0也能正常访问而导致数据库无分页拉爆…
2025-07-17 12:28:08 +08:00
zjy
dd5b2b660e fix:处理分页结构体PerPage的json别名pageSize 无法被验证导致 pageSize传0也能正常访问而导致数据库无分页拉爆数据库的问题 2025-07-17 12:09:44 +08:00
zjy
207bba186e fix:处理分页结构体PerPage的json别名pageSize 无法被验证导致 pageSize传0也能正常访问而导致数据库无分页拉爆数据库的问题 2025-07-17 12:06:12 +08:00
孟帅
42d5500941 发布v2.17.8版本,更新内容请查看:https://github.com/bufanyun/hotgo/blob/v2.0/docs/guide-zh-CN/start-update-log.md 2025-07-13 18:57:52 +08:00
孟帅
20a9e38fa8 Merge pull request #185 from rxrddd/v2.0
doc: 优化docsify文档体验
2025-07-13 18:42:08 +08:00
zjy
35c6387b4b doc: 优化docsify文档体验
1.调整在docsify下代码块乱掉的问题
2.新增docsify下的go/yaml/vue/json/sql代码高亮插件
3.新增docsify下的mermaid图解析插件
2025-07-13 18:29:28 +08:00
孟帅
17daeb9121 refactor 调整数据库初始数据,替换默认图片资源域名 2025-07-13 17:44:31 +08:00
孟帅
5efae235e4 Merge pull request #184 from zhangshican/v2.0
修复权限分配任无权限操作bug
2025-07-13 00:04:43 +08:00
ss
ef05cc946f Merge branch 'v2.0' of https://github.com/zhangshican/hotgo into v2.0
* 'v2.0' of https://github.com/zhangshican/hotgo:
  修复 goframe 配置读写分离后,获取不到数据库链接
  修复 多处基础错误 现在可以直接使用gf run .\main.go 运行程序
  恢复配置文件api  接口地址
  后台界面
  后台菜单搜索功能

# Conflicts:
#	server/internal/controller/admin/common/ems.go
#	server/internal/controller/admin/common/sms.go
2025-07-13 00:00:52 +08:00
孟帅
1017a92c29 Merge pull request #182 from 0x76long/2.0-bugfix
修复 goframe 配置读写分离后,获取不到数据库链接
2025-07-12 14:29:12 +08:00
孟帅
1a5f77ffb4 Merge pull request #181 from user1121114685/v2.0
修复 多处基础错误 现在可以直接使用gf run .\main.go 运行程序
2025-07-12 14:28:43 +08:00
孟帅
9f2038cc4b Merge pull request #180 from aklivecai/v2.0
vue后台更新
2025-07-12 14:27:36 +08:00
ss
be6c13e781 修复拉取新项目报错bug
修复权限分配任无权限操作bug
2025-07-12 13:52:15 +08:00
vlong
6da8cafb6f 修复 goframe 配置读写分离后,获取不到数据库链接 2025-07-10 18:18:10 +08:00
联盟少侠
d79138d278 修复 多处基础错误 现在可以直接使用gf run .\main.go 运行程序 2025-07-09 13:16:46 +08:00
tak
3146dc13ed 恢复配置文件api 接口地址 2025-07-04 14:30:01 +08:00
tak
6f8761756a 后台界面
1. 演示帐号动态配置
2. vite 动态加载异常问题修复
2025-07-04 14:17:03 +08:00
tak
c9af5ae093 后台菜单搜索功能 2025-07-04 14:15:45 +08:00
孟帅
6fcfa61dff Merge pull request #177 from tomtomtomtony/feat-supportpg-tom-20250626
提供支持pg的sql
2025-07-01 00:08:26 +08:00
孟帅
1564e8605d Merge pull request #176 from Yazzyk/v2.0
处理了 2 个漏洞,并增加验证码方式选择
2025-07-01 00:07:53 +08:00
孟帅
cce0476bb9 Merge pull request #170 from zhangshican/v2.0
优化代码风格
2025-07-01 00:05:57 +08:00
tom
4d5ae6907a 提供支持pg的sql 2025-06-26 19:28:54 +08:00
yazzyk
ae3ad53806 修复高危漏洞:token抓包暴露 2025-06-25 18:03:43 +08:00
yazzyk
d807084d55 数据库添加验证码方式 2025-06-25 17:50:48 +08:00
yazzyk
99967d35e5 处理低危漏洞:用户枚举 2025-06-25 17:43:38 +08:00
yazzyk
6cb0fcfd93 添加验证码选择,可自由选择字符或计算 2025-06-25 17:33:28 +08:00
yazzyk
c377b6b92d 添加验证码选择,可以自己选择使用算数或字符串 2025-06-25 17:31:43 +08:00
孟帅
56efd5d206 Merge pull request #172 from rnicrosoft-studio/v2.0
Add github pages for docs
2025-05-24 12:13:01 +08:00
wohenbushuang
9da8eb264d fix(docs): sidebar 2025-05-10 05:55:59 +00:00
wohenbushuang
416ae4c27f feat(docs): add github pages using docsify 2025-05-09 22:02:36 +00:00
ss
19c0c0c1bc 系统大量出现where("id",xx) fields("user_id") 固定字符串,修改按照统一规范使用dao.xxx.Columns().xxx 2025-04-21 17:46:06 +08:00
孟帅
0c5b27d864 fix: 修复GetComplexMemberIds组件查询外的WhereIn字段错误问题 2025-03-23 17:04:43 +08:00
孟帅
62af998991 发布v2.16.10版本,更新内容请查看:https://github.com/bufanyun/hotgo/blob/v2.0/docs/guide-zh-CN/start-update-log.md 2025-03-22 20:23:27 +08:00
孟帅
5301bedff2 Merge pull request #160 from hailaz/v2.0
fix: 修复日志记录时明文显示密码的问题
2025-01-09 18:38:07 +08:00
hailaz
b48079bbdc fix: 修复日志记录时明文显示密码的问题 2025-01-08 21:25:31 +08:00
孟帅
2fd3854aeb 发布v2.15.11版本,更新内容请查看:https://github.com/bufanyun/hotgo/blob/v2.0/docs/guide-zh-CN/start-update-log.md 2024-11-27 18:44:19 +08:00
孟帅
6254505a7d Merge pull request #153 from aklivecai/v2.0
bug修复,curd唯一校验
2024-11-25 23:01:07 +08:00
tak
07df5a20e1 Merge branch 'v2.0' of github.com:aklivecai/hotgo into v2.0 2024-10-19 12:17:41 +08:00
tak
8e7992d7f4 bug修复,curd唯一校验
新增编辑, 字段`唯一`校验勾选后, 查询条件默认id,模型可能主键不是id
2024-10-19 12:17:25 +08:00
孟帅
86805ba047 Merge pull request #146 from LUDA0831/dev
fix: 修复lodash-es类型错误
2024-10-01 10:51:59 +08:00
SpiderMan
abfd6a056f feat: 修复lodash-es类型错误
项目里使用的是lodash-es,开发类型安装的为@types/lodash
2024-09-28 17:38:46 +08:00
孟帅
e364aa4a4f Merge pull request #145 from LUDA0831/dev
fix: 修复eslint报错
2024-09-28 10:12:43 +08:00
SpiderMan
52c2538a66 fix: 修复eslint报错 2024-09-28 09:55:01 +08:00
孟帅
f010ef07ac Merge pull request #144 from LUDA0831/v2.0
fix: 修复使用pnpm build打包报错
2024-09-27 19:41:56 +08:00
SpiderMan
dbdfdaae93 fix: 修复使用pnpm build打包报错 2024-09-26 17:28:56 +08:00
孟帅
a2c6a8ac16 fix 修复树表生成选项 2024-09-16 19:45:19 +08:00
孟帅
1055e44b2b Merge pull request #138 from aklivecai/v2.0
CURD 优化
2024-09-16 12:15:32 +08:00
tak
01f194d7ef CURD 优化
1. `Delete`删除方法, 新增: `Unscoped()`, 已经有删除时间了, 不需要更新编辑时间, 新建时间,编辑时间, 删除时间独立
2. `List`列表方法, JOSN 字段搜索问题处理
3. 模版新增 `in.In` 参数, 在模版中使用`in`参数,如: 插件目录名称
2024-09-16 12:05:22 +08:00
孟帅
52263c608f Merge pull request #137 from apefuu/v2.0
Upgrade web Toolchain and update web docs
2024-09-16 11:29:27 +08:00
Lingjie Fu
ffce905371 Merge pull request #1
v2.0-refactoring
2024-09-06 14:41:14 +08:00
Lingjie Fu
ef8d0bde5b Merge branch 'bufanyun:v2.0' into v2.0-refactoring 2024-09-06 12:02:22 +08:00
apefuu
98233d7deb Upgrade Docs 2024-09-06 12:01:30 +08:00
apefuu
1c8dd5e6d2 Merge branch 'v2.0' into v2.0-refactoring 2024-09-03 21:06:10 +08:00
apefuu
0cba31c885 Upgrade all web dependencies and use pnpm instead of yarn 2024-09-03 21:05:17 +08:00
孟帅
f497fb7a1a fix 修复插件安装卸载时事务不生效问题 2024-09-03 17:55:26 +08:00
孟帅
f5e448a999 Merge pull request #135 from apefuu/v2.0-refactoring
Upgrade all libs and cleanup code
2024-09-03 17:44:07 +08:00
apefuu
a94c6745ea Upgrade all libs and cleanup code 2024-09-03 14:22:04 +08:00
孟帅
6caa644259 fix 修复潜在关键词查询sql注入漏洞 2024-09-02 14:03:50 +08:00
孟帅
37b2b82130 fix 优化deleted_by字段的crud生成功能
fix 优化数据`hotgo.sql`文件字段默认值和初始数据
fix 修复web端字典空数据可能引发的潜在问题
2024-08-27 19:24:28 +08:00
孟帅
33e5252516 up 更新web端依赖包版本,修复潜在错误 2024-08-27 17:37:23 +08:00
孟帅
6cf80ed0fe Merge pull request #131 from swift-fs/v2.0
refactor: 前台api/api目录按照gf gen ctrl规范编码,可以使用gf工具链快速生成控制器相关代码,也可手动编写
2024-08-27 10:17:46 +08:00
mh-swift
fa87584316 fix: 兼容hostname+host请求头 2024-08-23 12:23:06 +08:00
孟帅
194e86ea05 Merge pull request #133 from hailaz/v2.0
fix: 修复数据树为空时,无法显示的问题
2024-08-22 22:01:05 +08:00
hailaz
cc13a16e90 fix: 修复数据树为空时,无法显示的问题 2024-08-15 20:35:20 +08:00
mh-swift
d9b57e6c62 refactor(api/api):符合gf gen ctrl规范 2024-08-14 16:50:31 +08:00
mh-swift
09026a606b fix(controller/site): 获取配置接口在非浏览器环境中无法解析hostname问题修复 2024-07-30 18:36:11 +08:00
孟帅
950637a976 Merge pull request #127 from swift-fs/v2.0-fix
refactor: 代码优化相关
2024-07-30 10:16:20 +08:00
mh-swift
06fed9025f fix: 部门列表当前无分页,去除表格分页组件 2024-07-29 17:50:14 +08:00
mh-swift
7eb32efa92 refactor(admin): 去除硬编码,简化用户列表查询 2024-07-29 17:49:45 +08:00
mh-swift
2e322e2606 refactor(captcha): 优化验证代码 2024-07-29 13:56:35 +08:00
孟帅
804d5d5e59 perf 改进表格图片、文件展示组件使用方式,减少冗余
fix 修复生成树表时选项加载错误
chore 清理生成代码cli包中的测试文件
2024-07-25 16:47:59 +08:00
孟帅
a37d088360 发布v2.15.7版本,更新内容请查看:https://github.com/bufanyun/hotgo/tree/v2.0/docs/guide-zh-CN/addon-version-upgrade.md 2024-07-21 22:21:02 +08:00
孟帅
7d8330f72f Merge pull request #124 from dark-wind/patch-1
Update start-deploy.md
2024-07-19 19:54:53 +08:00
孟帅
b33591e8bd Merge pull request #122 from swift-fs/v2.0-fix
golangci/hotgo.sql fix
2024-07-19 18:37:05 +08:00
孟帅
71e2176a35 Merge pull request #117 from maxbad/v2.0
fix #100
2024-07-19 18:35:00 +08:00
shadow
733313d309 Update start-deploy.md
不切换回server目录下的话,gf命令不生效
2024-07-16 18:57:03 +08:00
mh-swift
9feb4c2022 perf: 数据库表名硬编码替换 2024-07-13 18:26:37 +08:00
mh-swift
f33e36803a fix(logic/sys): syncUpdate方法内短变量声明导致外部err被屏蔽 2024-07-11 18:50:45 +08:00
mh-swift
e914f1db33 perf: 避免连点enter登录导致异常登录日志触发 2024-07-11 17:10:38 +08:00
mh-swift
1b563e0957 fix: 创建新的菜单目录报tree字段不能为空问题 2024-07-10 16:09:16 +08:00
mh-swift
9133afb864 perf: 根据golangci检测结果,优化部分代码 2024-07-09 17:32:52 +08:00
mh-swift
5c3bcaf6cc style: 格式整理 2024-07-09 17:21:32 +08:00
mh-swift
e501a33163 chore(golangci): govet配置错误修复 2024-07-09 17:09:14 +08:00
mh-swift
491e6cef09 chore(golangci-lint): lint配置兼容性修复 2024-07-09 17:07:05 +08:00
maxbad
b005c80ba6 fix #100 2024-06-21 14:34:52 +08:00
maxbad
7bf0efe667 Merge pull request #63 from bufanyun/v2.0
up
2024-06-21 14:29:54 +08:00
孟帅
f78f44e00f Merge pull request #115 from qiuyier/bugfix/issue-109
fix(src/api/base/index.ts): 富文本无法上传图片
2024-06-20 18:00:55 +08:00
邱一二
93395df7fa fix(src/api/base/index.ts): 富文本无法上传图片
富文本调用上传接口时,content-type 为 application/json导致无法上传图片,修改上传接口,指定 content-type 为 multipart/form-data解决问题

Closes #109
2024-06-19 00:25:15 +08:00
孟帅
ea7cc97ed4 Merge pull request #113 from hailaz/v2.0
fix: #107
2024-06-14 19:01:57 +08:00
海亮
1292a15385 fix: #107 2024-06-04 11:08:05 +08:00
孟帅
bbca0e8db8 Merge pull request #105 from GreatSir/v2.0
fix multipart upload merge file
2024-05-16 13:37:08 +08:00
xlc
9ff6e2d690 fix multipart upload merge file 2024-05-16 13:33:53 +08:00
孟帅
69b8f42092 Merge pull request #103 from aklivecai/2024
角色权限-数据权限-数据范围-自定义部门选择 无法显示名称bug修复
2024-05-15 12:06:01 +08:00
孟帅
e672f54fbb Merge pull request #102 from zhangshican/v2.0
修复添加菜单填写了重定向,然后菜单类型为“菜单” 会执行重定向
2024-05-15 12:05:41 +08:00
tak
67520c9e38 角色权限-数据权限-数据范围-自定义部门选择 2024-05-15 10:14:30 +08:00
ss
a642c322e3 修复添加菜单填写了重定向,然后菜单类型为“菜单” 会执行重定向 2024-05-14 23:14:38 +08:00
孟帅
b2440e8ddc Merge pull request #101 from clh021/v2.0
Add and Sync sqlite sql file.
2024-05-14 19:01:27 +08:00
chenlianghong
59beb07e98 feat: upgrade sqlite sql sync offical hotgo.sql 2024-05-13 10:02:59 +08:00
chenlianghong
7180157259 feat: add sqlite sql 2024-05-13 09:14:38 +08:00
孟帅
b97410738e Merge pull request #99 from clh021/v2.0
feat: support sqlite_fields_comment
2024-05-11 17:37:12 +08:00
chenlianghong
ba2fa86767 feat: support sqlite_fields_comment 2024-05-10 09:35:08 +08:00
maxbad
406e3ef168 Merge pull request #62 from bufanyun/v2.0
up
2024-05-09 19:57:33 +08:00
孟帅
817482bedb fix 修复潜在索引越限问题 2024-05-09 11:25:05 +08:00
孟帅
dc20a86b33 fix 修复websocket在某些情况下不重连问题
fix 修复登录日志查看权限
feat 访问日志增加接口信息显示
perf 为所有orm的Insert操作增加OmitEmptyData选项
2024-04-24 23:29:50 +08:00
孟帅
269b2f9e43 fix 组件开启缓存后偶尔白屏问题 2024-04-24 11:56:14 +08:00
孟帅
211d3872e4 fix 清理打包资源 2024-04-23 12:19:21 +08:00
孟帅
6d0c22f98c fix 请求日志空指针问题 2024-04-23 12:17:56 +08:00
maxbad
90ea29051f Merge pull request #61 from bufanyun/v2.0
发布v2.15.1版本,更新内容请查看:https://github.com/bufanyun/hotgo/blob/v2.0/docs/…
2024-04-23 10:28:55 +08:00
maxbad
50a32db1d9 fix:表单添加后,loading隐藏 2024-04-10 14:07:20 +08:00
maxbad
0dddbcd50c Merge pull request #60 from bufanyun/v2.0
up
2024-04-10 14:04:40 +08:00
maxbad
ac46200a23 Merge pull request #59 from bufanyun/v2.0
v2.13.1
2024-03-11 10:57:15 +08:00
maxbad
ce4629e082 Merge pull request #58 from bufanyun/v2.0
up
2024-01-30 09:46:41 +08:00
631 changed files with 35304 additions and 9078 deletions

View File

@@ -1,24 +1,24 @@
# HotGo-V2 # HotGo-V2
<div align="center"> <div align="center">
<img width="140px" src="https://bufanyun.cn-bj.ufileos.com/hotgo/logo.sig.png"> <img width="140px" src="https://gmycos.facms.cn/hotgo/logo.sig.png">
<p> <p>
<h1>HotGo V2</h1> <h1>HotGo V2</h1>
</p> </p>
<p align="center"> <p align="center">
<a href="https://goframe.org/pages/viewpage.action?pageId=1114119" target="_blank"> <a href="https://goframe.org/pages/viewpage.action?pageId=1114119" target="_blank">
<img src="https://img.shields.io/badge/goframe-2.7-green" alt="goframe"> <img src="https://img.shields.io/badge/goframe-2.9.0-green" alt="goframe">
</a> </a>
<a href="https://v3.vuejs.org/" target="_blank"> <a href="https://v3.vuejs.org/" target="_blank">
<img src="https://img.shields.io/badge/vue.js-vue3.4-green" alt="vue"> <img src="https://img.shields.io/badge/vue.js-vue3.4-green" alt="vue">
</a> </a>
<a href="https://www.naiveui.com" target="_blank"> <a href="https://www.naiveui.com" target="_blank">
<img src="https://img.shields.io/badge/naiveui-%3E2.38.0-blue" alt="naiveui"> <img src="https://img.shields.io/badge/naiveui-%3E2.42.0-blue" alt="naiveui">
</a> </a>
<a href="https://www.tslang.cn/" target="_blank"> <a href="https://www.tslang.cn/" target="_blank">
<img src="https://img.shields.io/badge/typescript-%3E4.0.0-blue" alt="typescript"> <img src="https://img.shields.io/badge/typescript-%3E4.0.0-blue" alt="typescript">
</a> </a>
<a href="https://vitejs.dev/" target="_blank"> <a href="https://vitejs.dev/" target="_blank">
<img src="https://img.shields.io/badge/vite-%3E4.0.0-yellow" alt="vite"> <img src="https://img.shields.io/badge/vite-%3E5.4.2-yellow" alt="vite">
</a> </a>
<a href="https://github.com/bufanyun/hotgo/blob/v2.0/LICENSE" target="_blank"> <a href="https://github.com/bufanyun/hotgo/blob/v2.0/LICENSE" target="_blank">
<img src="https://img.shields.io/badge/license-MIT-success" alt="license"> <img src="https://img.shields.io/badge/license-MIT-success" alt="license">
@@ -124,8 +124,8 @@
## 交流QQ群 ## 交流QQ群
交流群①190966648 <a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=mJafkvme3VNyiQlCFIFNRtY8Xlr7pj9U&jump_from=webapi&authKey=jL10vIESr+vO8wpxwyd6DlChzkrbHpzN9uhAsIHgAinL/Vvd+nvuRyilf2UqUlCy"><img border="0" src="https://bufanyun.cn-bj.ufileos.com/hotgo/group.png" alt="HotGo框架交流1群" title="HotGo框架交流1群"></a> 交流群①190966648 <a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=mJafkvme3VNyiQlCFIFNRtY8Xlr7pj9U&jump_from=webapi&authKey=jL10vIESr+vO8wpxwyd6DlChzkrbHpzN9uhAsIHgAinL/Vvd+nvuRyilf2UqUlCy"><img border="0" src="https://gmycos.facms.cn/hotgo/group.png" alt="HotGo框架交流1群" title="HotGo框架交流1群"></a>
> <img src="https://bufanyun.cn-bj.ufileos.com/hotgo/hotgo1qun.png" width="400px"/> > <img src="https://gmycos.facms.cn/hotgo/hotgo1qun.png" width="400px"/>
## 商用说明 ## 商用说明
@@ -136,7 +136,7 @@
* 本项目包含的第三方源码和二进制文件之版权信息另行标注。 * 本项目包含的第三方源码和二进制文件之版权信息另行标注。
* 版权所有Copyright © 2020-2024 by Ms (https://github.com/bufanyun/hotgo) * 版权所有Copyright © 2020-2025 by Ms (https://github.com/bufanyun/hotgo)
* All rights reserved。 * All rights reserved。
@@ -154,11 +154,11 @@
## [感谢JetBrains提供的免费GoLand](https://jb.gg/OpenSource) ## [感谢JetBrains提供的免费GoLand](https://jb.gg/OpenSource)
[![avatar](https://camo.githubusercontent.com/323657c6e81419b8e151e9da4c71f409e3fcc65d630535170c59fe4807dbc905/68747470733a2f2f676f6672616d652e6f72672f646f776e6c6f61642f7468756d626e61696c732f313131343131392f6a6574627261696e732e706e67)](https://jb.gg/OpenSource) [![avatar](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](https://jb.gg/OpenSource)
## License ## License
[MIT © HotGo-2024](./LICENSE) [MIT © HotGo-2025](./LICENSE)

View File

@@ -14,7 +14,7 @@
1、HotGo 后台进入 开发工具->插件管理->找到创建新插件,根据引导进行创建即可。 1、HotGo 后台进入 开发工具->插件管理->找到创建新插件,根据引导进行创建即可。
``` ```shell
创建成功后默认情况下会在以下目录中生成插件文件假设新生成的插件名为hgexample 创建成功后默认情况下会在以下目录中生成插件文件假设新生成的插件名为hgexample
1. /server/addons/hgexample/ # 插件模块目录 1. /server/addons/hgexample/ # 插件模块目录
@@ -29,7 +29,7 @@
2、创建插件完毕重启服务端后插件管理中会出现你新创建的插件信息。操作栏有几个按钮在此进行说明 2、创建插件完毕重启服务端后插件管理中会出现你新创建的插件信息。操作栏有几个按钮在此进行说明
- 安装:会自动执行 server/hgexample/main.go 文件中的Install方法方法中的具体逻辑默认为空可以根据实际情况自行配置。如生成后台菜单、生成插件配置表初始化数据、迁移home页面、web项目文件等。 - 安装:会自动执行 server/hgexample/main.go 文件中的Install方法方法中的具体逻辑默认为空可以根据实际情况自行配置。如生成后台菜单、生成插件配置表初始化数据、迁移home页面、web项目文件等。
``` ```go
// Install 安装模块 // Install 安装模块
func (m *module) Install(ctx context.Context) (err error) { func (m *module) Install(ctx context.Context) (err error) {
// ... // ...
@@ -38,7 +38,7 @@ func (m *module) Install(ctx context.Context) (err error) {
``` ```
- 更新:会自动执行 server/hgexample/main.go 文件中的Upgrade方法方法中的具体逻辑默认为空可以根据实际情况自行配置。 - 更新:会自动执行 server/hgexample/main.go 文件中的Upgrade方法方法中的具体逻辑默认为空可以根据实际情况自行配置。
``` ```go
// Upgrade 更新模块 // Upgrade 更新模块
func (m *module) Upgrade(ctx context.Context) (err error) { func (m *module) Upgrade(ctx context.Context) (err error) {
// ... // ...
@@ -47,7 +47,7 @@ func (m *module) Upgrade(ctx context.Context) (err error) {
``` ```
- 卸载:会自动执行 server/hgexample/main.go 文件中的UnInstall方法方法中的具体逻辑默认为空可以根据实际情况自行配置。如会清除所有的数据表和已安装的信息等。 - 卸载:会自动执行 server/hgexample/main.go 文件中的UnInstall方法方法中的具体逻辑默认为空可以根据实际情况自行配置。如会清除所有的数据表和已安装的信息等。
``` ```go
// UnInstall 卸载模块 // UnInstall 卸载模块
func (m *module) UnInstall(ctx context.Context) (err error) { func (m *module) UnInstall(ctx context.Context) (err error) {
// ... // ...

View File

@@ -9,6 +9,7 @@
#### 模块结构 #### 模块结构
- 文件路径server/internal/library/addons/module.go - 文件路径server/internal/library/addons/module.go
```go ```go
// Skeleton 模块骨架 // Skeleton 模块骨架
type Skeleton struct { type Skeleton struct {
@@ -43,6 +44,7 @@ type Module interface {
#### 获取模块信息 #### 获取模块信息
- 在插件模块内 - 在插件模块内
```go ```go
package main package main
@@ -57,6 +59,7 @@ func test() {
``` ```
- 在插件模块外 - 在插件模块外
```go ```go
package main package main

View File

@@ -10,7 +10,7 @@ gf run main.go
# web端 # web端
cd web cd web
yarn dev pnpm run dev 或 npm run dev
``` ```
以下是一个关联表的CURD生成流程 以下是一个关联表的CURD生成流程

View File

@@ -10,7 +10,7 @@ gf run main.go
# web端 # web端
cd web cd web
yarn dev pnpm run dev 或 npm run dev
``` ```
以下是一个基本的CURD生成流程 以下是一个基本的CURD生成流程

View File

@@ -10,7 +10,7 @@ gf run main.go
# web端 # web端
cd web cd web
yarn dev pnpm run dev 或 npm run dev
``` ```
以下是一个基本的树形CURD生成流程 以下是一个基本的树形CURD生成流程

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

View File

@@ -41,8 +41,9 @@ cd server && make build
cd server # 切换到服务端目录下 cd server # 切换到服务端目录下
rm -rf ./resource/public/admin/ # 删除之前的web资源 rm -rf ./resource/public/admin/ # 删除之前的web资源
mkdir ./resource/public/admin/ # 重新创建web资源存放目录除首次编译后续可以跳过执行此步骤 mkdir ./resource/public/admin/ # 重新创建web资源存放目录除首次编译后续可以跳过执行此步骤
cd ../web && yarn build # 切换到web项目下编译web项目 cd ../web && pnpm run build # 切换到web项目下编译web项目
\cp -rf ./dist/* ../server/resource/public/admin/ # 将编译好的web资源复制到server对应的资源存放路径下 \cp -rf ./dist/* ../server/resource/public/admin/ # 将编译好的web资源复制到server对应的资源存放路径下
cd ../server # 切换回服务端目录下
echo "y" | gf build # 编译hotgo服务端 echo "y" | gf build # 编译hotgo服务端
# 不出意外你已经编译好了hotgo可执行文件 # 不出意外你已经编译好了hotgo可执行文件
@@ -57,7 +58,7 @@ echo "y" | gf build # 编译hotgo服务端
# 编译web端 # 编译web端
cd web cd web
yarn build pnpm run build 或 npm run build
# web端编译完成后将web/dist/*中的文件上传到`server`端线上运行目录:/resource/public/admin即可 # web端编译完成后将web/dist/*中的文件上传到`server`端线上运行目录:/resource/public/admin即可
# 至此web端和server端都可以独立覆盖更新 # 至此web端和server端都可以独立覆盖更新
@@ -77,7 +78,7 @@ yarn build
### Nginx配置 ### Nginx配置
``` ```
# websocket # websocket
location ^~ /socket { location = /socket {
proxy_pass http://127.0.0.1:8000/socket; proxy_pass http://127.0.0.1:8000/socket;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -97,7 +98,9 @@ yarn build
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8000/; # 设置代理服务器的协议和地址 proxy_pass http://127.0.0.1:8000/;
proxy_redirect off;
proxy_buffering off;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade; proxy_set_header Connection upgrade;

View File

@@ -11,21 +11,21 @@
1. 前往https://nodejs.org/zh-cn/下载当前版本node 1. 前往https://nodejs.org/zh-cn/下载当前版本node
2. 命令行运行 `node -v` 若控制台输出版本号则node安装成功 2. 命令行运行 `node -v` 若控制台输出版本号则node安装成功
3. node 版本需大于等于 `16.0` 3. node 版本需大于等于 `16.0`
4. 安装yarn`npm install -g yarn` 4. 安装pnpm`npm install -g pnpm`
5. 命令行运行 `yarn -v` 若控制台输出版本号则前端环境搭建成功 5. 命令行运行 `pnpm -v` 若控制台输出版本号则前端环境搭建成功
### 后端环境 ### 后端环境
1. 下载golang安装 版本号需>=1.21 1. 下载golang安装 版本号需>=1.23
2. 国际: https://golang.org/dl/ 2. 国际: https://golang.org/dl/
3. 国内: https://golang.google.cn/dl/ 3. 国内: https://golang.google.cn/dl/
4. 命令行运行 go 若控制台输出各类提示命令 则安装成功 输入 `go version` 确认版本大于1.19 4. 命令行运行 go 若控制台输出各类提示命令 则安装成功 输入 `go version` 确认版本大于1.23
5. 开发工具推荐 [Goland](https://www.jetbrains.com/go/) 5. 开发工具推荐 [Goland](https://www.jetbrains.com/go/)
### 使用说明 ### 使用说明
> 需要本地具有 git node golang 环境 > 需要本地具有 git node golang 环境
- node版本 >= 16.0.0 - node版本 >= 20.0.0
- golang版本 >= 1.21 - golang版本 >= 1.23
- mysql版本 >= 5.7,引擎需要是 innoDB - mysql版本 >= 5.7,引擎需要是 innoDB
- IDE推荐Goland - IDE推荐Goland

View File

@@ -7,8 +7,8 @@
### 环境要求 ### 环境要求
- node版本 >= v16.0.0 - node版本 >= v20.0.0
- golang版本 >= v1.21 - golang版本 >= v1.23
- goframe版本 >=v2.7.0 - goframe版本 >=v2.7.0
- mysql版本 >=5.7 - mysql版本 >=5.7
@@ -69,7 +69,7 @@ gfcli:
三、 启动服务 三、 启动服务
1、服务端 1、服务端
```shell script ```shell
cd server cd server
# 设置国内代理,如果已经设置好了代理可以跳过 # 设置国内代理,如果已经设置好了代理可以跳过
@@ -86,15 +86,15 @@ gfcli:
``` ```
2、web前端 2、web前端
```shell script ```shell
cd web cd web
# 首先确定你以安装node16.0以上版本并安装了包[npm、yarn],否则可能会出现一些未知报错 # 首先确定你以安装node16.0以上版本并安装了包[npm、pnpm],否则可能会出现一些未知报错
# 安装依赖 # 安装依赖
yarn install pnpm install
# 启动web项目 # 启动web项目
yarn dev pnpm run dev
# 如果顺利至此到浏览器打开http://你的IP:8001/admin # 如果顺利至此到浏览器打开http://你的IP:8001/admin
# 登录账号admin, 密码123456 # 登录账号admin, 密码123456

View File

@@ -22,7 +22,7 @@
#### 1、安装数据库出现 json 报错不支持 #### 1、安装数据库出现 json 报错不支持
请安装 mysql5.7 及以上版本的数据库 请安装 mysql5.7 及以上版本的数据库。如果你使用的是mariadb请确认版本号mariadb从 10.2 版本开始支持 json 数据类型。
@@ -50,7 +50,31 @@
系统运行目录下配置hack/config.yaml文件。如果是生产环境运行并且不需要开发工具相关功能可以将`manifest/config/config.yaml`配置文件中的`system.mode`值改为`product`,这样启动时不会加载开发工具相关功能 系统运行目录下配置hack/config.yaml文件。如果是生产环境运行并且不需要开发工具相关功能可以将`manifest/config/config.yaml`配置文件中的`system.mode`值改为`product`,这样启动时不会加载开发工具相关功能
#### 4、非超管角色提示你没有访问权限
![1.4.0.png](./images/issue/1.4.0.png)
此问题因当前角色访问的页面包含未分配权限的接口所致,在多角色场景中较为常见,解决步骤如下:
1. 定位缺失权限的接口
- 用超管账号进入系统应用 -> 日志管理 -> 全局日志,搜索状态码为`62 无访问权限`的记录
- 示例:若请求接口为`/admin/hgexample/treeTable/list`,需处理的权限路径为`/hgexample/treeTable/list`(去除`/admin`前缀)
![1.4.1.png](./images/issue/1.4.1.png)
假如查到请求接口是:`/admin/hgexample/treeTable/list`,那需要分配的菜单权限就是:`/hgexample/treeTable/list`,要把`/admin`去掉
2. 配置菜单权限
- 进入权限管理 -> 菜单权限:
- 若目标菜单不存在,先新增菜单
- 若菜单已存在但未配置接口权限就把步骤1中的权限路径添加到【分配权限】中已配置则跳过
![1.4.2.png](./images/issue/1.4.2.png)
3. 分配权限给角色
- 进入权限管理 -> 角色权限,找到对应角色并点击【菜单权限】
- 勾选步骤2中配置的菜单权限保存即可
![1.4.3.png](./images/issue/1.4.3.png)
### 四、前端相关 ### 四、前端相关

View File

@@ -11,6 +11,54 @@
> 如果升级(覆盖)代码后打开会出现 sql 报错, 请检查更新的数据库格式或自行调整 > 如果升级(覆盖)代码后打开会出现 sql 报错, 请检查更新的数据库格式或自行调整
### v2.17.8
updated 2025.7.13
- 优化:表格排序处理器兼容关联表别名
- 优化优化动态统计数字在0值时显示问题
- 优化:优化首页快捷菜单点击事件范围
- 优化:优化短信、邮件验证码相关验证类数据排序
- 优化优化Nginx配置支持流式请求和兼容部分版本无法匹配到websocket规则问题
- 优化naive-ui版本升级到2.42.0
- 优化vue3-json-viewer版本升级到2.4.1
- 修复:修复可选用户选项`Fields`生成错误问题
### v2.16.10
updated 2025.3.22
- 增加:增加组合下拉用户筛选组件
- 优化:文件上传类型限制改为统一由后台配置控制
- 优化websocket重连时间调整为10秒初始化数据库中的网站地址调整为`127.0.0.1`
- 优化:优化访问日志字段展示方式
- 优化:系统公告发送编辑模态框调整为抽屉
- 优化gf版本升级到v2.9.0
- 优化naive-ui版本升级到2.41.0
- 修复修复vue路由`Redirect`命名重复问题
- 修复:优化代码生成在插件中`使用生成字典选项`时model包名重复问题
### v2.15.11
updated 2024.11.27
- 增加:增加配置管理子页面选项参数记忆
- 修复:修复定时任务中日志配置的读取并发读问题
- 优化gf版本升级到v2.8.2
- 优化:优化数据卡片展示
### v2.15.7
updated 2024.7.21
- 增加:访问日志、服务日志增加关键词搜索
- 增加web端增加字典状态管理重构字典选项使用方式大幅减少冗余代码
- 修复修复生成代码选项式树表已知的一些小bug
- 优化gf版本升级到v2.7.2
- 优化naive-ui版本升级到2.39.0
- 优化:访问日志不再记录过大的请求头参数,减少日志大小
### v2.15.1 ### v2.15.1
updated 2024.4.22 updated 2024.4.22

View File

@@ -128,7 +128,7 @@ gfcli:
### 生成CRUD表格 ### 生成CRUD表格
- 推荐使用热编译方式启动HotGo这样生成完成页面自动刷新即可看到新生成内容无需手动重启 - 推荐使用热编译方式启动HotGo这样生成完成页面自动刷新即可看到新生成内容无需手动重启
- 服务端热编译启动:`gf run main.go`, web前端启动`yarn dev` - 服务端热编译启动:`gf run main.go`, web前端启动`pnpm run dev``npm run dev`
1、创建数据表 1、创建数据表
@@ -176,7 +176,7 @@ CREATE TABLE `hg_test_category` (
1.3 插入测试数据 1.3 插入测试数据
```mysql ```mysql
INSERT INTO `hg_test_table` (`id`, `category_id`, `title`, `description`, `content`, `image`, `attachfile`, `city_id`, `switch`, `sort`, `status`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`) VALUES (1, 1, '测试标题', '描述', '<h2><strong>不知道写点啥!</strong></h2><p><br></p><iframe class=\"ql-video\" frameborder=\"0\" allowfullscreen=\"true\" src=\"https://media.w3.org/2010/05/sintel/trailer.mp4\"></iframe><p><br></p><p><img src=\"http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2023-02-09/cqdq9iuv0phsg8patk.png\"></p>', 'https://bufanyun.cn-bj.ufileos.com/hotgo/logo.sig.png', 'http://bufanyun.cn-bj.ufileos.com/hotgo/attachment/2022-12-30/cpf1x44idoycrtajf2.xlsx', 110102, 1, 10, 1, 0, 1, '2022-12-15 19:30:14', '2023-02-23 13:55:32', NULL); INSERT INTO `hg_test_table` (`id`, `category_id`, `title`, `description`, `content`, `image`, `attachfile`, `city_id`, `switch`, `sort`, `status`, `created_by`, `updated_by`, `created_at`, `updated_at`, `deleted_at`) VALUES (1, 1, '测试标题', '描述', '<h2><strong>不知道写点啥!</strong></h2><p><br></p><iframe class=\"ql-video\" frameborder=\"0\" allowfullscreen=\"true\" src=\"https://media.w3.org/2010/05/sintel/trailer.mp4\"></iframe><p><br></p><p><img src=\"https://gmycos.facms.cn/hotgo/attachment/2023-02-09/cqdq9iuv0phsg8patk.png\"></p>', 'https://gmycos.facms.cn/hotgo/logo.sig.png', 'https://gmycos.facms.cn/hotgo/attachment/2022-12-30/cpf1x44idoycrtajf2.xlsx', 110102, 1, 10, 1, 0, 1, '2022-12-15 19:30:14', '2023-02-23 13:55:32', NULL);
``` ```

View File

@@ -117,6 +117,7 @@
![](images/sys-db-by2.png) ![](images/sys-db-by2.png)
- 查询代码片段,参考路径:[server/internal/logic/admin/member.go](../../server/internal/logic/admin/member.go) - 查询代码片段,参考路径:[server/internal/logic/admin/member.go](../../server/internal/logic/admin/member.go)
```go ```go
// 查询创建者 // 查询创建者

View File

@@ -63,6 +63,7 @@
#### import #### import
* 单行import不建议用圆括号包裹 * 单行import不建议用圆括号包裹
* 按照`官方包`NEW LINE`当前工程包`NEW LINE`第三方依赖包`顺序引入 * 按照`官方包`NEW LINE`当前工程包`NEW LINE`第三方依赖包`顺序引入
```go ```go
import ( import (
"context" "context"
@@ -84,6 +85,7 @@
#### 函数体编码 #### 函数体编码
* 建议一个block结束空一行如if、for等 * 建议一个block结束空一行如if、for等
```go ```go
func main (){ func main (){
if x==1{ if x==1{
@@ -94,6 +96,7 @@
} }
``` ```
* return前尽可能空一行 * return前尽可能空一行
```go ```go
func getUser(id string)(string,error){ func getUser(id string)(string,error){
.... ....

View File

@@ -158,6 +158,7 @@ func test(ctx context.Context) {
#### 字典数据选项 #### 字典数据选项
- 文件路径server/internal/model/dict.go - 文件路径server/internal/model/dict.go
```go ```go
package model package model
@@ -232,6 +233,7 @@ var CreditGroupOptions = []*model.Option{
##### 方法字典接口 ##### 方法字典接口
- 文件路径server/internal/consts/credit_log.go - 文件路径server/internal/consts/credit_log.go
```go ```go
package dict package dict

View File

@@ -82,6 +82,7 @@ func main() {
- 下面我们以`text/xml`为例简单演示几种使用方法: - 下面我们以`text/xml`为例简单演示几种使用方法:
1. 当你使用规范化路由时可直接在XxxRes结构体的`g.Meta`中声明响应类型: 1. 当你使用规范化路由时可直接在XxxRes结构体的`g.Meta`中声明响应类型:
```go ```go
type HelloReq struct { type HelloReq struct {
g.Meta `path:"/hello" tags:"Hello" method:"get" summary:"You first hello api"` g.Meta `path:"/hello" tags:"Hello" method:"get" summary:"You first hello api"`
@@ -95,6 +96,7 @@ type HelloRes struct {
``` ```
2. 在响应前设置响应头: 2. 在响应前设置响应头:
```go ```go
var ( var (
Hello = cHello{} Hello = cHello{}
@@ -146,9 +148,7 @@ func main() {
2.`server/internal/logic/middleware/response.go`中根据请求的独有特征进行单独的处理兼容后续http处理。 2.`server/internal/logic/middleware/response.go`中根据请求的独有特征进行单独的处理兼容后续http处理。
#### 重写响应错误提示 #### 重写响应错误提示
- 在实际开发中我们可能想要隐藏一些敏感错误返回给客户端友好的错误提示但开发者同时又想需要看到真实的敏感错误。对此hotgo已经进行了过滤处理下面是一个简单的例子 - 在实际开发中我们可能想要隐藏一些敏感错误返回给客户端友好的错误提示但开发者同时又想需要看到真实的敏感错误。对此hotgo已经进行了过滤处理下面是一个简单的例子
```go ```go
@@ -195,6 +195,7 @@ func test() error {
``` ```
- 控制台的输出日志: - 控制台的输出日志:
```shell ```shell
2023-05-15 18:05:07.776 {084022730d495f17f19e550140f3e1a8} 200 "GET http localhost:8000 /admin/member/list?page=1&pageSize=10&roleId=-1 HTTP/1.1" 0.002, 127.0.0.1, "http://192.168.0.207:8001/login", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Co 2023-05-15 18:05:07.776 {084022730d495f17f19e550140f3e1a8} 200 "GET http localhost:8000 /admin/member/list?page=1&pageSize=10&roleId=-1 HTTP/1.1" 0.002, 127.0.0.1, "http://192.168.0.207:8001/login", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Co
re/1.94.197.400 QQBrowser/11.7.5287.400", -1, "", "" re/1.94.197.400 QQBrowser/11.7.5287.400", -1, "", ""

View File

@@ -44,6 +44,7 @@ SaaS系统多租户多应用设计已成为互联网企业的重要发展建
- 在用户登录成功后server端可通过上下文来获取用户部门类型来确定用户身份 - 在用户登录成功后server端可通过上下文来获取用户部门类型来确定用户身份
- 文件路径server/internal/library/contexts/context.go - 文件路径server/internal/library/contexts/context.go
```go ```go
package contexts package contexts
@@ -87,6 +88,7 @@ func IsUserDept(ctx context.Context) bool {
- 在用户登录成功后web端可通`useUserStore`来获取用户部门类型来确定用户身份 - 在用户登录成功后web端可通`useUserStore`来获取用户部门类型来确定用户身份
- 文件路径web/src/store/modules/user.ts - 文件路径web/src/store/modules/user.ts
```vue ```vue
<script lang="ts" setup> <script lang="ts" setup>
import { useUserStore } from '@/store/modules/user'; import { useUserStore } from '@/store/modules/user';
@@ -125,6 +127,7 @@ HotGo定位是中小型应用开发推荐采用一套数据库不同Schema。
下面是多租户功能演示例子代码中的使用片段 下面是多租户功能演示例子代码中的使用片段
- 封装查询Model - 封装查询Model
```go ```go
// Model 多租户功能演示ORM模型 // Model 多租户功能演示ORM模型
func (s *sSysTenantOrder) Model(ctx context.Context, option ...*handler.Option) *gdb.Model { func (s *sSysTenantOrder) Model(ctx context.Context, option ...*handler.Option) *gdb.Model {

View File

@@ -12,6 +12,7 @@
### 全局消息监听 ### 全局消息监听
- 所有全局的消息监听都在这里 - 所有全局的消息监听都在这里
- 文件路径web/src/utils/websocket/registerMessage.ts - 文件路径web/src/utils/websocket/registerMessage.ts
```ts ```ts
import { TABS_ROUTES } from '@/store/mutation-types'; import { TABS_ROUTES } from '@/store/mutation-types';
import { SocketEnum } from '@/enums/socketEnum'; import { SocketEnum } from '@/enums/socketEnum';
@@ -51,6 +52,7 @@ export function registerGlobalMessage() {
#### 单页面消息监听 #### 单页面消息监听
- 当你只需要某个页面使用WebSocket这将是一个不错的选择下面是一个简单的演示例子 - 当你只需要某个页面使用WebSocket这将是一个不错的选择下面是一个简单的演示例子
- 文件路径web/src/views/addons/hgexample/portal/websocketTest.vue - 文件路径web/src/views/addons/hgexample/portal/websocketTest.vue
```vue ```vue
<template> <template>
<div> <div>
@@ -190,6 +192,7 @@ export function registerGlobalMessage() {
#### 发送消息 #### 发送消息
- 向服务器发送一条消息 - 向服务器发送一条消息
```ts ```ts
import { sendMsg } from '@/utils/websocket'; import { sendMsg } from '@/utils/websocket';

View File

@@ -16,6 +16,7 @@
#### 1.消息处理接口 #### 1.消息处理接口
- 消息处理在设计上采用了接口化的思路。只需要实现以下接口即可进行WebSocket消息注册 - 消息处理在设计上采用了接口化的思路。只需要实现以下接口即可进行WebSocket消息注册
- 文件路径server/internal/websocket/model.go - 文件路径server/internal/websocket/model.go
```go ```go
package websocket package websocket
@@ -26,6 +27,7 @@ type EventHandler func(client *Client, req *WRequest)
#### 2.定义消息处理方法 #### 2.定义消息处理方法
- 以下是功能案例中的一个简单演示,实现了消息处理接口,并将收到的消息原样发送给客户端 - 以下是功能案例中的一个简单演示,实现了消息处理接口,并将收到的消息原样发送给客户端
- 文件路径server/addons/hgexample/controller/websocket/handler/index.go - 文件路径server/addons/hgexample/controller/websocket/handler/index.go
```go ```go
package handler package handler
@@ -52,6 +54,7 @@ func (c *cIndex) TestMessage(client *websocket.Client, req *websocket.WRequest)
#### 3.注册消息 #### 3.注册消息
- 定义消息处理方法后需要将其注册到WebSocket消息处理器一般放在对应应用模块的`router/websocket.go`下即可 - 定义消息处理方法后需要将其注册到WebSocket消息处理器一般放在对应应用模块的`router/websocket.go`下即可
- 文件路径server/addons/hgexample/router/websocket.go - 文件路径server/addons/hgexample/router/websocket.go
```go ```go
package router package router
@@ -80,6 +83,7 @@ func WebSocket(ctx context.Context, group *ghttp.RouterGroup) {
### 常用方法 ### 常用方法
- websocket服务器还提供了一些常用的方法下面只对部分进行说明 - websocket服务器还提供了一些常用的方法下面只对部分进行说明
```go ```go
func test() { func test() {
websocket.SendToAll() // 发送全部客户端 websocket.SendToAll() // 发送全部客户端
@@ -105,6 +109,7 @@ func test() {
### 其他 ### 其他
- WebSocket被连接时需验证用户认证中间件所以用户必须登录成功后才能连接成功 - WebSocket被连接时需验证用户认证中间件所以用户必须登录成功后才能连接成功
- 参考文件server/internal/logic/middleware/weboscket_auth.go - 参考文件server/internal/logic/middleware/weboscket_auth.go
```go ```go
package middleware package middleware

View File

@@ -15,7 +15,7 @@
项目开发完成之后,执行以下命令进行构建 项目开发完成之后,执行以下命令进行构建
```shell ```shell
yarn build pnpm run build 或 npm run build
``` ```
构建打包成功之后,会在根目录生成 dist 文件夹,里面就是构建打包好的文件 构建打包成功之后,会在根目录生成 dist 文件夹,里面就是构建打包好的文件
@@ -40,15 +40,15 @@ VITE_LEGACY = true
使用项目自定的命令进行预览(推荐) 使用项目自定的命令进行预览(推荐)
```shell ```shell
# 先打包在进行预览 # 先打包在进行预览
yarn preview pnpm run preview 或 npm run preview
# 直接预览本地 dist 文件目录 # 直接预览本地 dist 文件目录
yarn preview:dist pnpm run preview:dist 或 npm run preview:dist
``` ```
- 本地服务器预览(通过 live-server) - 本地服务器预览(通过 live-server)
```shell ```shell
# 1.全局安装live-server # 1.全局安装live-server
yarn global add live-server npm -g install live-server
# 2. 进入打包的后目录 # 2. 进入打包的后目录
cd ./dist cd ./dist
# 本地预览默认端口8080 # 本地预览默认端口8080
@@ -60,7 +60,7 @@ live-server --port 9000
### 分析构建文件体积 ### 分析构建文件体积
如果你的构建文件很大,可以通过项目内置 [rollup-plugin-analyzer](https://github.com/doesdev/rollup-plugin-analyzer) 插件进行代码体积分析,从而优化你的代码。 如果你的构建文件很大,可以通过项目内置 [rollup-plugin-analyzer](https://github.com/doesdev/rollup-plugin-analyzer) 插件进行代码体积分析,从而优化你的代码。
```shell ```shell
yarn report pnpm run report 或 npm run report
``` ```
运行之后,在自动打开的页面可以看到具体的体积分布,以分析哪些依赖有问题。 运行之后,在自动打开的页面可以看到具体的体积分布,以分析哪些依赖有问题。

187
index.html Normal file
View File

@@ -0,0 +1,187 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1, minimum-scale=1.0, shrink-to-fit=no, viewport-fit=cover">
<!-- Replace with your own title and description. -->
<title>HotGo-V2</title>
<meta name="description" content="基于全新GoFrame2+Vue3+NaiveUI+uniapp开发的全栖框架为二次开发而生适合中小型完整应用开发。">
<!-- Default Theme (see //docsify.js.org/#/themes) -->
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css">
</head>
<body>
<div id="app"></div>
<script>
// Docsify Configuration (see //docsify.js.org/#/configuration)
window.$docsify = {
name: "HotGo-V2",
nameLink: {
'/': '/hotgo/',
},
relativePath: true,
// alias: {
// "/.*/_navbar.md": "/_navbar.md",
// },
// themeColor: "#42b983",
// logo: "//bufanyun.cn-bj.ufileos.com/hotgo/logo.sig.png",
// coverpage: true,
// homepage: "README.md",
// Sidebar Configuration
auto2top: true,
loadSidebar: "sidebar.md",
// maxLevel: 2,
// Set subMaxLevel to 0 to remove automatic display of page table of contents (TOC) in Sidebar
// subMaxLevel: 3,
// Navbar Configuration
// loadNavbar: true,
// Search Plugin Configuration
search: {
placeholder: {
"/": "搜索",
// "/": "Type to search"
},
noData: {
"/": "找不到结果",
// "/": "No Results"
},
// Headline depth, 1 - 6
// depth: 2,
},
// Flexible-alerts Plugin Configuration
"flexible-alerts": {
important: {
label: "Important",
// localization
label: {
// "/zh-cn": "重要",
"/": "Important"
},
// Assuming that we use Font Awesome
icon: "far fa-message",
className: "important"
},
warning: {
label: "Warning",
// localization
label: {
// "/zh-cn": "警告",
"/": "Warning"
},
// Assuming that we use Font Awesome
icon: "fas fa-triangle-exclamation",
className: "warning"
},
caution: {
label: "Caution",
// localization
label: {
// "/zh-cn": "注意",
"/": "Caution"
},
// Assuming that we use Font Awesome
icon: "fas fa-circle-exclamation",
className: "attention"
},
},
// Hide-code Plugin Configuration
hideCode: {
// scroll: false, // Enable scrolling
height: 300 // Max height
},
// Versioned Plugin Configuration
// versions: [
// { folder: "/", label: "v2", default: true },
// ],
// versionSelectorLabel: "Version",
// Progress Plugin Configuration
progress: {
position: "top",
// color: "var(--theme-color,#42b983)",
height: "3px",
},
};
</script>
<!-- Required -->
<script src="//cdn.jsdelivr.net/npm/docsify@4/lib/docsify.min.js"></script>
<!-- Recommended -->
<script src="//cdn.jsdelivr.net/npm/docsify@4/lib/plugins/zoom-image.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify@4/lib/plugins/search.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify-copy-code/dist/docsify-copy-code.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify-pagination/dist/docsify-pagination.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify-hide-code/dist/docsify-hide-code.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify-progress@latest/dist/progress.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify-example-panels"></script>
<!-- Prism code highlight -->
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-bash.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-matlab.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-go.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-yaml.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-vue.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-json.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-sql.min.js"></script>
<!--mermaid插件-->
<script type="module">
import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs";
mermaid.initialize({ startOnLoad: true });
window.mermaid = mermaid;
</script>
<script src="//unpkg.com/docsify-mermaid@2.0.1/dist/docsify-mermaid.js"></script>
<!-- docsify-dark-switcher -->
<script src="//cdn.jsdelivr.net/gh/LIGMATV/docsify-dark-switcher@latest/docsify-dark-switcher.js"></script>
<style>
:root {
--dark-base-background: #222;
--dark-base-color: #bbc0c4;
--dark-theme-color: var(--theme-color, #42b983);
--dark-code-color: var(--dark-color);
--dark-heading-color: var(--dark-theme-color);
--dark-cover-background: #000000a8;
--dark-code-background: #303030;
--dark-tip-background: #2c0000;
--dark-warn-background: #005842;
--dark-icon-size: 25px;
--dark-icon-transition: .1s ease-in-out .1s;
--dark-moon-color: #000000;
--dark-sun-color: #ffffff;
}
</style>
<!-- docsify-plugin-flexible-alerts -->
<script src="//cdn.jsdelivr.net/npm/docsify-plugin-flexible-alerts/dist/docsify-plugin-flexible-alerts.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/js/all.min.js"></script>
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/fontawesome.min.css">
<!-- docsify-versioned-plugin -->
<!-- <script src="//cdn.jsdelivr.net/npm/docsify-versioned-plugin@0.0.1/index.js"></script>
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify-versioned-plugin@0.0.1/styles.css"> -->
</body>
</html>

View File

@@ -13,14 +13,15 @@ run:
# Include test files or not. # Include test files or not.
# Default: true # Default: true
tests: false tests: false
go: "1.20"
# Which dirs to skip: issues from them won't be reported. # Which dirs to skip: issues from them won't be reported.
# Can use regexp here: `generated.*`, regexp is applied on full path. # Can use regexp here: `generated.*`, regexp is applied on full path.
# Default value is empty list, # Default value is empty list,
# but default dirs are skipped independently of this option's value (see skip-dirs-use-default). # but default dirs are skipped independently of this option's value (see skip-dirs-use-default).
# "/" will be replaced by current OS file path separator to properly work on Windows. # "/" will be replaced by current OS file path separator to properly work on Windows.
skip-dirs: # skip-dirs:
- internal/library/hggen/internal # - internal/library/hggen/internal
# Which files to skip: they will be analyzed, but issues from them won't be reported. # Which files to skip: they will be analyzed, but issues from them won't be reported.
# Default value is empty list, # Default value is empty list,
@@ -28,7 +29,7 @@ run:
# we confidently recognize autogenerated files. # we confidently recognize autogenerated files.
# If it's not please let us know. # If it's not please let us know.
# "/" will be replaced by current OS file path separator to properly work on Windows. # "/" will be replaced by current OS file path separator to properly work on Windows.
skip-files: [] # skip-files: []
# Main linters configurations. # Main linters configurations.
@@ -71,6 +72,9 @@ issues:
- linters: - linters:
- gocritic - gocritic
text: "unnecessaryDefer:" text: "unnecessaryDefer:"
exclude-dirs:
- internal/library/hggen/internal
exclude-files: []
# https://golangci-lint.run/usage/linters # https://golangci-lint.run/usage/linters
@@ -176,7 +180,7 @@ linters-settings:
# Select the Go version to target. # Select the Go version to target.
# Default: 1.13 # Default: 1.13
# Deprecated: use the global `run.go` instead. # Deprecated: use the global `run.go` instead.
go: "1.15" # go: "1.15"
# Sxxxx checks in https://staticcheck.io/docs/configuration/options/#checks # Sxxxx checks in https://staticcheck.io/docs/configuration/options/#checks
# Default: ["*"] # Default: ["*"]
checks: [ checks: [
@@ -187,7 +191,7 @@ linters-settings:
govet: govet:
# Report about shadowed variables. # Report about shadowed variables.
# Default: false # Default: false
check-shadowing: true # check-shadowing: true
# Settings per analyzer. # Settings per analyzer.
settings: settings:
# Analyzer name, run `go tool vet help` to see all analyzers. # Analyzer name, run `go tool vet help` to see all analyzers.
@@ -263,7 +267,7 @@ linters-settings:
# Select the Go version to target. # Select the Go version to target.
# Default: "1.13" # Default: "1.13"
# Deprecated: use the global `run.go` instead. # Deprecated: use the global `run.go` instead.
go: "1.15" # go: "1.15"
# SAxxxx checks in https://staticcheck.io/docs/configuration/options/#checks # SAxxxx checks in https://staticcheck.io/docs/configuration/options/#checks
# Default: ["*"] # Default: ["*"]
checks: [ "all","-SA1019","-SA4015","-SA1029","-SA1016","-SA9003","-SA4006","-SA6003" ] checks: [ "all","-SA1019","-SA4015","-SA1029","-SA1016","-SA9003","-SA4006","-SA6003" ]

View File

@@ -9,7 +9,8 @@ ADMIN_RESOURCE_PATH = "/resource/public/admin/"
build: build:
@rm -rf ./$(ADMIN_RESOURCE_PATH) @rm -rf ./$(ADMIN_RESOURCE_PATH)
@mkdir ./$(ADMIN_RESOURCE_PATH) @mkdir ./$(ADMIN_RESOURCE_PATH)
@cd ../web && yarn build && \cp -rf ./dist/* ../server$(ADMIN_RESOURCE_PATH) @cd ../web && pnpm run build && \cp -rf ./dist/* ../server$(ADMIN_RESOURCE_PATH)
@cd ../server
@echo "y" | gf build @echo "y" | gf build
# 通过热编译启动所有服务 # 通过热编译启动所有服务
@@ -36,7 +37,7 @@ auth:
# 启动web服务 # 启动web服务
.PHONY: web .PHONY: web
web: web:
@cd ../web && yarn dev @cd ../web && pnpm run dev
# 刷新casbin权限 # 刷新casbin权限
.PHONY: refresh .PHONY: refresh

View File

@@ -0,0 +1,45 @@
## 轮播图管理
### 简介
### 使用说明
### 迁移或安装
1安装 HotGo (2.17.8及以上)
项目介绍https://github.com/bufanyun/hotgo
2将当前插件项目拷贝进 HotGo 根目录的 server/addons 目录下
3 HotGo 根目录的 server/addons/modules 目录下创建go文件:flashbanner.go内容如下
```go
package modules
import _ "hotgo/addons/flashbanner"
```
4HotGo 后台进入 开发工具->插件管理->找到 轮播图管理 (flashbanner) 进行安装
5重启服务即可生效
### 常用命令行
```shell
# 接口维护-gen service
gf gen service -s=addons/flashbanner/logic -d=addons/flashbanner/service
```
### `gf gen dao` 之后迁移model文件
```
cp .\internal\dao\internal\banner* .\addons\flashbanner\dao\internal\
cp .\internal\model\entity\banner* .\addons\flashbanner\model\entity\
```

View File

@@ -0,0 +1,65 @@
// Package banner
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package banner
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/addons/flashbanner/model/input/sysin"
"hotgo/internal/model/input/form"
)
// CreateReq 创建轮播图
type CreateReq struct {
g.Meta `path:"/banner/create" method:"post" tags:"轮播图" summary:"创建轮播图"`
sysin.BannerCreateInp
}
type CreateRes struct{}
// ListReq 查询列表
type ListReq struct {
g.Meta `path:"/banner/list" method:"get" tags:"轮播图" summary:"获取轮播图列表"`
sysin.BannerListInp
}
type ListRes struct {
List []*sysin.BannerListModel `json:"list" dc:"数据列表"`
form.PageRes
}
// ViewReq 获取指定信息
type ViewReq struct {
g.Meta `path:"/banner/view" method:"get" tags:"轮播图" summary:"获取指定轮播图信息"`
sysin.BannerViewInp
}
type ViewRes struct {
*sysin.BannerViewModel
}
// EditReq 修改/新增轮播图
type EditReq struct {
g.Meta `path:"/banner/edit" method:"post" tags:"轮播图" summary:"修改/新增轮播图"`
sysin.BannerEditInp
}
type EditRes struct{}
// DeleteReq 删除轮播图
type DeleteReq struct {
g.Meta `path:"/banner/delete" method:"post" tags:"轮播图" summary:"删除轮播图"`
sysin.BannerDeleteInp
}
type DeleteRes struct{}
// StatusReq 更新轮播图状态
type StatusReq struct {
g.Meta `path:"/banner/status" method:"post" tags:"轮播图" summary:"更新轮播图状态"`
sysin.BannerStatusInp
}
type StatusRes struct{}

View File

@@ -0,0 +1,30 @@
// Package config
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package config
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/addons/flashbanner/model/input/sysin"
)
// GetReq 获取指定分组的配置
type GetReq struct {
g.Meta `path:"/config/get" method:"get" tags:"轮播图管理" summary:"获取指定分组的配置"`
sysin.GetConfigInp
}
type GetRes struct {
*sysin.GetConfigModel
}
// UpdateReq 获取指定分组的配置
type UpdateReq struct {
g.Meta `path:"/config/update" method:"post" tags:"轮播图管理" summary:"获取指定分组的配置"`
sysin.UpdateConfigInp
}
type UpdateRes struct {
}

View File

@@ -0,0 +1,33 @@
// Package banner
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package banner
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/addons/flashbanner/model/input/sysin"
"hotgo/internal/model/input/form"
)
// ListReq 查询列表
type ListReq struct {
g.Meta `path:"/banner/list" method:"get" tags:"轮播图" summary:"获取轮播图列表"`
sysin.BannerListInp
}
type ListRes struct {
List []*sysin.BannerListModel `json:"list" dc:"数据列表"`
form.PageRes
}
// ViewReq 获取指定信息
type ViewReq struct {
g.Meta `path:"/banner/view" method:"get" tags:"轮播图" summary:"获取指定轮播图信息"`
sysin.BannerViewInp
}
type ViewRes struct {
*sysin.BannerViewModel
}

View File

@@ -0,0 +1,23 @@
// Package index
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package index
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/addons/flashbanner/model/input/sysin"
)
// TestReq 测试
type TestReq struct {
g.Meta `path:"/index/test" method:"get" tags:"轮播图管理" summary:"测试后台API"`
sysin.IndexTestInp
}
type TestRes struct {
*sysin.IndexTestModel
}

View File

@@ -0,0 +1,21 @@
// Package index
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package index
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/addons/flashbanner/model/input/sysin"
)
// TestReq 测试
type TestReq struct {
g.Meta `path:"/index/test" method:"get" tags:"轮播图管理" summary:"测试前台API"`
sysin.IndexTestInp
}
type TestRes struct {
*sysin.IndexTestModel
}

View File

@@ -0,0 +1,21 @@
// Package index
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package index
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/addons/flashbanner/model/input/sysin"
)
// TestReq 测试
type TestReq struct {
g.Meta `path:"/index/test" method:"get" summary:"轮播图管理" tags:"测试首页"`
sysin.IndexTestInp
}
type TestRes struct {
g.Meta `mime:"text/html" type:"string" example:"<html/>"`
}

View File

@@ -0,0 +1,21 @@
// Package index
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package index
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/addons/flashbanner/model/input/sysin"
)
// TestReq 测试
type TestReq struct {
g.Meta `path:"/index/test" method:"get" tags:"轮播图管理" summary:"测试websocket"`
sysin.IndexTestInp
}
type TestRes struct {
*sysin.IndexTestModel
}

View File

@@ -0,0 +1,9 @@
// Package consts
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package consts
// 常量枚举.
// 插件中的常量枚举可以统一在这目录下

View File

@@ -0,0 +1,81 @@
// Package banner
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package banner
import (
"context"
"hotgo/addons/flashbanner/api/admin/banner"
"hotgo/addons/flashbanner/service"
)
var (
Banner = cBanner{}
)
type cBanner struct{}
// Create 创建轮播图
func (c *cBanner) Create(ctx context.Context, req *banner.CreateReq) (res *banner.CreateRes, err error) {
err = service.SysBanner().Create(ctx, &req.BannerCreateInp)
if err != nil {
return nil, err
}
res = &banner.CreateRes{}
return res, nil
}
// List 获取轮播图列表
func (c *cBanner) List(ctx context.Context, req *banner.ListReq) (res *banner.ListRes, err error) {
list, totalCount, err := service.SysBanner().List(ctx, &req.BannerListInp)
if err != nil {
return nil, err
}
res = &banner.ListRes{
List: list,
}
res.PageRes.Pack(&req.BannerListInp, totalCount)
return res, nil
}
// View 获取指定轮播图信息
func (c *cBanner) View(ctx context.Context, req *banner.ViewReq) (res *banner.ViewRes, err error) {
model, err := service.SysBanner().View(ctx, &req.BannerViewInp)
if err != nil {
return nil, err
}
res = &banner.ViewRes{model}
return res, nil
}
// Edit 修改/新增轮播图
func (c *cBanner) Edit(ctx context.Context, req *banner.EditReq) (res *banner.EditRes, err error) {
err = service.SysBanner().Edit(ctx, &req.BannerEditInp)
if err != nil {
return nil, err
}
res = &banner.EditRes{}
return res, nil
}
// Delete 删除轮播图
func (c *cBanner) Delete(ctx context.Context, req *banner.DeleteReq) (res *banner.DeleteRes, err error) {
err = service.SysBanner().Delete(ctx, &req.BannerDeleteInp)
if err != nil {
return nil, err
}
res = &banner.DeleteRes{}
return res, nil
}
// Status 更新轮播图状态
func (c *cBanner) Status(ctx context.Context, req *banner.StatusReq) (res *banner.StatusRes, err error) {
err = service.SysBanner().Status(ctx, &req.BannerStatusInp)
if err != nil {
return nil, err
}
res = &banner.StatusRes{}
return res, nil
}

View File

@@ -0,0 +1,14 @@
// Package sys
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sys
import (
"hotgo/addons/flashbanner/controller/admin/banner"
)
var (
Banner = banner.Banner
)

View File

@@ -0,0 +1,33 @@
// Package sys
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sys
import (
"context"
"hotgo/addons/flashbanner/api/admin/config"
"hotgo/addons/flashbanner/service"
)
var (
Config = cConfig{}
)
type cConfig struct{}
// GetConfig 获取指定分组的配置
func (c *cConfig) GetConfig(ctx context.Context, req *config.GetReq) (res *config.GetRes, err error) {
data, err := service.SysConfig().GetConfigByGroup(ctx, &req.GetConfigInp)
res = new(config.GetRes)
res.GetConfigModel = data
return
}
// UpdateConfig 更新指定分组的配置
func (c *cConfig) UpdateConfig(ctx context.Context, req *config.UpdateReq) (res *config.UpdateRes, err error) {
err = service.SysConfig().UpdateConfigByGroup(ctx, &req.UpdateConfigInp)
return
}

View File

@@ -0,0 +1,30 @@
// Package sys
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sys
import (
"context"
"hotgo/addons/flashbanner/api/admin/index"
"hotgo/addons/flashbanner/service"
)
var (
Index = cIndex{}
)
type cIndex struct{}
// Test 测试
func (c *cIndex) Test(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
data, err := service.SysIndex().Test(ctx, &req.IndexTestInp)
if err != nil {
return
}
res = new(index.TestRes)
res.IndexTestModel = data
return
}

View File

@@ -0,0 +1,41 @@
// Package banner
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package banner
import (
"context"
"hotgo/addons/flashbanner/api/admin/banner"
"hotgo/addons/flashbanner/service"
)
var (
BannerIndex = cBanner{}
)
type cBanner struct{}
// List 获取轮播图列表
func (c *cBanner) List(ctx context.Context, req *banner.ListReq) (res *banner.ListRes, err error) {
list, totalCount, err := service.SysBanner().List(ctx, &req.BannerListInp)
if err != nil {
return nil, err
}
res = &banner.ListRes{
List: list,
}
res.PageRes.Pack(&req.BannerListInp, totalCount)
return res, nil
}
// View 获取指定轮播图信息
func (c *cBanner) View(ctx context.Context, req *banner.ViewReq) (res *banner.ViewRes, err error) {
model, err := service.SysBanner().View(ctx, &req.BannerViewInp)
if err != nil {
return nil, err
}
res = &banner.ViewRes{model}
return res, nil
}

View File

@@ -0,0 +1,31 @@
// Package api
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package api
import (
"context"
"hotgo/addons/flashbanner/api/api/index"
"hotgo/addons/flashbanner/service"
)
var (
Index = cIndex{}
)
type cIndex struct{}
// Test 测试
func (c *cIndex) Test(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
data, err := service.SysIndex().Test(ctx, &req.IndexTestInp)
if err != nil {
return
}
res = new(index.TestRes)
res.IndexTestModel = data
return
}

View File

@@ -0,0 +1,34 @@
// Package home
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package home
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"hotgo/addons/flashbanner/api/home/index"
"hotgo/addons/flashbanner/service"
"hotgo/internal/model"
isc "hotgo/internal/service"
)
// Index 基础
var Index = cIndex{}
type cIndex struct{}
func (a *cIndex) Index(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
data, err := service.SysIndex().Test(ctx, &req.IndexTestInp)
if err != nil {
return
}
isc.View().RenderTpl(ctx, "home/index.html", model.View{Data: g.Map{
"name": data.Name,
"module": data.Module,
"time": data.Time,
}})
return
}

View File

@@ -0,0 +1,30 @@
// Package websocket
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package websocket
import (
"context"
"hotgo/addons/flashbanner/api/websocket/index"
"hotgo/addons/flashbanner/service"
)
var (
Index = cIndex{}
)
type cIndex struct{}
// Test 测试
func (c *cIndex) Test(ctx context.Context, req *index.TestReq) (res *index.TestRes, err error) {
data, err := service.SysIndex().Test(ctx, &req.IndexTestInp)
if err != nil {
return
}
res = new(index.TestRes)
res.IndexTestModel = data
return
}

View File

@@ -0,0 +1,9 @@
// Package crons
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package crons
// 定时任务.
// 插件中的定时任务可以统一在这里注册和处理

View File

@@ -0,0 +1,12 @@
// Package dao
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package dao
import "hotgo/addons/flashbanner/dao/internal"
var (
Banner = internal.NewBannerDao()
)

View File

@@ -0,0 +1,89 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// BannerDao is the data access object for table hg_banner.
type BannerDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of current DAO.
columns BannerColumns // columns contains all the column names of Table for convenient usage.
}
// BannerColumns defines and stores column names for table hg_banner.
type BannerColumns struct {
Id string //
Name string // 轮播图名称
Cover string // 图片URL
Link string // 跳转链接,小程序内用相对地址
Type string // 类型默认不传
Status string // 1可用
Sort string // 排序,数字越大越靠前
CreatedAt string //
UpdatedAt string //
}
// bannerColumns holds the columns for table hg_banner.
var bannerColumns = BannerColumns{
Id: "id",
Name: "name",
Cover: "cover",
Link: "link",
Type: "type",
Status: "status",
Sort: "sort",
CreatedAt: "created_at",
UpdatedAt: "updated_at",
}
// NewBannerDao creates and returns a new DAO object for table data access.
func NewBannerDao() *BannerDao {
return &BannerDao{
group: "default",
table: "hg_banner",
columns: bannerColumns,
}
}
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *BannerDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of current dao.
func (dao *BannerDao) Table() string {
return dao.table
}
// Columns returns all column names of current dao.
func (dao *BannerDao) Columns() BannerColumns {
return dao.columns
}
// Group returns the configuration group name of database of current dao.
func (dao *BannerDao) Group() string {
return dao.group
}
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *BannerDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function.
func (dao *BannerDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@@ -0,0 +1,12 @@
// Package global
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package global
import "hotgo/internal/library/addons"
var (
skeleton *addons.Skeleton // 插件架子
)

View File

@@ -0,0 +1,22 @@
// Package global
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package global
import (
"context"
"hotgo/internal/library/addons"
)
func Init(ctx context.Context, sk *addons.Skeleton) {
skeleton = sk
}
func GetSkeleton() *addons.Skeleton {
if skeleton == nil {
panic("addon skeleton not initialized.")
}
return skeleton
}

View File

View File

@@ -0,0 +1,9 @@
// ==========================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package logic
import (
_ "hotgo/addons/flashbanner/logic/sys"
)

View File

@@ -0,0 +1,173 @@
// Package sys
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sys
import (
"context"
"hotgo/addons/flashbanner/dao"
"hotgo/addons/flashbanner/model/entity"
"hotgo/addons/flashbanner/model/input/sysin"
"hotgo/addons/flashbanner/service"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
type sSysBanner struct{}
func NewSysBanner() *sSysBanner {
return &sSysBanner{}
}
func init() {
service.RegisterSysBanner(NewSysBanner())
}
// GetMaxSort 获取最大排序值
func (s *sSysBanner) GetMaxSort(ctx context.Context) (maxSort int, err error) {
var result struct {
MaxSort int `json:"maxSort"`
}
err = dao.Banner.Ctx(ctx).Fields("MAX(sort) as maxSort").Scan(&result)
if err != nil {
return 0, gerror.Wrap(err, "获取最大排序值失败")
}
return result.MaxSort, nil
}
// Create 创建轮播图
func (s *sSysBanner) Create(ctx context.Context, in *sysin.BannerCreateInp) (err error) {
// 如果没有设置排序值,自动设置为最大值+1
if in.Sort == 0 {
maxSort, err := s.GetMaxSort(ctx)
if err != nil {
return err
}
in.Sort = maxSort + 1
}
_, err = dao.Banner.Ctx(ctx).Data(g.Map{
dao.Banner.Columns().Name: in.Name,
dao.Banner.Columns().Cover: in.Cover,
dao.Banner.Columns().Link: in.Link,
dao.Banner.Columns().Type: in.Type,
dao.Banner.Columns().Status: 1, // 默认启用
dao.Banner.Columns().Sort: in.Sort,
dao.Banner.Columns().CreatedAt: gtime.Now(),
dao.Banner.Columns().UpdatedAt: gtime.Now(),
}).Insert()
if err != nil {
err = gerror.Wrap(err, "创建轮播图失败")
return
}
return
}
// Edit 修改/新增轮播图
func (s *sSysBanner) Edit(ctx context.Context, in *sysin.BannerEditInp) (err error) {
if in.Id > 0 {
// 修改
_, err = dao.Banner.Ctx(ctx).Where(dao.Banner.Columns().Id, in.Id).Data(g.Map{
dao.Banner.Columns().Name: in.Name,
dao.Banner.Columns().Cover: in.Cover,
dao.Banner.Columns().Link: in.Link,
dao.Banner.Columns().Type: in.Type,
dao.Banner.Columns().Status: in.Status,
dao.Banner.Columns().Sort: in.Sort,
dao.Banner.Columns().UpdatedAt: gtime.Now(),
}).Update()
if err != nil {
err = gerror.Wrap(err, "修改轮播图失败")
return
}
} else {
// 新增
_, err = dao.Banner.Ctx(ctx).Data(g.Map{
dao.Banner.Columns().Name: in.Name,
dao.Banner.Columns().Cover: in.Cover,
dao.Banner.Columns().Link: in.Link,
dao.Banner.Columns().Type: in.Type,
dao.Banner.Columns().Status: in.Status,
dao.Banner.Columns().Sort: in.Sort,
dao.Banner.Columns().CreatedAt: gtime.Now(),
dao.Banner.Columns().UpdatedAt: gtime.Now(),
}).Insert()
if err != nil {
err = gerror.Wrap(err, "新增轮播图失败")
return
}
}
return
}
// Delete 删除轮播图
func (s *sSysBanner) Delete(ctx context.Context, in *sysin.BannerDeleteInp) (err error) {
_, err = dao.Banner.Ctx(ctx).Where(dao.Banner.Columns().Id, in.Id).Delete()
if err != nil {
err = gerror.Wrap(err, "删除轮播图失败")
return
}
return
}
// View 获取指定轮播图信息
func (s *sSysBanner) View(ctx context.Context, in *sysin.BannerViewInp) (res *sysin.BannerViewModel, err error) {
var banner entity.Banner
err = dao.Banner.Ctx(ctx).Where(dao.Banner.Columns().Id, in.Id).Scan(&banner)
if err != nil {
err = gerror.Wrap(err, "获取轮播图信息失败")
return
}
if banner.Id == 0 {
err = gerror.New("轮播图不存在")
return
}
res = &sysin.BannerViewModel{Banner: banner}
return
}
// List 获取轮播图列表
func (s *sSysBanner) List(ctx context.Context, in *sysin.BannerListInp) (list []*sysin.BannerListModel, totalCount int, err error) {
m := dao.Banner.Ctx(ctx)
// 条件查询
if in.Name != "" {
m = m.WhereLike(dao.Banner.Columns().Name, "%"+in.Name+"%")
}
if in.Type > 0 {
m = m.Where(dao.Banner.Columns().Type, in.Type)
}
var banners []*entity.Banner
if in.Page > 0 && in.PerPage > 0 {
err = m.Page(in.Page, in.PerPage).OrderDesc(dao.Banner.Columns().Sort).OrderDesc(dao.Banner.Columns().Id).ScanAndCount(&banners, &totalCount, false)
} else {
err = m.OrderDesc(dao.Banner.Columns().Sort).OrderDesc(dao.Banner.Columns().Id).ScanAndCount(&banners, &totalCount, false)
}
if err != nil {
err = gerror.Wrap(err, "获取轮播图列表失败")
return
}
list = make([]*sysin.BannerListModel, len(banners))
for i, banner := range banners {
list[i] = &sysin.BannerListModel{Banner: *banner}
}
return
}
// Status 更新轮播图状态
func (s *sSysBanner) Status(ctx context.Context, in *sysin.BannerStatusInp) (err error) {
_, err = dao.Banner.Ctx(ctx).Where(dao.Banner.Columns().Id, in.Id).Data(g.Map{
dao.Banner.Columns().Status: in.Status,
dao.Banner.Columns().UpdatedAt: gtime.Now(),
}).Update()
if err != nil {
err = gerror.Wrap(err, "更新轮播图状态失败")
return
}
return
}

View File

@@ -0,0 +1,59 @@
// Package sys
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sys
import (
"context"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/addons/flashbanner/global"
"hotgo/addons/flashbanner/model"
"hotgo/addons/flashbanner/model/input/sysin"
"hotgo/addons/flashbanner/service"
isc "hotgo/internal/service"
)
type sSysConfig struct{}
func NewSysConfig() *sSysConfig {
return &sSysConfig{}
}
func init() {
service.RegisterSysConfig(NewSysConfig())
}
// GetBasic 获取基础配置
func (s *sSysConfig) GetBasic(ctx context.Context) (conf *model.BasicConfig, err error) {
var in sysin.GetConfigInp
in.GetAddonsConfigInp.AddonName = global.GetSkeleton().Name
in.GetAddonsConfigInp.Group = "basic"
models, err := isc.SysAddonsConfig().GetConfigByGroup(ctx, &in.GetAddonsConfigInp)
if err != nil {
return
}
err = gconv.Struct(models.List, &conf)
return
}
// GetConfigByGroup 获取指定分组配置
func (s *sSysConfig) GetConfigByGroup(ctx context.Context, in *sysin.GetConfigInp) (res *sysin.GetConfigModel, err error) {
in.GetAddonsConfigInp.AddonName = global.GetSkeleton().Name
models, err := isc.SysAddonsConfig().GetConfigByGroup(ctx, &in.GetAddonsConfigInp)
if err != nil {
return
}
res = new(sysin.GetConfigModel)
res.List = models.List
return
}
// UpdateConfigByGroup 更新指定分组的配置
func (s *sSysConfig) UpdateConfigByGroup(ctx context.Context, in *sysin.UpdateConfigInp) error {
in.UpdateAddonsConfigInp.AddonName = global.GetSkeleton().Name
return isc.SysAddonsConfig().UpdateConfigByGroup(ctx, &in.UpdateAddonsConfigInp)
}

View File

@@ -0,0 +1,35 @@
// Package sys
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sys
import (
"context"
"fmt"
"github.com/gogf/gf/v2/os/gtime"
"hotgo/addons/flashbanner/global"
"hotgo/addons/flashbanner/model/input/sysin"
"hotgo/addons/flashbanner/service"
"hotgo/internal/library/contexts"
)
type sSysIndex struct{}
func NewSysIndex() *sSysIndex {
return &sSysIndex{}
}
func init() {
service.RegisterSysIndex(NewSysIndex())
}
// Test 测试
func (s *sSysIndex) Test(ctx context.Context, in *sysin.IndexTestInp) (res *sysin.IndexTestModel, err error) {
res = new(sysin.IndexTestModel)
res.Name = in.Name
res.Module = fmt.Sprintf("当前插件模块是:%s当前应用模块是%s", global.GetSkeleton().Name, contexts.Get(ctx).Module)
res.Time = gtime.Now()
return
}

View File

@@ -0,0 +1,176 @@
// Package flashbanner
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package flashbanner
import (
"context"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gctx"
_ "hotgo/addons/flashbanner/crons"
"hotgo/addons/flashbanner/global"
_ "hotgo/addons/flashbanner/logic"
_ "hotgo/addons/flashbanner/queues"
"hotgo/addons/flashbanner/router"
"hotgo/addons/migrations"
"hotgo/internal/library/addons"
"hotgo/internal/service"
"sync"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
)
type module struct {
skeleton *addons.Skeleton
ctx context.Context
sync.Mutex
}
func init() {
newModule()
}
func newModule() {
m := &module{
skeleton: &addons.Skeleton{
Label: `轮播图管理`,
Name: `flashbanner`,
Group: 6,
Logo: "",
Brief: ``,
Description: ``,
Author: ``,
Version: `v1.0.0`, // 当该版本号高于已安装的版本号时,会提示可以更新
},
ctx: gctx.New(),
}
addons.RegisterModule(m)
}
// Start 启动模块
func (m *module) Start(option *addons.Option) (err error) {
// 初始化模块
global.Init(m.ctx, m.skeleton)
// 注册插件路由
option.Server.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(service.Middleware().Addon)
router.Admin(m.ctx, group)
router.Api(m.ctx, group)
router.Home(m.ctx, group)
router.WebSocket(m.ctx, group)
})
return
}
// Stop 停止模块
func (m *module) Stop() (err error) {
return
}
// Ctx 上下文
func (m *module) Ctx() context.Context {
return m.ctx
}
// GetSkeleton 获取模块
func (m *module) GetSkeleton() *addons.Skeleton {
return m.skeleton
}
// Install 安装模块
func (m *module) Install(ctx context.Context) (err error) {
// 执行数据库安装文件
// 获取当前目录
sqlPath := gfile.Pwd() + gfile.Separator + "addons/migrations/flashbanner/install.sql"
g.Log().Debug(ctx, "安装模块", m.skeleton.Label, "路径", sqlPath)
result, err := migrations.DoSqlContent(ctx, sqlPath)
if err != nil {
g.Log().Error(ctx, "安装模块", m.skeleton.Label, "失败", err)
return
}
g.Log().Debug(ctx, "安装模块", m.skeleton.Label, "成功", result)
// 复制web目录下的文件到管理后台对应位置
// 插件的前端配置文件位于插件目录下的web子目录
sourceWebPath := gfile.Pwd() + gfile.Separator + "addons/" + m.skeleton.Name + "/web/src/views/addons/" + m.skeleton.Name
targetWebPath := "../web/src/views/addons/" + m.skeleton.Name
g.Log().Debug(ctx, "复制前端配置文件", "源路径:", sourceWebPath, "目标路径:", targetWebPath)
// 检查源路径是否存在
if gfile.Exists(sourceWebPath) {
err = gfile.CopyDir(sourceWebPath, targetWebPath)
if err != nil {
g.Log().Error(ctx, "复制前端配置文件失败:", err)
} else {
g.Log().Debug(ctx, "复制前端配置文件成功")
}
} else {
g.Log().Warning(ctx, "前端配置文件源路径不存在:", sourceWebPath)
}
// 复制API文件
sourceApiPath := gfile.Pwd() + gfile.Separator + "addons/" + m.skeleton.Name + "/web/src/api/addons/" + m.skeleton.Name
targetApiPath := "../web/src/api/addons/" + m.skeleton.Name
g.Log().Debug(ctx, "复制API文件", "源路径:", sourceApiPath, "目标路径:", targetApiPath)
if gfile.Exists(sourceApiPath) {
err = gfile.CopyDir(sourceApiPath, targetApiPath)
if err != nil {
g.Log().Error(ctx, "复制API文件失败:", err)
} else {
g.Log().Debug(ctx, "复制API文件成功")
}
} else {
g.Log().Warning(ctx, "API文件源路径不存在:", sourceApiPath)
}
return
}
// Upgrade 更新模块
func (m *module) Upgrade(ctx context.Context) (err error) {
// ...
return
}
// UnInstall 卸载模块
func (m *module) UnInstall(ctx context.Context) (err error) {
// ...
// 移除数据库安装文件
sqlPath := gfile.Pwd() + gfile.Separator + "addons/migrations/flashbanner/uninstall.sql"
g.Log().Debug(ctx, "卸载模块", m.skeleton.Label, "路径", sqlPath)
result, err := migrations.DoSqlContent(ctx, sqlPath)
if err != nil {
g.Log().Error(ctx, "卸载模块", m.skeleton.Label, "失败", err)
return
}
g.Log().Debug(ctx, "卸载模块", m.skeleton.Label, "成功", result)
// 删除前端文件
targetWebPath := "../web/src/views/addons/" + m.skeleton.Name
targetApiPath := "../web/src/api/addons/" + m.skeleton.Name
// 删除配置页面文件
if gfile.Exists(targetWebPath) {
err = gfile.Remove(targetWebPath)
if err != nil {
g.Log().Warning(ctx, "删除前端配置文件失败:", err)
} else {
g.Log().Debug(ctx, "删除前端配置文件成功")
}
}
// 删除API文件
if gfile.Exists(targetApiPath) {
err = gfile.Remove(targetApiPath)
if err != nil {
g.Log().Warning(ctx, "删除API文件失败:", err)
} else {
g.Log().Debug(ctx, "删除API文件成功")
}
}
return
}

View File

@@ -0,0 +1,11 @@
// Package model
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package model
// BasicConfig 基础配置
type BasicConfig struct {
Test string `json:"basicTest"`
}

View File

@@ -0,0 +1,22 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// Banner is the golang structure for table banner.
type Banner struct {
Id int `json:"id" orm:"id" description:""`
Name string `json:"name" orm:"name" description:"轮播图名称"`
Cover string `json:"cover" orm:"cover" description:"图片URL"`
Link string `json:"link" orm:"link" description:"跳转链接,小程序内用相对地址"`
Type int `json:"type" orm:"type" description:"类型默认不传"`
Status uint `json:"status" orm:"status" description:"1可用"`
Sort int `json:"sort" orm:"sort" description:"排序,数字越大越靠前"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""`
}

View File

@@ -0,0 +1,98 @@
// Package sysin
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sysin
import (
"context"
"hotgo/addons/flashbanner/model/entity"
"hotgo/internal/model/input/form"
"github.com/gogf/gf/v2/errors/gerror"
)
// BannerCreateInp 创建轮播图
type BannerCreateInp struct {
Name string `json:"name" v:"required#轮播图名称不能为空" dc:"轮播图名称"`
Cover string `json:"cover" v:"required#轮播图封面不能为空" dc:"轮播图封面"`
Link string `json:"link" dc:"轮播图链接"`
Type int `json:"type" dc:"轮播图类型"`
Sort int `json:"sort" dc:"排序,数字越大越靠前"`
}
func (in *BannerCreateInp) Filter(ctx context.Context) (err error) {
return
}
type BannerCreateModel struct{}
// BannerEditInp 修改/新增轮播图
type BannerEditInp struct {
entity.Banner
}
func (in *BannerEditInp) Filter(ctx context.Context) (err error) {
if in.Name == "" {
err = gerror.New("轮播图名称不能为空")
return
}
if in.Cover == "" {
err = gerror.New("轮播图封面不能为空")
return
}
return
}
type BannerEditModel struct{}
// BannerDeleteInp 删除轮播图
type BannerDeleteInp struct {
Id interface{} `json:"id" v:"required#轮播图ID不能为空" dc:"轮播图ID"`
}
func (in *BannerDeleteInp) Filter(ctx context.Context) (err error) {
return
}
type BannerDeleteModel struct{}
// BannerViewInp 获取指定轮播图信息
type BannerViewInp struct {
Id int64 `json:"id" v:"required#轮播图ID不能为空" dc:"轮播图ID"`
}
func (in *BannerViewInp) Filter(ctx context.Context) (err error) {
return
}
type BannerViewModel struct {
entity.Banner
}
// BannerListInp 获取轮播图列表
type BannerListInp struct {
form.PageReq
Name string `json:"name" dc:"轮播图名称"`
Type int `json:"type" dc:"轮播图类型"`
}
func (in *BannerListInp) Filter(ctx context.Context) (err error) {
return
}
type BannerListModel struct {
entity.Banner
}
// BannerStatusInp 更新轮播图状态
type BannerStatusInp struct {
Id int64 `json:"id" v:"required#轮播图ID不能为空" dc:"轮播图ID"`
Status int `json:"status" v:"required#状态不能为空" dc:"状态"`
}
func (in *BannerStatusInp) Filter(ctx context.Context) (err error) {
return
}
type BannerStatusModel struct{}

View File

@@ -0,0 +1,24 @@
// Package sysin
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sysin
import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/internal/model/input/sysin"
)
// UpdateConfigInp 更新指定配置
type UpdateConfigInp struct {
sysin.UpdateAddonsConfigInp
}
type GetConfigInp struct {
sysin.GetAddonsConfigInp
}
type GetConfigModel struct {
List g.Map `json:"list"`
}

View File

@@ -0,0 +1,27 @@
// Package sysin
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package sysin
import (
"context"
"github.com/gogf/gf/v2/os/gtime"
)
// IndexTestInp 测试
type IndexTestInp struct {
Name string `json:"name" d:"HotGo" dc:"名称"`
}
func (in *IndexTestInp) Filter(ctx context.Context) (err error) {
return
}
type IndexTestModel struct {
Name string `json:"name" dc:"名称"`
Module string `json:"module" dc:"当前插件模块"`
Time *gtime.Time `json:"time" dc:"当前时间"`
}

View File

@@ -0,0 +1,9 @@
// Package queues
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package queues
// 消息队列.
// 插件中的消息队列消费者可以统一在这里注册和处理

View File

@@ -0,0 +1 @@
Hello这是创建插件 [轮播图管理] 时默认生成的一个静态目录文件用于测试当你看到这个提示时说明已经联调成功啦

View File

@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no">
<meta name="keywords" content="@{.Keywords}"/>
<meta name="description" content="@{.Description}"/>
<title>@{.Title}</title>
<script type="text/javascript" src="/resource/home/js/jquery-3.6.0.min.js"></script>
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background-color: #f6f6f6;
}
</style>
</head>
<body>
<div style="padding-top: 100px;text-align:center;">
<h1><p>Hello@{.Data.name}!!</p></h1>
<h2><p>@{.Data.module}</p></h2>
<h2><p>服务器时间@{.Data.time}</p></h2>
</div>
</body>
<script>
</script>
</html>

View File

@@ -0,0 +1,36 @@
// Package router
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package router
import (
"context"
"github.com/gogf/gf/v2/net/ghttp"
"hotgo/addons/flashbanner/controller/admin/sys"
"hotgo/addons/flashbanner/controller/admin/banner"
"hotgo/addons/flashbanner/global"
"hotgo/addons/flashbanner/router/genrouter"
"hotgo/internal/consts"
"hotgo/internal/library/addons"
"hotgo/internal/service"
)
// Admin 后台路由
func Admin(ctx context.Context, group *ghttp.RouterGroup) {
prefix := addons.RouterPrefix(ctx, consts.AppAdmin, global.GetSkeleton().Name)
group.Group(prefix, func(group *ghttp.RouterGroup) {
group.Bind(
sys.Index,
)
group.Middleware(service.Middleware().AdminAuth)
group.Bind(
sys.Config,
banner.Banner,
)
})
// 注册生成路由
genrouter.Register(ctx, group)
}

View File

@@ -0,0 +1,32 @@
// Package router
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package router
import (
"context"
"github.com/gogf/gf/v2/net/ghttp"
"hotgo/addons/flashbanner/controller/api/banner"
"hotgo/addons/flashbanner/global"
"hotgo/internal/consts"
"hotgo/internal/library/addons"
"hotgo/internal/service"
)
// Api 前台路由
func Api(ctx context.Context, group *ghttp.RouterGroup) {
prefix := addons.RouterPrefix(ctx, consts.AppApi, global.GetSkeleton().Name)
group.Group(prefix, func(group *ghttp.RouterGroup) {
group.Bind(
// 无需验证的路由
banner.BannerIndex,
)
group.Middleware(service.Middleware().ApiAuth)
group.Bind(
// 需要验证的路由
// ...
)
})
}

View File

@@ -0,0 +1,34 @@
// Package genrouter
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package genrouter
import (
"context"
"github.com/gogf/gf/v2/net/ghttp"
"hotgo/addons/flashbanner/global"
"hotgo/internal/consts"
"hotgo/internal/library/addons"
"hotgo/internal/service"
)
var (
NoLoginRouter []interface{} // 无需登录
LoginRequiredRouter []interface{} // 需要登录
)
// Register 注册通过代码生成的后台路由
func Register(ctx context.Context, group *ghttp.RouterGroup) {
prefix := addons.RouterPrefix(ctx, consts.AppAdmin, global.GetSkeleton().Name)
group.Group(prefix, func(group *ghttp.RouterGroup) {
if len(NoLoginRouter) > 0 {
group.Bind(NoLoginRouter...)
}
group.Middleware(service.Middleware().AdminAuth)
if len(LoginRequiredRouter) > 0 {
group.Bind(LoginRequiredRouter...)
}
})
}

View File

@@ -0,0 +1,25 @@
// Package router
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package router
import (
"context"
"github.com/gogf/gf/v2/net/ghttp"
"hotgo/addons/flashbanner/controller/home"
"hotgo/addons/flashbanner/global"
"hotgo/internal/consts"
"hotgo/internal/library/addons"
)
// Home 前台页面路由
func Home(ctx context.Context, group *ghttp.RouterGroup) {
prefix := addons.RouterPrefix(ctx, consts.AppHome, global.GetSkeleton().Name)
group.Group(prefix, func(group *ghttp.RouterGroup) {
group.Bind(
home.Index,
)
})
}

View File

@@ -0,0 +1,39 @@
// Package router
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package router
import (
"context"
"github.com/gogf/gf/v2/net/ghttp"
"hotgo/addons/flashbanner/controller/websocket"
"hotgo/addons/flashbanner/global"
"hotgo/internal/consts"
"hotgo/internal/library/addons"
"hotgo/internal/service"
ws "hotgo/internal/websocket"
)
// WebSocket ws路由配置
func WebSocket(ctx context.Context, group *ghttp.RouterGroup) {
prefix := addons.RouterPrefix(ctx, consts.AppWebSocket, global.GetSkeleton().Name)
group.Group(prefix, func(group *ghttp.RouterGroup) {
group.Bind(
// 无需验证的路由
websocket.Index,
)
// ws连接中间件
group.Middleware(service.Middleware().WebSocketAuth)
group.Bind(
// 需要验证的路由
// ..
)
})
// 注册消息路由
ws.RegisterMsg(ws.EventHandlers{
// ...
})
}

View File

@@ -0,0 +1,71 @@
// ================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
import (
"context"
"hotgo/addons/flashbanner/model"
"hotgo/addons/flashbanner/model/input/sysin"
)
type (
ISysConfig interface {
GetBasic(ctx context.Context) (conf *model.BasicConfig, err error)
GetConfigByGroup(ctx context.Context, in *sysin.GetConfigInp) (res *sysin.GetConfigModel, err error)
UpdateConfigByGroup(ctx context.Context, in *sysin.UpdateConfigInp) error
}
ISysIndex interface {
Test(ctx context.Context, in *sysin.IndexTestInp) (res *sysin.IndexTestModel, err error)
}
ISysBanner interface {
Create(ctx context.Context, in *sysin.BannerCreateInp) (err error)
Edit(ctx context.Context, in *sysin.BannerEditInp) (err error)
Delete(ctx context.Context, in *sysin.BannerDeleteInp) (err error)
View(ctx context.Context, in *sysin.BannerViewInp) (res *sysin.BannerViewModel, err error)
List(ctx context.Context, in *sysin.BannerListInp) (list []*sysin.BannerListModel, totalCount int, err error)
Status(ctx context.Context, in *sysin.BannerStatusInp) (err error)
GetMaxSort(ctx context.Context) (maxSort int, err error)
}
)
var (
localSysConfig ISysConfig
localSysIndex ISysIndex
localSysBanner ISysBanner
)
func SysConfig() ISysConfig {
if localSysConfig == nil {
panic("implement not found for interface ISysConfig, forgot register?")
}
return localSysConfig
}
func RegisterSysConfig(i ISysConfig) {
localSysConfig = i
}
func SysIndex() ISysIndex {
if localSysIndex == nil {
panic("implement not found for interface ISysIndex, forgot register?")
}
return localSysIndex
}
func RegisterSysIndex(i ISysIndex) {
localSysIndex = i
}
func SysBanner() ISysBanner {
if localSysBanner == nil {
panic("implement not found for interface ISysBanner, forgot register?")
}
return localSysBanner
}
func RegisterSysBanner(i ISysBanner) {
localSysBanner = i
}

View File

@@ -0,0 +1,17 @@
import { http } from '@/utils/http/axios';
export function getConfig(params) {
return http.request({
url: '/flashbanner/config/get',
method: 'get',
params,
});
}
export function updateConfig(params) {
return http.request({
url: '/flashbanner/config/update',
method: 'post',
params,
});
}

View File

@@ -0,0 +1,33 @@
import { http } from '@/utils/http/axios';
export function List(params) {
return http.request({
url: '/flashbanner/banner/list',
method: 'GET',
params,
});
}
export function Add(params) {
return http.request({
url: '/flashbanner/banner/create',
method: 'POST',
params,
});
}
export function Edit(params) {
return http.request({
url: '/flashbanner/banner/edit',
method: 'POST',
params,
});
}
export function Delete(params) {
return http.request({
url: '/flashbanner/banner/delete',
method: 'POST',
params,
});
}

View File

@@ -0,0 +1,106 @@
<template>
<div>
<n-modal
v-model:show="showModal"
:on-after-leave="cancelForm"
:mask-closable="false"
:show-icon="false"
preset="dialog"
:title="formParams?.id > 0 ? '编辑 #' + formParams?.id : '添加'"
:style="{
width: dialogWidth,
}"
>
<n-form
:model="formParams"
:rules="rules"
ref="formRef"
label-placement="left"
:label-width="100"
class="py-8"
>
<n-grid x-gap="24" :cols="1">
<n-gi>
<n-form-item label="名称" path="name">
<n-input placeholder="请输入名称" v-model:value="formParams.name" />
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="上传图片" path="cover">
<UploadImage v-model:value="formParams.cover" />
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="链接地址" path="link">
<n-input placeholder="请输入链接地址" v-model:value="formParams.link" />
</n-form-item>
</n-gi>
</n-grid>
</n-form>
<template #action>
<n-space>
<n-button @click="cancelForm">取消</n-button>
<n-button type="info" :loading="formBtnLoading" @click="confirmForm">确定</n-button>
</n-space>
</template>
</n-modal>
</div>
</template>
<script lang="ts" setup>
import { h, reactive, ref, computed, defineExpose, defineEmits } from 'vue';
import { useDialog, useMessage } from 'naive-ui';
import UploadImage from '@/components/Upload/uploadImage.vue';
import { rules } from './model';
import { Edit, Add } from '@/api/addons/flashbanner/index';
import { adaModalWidth } from '@/utils/hotgo';
import { cloneDeep } from 'lodash-es';
const emit = defineEmits(['on-refresh']);
const defaultState = {
name: '',
cover: '',
link: '',
};
const message = useMessage();
const showModal = ref(false);
const formBtnLoading = ref(false);
const formRef = ref<any>();
const formParams = ref<any>(cloneDeep(defaultState));
const dialogWidth = computed(() => {
return adaModalWidth();
});
// 关闭表单
const cancelForm = () => {
showModal.value = false;
formParams.value = cloneDeep(defaultState);
};
// 新增或编辑
function confirmForm(e) {
e.preventDefault();
formBtnLoading.value = true;
const Request = formParams.value.id > 0 ? Edit : Add;
formRef.value.validate((errors) => {
if (!errors) {
Request(formParams.value).then((_res) => {
message.success('操作成功');
cancelForm();
emit('on-refresh');
});
} else {
message.error('请填写完整信息');
}
formBtnLoading.value = false;
});
}
defineExpose({ showModal, formParams });
</script>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,83 @@
import { h, render } from 'vue';
import { FormSchema, useForm } from '@/components/Form';
import { NImage } from 'naive-ui';
import { fallbackSrc } from '@/utils/hotgo';
// **********查询表单********
const detailSchemas: FormSchema[] = [
{
field: 'name',
component: 'NInput',
label: '图片名称',
defaultValue: null,
componentProps: {
placeholder: '请输入图片名称',
},
},
];
export const [register, {}] = useForm({
gridProps: { cols: '1 s:1 m:2 l:3 xl:4 2xl:4' },
labelWidth: 80,
schemas: detailSchemas,
});
// *********表格**********
export const defaultColumns = [
{
title: 'ID',
key: 'id',
width: 100,
},
{
title: '图片名称',
key: 'name',
},
{
title: '图片',
key: 'cover',
render(row) {
if (row.cover !== '') {
return h(NImage, {
width: 40,
height: 40,
src: row.cover,
fallbackSrc: fallbackSrc(),
style: {
width: '40px',
height: '40px',
'max-width': '100%',
'max-height': '100%',
},
});
} else {
return '暂无图片'
}
},
},
{
title: '链接地址',
key: 'link',
render(row) {
return h('a', { href: row.link, target: '_blank' }, row.link);
}
},
{
title: '创建时间',
key: 'createdAt',
width: 180,
},
];
// *********编辑表单规则***********
export const rules = {
name: {
required: true,
trigger: ['blur', 'input'],
message: '请输入图片名称',
},
cover: {
required: true,
trigger: ['blur', 'input'],
message: '请上传图片',
},
};

View File

@@ -0,0 +1,74 @@
<template>
<div>
<n-spin :show="show" description="请稍候...">
<n-form :label-width="80" :model="formValue" :rules="rules" ref="formRef">
<n-form-item label="测试参数" path="basicTest">
<n-input v-model:value="formValue.basicTest" placeholder="请输入测试参数" />
<template #feedback>
这是一个测试参数每个插件都可以有独立的配置项可以按需添加</template
>
</n-form-item>
<div>
<n-space>
<n-button type="primary" @click="formSubmit">保存更新</n-button>
</n-space>
</div>
</n-form>
</n-spin>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { useMessage } from 'naive-ui';
import { getConfig, updateConfig } from '@/api/addons/flashbanner/config';
const group = ref('basic');
const show = ref(false);
const rules = {
basicTest: {
required: true,
message: '请输入测试参数',
trigger: 'blur',
},
};
const formRef: any = ref(null);
const message = useMessage();
const formValue = ref({
basicTest: 'HotGo',
});
function formSubmit() {
formRef.value.validate((errors) => {
if (!errors) {
updateConfig({ group: group.value, list: formValue.value }).then((_res) => {
message.success('更新成功');
load();
});
} else {
message.error('验证失败请填写完整信息');
}
});
}
onMounted(() => {
load();
});
function load() {
show.value = true;
new Promise((_resolve, _reject) => {
getConfig({ group: group.value })
.then((res) => {
formValue.value = res.list;
})
.finally(() => {
show.value = false;
});
});
}
</script>

View File

@@ -0,0 +1,82 @@
<template>
<div>
<n-grid cols="24 300:1 600:24" :x-gap="12">
<n-grid-item span="6">
<n-card :bordered="false" size="small" class="proCard">
<n-thing
class="thing-cell"
v-for="item in typeTabList"
:key="item.key"
:class="{ 'thing-cell-on': type === item.key }"
@click="switchType(item)"
>
<template #header>{{ item.name }}</template>
<template #description>{{ item.desc }}</template>
</n-thing>
</n-card>
</n-grid-item>
<n-grid-item span="18">
<n-card :bordered="false" size="small" :title="typeTitle" class="proCard">
<BasicSetting v-if="type === 1" />
</n-card>
</n-grid-item>
</n-grid>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs } from 'vue';
import BasicSetting from './BasicSetting.vue';
const typeTabList = [
{
name: '基本设置',
desc: '系统常规设置',
key: 1,
},
];
export default defineComponent({
components: {
BasicSetting,
},
setup() {
const state = reactive({
type: 1,
typeTitle: '基本设置',
});
function switchType(e) {
state.type = e.key;
state.typeTitle = e.name;
}
return {
...toRefs(state),
switchType,
typeTabList,
};
},
});
</script>
<style lang="less" scoped>
.thing-cell {
margin: 0 -16px 10px;
padding: 5px 16px;
&:hover {
background: #f3f3f3;
cursor: pointer;
}
}
.thing-cell-on {
background: #f0faff;
color: #2d8cf0;
::v-deep(.n-thing-main .n-thing-header .n-thing-header__title) {
color: #2d8cf0;
}
&:hover {
background: #f0faff;
}
}
</style>

View File

@@ -0,0 +1,151 @@
<template>
<div>
<n-card :bordered="false" class="proCard" title="轮播图管理">
<BasicForm
@register="register"
@submit="handleQuery"
@reset="resetForm"
@keyup.enter="handleQuery"
ref="searchFormRef"
>
<template #statusSlot="{ model, field }">
<n-input v-model:value="model[field]" />
</template>
</BasicForm>
<BasicTable
:openChecked="true"
:columns="columns"
:actionColumn="actionColumn"
:request="loadDataTable"
:row-key="(row) => row.id"
ref="tableRef"
:scroll-x="scrollX"
:resizeHeightOffset="-10000"
>
<template #tableTitle>
<n-button
type="primary"
@click="handleAdd"
class="min-left-space"
v-if="hasPermission(['/member/edit'])"
>
<template #icon>
<n-icon>
<PlusOutlined />
</n-icon>
</template>
添加
</n-button>
</template>
</BasicTable>
<BasicEdit ref="editRef" @on-refresh="onRefresh" />
</n-card>
</div>
</template>
<script lang="ts" setup>
import { h, onMounted, ref, computed, watch, reactive } from 'vue';
import { register, defaultColumns } from './components/model';
import BasicEdit from './components/Edit.vue';
import { BasicForm } from '@/components/Form/index';
import { BasicTable, TableAction } from '@/components/Table';
import { usePermission } from '@/hooks/web/usePermission';
import { List, Delete } from '@/api/addons/flashbanner/index';
import { PlusOutlined } from '@vicons/antd';
import { useDialog, useMessage } from 'naive-ui';
import { cloneDeep } from 'lodash-es';
import { adaTableScrollX } from '@/utils/hotgo';
interface TableActionState {
reload: () => void;
}
const { hasPermission } = usePermission();
const dialog = useDialog();
const message = useMessage();
const formParams = ref({});
const tableRef = ref<TableActionState>();
const editRef = ref();
const columns = ref(defaultColumns);
const actionColumn = reactive({
width: 200,
title: '操作',
key: 'action',
fixed: 'right',
render(record) {
return h(TableAction as any, {
style: 'button',
actions: [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: ['/member/delete'],
},
{
label: '删除',
onClick: handleDelete.bind(null, record),
auth: ['/member/delete'],
},
],
});
},
});
const scrollX = computed(() => {
return adaTableScrollX(defaultColumns, actionColumn.width);
});
const loadDataTable = async (res) => {
return await List({ ...formParams.value, ...res });
};
// 刷新table
const onRefresh = () => {
tableRef.value?.reload();
};
// 重置查询框
const resetForm = () => {
formParams.value = {};
onRefresh();
};
// 查询
const handleQuery = (e: any) => {
formParams.value = { ...e };
onRefresh();
};
// 添加
const handleAdd = () => {
if (editRef.value) {
editRef.value.showModal = true;
}
};
// 编辑
const handleEdit = (record: Recordable) => {
if (editRef.value) {
editRef.value.showModal = true;
editRef.value.formParams = cloneDeep(record);
}
}
// 删除
const handleDelete = (record: Recordable) => {
dialog.warning({
title: '警告',
content: '你确定要删除',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
Delete({ id: record.id }).then((_res) => {
message.success('操作成功');
onRefresh();
});
},
});
}
</script>
<style lang="less"></style>

View File

@@ -153,7 +153,7 @@ func (s *sSysTable) Edit(ctx context.Context, in *sysin.TableEditInp) (err error
// 新增 // 新增
in.CreatedBy = contexts.GetUserId(ctx) in.CreatedBy = contexts.GetUserId(ctx)
if _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).Data(in).Insert(); err != nil { if _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).Data(in).OmitEmptyData().Insert(); err != nil {
err = gerror.Wrap(err, "新增表格失败,请稍后重试!") err = gerror.Wrap(err, "新增表格失败,请稍后重试!")
return return
} }

View File

@@ -133,7 +133,6 @@ func (s *sSysTenantOrder) Export(ctx context.Context, in *sysin.TenantOrderListI
// Edit 修改/新增多租户功能演示 // Edit 修改/新增多租户功能演示
func (s *sSysTenantOrder) Edit(ctx context.Context, in *sysin.TenantOrderEditInp) (err error) { func (s *sSysTenantOrder) Edit(ctx context.Context, in *sysin.TenantOrderEditInp) (err error) {
return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) { return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
// 修改 // 修改
if in.Id > 0 { if in.Id > 0 {
if _, err = s.Model(ctx). if _, err = s.Model(ctx).
@@ -158,7 +157,6 @@ func (s *sSysTenantOrder) Edit(ctx context.Context, in *sysin.TenantOrderEditInp
// Delete 删除多租户功能演示 // Delete 删除多租户功能演示
func (s *sSysTenantOrder) Delete(ctx context.Context, in *sysin.TenantOrderDeleteInp) (err error) { func (s *sSysTenantOrder) Delete(ctx context.Context, in *sysin.TenantOrderDeleteInp) (err error) {
if _, err = s.Model(ctx).WherePri(in.Id).Delete(); err != nil { if _, err = s.Model(ctx).WherePri(in.Id).Delete(); err != nil {
err = gerror.Wrap(err, "删除多租户功能演示失败,请稍后重试!") err = gerror.Wrap(err, "删除多租户功能演示失败,请稍后重试!")
return return

View File

@@ -125,7 +125,7 @@ func (s *sSysTreeTable) Edit(ctx context.Context, in *sysin.TableEditInp) (err e
} }
} else { } else {
in.CreatedBy = contexts.GetUserId(ctx) in.CreatedBy = contexts.GetUserId(ctx)
if _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).Data(in).Insert(); err != nil { if _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).Data(in).OmitEmptyData().Insert(); err != nil {
err = gerror.Wrap(err, "新增表格失败,请稍后重试!") err = gerror.Wrap(err, "新增表格失败,请稍后重试!")
return err return err
} }

View File

@@ -0,0 +1,167 @@
-- 删除表如果存在
DROP TABLE IF EXISTS hg_banner;
-- 创建表
CREATE TABLE hg_banner (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
cover VARCHAR(255) DEFAULT NULL,
link VARCHAR(255) DEFAULT NULL,
type INTEGER DEFAULT 0,
status SMALLINT DEFAULT 1,
sort INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NULL,
updated_at TIMESTAMP DEFAULT NULL
);
-- 添加表注释
COMMENT ON TABLE hg_banner IS '轮播图表';
-- 添加列注释
COMMENT ON COLUMN hg_banner.name IS '轮播图名称';
COMMENT ON COLUMN hg_banner.cover IS '图片URL';
COMMENT ON COLUMN hg_banner.link IS '跳转链接小程序内用相对地址';
COMMENT ON COLUMN hg_banner.type IS '类型默认不传';
COMMENT ON COLUMN hg_banner.status IS '1可用,2不可用';
COMMENT ON COLUMN hg_banner.sort IS '排序数字越大越靠前';
-- 添加 updated_at 字段的更新触发器模拟 MySQL ON UPDATE CURRENT_TIMESTAMP
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_update_updated_at
BEFORE UPDATE ON hg_banner
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- 添加菜单项
-- 先查找或创建"内容管理"父菜单如果不存在
INSERT INTO hg_admin_menu (pid, level, tree, title, name, path, icon, type, redirect, permissions, permission_name, component, always_show, active_menu, is_root, is_frame, frame_src, keep_alive, hidden, affix, sort, remark, status, updated_at, created_at)
SELECT 0, 1, '', '内容管理', 'content', '/content', 'BookOutlined', 1, '/content', '', '', 'LAYOUT', 2, '', 1, 2, '', 2, 2, 2, 12, '内容管理模块', 1, NOW(), NOW()
WHERE NOT EXISTS (SELECT 1 FROM hg_admin_menu WHERE name = 'content');
-- 获取内容管理菜单ID并添加轮播图管理菜单
WITH content_parent AS (
SELECT id FROM hg_admin_menu WHERE name = 'content' LIMIT 1
),
inserted_menu AS (
INSERT INTO hg_admin_menu (pid, level, tree, title, name, path, icon, type, redirect, permissions, permission_name, component, always_show, active_menu, is_root, is_frame, frame_src, keep_alive, hidden, affix, sort, remark, status, updated_at, created_at)
SELECT
cp.id,
2,
'tr_' || cp.id::text || ' ',
'轮播图管理',
'flashbanner',
'/flashbanner',
'',
2,
'',
'/flashbanner/banner/list',
'',
'/addons/flashbanner/index',
2,
'',
2,
2,
'',
1,
2,
2,
10,
'轮播图管理模块',
1,
NOW(),
NOW()
FROM content_parent cp
RETURNING id
)
-- 添加子菜单和按钮
INSERT INTO hg_admin_menu (pid, level, tree, title, name, path, icon, type, redirect, permissions, permission_name, component, always_show, active_menu, is_root, is_frame, frame_src, keep_alive, hidden, affix, sort, remark, status, updated_at, created_at)
SELECT
im.id,
3,
'tr_' || (SELECT id FROM content_parent)::text || ' tr_' || im.id::text || ' ',
'新增轮播',
'addbanner',
'',
'',
3,
'',
'/flashbanner/banner/create',
'',
'',
2,
'',
2,
2,
'',
2,
2,
2,
10,
'新增轮播图权限',
1,
NOW(),
NOW()
FROM inserted_menu im
UNION ALL
SELECT
im.id,
3,
'tr_' || (SELECT id FROM content_parent)::text || ' tr_' || im.id::text || ' ',
'轮播编辑',
'editbanner',
'',
'',
3,
'',
'/flashbanner/banner/update',
'',
'',
2,
'',
2,
2,
'',
2,
2,
2,
10,
'编辑轮播图权限',
1,
NOW(),
NOW()
FROM inserted_menu im
UNION ALL
SELECT
im.id,
3,
'tr_' || (SELECT id FROM content_parent)::text || ' tr_' || im.id::text || ' ',
'删除轮播',
'delbanner',
'',
'',
3,
'',
'/flashbanner/banner/delete',
'',
'',
2,
'',
2,
2,
'',
2,
2,
2,
10,
'删除轮播图权限',
1,
NOW(),
NOW()
FROM inserted_menu im;

View File

@@ -0,0 +1,33 @@
DROP TABLE IF EXISTS `hg_banner`;
CREATE TABLE `hg_banner` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL COMMENT '轮播图名称',
`cover` varchar(255) DEFAULT NULL COMMENT '图片URL',
`link` varchar(255) DEFAULT NULL COMMENT '跳转链接小程序内用相对地址',
`type` int(11) DEFAULT 0 COMMENT '类型默认不传',
`status` tinyint(1) DEFAULT 1 COMMENT '1可用,2不可用',
`sort` int(11) DEFAULT 0 COMMENT '排序数字越大越靠前',
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='轮播图表';
-- 添加菜单项
-- 先查找或创建"内容管理"父菜单如果不存在
INSERT IGNORE INTO `hg_admin_menu`(`pid`, `level`, `tree`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `sort`, `remark`, `status`, `updated_at`, `created_at`) VALUES
(0, 1, '', '内容管理', 'content', '/content', 'BookOutlined', 1, '/content', '', '', 'LAYOUT', 2, '', 1, 2, '', 2, 2, 2, 12, '内容管理模块', 1, NOW(), NOW());
-- 获取内容管理菜单ID并添加轮播图管理菜单
SET @content_parent_id = (SELECT id FROM `hg_admin_menu` WHERE `name` = 'content' LIMIT 1);
INSERT INTO `hg_admin_menu`(`pid`, `level`, `tree`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `sort`, `remark`, `status`, `updated_at`, `created_at`) VALUES
(@content_parent_id, 2, CONCAT('tr_', @content_parent_id, ' '), '轮播图管理', 'flashbanner', '/flashbanner', '', 2, '', '/flashbanner/banner/list', '', '/addons/flashbanner/index', 2, '', 2, 2, '', 1, 2, 2, 10, '轮播图管理模块', 1, NOW(), NOW());
-- 添加子菜单和按钮
SET @flashbanner_menu_id = LAST_INSERT_ID();
INSERT INTO `hg_admin_menu`(`pid`, `level`, `tree`, `title`, `name`, `path`, `icon`, `type`, `redirect`, `permissions`, `permission_name`, `component`, `always_show`, `active_menu`, `is_root`, `is_frame`, `frame_src`, `keep_alive`, `hidden`, `affix`, `sort`, `remark`, `status`, `updated_at`, `created_at`) VALUES
(@flashbanner_menu_id, 3, CONCAT('tr_', @content_parent_id, ' tr_', @flashbanner_menu_id, ' '), '新增轮播', 'addbanner', '', '', 3, '', '/flashbanner/banner/create', '', '', 2, '', 2, 2, '', 2, 2, 2, 10, '新增轮播图权限', 1, NOW(), NOW()),
(@flashbanner_menu_id, 3, CONCAT('tr_', @content_parent_id, ' tr_', @flashbanner_menu_id, ' '), '轮播编辑', 'editbanner', '', '', 3, '', '/flashbanner/banner/update', '', '', 2, '', 2, 2, '', 2, 2, 2, 10, '编辑轮播图权限', 1, NOW(), NOW()),
(@flashbanner_menu_id, 3, CONCAT('tr_', @content_parent_id, ' tr_', @flashbanner_menu_id, ' '), '删除轮播', 'delbanner', '', '', 3, '', '/flashbanner/banner/delete', '', '', 2, '', 2, 2, '', 2, 2, 2, 10, '删除轮播图权限', 1, NOW(), NOW());

View File

@@ -0,0 +1,9 @@
-- 删除表
DROP TABLE IF EXISTS hg_banner;
-- 删除 flashbanner 相关菜单
-- 先删除子菜单权限按钮
DELETE FROM hg_admin_menu WHERE name IN ('addbanner', 'editbanner', 'delbanner');
-- 删除主菜单
DELETE FROM hg_admin_menu WHERE name = 'flashbanner';

View File

@@ -0,0 +1,9 @@
-- 删除表
DROP TABLE IF EXISTS `hg_banner`;
-- 删除 flashbanner 相关菜单
-- 先删除子菜单权限按钮
DELETE FROM `hg_admin_menu` WHERE `name` IN ('addbanner', 'editbanner', 'delbanner');
-- 删除主菜单
DELETE FROM `hg_admin_menu` WHERE `name` = 'flashbanner';

View File

@@ -0,0 +1,2 @@
# 为了在容器映射sql所以需要独立出来
# 兼容数据库和前端文件的迁移

View File

@@ -0,0 +1,66 @@
package migrations
import (
"context"
"io"
"os"
"strings"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/container/gvar"
)
func DoSqlContent(ctx context.Context, sqlPath string) (string, error) {
open, err := os.Open(sqlPath)
if err != nil {
return "fail", err
}
defer open.Close()
sqlContent, err := io.ReadAll(open)
if err != nil {
return "fail", err
}
// 首先尝试整个执行
_, err = g.DB().Exec(ctx, string(sqlContent))
if err != nil {
g.Log().Error(ctx, "整个执行SQL失败尝试分句执行:", err)
// 整个执行失败,尝试按分号分割执行
sqls := strings.Split(string(sqlContent), ";")
for _, sql := range sqls {
sql = strings.TrimSpace(sql)
if sql != "" {
_, err := g.DB().Exec(ctx, sql)
if err != nil {
g.Log().Error(ctx, "执行SQL失败:", err, sql)
return "fail", err
}
}
}
}
return "success", nil
}
func GetDbLink(ctx context.Context) *gvar.Var {
link := g.Cfg().MustGet(ctx, "database.default")
//读写分离
if !link.IsSlice() {
return g.Cfg().MustGet(ctx, "database.default.link")
}
for _, v := range link.Array() {
// 只获取主库
val := v.(map[string]interface{})
if val["role"] == "master" {
return gvar.New(val["link"])
}
}
return gvar.New("database.default.0.link")
}
func GetDbType(ctx context.Context) string {
var (
link = GetDbLink(ctx)
)
config := strings.SplitN(link.String(), ":", 2)
return config[0]
}

View File

@@ -0,0 +1,8 @@
// Package modules
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package modules
import _ "hotgo/addons/flashbanner"

View File

@@ -47,21 +47,3 @@ type ClearKindReq struct {
} }
type ClearKindRes struct{} type ClearKindRes struct{}
// ChooserOptionReq 获取选择器选项
type ChooserOptionReq struct {
g.Meta `path:"/attachment/chooserOption" method:"get" tags:"附件" summary:"获取选择器选项"`
}
type ChooserOptionRes struct {
Drive sysin.DataSelectModel `json:"drive" dc:"驱动"`
Kind []KindSelect `json:"kind" dc:"上传类型"`
}
type KindSelect struct {
Key string `json:"key"`
Value string `json:"value"`
Tag string `json:"listClass"`
Label string `json:"label"`
Icon string `json:"icon"`
}

View File

@@ -3,7 +3,7 @@
// @Copyright Copyright (c) 2024 HotGo CLI // @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com> // @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE // @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.13.1 // @AutoGenerate Version 2.15.7
package curddemo package curddemo
import ( import (
@@ -68,6 +68,14 @@ type MaxSortRes struct {
*sysin.CurdDemoMaxSortModel *sysin.CurdDemoMaxSortModel
} }
// StatusReq 更新CURD列表状态
type StatusReq struct {
g.Meta `path:"/curdDemo/status" method:"post" tags:"CURD列表" summary:"更新CURD列表状态"`
sysin.CurdDemoStatusInp
}
type StatusRes struct{}
// SwitchReq 更新CURD列表开关状态 // SwitchReq 更新CURD列表开关状态
type SwitchReq struct { type SwitchReq struct {
g.Meta `path:"/curdDemo/switch" method:"post" tags:"CURD列表" summary:"更新CURD列表状态"` g.Meta `path:"/curdDemo/switch" method:"post" tags:"CURD列表" summary:"更新CURD列表状态"`

View File

@@ -30,16 +30,6 @@ type ExportReq struct {
type ExportRes struct{} type ExportRes struct{}
// ViewReq 获取登录日志指定信息
type ViewReq struct {
g.Meta `path:"/loginLog/view" method:"get" tags:"登录日志" summary:"获取登录日志指定信息"`
sysin.LoginLogViewInp
}
type ViewRes struct {
*sysin.LoginLogViewModel
}
// DeleteReq 删除登录日志 // DeleteReq 删除登录日志
type DeleteReq struct { type DeleteReq struct {
g.Meta `path:"/loginLog/delete" method:"post" tags:"登录日志" summary:"删除登录日志"` g.Meta `path:"/loginLog/delete" method:"post" tags:"登录日志" summary:"删除登录日志"`

View File

@@ -87,7 +87,6 @@ type NetOptionReq struct {
} }
type NetOptionRes struct { type NetOptionRes struct {
LicenseGroup form.Selects `json:"licenseGroup" dc:"授权分组"`
Routes []*RouteSelect `json:"routes" dc:"路由选项"` Routes []*RouteSelect `json:"routes" dc:"路由选项"`
} }

View File

@@ -3,7 +3,7 @@
// @Copyright Copyright (c) 2024 HotGo CLI // @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com> // @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE // @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.13.1 // @AutoGenerate Version 2.15.7
package normaltreedemo package normaltreedemo
import ( import (

View File

@@ -3,7 +3,7 @@
// @Copyright Copyright (c) 2024 HotGo CLI // @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com> // @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE // @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.13.1 // @AutoGenerate Version 2.15.7
package optiontreedemo package optiontreedemo
import ( import (

View File

@@ -3,7 +3,7 @@
// @Copyright Copyright (c) 2024 HotGo CLI // @Copyright Copyright (c) 2024 HotGo CLI
// @Author Ms <133814250@qq.com> // @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE // @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.13.1 // @AutoGenerate Version 2.15.7
package testcategory package testcategory
import ( import (

View File

@@ -1,16 +1,15 @@
// Package member // =================================================================================
// @Link https://github.com/bufanyun/hotgo // Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// @Copyright Copyright (c) 2023 HotGo CLI // =================================================================================
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package member package member
import "github.com/gogf/gf/v2/frame/g" import (
"context"
// GetIdByCodeReq 通过邀请码获取用户ID "hotgo/api/api/member/v1"
type GetIdByCodeReq struct { )
g.Meta `path:"/member/getIdByCode" method:"post" tags:"用户" summary:"通过邀请码获取用户ID"`
Code string `json:"code" dc:"邀请码"` type IMemberV1 interface {
GetIdByCode(ctx context.Context, req *v1.GetIdByCodeReq) (res *v1.GetIdByCodeRes, err error)
} }
type GetIdByCodeRes struct{}

View File

@@ -0,0 +1,16 @@
// Package member
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package v1
import "github.com/gogf/gf/v2/frame/g"
// GetIdByCodeReq 通过邀请码获取用户ID
type GetIdByCodeReq struct {
g.Meta `path:"/member/getIdByCode" method:"post" tags:"用户" summary:"通过邀请码获取用户ID"`
Code string `json:"code" dc:"邀请码"`
}
type GetIdByCodeRes struct{}

17
server/api/api/pay/pay.go Normal file
View File

@@ -0,0 +1,17 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package pay
import (
"context"
"hotgo/api/api/pay/v1"
)
type IPayV1 interface {
NotifyAliPay(ctx context.Context, req *v1.NotifyAliPayReq) (res *v1.NotifyAliPayRes, err error)
NotifyWxPay(ctx context.Context, req *v1.NotifyWxPayReq) (res *v1.NotifyWxPayRes, err error)
NotifyQQPay(ctx context.Context, req *v1.NotifyQQPayReq) (res *v1.NotifyQQPayRes, err error)
}

View File

@@ -3,11 +3,12 @@
// @Copyright Copyright (c) 2023 HotGo CLI // @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com> // @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE // @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package pay package v1
import ( import (
"github.com/gogf/gf/v2/frame/g"
"hotgo/internal/model/input/payin" "hotgo/internal/model/input/payin"
"github.com/gogf/gf/v2/frame/g"
) )
// NotifyAliPayReq 支付宝回调 // NotifyAliPayReq 支付宝回调

View File

@@ -1,141 +1,159 @@
module hotgo module hotgo
go 1.21 go 1.24.4
toolchain go1.22.1
require ( require (
github.com/Shopify/sarama v1.34.1 github.com/IBM/sarama v1.45.2
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.2 github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.7
github.com/alibabacloud-go/dysmsapi-20170525/v3 v3.0.5 github.com/alibabacloud-go/dysmsapi-20170525/v3 v3.0.6
github.com/alibabacloud-go/tea v1.1.20 github.com/alibabacloud-go/tea v1.3.9
github.com/alibabacloud-go/tea-utils/v2 v2.0.1 github.com/alibabacloud-go/tea-utils/v2 v2.0.7
github.com/aliyun/aliyun-oss-go-sdk v2.2.6+incompatible github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
github.com/apache/rocketmq-client-go/v2 v2.1.2 github.com/apache/rocketmq-client-go/v2 v2.1.2
github.com/casbin/casbin/v2 v2.55.0 github.com/casbin/casbin/v2 v2.108.0
github.com/forgoer/openssl v1.4.0 github.com/forgoer/openssl v1.6.1
github.com/go-pay/gopay v1.5.91 github.com/go-pay/crypto v0.0.1
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.7.0 github.com/go-pay/gopay v1.5.114
github.com/gogf/gf/contrib/nosql/redis/v2 v2.7.0 github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.0
github.com/gogf/gf/contrib/trace/jaeger/v2 v2.7.0 github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.0
github.com/gogf/gf/v2 v2.7.0 github.com/gogf/gf/contrib/trace/jaeger/v2 v2.7.4
github.com/gogf/gf/v2 v2.9.1-0.20250624075347-5fa656d1cc92
github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f github.com/gogf/selfupdate v0.0.0-20231215043001-5c48c528462f
github.com/golang-jwt/jwt/v5 v5.0.0 github.com/golang-jwt/jwt/v5 v5.2.2
github.com/gorilla/websocket v1.5.1 github.com/gorilla/websocket v1.5.3
github.com/kayon/iploc v0.0.0-20200312105652-bda3e968a794 github.com/kayon/iploc v0.0.0-20200312105652-bda3e968a794
github.com/minio/minio-go/v7 v7.0.63 github.com/minio/minio-go/v7 v7.0.94
github.com/mojocn/base64Captcha v1.3.6 github.com/mojocn/base64Captcha v1.3.8
github.com/olekukonko/tablewriter v0.0.5 github.com/olekukonko/tablewriter v0.0.5
github.com/qiniu/go-sdk/v7 v7.14.0 github.com/qiniu/go-sdk/v7 v7.25.4
github.com/shirou/gopsutil/v3 v3.23.3 github.com/schollz/progressbar/v3 v3.18.0
github.com/silenceper/wechat/v2 v2.1.4 github.com/shirou/gopsutil/v3 v3.24.5
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.633 github.com/silenceper/wechat/v2 v2.1.9
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.0.633 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1202
github.com/tencentyun/cos-go-sdk-v5 v0.7.45 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.0.1200
github.com/ufilesdk-dev/ufile-gosdk v1.0.3 github.com/tencentyun/cos-go-sdk-v5 v0.7.66
github.com/xuri/excelize/v2 v2.6.0 github.com/ufilesdk-dev/ufile-gosdk v1.0.6
go.opentelemetry.io/otel v1.25.0 github.com/xuri/excelize/v2 v2.9.1
golang.org/x/mod v0.9.0 go.opentelemetry.io/otel v1.37.0
golang.org/x/net v0.24.0 golang.org/x/mod v0.25.0
golang.org/x/tools v0.7.0 golang.org/x/net v0.41.0
golang.org/x/tools v0.34.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )
require ( require (
aead.dev/minisign v0.2.0 // indirect aead.dev/minisign v0.2.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect github.com/BurntSushi/toml v1.4.0 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect github.com/alex-ant/gomath v0.0.0-20160516115720-89013a210a82 // indirect
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect github.com/alibabacloud-go/debug v1.0.1 // indirect
github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // indirect
github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
github.com/alibabacloud-go/openapi-util v0.1.0 // indirect github.com/alibabacloud-go/openapi-util v0.1.0 // indirect
github.com/alibabacloud-go/tea-utils v1.3.1 // indirect github.com/alibabacloud-go/tea-utils v1.3.1 // indirect
github.com/alibabacloud-go/tea-xml v1.1.2 // indirect github.com/aliyun/credentials-go v1.4.5 // indirect
github.com/aliyun/credentials-go v1.1.2 // indirect github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d // indirect github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d // indirect
github.com/casbin/govaluate v1.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clbanning/mxj v1.8.4 // indirect github.com/clbanning/mxj v1.8.4 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dustin/go-humanize v1.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect
github.com/eapache/go-resiliency v1.2.0 // indirect github.com/eapache/go-resiliency v1.7.0 // indirect
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect
github.com/eapache/queue v1.1.0 // indirect github.com/eapache/queue v1.1.0 // indirect
github.com/emirpasic/gods v1.12.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.18.0 // indirect
github.com/fatih/structs v1.1.0 // indirect github.com/fatih/structs v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect github.com/gammazero/toposort v0.1.1 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-pay/errgroup v0.0.3 // indirect
github.com/go-pay/smap v0.0.2 // indirect
github.com/go-pay/util v0.0.4 // indirect
github.com/go-pay/xlog v0.0.3 // indirect
github.com/go-pay/xtime v0.0.2 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/mock v1.6.0 // indirect github.com/golang/mock v1.4.4 // indirect
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.1.2 // indirect github.com/google/btree v1.1.3 // indirect
github.com/google/go-querystring v1.0.0 // indirect github.com/google/go-querystring v1.0.0 // indirect
github.com/google/uuid v1.3.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/grokify/html-strip-tags-go v0.1.0 // indirect github.com/grokify/html-strip-tags-go v0.1.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-uuid v1.0.2 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
github.com/jcmturner/gofork v1.0.0 // indirect github.com/jcmturner/gofork v1.7.6 // indirect
github.com/jcmturner/gokrb5/v8 v8.4.2 // indirect github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/jcmturner/rpc/v2 v2.0.3 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.2 // indirect github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.7 // indirect github.com/magiconair/properties v1.8.9 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/minio/crc64nvme v1.0.1 // indirect
github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/mozillazg/go-httpheader v0.2.1 // indirect github.com/mozillazg/go-httpheader v0.2.1 // indirect
github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 // indirect
github.com/olekukonko/ll v0.0.8 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pierrec/lz4/v4 v4.1.18 // indirect github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/pkg/errors v0.8.1 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/redis/go-redis/v9 v9.5.1 // indirect github.com/redis/go-redis/v9 v9.7.0 // indirect
github.com/richardlehane/mscfb v1.0.4 // indirect github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.1 // indirect github.com/richardlehane/msoleps v1.0.4 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/rs/xid v1.5.0 // indirect github.com/rs/xid v1.6.0 // indirect
github.com/shoenig/go-m1cpu v0.1.4 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect github.com/sirupsen/logrus v1.9.0 // indirect
github.com/spf13/cast v1.4.1 // indirect github.com/spf13/cast v1.4.1 // indirect
github.com/tidwall/gjson v1.14.1 // indirect github.com/tidwall/gjson v1.14.1 // indirect
github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/pretty v1.2.0 // indirect
github.com/tjfoc/gmsm v1.3.2 // indirect github.com/tiendc/go-deepcopy v1.6.0 // indirect
github.com/tklauser/go-sysconf v0.3.11 // indirect github.com/tinylib/msgp v1.3.0 // indirect
github.com/tklauser/numcpus v0.6.0 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/xuri/efp v0.0.0-20220407160117-ad0f7a785be8 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/xuri/efp v0.0.1 // indirect
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect github.com/xuri/nfp v0.0.1 // indirect
go.opentelemetry.io/otel/metric v1.25.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.opentelemetry.io/otel/sdk v1.25.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel/trace v1.25.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect
go.uber.org/atomic v1.7.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect
golang.org/x/crypto v0.22.0 // indirect go.opentelemetry.io/otel/sdk v1.32.0 // indirect
golang.org/x/image v0.13.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect
golang.org/x/sync v0.1.0 // indirect go.uber.org/atomic v1.5.1 // indirect
golang.org/x/sys v0.19.0 // indirect golang.org/x/crypto v0.39.0 // indirect
golang.org/x/text v0.14.0 // indirect golang.org/x/image v0.25.0 // indirect
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect
golang.org/x/sync v0.15.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/time v0.12.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
modernc.org/fileutil v1.0.0 // indirect
stathat.com/c/consistent v1.0.0 // indirect stathat.com/c/consistent v1.0.0 // indirect
) )

Some files were not shown because too many files have changed in this diff Show More