├── .air.conf.example ├── .dockerignore ├── .gitattributes ├── .gitignore ├── Makefile ├── README.md ├── api ├── app.pb.go ├── app.proto ├── app_grpc.pb.go ├── app_http.pb.go ├── cms.pb.go ├── cms.proto ├── cms_grpc.pb.go └── cms_http.pb.go ├── cmd └── server │ ├── main.go │ ├── wire.go │ └── wire_gen.go ├── configs └── example.yaml ├── deploy └── Dockerfile ├── docs ├── app.sql ├── rest.http └── schema.sql ├── go.mod ├── go.sum ├── internal ├── biz │ ├── admin.go │ ├── biz.go │ ├── book.go │ ├── group.go │ ├── lesson.go │ ├── log.go │ ├── permission.go │ ├── teacher.go │ └── user.go ├── conf │ ├── conf.pb.go │ └── conf.proto ├── data │ ├── book.go │ ├── cache │ │ └── init.go │ ├── data.go │ ├── group.go │ ├── groupPermission.go │ ├── init.go │ ├── lesson.go │ ├── log.go │ ├── model │ │ ├── area.gen.go │ │ ├── book.gen.go │ │ ├── lesson.gen.go │ │ ├── lesson_comment.gen.go │ │ ├── lesson_signin.gen.go │ │ ├── lesson_signup.gen.go │ │ ├── lin_file.gen.go │ │ ├── lin_group.gen.go │ │ ├── lin_group_permission.gen.go │ │ ├── lin_log.gen.go │ │ ├── lin_permission.gen.go │ │ ├── lin_user.gen.go │ │ ├── lin_user_group.gen.go │ │ ├── lin_user_identiy.gen.go │ │ ├── teacher.gen.go │ │ └── user.gen.go │ ├── permission.go │ ├── teacher.go │ └── user.go ├── server │ ├── http.go │ ├── middleware.go │ ├── router.go │ └── server.go └── service │ ├── admin.go │ ├── app.go │ ├── book.go │ ├── cms.go │ ├── group.go │ ├── log.go │ ├── permission.go │ ├── service.go │ └── user.go ├── pkg ├── errcode │ └── message.go └── lib │ ├── upload.go │ └── wechat.go └── test ├── helper.go ├── log_test.go ├── main_test.go └── user_test.go /.air.conf.example: -------------------------------------------------------------------------------- 1 | # Config file for [Air](https://github.com/cosmtrek/air) in TOML format 2 | 3 | # Working directory 4 | # . or absolute path, please note that the directories following must be under root. 5 | root = "." 6 | tmp_dir = "tmp" 7 | 8 | [build] 9 | # Just plain old shell command. You could use `make` as well. 10 | cmd = "go build -o lin-cms-go.exe " 11 | # Binary file yields from `cmd`. 12 | bin = "lin-cms-go.exe" 13 | # Customize binary. 14 | full_bin = " ./lin-cms-go.exe godoc -http=:6060" 15 | # Watch these filename extensions. 16 | include_ext = ["go", "html"] 17 | # Ignore these filename extensions or directories. 18 | exclude_dir = ["assets", "tmp", "vendor", "frontend/node_modules"] 19 | # Watch these directories if you specified. 20 | include_dir = [] 21 | # Exclude files. 22 | exclude_file = [] 23 | # It's not necessary to trigger build each time file changes if it's too frequent. 24 | delay = 10 # ms 25 | # Stop to run old binary when build errors occur. 26 | stop_on_error = true 27 | # This log file places in your tmp_dir. 28 | log = "air_errors.log" 29 | 30 | [log] 31 | # Show log time 32 | time = false 33 | 34 | [color] 35 | # Customize each part's color. If no color found, use the raw app log. 36 | main = "magenta" 37 | watcher = "cyan" 38 | build = "yellow" 39 | runner = "green" 40 | 41 | [misc] 42 | # Delete tmp directory on exit 43 | clean_on_exit = true -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.git 2 | **/.gitignore 3 | **/.vscode 4 | **/*.sql 5 | **/*.log 6 | README.md 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=GO 2 | *.css linguist-language=GO 3 | *.html linguist-language=GO -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | /.idea 3 | /.vscode 4 | *.exe 5 | *.log 6 | 7 | 8 | /tmp 9 | .air.conf 10 | third_party 11 | config.yaml -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | INTERNAL_PROTO_FILES=$(shell find internal -name *.proto) 2 | API_PROTO_FILES=$(shell find api -name *.proto) 3 | BIZ_FILES=$(shell find internal/biz -name *.go) 4 | .PHONY: init 5 | init: 6 | go install github.com/google/wire/cmd/wire@latest 7 | go install github.com/golang/mock/mockgen@latest 8 | go install github.com/swaggo/swag/cmd/swag@latest 9 | go install google.golang.org/protobuf/cmd/protoc-gen-go@latest 10 | go install github.com/favadi/protoc-go-inject-tag@latest 11 | go install github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2@latest 12 | 13 | .PHONY: generate 14 | # generate 15 | generate: 16 | 17 | go generate ./... 18 | 19 | .PHONY: mock 20 | mock: 21 | mockgen -source=internal/biz/area.go -destination mocks/biz/area.go 22 | mockgen -source=internal/biz/report.go -destination mocks/biz/report.go 23 | mockgen -source=internal/biz/comment.go -destination mocks/biz/comment.go 24 | mockgen -source=internal/biz/draft.go -destination mocks/biz/draft.go 25 | mockgen -source=internal/biz/follow.go -destination mocks/biz/follow.go 26 | mockgen -source=internal/biz/hotspot.go -destination mocks/biz/hotspot.go 27 | mockgen -source=internal/biz/like.go -destination mocks/biz/like.go 28 | mockgen -source=internal/biz/missionUser.go -destination mocks/biz/missionUser.go 29 | mockgen -source=internal/biz/notify.go -destination mocks/biz/notify.go 30 | mockgen -source=internal/biz/reply.go -destination mocks/biz/reply.go 31 | mockgen -source=internal/biz/report.go -destination mocks/biz/report.go 32 | mockgen -source=internal/biz/suggest.go -destination mocks/biz/suggest.go 33 | mockgen -source=internal/biz/visit.go -destination mocks/biz/visit.go 34 | 35 | 36 | 37 | .PHONY: test 38 | test: 39 | go test -cover lin-cms-go/internal/biz -coverprofile ./coverage.out 40 | go tool cover -html=./coverage.out -o coverage.html 41 | 42 | .PHONY: build 43 | build: 44 | go build -toolexec="/apps/apm/skywalking-go/go-agent" -a -o test -ldflags="-s -w" -o ./bin/server ./cmd/server 45 | 46 | 47 | .PHONY: swag 48 | swag: 49 | swag init -g ./cmd/server/main.go -o ./docs 50 | 51 | .PHONY: config 52 | config: 53 | protoc --proto_path=./internal \ 54 | --go_out=paths=source_relative:./internal \ 55 | $(INTERNAL_PROTO_FILES) 56 | 57 | .PHONY: api 58 | # generate api proto 59 | api: 60 | protoc --proto_path=./api \ 61 | --proto_path=./third_party \ 62 | --go_out=paths=source_relative:./api \ 63 | --go-http_out=paths=source_relative:./api \ 64 | --go-grpc_out=paths=source_relative:./api \ 65 | $(API_PROTO_FILES) 66 | protoc-go-inject-tag -input="./api/*.pb.go" 67 | ls ./api/*.pb.go | xargs -n1 -IX bash -c 'sed s/,omitempty// X > X.tmp && mv X{.tmp,}' 68 | 69 | 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 |
5 | lin-cms-go 6 |

7 | 8 |

9 | go version 10 | fiber version 11 | lisence 12 |

13 | 14 | # 简介 15 | 16 | ## 预防针 17 | 18 | * 本项目非官方团队出品,仅出于学习、研究目的丰富下官方项目的语言支持 19 | * 本项目采取后跟进官方团队功能的形式,即官方团队出什么功能,这边就跟进开发什么功能,开发者不必担心前端适配问题。 20 | * 在上一点的基础上,我们会尝试加入一些自己的想法并实现。 21 | * 局限于本人水平,有些地方还需重构,已经纳入了计划中,当然也会有我没考虑到的,希望有更多人参与进来一起完善。 22 | 23 | ## 专栏教程 (todo) 24 | 25 | * lin cms 全家桶(lin-cms-vue & lin-cms-go)为一个前端应用实现内容管理系统。一套教程入门上手 vue、fiber 两大框架。 26 | 27 | * 读者反馈:[《lin cms go &vue 教程》读者反馈贴](https://github.com/xushuhui/lin-cms-go/issues/47) 28 | 29 | ## 线上文档地址(完善中) 30 | 31 | [https://github.com/xushuhui/lin-cms-go](https://github.com/xushuhui/lin-cms-go/) 32 | 33 | ## 线上 demo 34 | 35 | 可直接参考官方团队的线上 demo:[http://face.cms.talelin.com/](http://face.cms.talelin.com/),用户名:super,密码:123456 36 | 37 | ## 什么是 lin cms? 38 | 39 | > lin-cms 是林间有风团队经过大量项目实践所提炼出的一套**内容管理系统框架**。lin-cms 可以有效的帮助开发者提高 cms 的开发效率。 40 | 41 | 本项目是基于 fiber 5.1 的 lin cms 后端实现。 42 | 43 | 官方团队产品了解请访问 [talelin](https://github.com/talelin) 44 | 45 | ## lin cms 的特点 46 | 47 | lin cms 的构筑思想是有其自身特点的。下面我们阐述一些 lin 的主要特点。 48 | 49 | **lin cms 是一个前后端分离的 cms 解决方案** 50 | 51 | 这意味着,lin 既提供后台的支撑,也有一套对应的前端系统,当然双端分离的好处不仅仅在于此,我们会在后续提供 nodejs 和 php 版本的 lin。如果你心仪 lin,却又因为技术栈的原因无法即可使用,没关系,我们会在后续提供更多的语言版本。为什么 lin 要选择前后端分离的单页面架构呢? 52 | 53 | 首先,传统的网站开发更多的是采用服务端渲染的方式,需用使用一种模板语言在服务端完成页面渲染:比如 jinja2、jade 等。 服务端渲染的好处在于可以比较好的支持 seo,但作为内部使用的 cms 管理系统,seo 并不重要。 54 | 55 | 但一个不可忽视的事实是,服务器渲染的页面到底是由前端开发者来完成,还是由服务器开发者来完成?其实都不太合适。现在已经没有多少前端开发者是了解这些服务端模板语言的,而服务器开发者本身是不太擅长开发页面的。那还是分开吧,前端用最熟悉的 vue 写 js 和 css,而服务器只关注自己的 api 即可。 56 | 57 | 其次,单页面应用程序的体验本身就要好于传统网站。 58 | 59 | 更多关于 lin cms 的介绍请访问 [lin cms 线上文档](http://doc.cms.talelin.com/) 60 | 61 | **框架本身已内置了 cms 常用的功能** 62 | 63 | lin 已经内置了 cms 中最为常见的需求:用户管理、权限管理、日志系统等。开发者只需要集中精力开发自己的 cms 业务即可 64 | 65 | ## lin cms go 的特点 66 | 67 | 在当前项目的版本`(0.0.1)`中,特点更多来自于`fiber`框架本身带来的特点。通过充分利用框架的特性,实现高效的后端使用、开发,也就是说,只要你熟悉`fiber`框架,那么对于理解使用和二次开发本项目是没有难度的,即便对于框架的某些功能存在疑问也完全可以通过 fiber 官方的开发手册找到答案。当然我们更欢迎你通过 [issues](https://github.com/xushuhui/lin-cms-go/issues) 来向我们提问:) 68 | 69 | 在下一个版本中`(>0.0.1)`, 我们会在框架的基础上融入一些自己的东西来增强或者优化框架的使用、开发体验。 70 | 71 | ## 所需基础 72 | 73 | 由于 lin 采用的是前后端分离的架构,所以你至少需要熟悉 go 和 vue。 74 | 75 | lin 的服务端框架是基于 fiber2.20 的,所以如果你比较熟悉 fiber 的开发模式,那将可以更好的使用本项目。但如果你并不熟悉 fiber,我们认为也没有太大的关系,因为框架本身已经提供了一套完整的开发机制,你只需要在框架下用 go 来编写自己的业务代码即可。照葫芦画瓢应该就是这种感觉。 76 | 77 | 但前端不同,前端还是需要开发者比较熟悉 vue 的。但我想以 vue 在国内的普及程度,绝大多数的开发者是没有问题的。这也正是我们选择 vue 作为前端框架的原因。如果你喜欢 react or angular,那么加入我们,为 lin 开发一个对应的版本吧。 78 | 79 | # 快速开始 80 | 81 | ## server 端必备环境 82 | 83 | * 安装 mysql(version: 5.7+) 84 | 85 | * 安装 go 环境 (version: 1.14+) 86 | 87 | ## 获取工程项目 88 | 89 | ```bash 90 | git clone https://github.com/xushuhui/lin-cms-go.git 91 | ``` 92 | 93 | > 执行完毕后会生成 lin-cms-go 目录 94 | 95 | ## 安装依赖包 96 | 97 | ```bash 98 | 99 | go mod tidy 100 | 101 | ``` 102 | 103 | ## 数据库配置 104 | 105 | lin 需要你自己在 mysql 中新建一个数据库,名字由你自己决定。例如,新建一个名为` lin-cms `的数据库。接着,我们需要在工程中进行一项简单的配置。使用编辑器打开 lin 工程根目录下`/configs/config.yaml`,找到如下配置项: 106 | 107 | ```yaml 108 | data: 109 | datasource: 110 | source: 用户名:密码@tcp(服务器地址)/数据库名?charset=utf8mb4&parseTime=True 111 | ``` 112 | 113 | **请务必根据自己的实际情况修改此配置项** 114 | 115 | ## 导入数据 116 | 117 | 接下来使用你本机上任意一款数据库可视化工具,为已经创建好的`lin-cms`数据库运行 lin-cms-go 根目录下的`schema.sql`文件,这个 SQL 脚本文件将为为你生成一些基础的数据库表和数据。 118 | 119 | ## 运行 120 | 121 | 如果前面的过程一切顺利,项目所需的准备工作就已经全部完成,这时候你就可以试着让工程运行起来了。在工程的根目录打开命令行,输入: 122 | 123 | ```bash 124 | go build -o //启动 Web 服务器 125 | ``` 126 | 127 | 启动成功后会看到如下提示: 128 | 129 | ```bash 130 | Fiber v2.20.2 131 | http://127.0.0.1:3000/ 132 | 133 | ``` 134 | 135 | 打开浏览器,访问``http://127.0.0.1:3000``,你会看到一个欢迎界面,至此,lin-cms-go 部署完毕,可搭配 [lin-cms-vue](https://github.com/TaleLin/lin-cms-vue) 使用了。 136 | 137 | ## 更新日志 138 | 139 | [查看日志](http://github.com/xushuhui/lin-cms-go//) 140 | 141 | ## 常见问题 142 | 143 | [查看常见问题](http://github.com/xushuhui/lin-cms-go/) 144 | 145 | ## 讨论交流 146 | 147 | ### 微信公众号 148 | 149 | ![扫码关注](https://tvax4.sinaimg.cn/large/a616b9a4gy1grl9d1rdpvj2076076wey.jpg) 150 | -------------------------------------------------------------------------------- /api/app.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package api; 3 | import "google/api/annotations.proto"; 4 | import "google/protobuf/empty.proto"; 5 | import "cms.proto"; 6 | option go_package = "lin-cms-go/api"; 7 | 8 | service App { 9 | rpc CreateLesson(CreateLessonRequest) returns (google.protobuf.Empty) { 10 | option (google.api.http) = { 11 | post : "/v1/lesson" 12 | body : "*" 13 | }; 14 | } 15 | rpc ListLesson(PageRequest) returns (ListLessonReply) { 16 | option (google.api.http) = { 17 | get : "/v1/lesson" 18 | }; 19 | } 20 | rpc GetLesson(IDRequest) returns (GetLessonReply) { 21 | option (google.api.http) = { 22 | get : "/v1/lesson/{id}" 23 | }; 24 | } 25 | rpc UpdateLesson(UpdateLessonRequest) returns (google.protobuf.Empty) { 26 | option (google.api.http) = { 27 | put : "/v1/lesson/{id}" 28 | body : "*" 29 | }; 30 | } 31 | rpc UpdateLessonStatus(UpdateLessonRequest) returns (google.protobuf.Empty) { 32 | option (google.api.http) = { 33 | put : "/v1/lesson/{id}/status" 34 | body : "*" 35 | }; 36 | } 37 | rpc DeleteLesson(IDRequest) returns (google.protobuf.Empty) { 38 | option (google.api.http) = { 39 | delete : "/v1/lesson/{id}" 40 | }; 41 | } 42 | rpc CreateTeacher(CreateTeacherRequest) returns (google.protobuf.Empty) { 43 | option (google.api.http) = { 44 | post : "/v1/teacher" 45 | body : "*" 46 | }; 47 | } 48 | rpc ListTeacher(PageRequest) returns (ListTeacherReply) { 49 | option (google.api.http) = { 50 | get : "/v1/teacher" 51 | }; 52 | } 53 | rpc GetTeacher(IDRequest) returns (GetTeacherReply) { 54 | option (google.api.http) = { 55 | get : "/v1/teacher/{id}" 56 | }; 57 | } 58 | rpc UpdateTeacher(UpdateTeacherRequest) returns (google.protobuf.Empty) { 59 | option (google.api.http) = { 60 | put : "/v1/teacher/{id}" 61 | body : "*" 62 | }; 63 | } 64 | rpc DeleteTeacher(IDRequest) returns (google.protobuf.Empty) { 65 | option (google.api.http) = { 66 | delete : "/v1/teacher/{id}" 67 | }; 68 | } 69 | rpc CreateBook(CreateBookRequest) returns (google.protobuf.Empty) { 70 | option (google.api.http) = { 71 | post : "/v1/book" 72 | body : "*" 73 | }; 74 | } 75 | rpc ListBook(PageRequest) returns (ListBookReply) { 76 | option (google.api.http) = { 77 | get : "/v1/book" 78 | }; 79 | } 80 | rpc GetBook(IDRequest) returns (GetBookReply) { 81 | option (google.api.http) = { 82 | get : "/v1/book/{id}" 83 | }; 84 | } 85 | rpc UpdateBook(UpdateBookRequest) returns (google.protobuf.Empty) { 86 | option (google.api.http) = { 87 | put : "/v1/book/{id}" 88 | body : "*" 89 | }; 90 | } 91 | rpc DeleteBook(IDRequest) returns (google.protobuf.Empty) { 92 | option (google.api.http) = { 93 | delete : "/v1/book/{id}" 94 | }; 95 | } 96 | } 97 | message CreateTeacherRequest { 98 | string name = 2; 99 | string nickname=3; 100 | string area=4; 101 | string introduce=5; 102 | string avatar=6; 103 | string phone=7; 104 | string domain=8; 105 | string classHour=9; 106 | string remark=10; 107 | } 108 | message UpdateTeacherRequest { 109 | int64 id = 1; 110 | string name = 2; 111 | string nickname=3; 112 | string area=4; 113 | string introduce=5; 114 | string avatar=6; 115 | string phone=7; 116 | string domain=8; 117 | string classHour=9; 118 | string remark=10; 119 | } 120 | message CreateLessonRequest { string title = 1; } 121 | message UpdateLessonRequest { 122 | int64 id = 1; 123 | string title = 2; 124 | int32 status=3; 125 | } 126 | 127 | message GetLessonReply { Lesson lesson = 1; } 128 | message Lesson { 129 | uint32 id = 1; 130 | string title = 2; 131 | } 132 | message ListLessonReply { 133 | repeated Lesson list = 1; 134 | uint32 total = 2; 135 | int32 page = 3; 136 | int32 size = 4; 137 | } 138 | message ListTeacherReply { 139 | repeated Teacher list = 1; 140 | uint32 total = 2; 141 | int32 page = 3; 142 | int32 size = 4; 143 | } 144 | message Teacher { 145 | uint32 id = 1; 146 | string name = 2; 147 | string domain=3; 148 | string area=4; 149 | } 150 | message GetTeacherReply { 151 | uint32 id = 1; 152 | string name = 2; 153 | string nickname=3; 154 | string domain=8; 155 | string area=4; 156 | string introduce=5; 157 | string avatar=6; 158 | string phone=7; 159 | string classHour=9; 160 | string remark=10; 161 | } 162 | message CreateBookReply { int64 id = 1; } 163 | message Book { 164 | uint32 id = 1; 165 | string title = 2; 166 | string author = 3; 167 | string summary = 4; 168 | string image = 5; 169 | string created_at = 6; 170 | } 171 | message ListBookReply { 172 | repeated Book list = 1; 173 | uint32 total = 2; 174 | int32 page = 3; 175 | int32 size = 4; 176 | } 177 | message GetBookReply { Book book = 1; } 178 | message CreateBookRequest { 179 | string title = 1; 180 | string author = 2; 181 | string summary = 3; 182 | string image = 4; 183 | } 184 | message UpdateBookRequest { 185 | int64 id = 1; 186 | string title = 2; 187 | string author = 3; 188 | string summary = 4; 189 | string image = 5; 190 | } 191 | 192 | -------------------------------------------------------------------------------- /api/app_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.3.0 4 | // - protoc v3.21.12 5 | // source: app.proto 6 | 7 | package api 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | emptypb "google.golang.org/protobuf/types/known/emptypb" 15 | ) 16 | 17 | // This is a compile-time assertion to ensure that this generated file 18 | // is compatible with the grpc package it is being compiled against. 19 | // Requires gRPC-Go v1.32.0 or later. 20 | const _ = grpc.SupportPackageIsVersion7 21 | 22 | const ( 23 | App_CreateLesson_FullMethodName = "/api.App/CreateLesson" 24 | App_ListLesson_FullMethodName = "/api.App/ListLesson" 25 | App_GetLesson_FullMethodName = "/api.App/GetLesson" 26 | App_UpdateLesson_FullMethodName = "/api.App/UpdateLesson" 27 | App_UpdateLessonStatus_FullMethodName = "/api.App/UpdateLessonStatus" 28 | App_DeleteLesson_FullMethodName = "/api.App/DeleteLesson" 29 | App_CreateTeacher_FullMethodName = "/api.App/CreateTeacher" 30 | App_ListTeacher_FullMethodName = "/api.App/ListTeacher" 31 | App_GetTeacher_FullMethodName = "/api.App/GetTeacher" 32 | App_UpdateTeacher_FullMethodName = "/api.App/UpdateTeacher" 33 | App_DeleteTeacher_FullMethodName = "/api.App/DeleteTeacher" 34 | App_CreateBook_FullMethodName = "/api.App/CreateBook" 35 | App_ListBook_FullMethodName = "/api.App/ListBook" 36 | App_GetBook_FullMethodName = "/api.App/GetBook" 37 | App_UpdateBook_FullMethodName = "/api.App/UpdateBook" 38 | App_DeleteBook_FullMethodName = "/api.App/DeleteBook" 39 | ) 40 | 41 | // AppClient is the client API for App service. 42 | // 43 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 44 | type AppClient interface { 45 | CreateLesson(ctx context.Context, in *CreateLessonRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) 46 | ListLesson(ctx context.Context, in *PageRequest, opts ...grpc.CallOption) (*ListLessonReply, error) 47 | GetLesson(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*GetLessonReply, error) 48 | UpdateLesson(ctx context.Context, in *UpdateLessonRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) 49 | UpdateLessonStatus(ctx context.Context, in *UpdateLessonRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) 50 | DeleteLesson(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) 51 | CreateTeacher(ctx context.Context, in *CreateTeacherRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) 52 | ListTeacher(ctx context.Context, in *PageRequest, opts ...grpc.CallOption) (*ListTeacherReply, error) 53 | GetTeacher(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*GetTeacherReply, error) 54 | UpdateTeacher(ctx context.Context, in *UpdateTeacherRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) 55 | DeleteTeacher(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) 56 | CreateBook(ctx context.Context, in *CreateBookRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) 57 | ListBook(ctx context.Context, in *PageRequest, opts ...grpc.CallOption) (*ListBookReply, error) 58 | GetBook(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*GetBookReply, error) 59 | UpdateBook(ctx context.Context, in *UpdateBookRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) 60 | DeleteBook(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) 61 | } 62 | 63 | type appClient struct { 64 | cc grpc.ClientConnInterface 65 | } 66 | 67 | func NewAppClient(cc grpc.ClientConnInterface) AppClient { 68 | return &appClient{cc} 69 | } 70 | 71 | func (c *appClient) CreateLesson(ctx context.Context, in *CreateLessonRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { 72 | out := new(emptypb.Empty) 73 | err := c.cc.Invoke(ctx, App_CreateLesson_FullMethodName, in, out, opts...) 74 | if err != nil { 75 | return nil, err 76 | } 77 | return out, nil 78 | } 79 | 80 | func (c *appClient) ListLesson(ctx context.Context, in *PageRequest, opts ...grpc.CallOption) (*ListLessonReply, error) { 81 | out := new(ListLessonReply) 82 | err := c.cc.Invoke(ctx, App_ListLesson_FullMethodName, in, out, opts...) 83 | if err != nil { 84 | return nil, err 85 | } 86 | return out, nil 87 | } 88 | 89 | func (c *appClient) GetLesson(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*GetLessonReply, error) { 90 | out := new(GetLessonReply) 91 | err := c.cc.Invoke(ctx, App_GetLesson_FullMethodName, in, out, opts...) 92 | if err != nil { 93 | return nil, err 94 | } 95 | return out, nil 96 | } 97 | 98 | func (c *appClient) UpdateLesson(ctx context.Context, in *UpdateLessonRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { 99 | out := new(emptypb.Empty) 100 | err := c.cc.Invoke(ctx, App_UpdateLesson_FullMethodName, in, out, opts...) 101 | if err != nil { 102 | return nil, err 103 | } 104 | return out, nil 105 | } 106 | 107 | func (c *appClient) UpdateLessonStatus(ctx context.Context, in *UpdateLessonRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { 108 | out := new(emptypb.Empty) 109 | err := c.cc.Invoke(ctx, App_UpdateLessonStatus_FullMethodName, in, out, opts...) 110 | if err != nil { 111 | return nil, err 112 | } 113 | return out, nil 114 | } 115 | 116 | func (c *appClient) DeleteLesson(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { 117 | out := new(emptypb.Empty) 118 | err := c.cc.Invoke(ctx, App_DeleteLesson_FullMethodName, in, out, opts...) 119 | if err != nil { 120 | return nil, err 121 | } 122 | return out, nil 123 | } 124 | 125 | func (c *appClient) CreateTeacher(ctx context.Context, in *CreateTeacherRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { 126 | out := new(emptypb.Empty) 127 | err := c.cc.Invoke(ctx, App_CreateTeacher_FullMethodName, in, out, opts...) 128 | if err != nil { 129 | return nil, err 130 | } 131 | return out, nil 132 | } 133 | 134 | func (c *appClient) ListTeacher(ctx context.Context, in *PageRequest, opts ...grpc.CallOption) (*ListTeacherReply, error) { 135 | out := new(ListTeacherReply) 136 | err := c.cc.Invoke(ctx, App_ListTeacher_FullMethodName, in, out, opts...) 137 | if err != nil { 138 | return nil, err 139 | } 140 | return out, nil 141 | } 142 | 143 | func (c *appClient) GetTeacher(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*GetTeacherReply, error) { 144 | out := new(GetTeacherReply) 145 | err := c.cc.Invoke(ctx, App_GetTeacher_FullMethodName, in, out, opts...) 146 | if err != nil { 147 | return nil, err 148 | } 149 | return out, nil 150 | } 151 | 152 | func (c *appClient) UpdateTeacher(ctx context.Context, in *UpdateTeacherRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { 153 | out := new(emptypb.Empty) 154 | err := c.cc.Invoke(ctx, App_UpdateTeacher_FullMethodName, in, out, opts...) 155 | if err != nil { 156 | return nil, err 157 | } 158 | return out, nil 159 | } 160 | 161 | func (c *appClient) DeleteTeacher(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { 162 | out := new(emptypb.Empty) 163 | err := c.cc.Invoke(ctx, App_DeleteTeacher_FullMethodName, in, out, opts...) 164 | if err != nil { 165 | return nil, err 166 | } 167 | return out, nil 168 | } 169 | 170 | func (c *appClient) CreateBook(ctx context.Context, in *CreateBookRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { 171 | out := new(emptypb.Empty) 172 | err := c.cc.Invoke(ctx, App_CreateBook_FullMethodName, in, out, opts...) 173 | if err != nil { 174 | return nil, err 175 | } 176 | return out, nil 177 | } 178 | 179 | func (c *appClient) ListBook(ctx context.Context, in *PageRequest, opts ...grpc.CallOption) (*ListBookReply, error) { 180 | out := new(ListBookReply) 181 | err := c.cc.Invoke(ctx, App_ListBook_FullMethodName, in, out, opts...) 182 | if err != nil { 183 | return nil, err 184 | } 185 | return out, nil 186 | } 187 | 188 | func (c *appClient) GetBook(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*GetBookReply, error) { 189 | out := new(GetBookReply) 190 | err := c.cc.Invoke(ctx, App_GetBook_FullMethodName, in, out, opts...) 191 | if err != nil { 192 | return nil, err 193 | } 194 | return out, nil 195 | } 196 | 197 | func (c *appClient) UpdateBook(ctx context.Context, in *UpdateBookRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { 198 | out := new(emptypb.Empty) 199 | err := c.cc.Invoke(ctx, App_UpdateBook_FullMethodName, in, out, opts...) 200 | if err != nil { 201 | return nil, err 202 | } 203 | return out, nil 204 | } 205 | 206 | func (c *appClient) DeleteBook(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { 207 | out := new(emptypb.Empty) 208 | err := c.cc.Invoke(ctx, App_DeleteBook_FullMethodName, in, out, opts...) 209 | if err != nil { 210 | return nil, err 211 | } 212 | return out, nil 213 | } 214 | 215 | // AppServer is the server API for App service. 216 | // All implementations must embed UnimplementedAppServer 217 | // for forward compatibility 218 | type AppServer interface { 219 | CreateLesson(context.Context, *CreateLessonRequest) (*emptypb.Empty, error) 220 | ListLesson(context.Context, *PageRequest) (*ListLessonReply, error) 221 | GetLesson(context.Context, *IDRequest) (*GetLessonReply, error) 222 | UpdateLesson(context.Context, *UpdateLessonRequest) (*emptypb.Empty, error) 223 | UpdateLessonStatus(context.Context, *UpdateLessonRequest) (*emptypb.Empty, error) 224 | DeleteLesson(context.Context, *IDRequest) (*emptypb.Empty, error) 225 | CreateTeacher(context.Context, *CreateTeacherRequest) (*emptypb.Empty, error) 226 | ListTeacher(context.Context, *PageRequest) (*ListTeacherReply, error) 227 | GetTeacher(context.Context, *IDRequest) (*GetTeacherReply, error) 228 | UpdateTeacher(context.Context, *UpdateTeacherRequest) (*emptypb.Empty, error) 229 | DeleteTeacher(context.Context, *IDRequest) (*emptypb.Empty, error) 230 | CreateBook(context.Context, *CreateBookRequest) (*emptypb.Empty, error) 231 | ListBook(context.Context, *PageRequest) (*ListBookReply, error) 232 | GetBook(context.Context, *IDRequest) (*GetBookReply, error) 233 | UpdateBook(context.Context, *UpdateBookRequest) (*emptypb.Empty, error) 234 | DeleteBook(context.Context, *IDRequest) (*emptypb.Empty, error) 235 | mustEmbedUnimplementedAppServer() 236 | } 237 | 238 | // UnimplementedAppServer must be embedded to have forward compatible implementations. 239 | type UnimplementedAppServer struct { 240 | } 241 | 242 | func (UnimplementedAppServer) CreateLesson(context.Context, *CreateLessonRequest) (*emptypb.Empty, error) { 243 | return nil, status.Errorf(codes.Unimplemented, "method CreateLesson not implemented") 244 | } 245 | func (UnimplementedAppServer) ListLesson(context.Context, *PageRequest) (*ListLessonReply, error) { 246 | return nil, status.Errorf(codes.Unimplemented, "method ListLesson not implemented") 247 | } 248 | func (UnimplementedAppServer) GetLesson(context.Context, *IDRequest) (*GetLessonReply, error) { 249 | return nil, status.Errorf(codes.Unimplemented, "method GetLesson not implemented") 250 | } 251 | func (UnimplementedAppServer) UpdateLesson(context.Context, *UpdateLessonRequest) (*emptypb.Empty, error) { 252 | return nil, status.Errorf(codes.Unimplemented, "method UpdateLesson not implemented") 253 | } 254 | func (UnimplementedAppServer) UpdateLessonStatus(context.Context, *UpdateLessonRequest) (*emptypb.Empty, error) { 255 | return nil, status.Errorf(codes.Unimplemented, "method UpdateLessonStatus not implemented") 256 | } 257 | func (UnimplementedAppServer) DeleteLesson(context.Context, *IDRequest) (*emptypb.Empty, error) { 258 | return nil, status.Errorf(codes.Unimplemented, "method DeleteLesson not implemented") 259 | } 260 | func (UnimplementedAppServer) CreateTeacher(context.Context, *CreateTeacherRequest) (*emptypb.Empty, error) { 261 | return nil, status.Errorf(codes.Unimplemented, "method CreateTeacher not implemented") 262 | } 263 | func (UnimplementedAppServer) ListTeacher(context.Context, *PageRequest) (*ListTeacherReply, error) { 264 | return nil, status.Errorf(codes.Unimplemented, "method ListTeacher not implemented") 265 | } 266 | func (UnimplementedAppServer) GetTeacher(context.Context, *IDRequest) (*GetTeacherReply, error) { 267 | return nil, status.Errorf(codes.Unimplemented, "method GetTeacher not implemented") 268 | } 269 | func (UnimplementedAppServer) UpdateTeacher(context.Context, *UpdateTeacherRequest) (*emptypb.Empty, error) { 270 | return nil, status.Errorf(codes.Unimplemented, "method UpdateTeacher not implemented") 271 | } 272 | func (UnimplementedAppServer) DeleteTeacher(context.Context, *IDRequest) (*emptypb.Empty, error) { 273 | return nil, status.Errorf(codes.Unimplemented, "method DeleteTeacher not implemented") 274 | } 275 | func (UnimplementedAppServer) CreateBook(context.Context, *CreateBookRequest) (*emptypb.Empty, error) { 276 | return nil, status.Errorf(codes.Unimplemented, "method CreateBook not implemented") 277 | } 278 | func (UnimplementedAppServer) ListBook(context.Context, *PageRequest) (*ListBookReply, error) { 279 | return nil, status.Errorf(codes.Unimplemented, "method ListBook not implemented") 280 | } 281 | func (UnimplementedAppServer) GetBook(context.Context, *IDRequest) (*GetBookReply, error) { 282 | return nil, status.Errorf(codes.Unimplemented, "method GetBook not implemented") 283 | } 284 | func (UnimplementedAppServer) UpdateBook(context.Context, *UpdateBookRequest) (*emptypb.Empty, error) { 285 | return nil, status.Errorf(codes.Unimplemented, "method UpdateBook not implemented") 286 | } 287 | func (UnimplementedAppServer) DeleteBook(context.Context, *IDRequest) (*emptypb.Empty, error) { 288 | return nil, status.Errorf(codes.Unimplemented, "method DeleteBook not implemented") 289 | } 290 | func (UnimplementedAppServer) mustEmbedUnimplementedAppServer() {} 291 | 292 | // UnsafeAppServer may be embedded to opt out of forward compatibility for this service. 293 | // Use of this interface is not recommended, as added methods to AppServer will 294 | // result in compilation errors. 295 | type UnsafeAppServer interface { 296 | mustEmbedUnimplementedAppServer() 297 | } 298 | 299 | func RegisterAppServer(s grpc.ServiceRegistrar, srv AppServer) { 300 | s.RegisterService(&App_ServiceDesc, srv) 301 | } 302 | 303 | func _App_CreateLesson_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 304 | in := new(CreateLessonRequest) 305 | if err := dec(in); err != nil { 306 | return nil, err 307 | } 308 | if interceptor == nil { 309 | return srv.(AppServer).CreateLesson(ctx, in) 310 | } 311 | info := &grpc.UnaryServerInfo{ 312 | Server: srv, 313 | FullMethod: App_CreateLesson_FullMethodName, 314 | } 315 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 316 | return srv.(AppServer).CreateLesson(ctx, req.(*CreateLessonRequest)) 317 | } 318 | return interceptor(ctx, in, info, handler) 319 | } 320 | 321 | func _App_ListLesson_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 322 | in := new(PageRequest) 323 | if err := dec(in); err != nil { 324 | return nil, err 325 | } 326 | if interceptor == nil { 327 | return srv.(AppServer).ListLesson(ctx, in) 328 | } 329 | info := &grpc.UnaryServerInfo{ 330 | Server: srv, 331 | FullMethod: App_ListLesson_FullMethodName, 332 | } 333 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 334 | return srv.(AppServer).ListLesson(ctx, req.(*PageRequest)) 335 | } 336 | return interceptor(ctx, in, info, handler) 337 | } 338 | 339 | func _App_GetLesson_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 340 | in := new(IDRequest) 341 | if err := dec(in); err != nil { 342 | return nil, err 343 | } 344 | if interceptor == nil { 345 | return srv.(AppServer).GetLesson(ctx, in) 346 | } 347 | info := &grpc.UnaryServerInfo{ 348 | Server: srv, 349 | FullMethod: App_GetLesson_FullMethodName, 350 | } 351 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 352 | return srv.(AppServer).GetLesson(ctx, req.(*IDRequest)) 353 | } 354 | return interceptor(ctx, in, info, handler) 355 | } 356 | 357 | func _App_UpdateLesson_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 358 | in := new(UpdateLessonRequest) 359 | if err := dec(in); err != nil { 360 | return nil, err 361 | } 362 | if interceptor == nil { 363 | return srv.(AppServer).UpdateLesson(ctx, in) 364 | } 365 | info := &grpc.UnaryServerInfo{ 366 | Server: srv, 367 | FullMethod: App_UpdateLesson_FullMethodName, 368 | } 369 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 370 | return srv.(AppServer).UpdateLesson(ctx, req.(*UpdateLessonRequest)) 371 | } 372 | return interceptor(ctx, in, info, handler) 373 | } 374 | 375 | func _App_UpdateLessonStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 376 | in := new(UpdateLessonRequest) 377 | if err := dec(in); err != nil { 378 | return nil, err 379 | } 380 | if interceptor == nil { 381 | return srv.(AppServer).UpdateLessonStatus(ctx, in) 382 | } 383 | info := &grpc.UnaryServerInfo{ 384 | Server: srv, 385 | FullMethod: App_UpdateLessonStatus_FullMethodName, 386 | } 387 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 388 | return srv.(AppServer).UpdateLessonStatus(ctx, req.(*UpdateLessonRequest)) 389 | } 390 | return interceptor(ctx, in, info, handler) 391 | } 392 | 393 | func _App_DeleteLesson_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 394 | in := new(IDRequest) 395 | if err := dec(in); err != nil { 396 | return nil, err 397 | } 398 | if interceptor == nil { 399 | return srv.(AppServer).DeleteLesson(ctx, in) 400 | } 401 | info := &grpc.UnaryServerInfo{ 402 | Server: srv, 403 | FullMethod: App_DeleteLesson_FullMethodName, 404 | } 405 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 406 | return srv.(AppServer).DeleteLesson(ctx, req.(*IDRequest)) 407 | } 408 | return interceptor(ctx, in, info, handler) 409 | } 410 | 411 | func _App_CreateTeacher_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 412 | in := new(CreateTeacherRequest) 413 | if err := dec(in); err != nil { 414 | return nil, err 415 | } 416 | if interceptor == nil { 417 | return srv.(AppServer).CreateTeacher(ctx, in) 418 | } 419 | info := &grpc.UnaryServerInfo{ 420 | Server: srv, 421 | FullMethod: App_CreateTeacher_FullMethodName, 422 | } 423 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 424 | return srv.(AppServer).CreateTeacher(ctx, req.(*CreateTeacherRequest)) 425 | } 426 | return interceptor(ctx, in, info, handler) 427 | } 428 | 429 | func _App_ListTeacher_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 430 | in := new(PageRequest) 431 | if err := dec(in); err != nil { 432 | return nil, err 433 | } 434 | if interceptor == nil { 435 | return srv.(AppServer).ListTeacher(ctx, in) 436 | } 437 | info := &grpc.UnaryServerInfo{ 438 | Server: srv, 439 | FullMethod: App_ListTeacher_FullMethodName, 440 | } 441 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 442 | return srv.(AppServer).ListTeacher(ctx, req.(*PageRequest)) 443 | } 444 | return interceptor(ctx, in, info, handler) 445 | } 446 | 447 | func _App_GetTeacher_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 448 | in := new(IDRequest) 449 | if err := dec(in); err != nil { 450 | return nil, err 451 | } 452 | if interceptor == nil { 453 | return srv.(AppServer).GetTeacher(ctx, in) 454 | } 455 | info := &grpc.UnaryServerInfo{ 456 | Server: srv, 457 | FullMethod: App_GetTeacher_FullMethodName, 458 | } 459 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 460 | return srv.(AppServer).GetTeacher(ctx, req.(*IDRequest)) 461 | } 462 | return interceptor(ctx, in, info, handler) 463 | } 464 | 465 | func _App_UpdateTeacher_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 466 | in := new(UpdateTeacherRequest) 467 | if err := dec(in); err != nil { 468 | return nil, err 469 | } 470 | if interceptor == nil { 471 | return srv.(AppServer).UpdateTeacher(ctx, in) 472 | } 473 | info := &grpc.UnaryServerInfo{ 474 | Server: srv, 475 | FullMethod: App_UpdateTeacher_FullMethodName, 476 | } 477 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 478 | return srv.(AppServer).UpdateTeacher(ctx, req.(*UpdateTeacherRequest)) 479 | } 480 | return interceptor(ctx, in, info, handler) 481 | } 482 | 483 | func _App_DeleteTeacher_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 484 | in := new(IDRequest) 485 | if err := dec(in); err != nil { 486 | return nil, err 487 | } 488 | if interceptor == nil { 489 | return srv.(AppServer).DeleteTeacher(ctx, in) 490 | } 491 | info := &grpc.UnaryServerInfo{ 492 | Server: srv, 493 | FullMethod: App_DeleteTeacher_FullMethodName, 494 | } 495 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 496 | return srv.(AppServer).DeleteTeacher(ctx, req.(*IDRequest)) 497 | } 498 | return interceptor(ctx, in, info, handler) 499 | } 500 | 501 | func _App_CreateBook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 502 | in := new(CreateBookRequest) 503 | if err := dec(in); err != nil { 504 | return nil, err 505 | } 506 | if interceptor == nil { 507 | return srv.(AppServer).CreateBook(ctx, in) 508 | } 509 | info := &grpc.UnaryServerInfo{ 510 | Server: srv, 511 | FullMethod: App_CreateBook_FullMethodName, 512 | } 513 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 514 | return srv.(AppServer).CreateBook(ctx, req.(*CreateBookRequest)) 515 | } 516 | return interceptor(ctx, in, info, handler) 517 | } 518 | 519 | func _App_ListBook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 520 | in := new(PageRequest) 521 | if err := dec(in); err != nil { 522 | return nil, err 523 | } 524 | if interceptor == nil { 525 | return srv.(AppServer).ListBook(ctx, in) 526 | } 527 | info := &grpc.UnaryServerInfo{ 528 | Server: srv, 529 | FullMethod: App_ListBook_FullMethodName, 530 | } 531 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 532 | return srv.(AppServer).ListBook(ctx, req.(*PageRequest)) 533 | } 534 | return interceptor(ctx, in, info, handler) 535 | } 536 | 537 | func _App_GetBook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 538 | in := new(IDRequest) 539 | if err := dec(in); err != nil { 540 | return nil, err 541 | } 542 | if interceptor == nil { 543 | return srv.(AppServer).GetBook(ctx, in) 544 | } 545 | info := &grpc.UnaryServerInfo{ 546 | Server: srv, 547 | FullMethod: App_GetBook_FullMethodName, 548 | } 549 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 550 | return srv.(AppServer).GetBook(ctx, req.(*IDRequest)) 551 | } 552 | return interceptor(ctx, in, info, handler) 553 | } 554 | 555 | func _App_UpdateBook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 556 | in := new(UpdateBookRequest) 557 | if err := dec(in); err != nil { 558 | return nil, err 559 | } 560 | if interceptor == nil { 561 | return srv.(AppServer).UpdateBook(ctx, in) 562 | } 563 | info := &grpc.UnaryServerInfo{ 564 | Server: srv, 565 | FullMethod: App_UpdateBook_FullMethodName, 566 | } 567 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 568 | return srv.(AppServer).UpdateBook(ctx, req.(*UpdateBookRequest)) 569 | } 570 | return interceptor(ctx, in, info, handler) 571 | } 572 | 573 | func _App_DeleteBook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 574 | in := new(IDRequest) 575 | if err := dec(in); err != nil { 576 | return nil, err 577 | } 578 | if interceptor == nil { 579 | return srv.(AppServer).DeleteBook(ctx, in) 580 | } 581 | info := &grpc.UnaryServerInfo{ 582 | Server: srv, 583 | FullMethod: App_DeleteBook_FullMethodName, 584 | } 585 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 586 | return srv.(AppServer).DeleteBook(ctx, req.(*IDRequest)) 587 | } 588 | return interceptor(ctx, in, info, handler) 589 | } 590 | 591 | // App_ServiceDesc is the grpc.ServiceDesc for App service. 592 | // It's only intended for direct use with grpc.RegisterService, 593 | // and not to be introspected or modified (even as a copy) 594 | var App_ServiceDesc = grpc.ServiceDesc{ 595 | ServiceName: "api.App", 596 | HandlerType: (*AppServer)(nil), 597 | Methods: []grpc.MethodDesc{ 598 | { 599 | MethodName: "CreateLesson", 600 | Handler: _App_CreateLesson_Handler, 601 | }, 602 | { 603 | MethodName: "ListLesson", 604 | Handler: _App_ListLesson_Handler, 605 | }, 606 | { 607 | MethodName: "GetLesson", 608 | Handler: _App_GetLesson_Handler, 609 | }, 610 | { 611 | MethodName: "UpdateLesson", 612 | Handler: _App_UpdateLesson_Handler, 613 | }, 614 | { 615 | MethodName: "UpdateLessonStatus", 616 | Handler: _App_UpdateLessonStatus_Handler, 617 | }, 618 | { 619 | MethodName: "DeleteLesson", 620 | Handler: _App_DeleteLesson_Handler, 621 | }, 622 | { 623 | MethodName: "CreateTeacher", 624 | Handler: _App_CreateTeacher_Handler, 625 | }, 626 | { 627 | MethodName: "ListTeacher", 628 | Handler: _App_ListTeacher_Handler, 629 | }, 630 | { 631 | MethodName: "GetTeacher", 632 | Handler: _App_GetTeacher_Handler, 633 | }, 634 | { 635 | MethodName: "UpdateTeacher", 636 | Handler: _App_UpdateTeacher_Handler, 637 | }, 638 | { 639 | MethodName: "DeleteTeacher", 640 | Handler: _App_DeleteTeacher_Handler, 641 | }, 642 | { 643 | MethodName: "CreateBook", 644 | Handler: _App_CreateBook_Handler, 645 | }, 646 | { 647 | MethodName: "ListBook", 648 | Handler: _App_ListBook_Handler, 649 | }, 650 | { 651 | MethodName: "GetBook", 652 | Handler: _App_GetBook_Handler, 653 | }, 654 | { 655 | MethodName: "UpdateBook", 656 | Handler: _App_UpdateBook_Handler, 657 | }, 658 | { 659 | MethodName: "DeleteBook", 660 | Handler: _App_DeleteBook_Handler, 661 | }, 662 | }, 663 | Streams: []grpc.StreamDesc{}, 664 | Metadata: "app.proto", 665 | } 666 | -------------------------------------------------------------------------------- /api/app_http.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-http. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-http v2.6.3 4 | // - protoc v3.21.12 5 | // source: app.proto 6 | 7 | package api 8 | 9 | import ( 10 | context "context" 11 | http "github.com/go-kratos/kratos/v2/transport/http" 12 | binding "github.com/go-kratos/kratos/v2/transport/http/binding" 13 | emptypb "google.golang.org/protobuf/types/known/emptypb" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the kratos package it is being compiled against. 18 | var _ = new(context.Context) 19 | var _ = binding.EncodeURL 20 | 21 | const _ = http.SupportPackageIsVersion1 22 | 23 | const OperationAppCreateBook = "/api.App/CreateBook" 24 | const OperationAppCreateLesson = "/api.App/CreateLesson" 25 | const OperationAppCreateTeacher = "/api.App/CreateTeacher" 26 | const OperationAppDeleteBook = "/api.App/DeleteBook" 27 | const OperationAppDeleteLesson = "/api.App/DeleteLesson" 28 | const OperationAppDeleteTeacher = "/api.App/DeleteTeacher" 29 | const OperationAppGetBook = "/api.App/GetBook" 30 | const OperationAppGetLesson = "/api.App/GetLesson" 31 | const OperationAppGetTeacher = "/api.App/GetTeacher" 32 | const OperationAppListBook = "/api.App/ListBook" 33 | const OperationAppListLesson = "/api.App/ListLesson" 34 | const OperationAppListTeacher = "/api.App/ListTeacher" 35 | const OperationAppUpdateBook = "/api.App/UpdateBook" 36 | const OperationAppUpdateLesson = "/api.App/UpdateLesson" 37 | const OperationAppUpdateLessonStatus = "/api.App/UpdateLessonStatus" 38 | const OperationAppUpdateTeacher = "/api.App/UpdateTeacher" 39 | 40 | type AppHTTPServer interface { 41 | CreateBook(context.Context, *CreateBookRequest) (*emptypb.Empty, error) 42 | CreateLesson(context.Context, *CreateLessonRequest) (*emptypb.Empty, error) 43 | CreateTeacher(context.Context, *CreateTeacherRequest) (*emptypb.Empty, error) 44 | DeleteBook(context.Context, *IDRequest) (*emptypb.Empty, error) 45 | DeleteLesson(context.Context, *IDRequest) (*emptypb.Empty, error) 46 | DeleteTeacher(context.Context, *IDRequest) (*emptypb.Empty, error) 47 | GetBook(context.Context, *IDRequest) (*GetBookReply, error) 48 | GetLesson(context.Context, *IDRequest) (*GetLessonReply, error) 49 | GetTeacher(context.Context, *IDRequest) (*GetTeacherReply, error) 50 | ListBook(context.Context, *PageRequest) (*ListBookReply, error) 51 | ListLesson(context.Context, *PageRequest) (*ListLessonReply, error) 52 | ListTeacher(context.Context, *PageRequest) (*ListTeacherReply, error) 53 | UpdateBook(context.Context, *UpdateBookRequest) (*emptypb.Empty, error) 54 | UpdateLesson(context.Context, *UpdateLessonRequest) (*emptypb.Empty, error) 55 | UpdateLessonStatus(context.Context, *UpdateLessonRequest) (*emptypb.Empty, error) 56 | UpdateTeacher(context.Context, *UpdateTeacherRequest) (*emptypb.Empty, error) 57 | } 58 | 59 | func RegisterAppHTTPServer(s *http.Server, srv AppHTTPServer) { 60 | r := s.Route("/") 61 | r.POST("/v1/lesson", _App_CreateLesson0_HTTP_Handler(srv)) 62 | r.GET("/v1/lesson", _App_ListLesson0_HTTP_Handler(srv)) 63 | r.GET("/v1/lesson/{id}", _App_GetLesson0_HTTP_Handler(srv)) 64 | r.PUT("/v1/lesson/{id}", _App_UpdateLesson0_HTTP_Handler(srv)) 65 | r.PUT("/v1/lesson/{id}/status", _App_UpdateLessonStatus0_HTTP_Handler(srv)) 66 | r.DELETE("/v1/lesson/{id}", _App_DeleteLesson0_HTTP_Handler(srv)) 67 | r.POST("/v1/teacher", _App_CreateTeacher0_HTTP_Handler(srv)) 68 | r.GET("/v1/teacher", _App_ListTeacher0_HTTP_Handler(srv)) 69 | r.GET("/v1/teacher/{id}", _App_GetTeacher0_HTTP_Handler(srv)) 70 | r.PUT("/v1/teacher/{id}", _App_UpdateTeacher0_HTTP_Handler(srv)) 71 | r.DELETE("/v1/teacher/{id}", _App_DeleteTeacher0_HTTP_Handler(srv)) 72 | r.POST("/v1/book", _App_CreateBook0_HTTP_Handler(srv)) 73 | r.GET("/v1/book", _App_ListBook0_HTTP_Handler(srv)) 74 | r.GET("/v1/book/{id}", _App_GetBook0_HTTP_Handler(srv)) 75 | r.PUT("/v1/book/{id}", _App_UpdateBook0_HTTP_Handler(srv)) 76 | r.DELETE("/v1/book/{id}", _App_DeleteBook0_HTTP_Handler(srv)) 77 | } 78 | 79 | func _App_CreateLesson0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 80 | return func(ctx http.Context) error { 81 | var in CreateLessonRequest 82 | if err := ctx.Bind(&in); err != nil { 83 | return err 84 | } 85 | http.SetOperation(ctx, OperationAppCreateLesson) 86 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 87 | return srv.CreateLesson(ctx, req.(*CreateLessonRequest)) 88 | }) 89 | out, err := h(ctx, &in) 90 | if err != nil { 91 | return err 92 | } 93 | reply := out.(*emptypb.Empty) 94 | return ctx.Result(200, reply) 95 | } 96 | } 97 | 98 | func _App_ListLesson0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 99 | return func(ctx http.Context) error { 100 | var in PageRequest 101 | if err := ctx.BindQuery(&in); err != nil { 102 | return err 103 | } 104 | http.SetOperation(ctx, OperationAppListLesson) 105 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 106 | return srv.ListLesson(ctx, req.(*PageRequest)) 107 | }) 108 | out, err := h(ctx, &in) 109 | if err != nil { 110 | return err 111 | } 112 | reply := out.(*ListLessonReply) 113 | return ctx.Result(200, reply) 114 | } 115 | } 116 | 117 | func _App_GetLesson0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 118 | return func(ctx http.Context) error { 119 | var in IDRequest 120 | if err := ctx.BindQuery(&in); err != nil { 121 | return err 122 | } 123 | if err := ctx.BindVars(&in); err != nil { 124 | return err 125 | } 126 | http.SetOperation(ctx, OperationAppGetLesson) 127 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 128 | return srv.GetLesson(ctx, req.(*IDRequest)) 129 | }) 130 | out, err := h(ctx, &in) 131 | if err != nil { 132 | return err 133 | } 134 | reply := out.(*GetLessonReply) 135 | return ctx.Result(200, reply) 136 | } 137 | } 138 | 139 | func _App_UpdateLesson0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 140 | return func(ctx http.Context) error { 141 | var in UpdateLessonRequest 142 | if err := ctx.Bind(&in); err != nil { 143 | return err 144 | } 145 | if err := ctx.BindVars(&in); err != nil { 146 | return err 147 | } 148 | http.SetOperation(ctx, OperationAppUpdateLesson) 149 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 150 | return srv.UpdateLesson(ctx, req.(*UpdateLessonRequest)) 151 | }) 152 | out, err := h(ctx, &in) 153 | if err != nil { 154 | return err 155 | } 156 | reply := out.(*emptypb.Empty) 157 | return ctx.Result(200, reply) 158 | } 159 | } 160 | 161 | func _App_UpdateLessonStatus0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 162 | return func(ctx http.Context) error { 163 | var in UpdateLessonRequest 164 | if err := ctx.Bind(&in); err != nil { 165 | return err 166 | } 167 | if err := ctx.BindVars(&in); err != nil { 168 | return err 169 | } 170 | http.SetOperation(ctx, OperationAppUpdateLessonStatus) 171 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 172 | return srv.UpdateLessonStatus(ctx, req.(*UpdateLessonRequest)) 173 | }) 174 | out, err := h(ctx, &in) 175 | if err != nil { 176 | return err 177 | } 178 | reply := out.(*emptypb.Empty) 179 | return ctx.Result(200, reply) 180 | } 181 | } 182 | 183 | func _App_DeleteLesson0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 184 | return func(ctx http.Context) error { 185 | var in IDRequest 186 | if err := ctx.BindQuery(&in); err != nil { 187 | return err 188 | } 189 | if err := ctx.BindVars(&in); err != nil { 190 | return err 191 | } 192 | http.SetOperation(ctx, OperationAppDeleteLesson) 193 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 194 | return srv.DeleteLesson(ctx, req.(*IDRequest)) 195 | }) 196 | out, err := h(ctx, &in) 197 | if err != nil { 198 | return err 199 | } 200 | reply := out.(*emptypb.Empty) 201 | return ctx.Result(200, reply) 202 | } 203 | } 204 | 205 | func _App_CreateTeacher0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 206 | return func(ctx http.Context) error { 207 | var in CreateTeacherRequest 208 | if err := ctx.Bind(&in); err != nil { 209 | return err 210 | } 211 | http.SetOperation(ctx, OperationAppCreateTeacher) 212 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 213 | return srv.CreateTeacher(ctx, req.(*CreateTeacherRequest)) 214 | }) 215 | out, err := h(ctx, &in) 216 | if err != nil { 217 | return err 218 | } 219 | reply := out.(*emptypb.Empty) 220 | return ctx.Result(200, reply) 221 | } 222 | } 223 | 224 | func _App_ListTeacher0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 225 | return func(ctx http.Context) error { 226 | var in PageRequest 227 | if err := ctx.BindQuery(&in); err != nil { 228 | return err 229 | } 230 | http.SetOperation(ctx, OperationAppListTeacher) 231 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 232 | return srv.ListTeacher(ctx, req.(*PageRequest)) 233 | }) 234 | out, err := h(ctx, &in) 235 | if err != nil { 236 | return err 237 | } 238 | reply := out.(*ListTeacherReply) 239 | return ctx.Result(200, reply) 240 | } 241 | } 242 | 243 | func _App_GetTeacher0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 244 | return func(ctx http.Context) error { 245 | var in IDRequest 246 | if err := ctx.BindQuery(&in); err != nil { 247 | return err 248 | } 249 | if err := ctx.BindVars(&in); err != nil { 250 | return err 251 | } 252 | http.SetOperation(ctx, OperationAppGetTeacher) 253 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 254 | return srv.GetTeacher(ctx, req.(*IDRequest)) 255 | }) 256 | out, err := h(ctx, &in) 257 | if err != nil { 258 | return err 259 | } 260 | reply := out.(*GetTeacherReply) 261 | return ctx.Result(200, reply) 262 | } 263 | } 264 | 265 | func _App_UpdateTeacher0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 266 | return func(ctx http.Context) error { 267 | var in UpdateTeacherRequest 268 | if err := ctx.Bind(&in); err != nil { 269 | return err 270 | } 271 | if err := ctx.BindVars(&in); err != nil { 272 | return err 273 | } 274 | http.SetOperation(ctx, OperationAppUpdateTeacher) 275 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 276 | return srv.UpdateTeacher(ctx, req.(*UpdateTeacherRequest)) 277 | }) 278 | out, err := h(ctx, &in) 279 | if err != nil { 280 | return err 281 | } 282 | reply := out.(*emptypb.Empty) 283 | return ctx.Result(200, reply) 284 | } 285 | } 286 | 287 | func _App_DeleteTeacher0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 288 | return func(ctx http.Context) error { 289 | var in IDRequest 290 | if err := ctx.BindQuery(&in); err != nil { 291 | return err 292 | } 293 | if err := ctx.BindVars(&in); err != nil { 294 | return err 295 | } 296 | http.SetOperation(ctx, OperationAppDeleteTeacher) 297 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 298 | return srv.DeleteTeacher(ctx, req.(*IDRequest)) 299 | }) 300 | out, err := h(ctx, &in) 301 | if err != nil { 302 | return err 303 | } 304 | reply := out.(*emptypb.Empty) 305 | return ctx.Result(200, reply) 306 | } 307 | } 308 | 309 | func _App_CreateBook0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 310 | return func(ctx http.Context) error { 311 | var in CreateBookRequest 312 | if err := ctx.Bind(&in); err != nil { 313 | return err 314 | } 315 | http.SetOperation(ctx, OperationAppCreateBook) 316 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 317 | return srv.CreateBook(ctx, req.(*CreateBookRequest)) 318 | }) 319 | out, err := h(ctx, &in) 320 | if err != nil { 321 | return err 322 | } 323 | reply := out.(*emptypb.Empty) 324 | return ctx.Result(200, reply) 325 | } 326 | } 327 | 328 | func _App_ListBook0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 329 | return func(ctx http.Context) error { 330 | var in PageRequest 331 | if err := ctx.BindQuery(&in); err != nil { 332 | return err 333 | } 334 | http.SetOperation(ctx, OperationAppListBook) 335 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 336 | return srv.ListBook(ctx, req.(*PageRequest)) 337 | }) 338 | out, err := h(ctx, &in) 339 | if err != nil { 340 | return err 341 | } 342 | reply := out.(*ListBookReply) 343 | return ctx.Result(200, reply) 344 | } 345 | } 346 | 347 | func _App_GetBook0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 348 | return func(ctx http.Context) error { 349 | var in IDRequest 350 | if err := ctx.BindQuery(&in); err != nil { 351 | return err 352 | } 353 | if err := ctx.BindVars(&in); err != nil { 354 | return err 355 | } 356 | http.SetOperation(ctx, OperationAppGetBook) 357 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 358 | return srv.GetBook(ctx, req.(*IDRequest)) 359 | }) 360 | out, err := h(ctx, &in) 361 | if err != nil { 362 | return err 363 | } 364 | reply := out.(*GetBookReply) 365 | return ctx.Result(200, reply) 366 | } 367 | } 368 | 369 | func _App_UpdateBook0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 370 | return func(ctx http.Context) error { 371 | var in UpdateBookRequest 372 | if err := ctx.Bind(&in); err != nil { 373 | return err 374 | } 375 | if err := ctx.BindVars(&in); err != nil { 376 | return err 377 | } 378 | http.SetOperation(ctx, OperationAppUpdateBook) 379 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 380 | return srv.UpdateBook(ctx, req.(*UpdateBookRequest)) 381 | }) 382 | out, err := h(ctx, &in) 383 | if err != nil { 384 | return err 385 | } 386 | reply := out.(*emptypb.Empty) 387 | return ctx.Result(200, reply) 388 | } 389 | } 390 | 391 | func _App_DeleteBook0_HTTP_Handler(srv AppHTTPServer) func(ctx http.Context) error { 392 | return func(ctx http.Context) error { 393 | var in IDRequest 394 | if err := ctx.BindQuery(&in); err != nil { 395 | return err 396 | } 397 | if err := ctx.BindVars(&in); err != nil { 398 | return err 399 | } 400 | http.SetOperation(ctx, OperationAppDeleteBook) 401 | h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { 402 | return srv.DeleteBook(ctx, req.(*IDRequest)) 403 | }) 404 | out, err := h(ctx, &in) 405 | if err != nil { 406 | return err 407 | } 408 | reply := out.(*emptypb.Empty) 409 | return ctx.Result(200, reply) 410 | } 411 | } 412 | 413 | type AppHTTPClient interface { 414 | CreateBook(ctx context.Context, req *CreateBookRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) 415 | CreateLesson(ctx context.Context, req *CreateLessonRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) 416 | CreateTeacher(ctx context.Context, req *CreateTeacherRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) 417 | DeleteBook(ctx context.Context, req *IDRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) 418 | DeleteLesson(ctx context.Context, req *IDRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) 419 | DeleteTeacher(ctx context.Context, req *IDRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) 420 | GetBook(ctx context.Context, req *IDRequest, opts ...http.CallOption) (rsp *GetBookReply, err error) 421 | GetLesson(ctx context.Context, req *IDRequest, opts ...http.CallOption) (rsp *GetLessonReply, err error) 422 | GetTeacher(ctx context.Context, req *IDRequest, opts ...http.CallOption) (rsp *GetTeacherReply, err error) 423 | ListBook(ctx context.Context, req *PageRequest, opts ...http.CallOption) (rsp *ListBookReply, err error) 424 | ListLesson(ctx context.Context, req *PageRequest, opts ...http.CallOption) (rsp *ListLessonReply, err error) 425 | ListTeacher(ctx context.Context, req *PageRequest, opts ...http.CallOption) (rsp *ListTeacherReply, err error) 426 | UpdateBook(ctx context.Context, req *UpdateBookRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) 427 | UpdateLesson(ctx context.Context, req *UpdateLessonRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) 428 | UpdateLessonStatus(ctx context.Context, req *UpdateLessonRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) 429 | UpdateTeacher(ctx context.Context, req *UpdateTeacherRequest, opts ...http.CallOption) (rsp *emptypb.Empty, err error) 430 | } 431 | 432 | type AppHTTPClientImpl struct { 433 | cc *http.Client 434 | } 435 | 436 | func NewAppHTTPClient(client *http.Client) AppHTTPClient { 437 | return &AppHTTPClientImpl{client} 438 | } 439 | 440 | func (c *AppHTTPClientImpl) CreateBook(ctx context.Context, in *CreateBookRequest, opts ...http.CallOption) (*emptypb.Empty, error) { 441 | var out emptypb.Empty 442 | pattern := "/v1/book" 443 | path := binding.EncodeURL(pattern, in, false) 444 | opts = append(opts, http.Operation(OperationAppCreateBook)) 445 | opts = append(opts, http.PathTemplate(pattern)) 446 | err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...) 447 | if err != nil { 448 | return nil, err 449 | } 450 | return &out, err 451 | } 452 | 453 | func (c *AppHTTPClientImpl) CreateLesson(ctx context.Context, in *CreateLessonRequest, opts ...http.CallOption) (*emptypb.Empty, error) { 454 | var out emptypb.Empty 455 | pattern := "/v1/lesson" 456 | path := binding.EncodeURL(pattern, in, false) 457 | opts = append(opts, http.Operation(OperationAppCreateLesson)) 458 | opts = append(opts, http.PathTemplate(pattern)) 459 | err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...) 460 | if err != nil { 461 | return nil, err 462 | } 463 | return &out, err 464 | } 465 | 466 | func (c *AppHTTPClientImpl) CreateTeacher(ctx context.Context, in *CreateTeacherRequest, opts ...http.CallOption) (*emptypb.Empty, error) { 467 | var out emptypb.Empty 468 | pattern := "/v1/teacher" 469 | path := binding.EncodeURL(pattern, in, false) 470 | opts = append(opts, http.Operation(OperationAppCreateTeacher)) 471 | opts = append(opts, http.PathTemplate(pattern)) 472 | err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...) 473 | if err != nil { 474 | return nil, err 475 | } 476 | return &out, err 477 | } 478 | 479 | func (c *AppHTTPClientImpl) DeleteBook(ctx context.Context, in *IDRequest, opts ...http.CallOption) (*emptypb.Empty, error) { 480 | var out emptypb.Empty 481 | pattern := "/v1/book/{id}" 482 | path := binding.EncodeURL(pattern, in, true) 483 | opts = append(opts, http.Operation(OperationAppDeleteBook)) 484 | opts = append(opts, http.PathTemplate(pattern)) 485 | err := c.cc.Invoke(ctx, "DELETE", path, nil, &out, opts...) 486 | if err != nil { 487 | return nil, err 488 | } 489 | return &out, err 490 | } 491 | 492 | func (c *AppHTTPClientImpl) DeleteLesson(ctx context.Context, in *IDRequest, opts ...http.CallOption) (*emptypb.Empty, error) { 493 | var out emptypb.Empty 494 | pattern := "/v1/lesson/{id}" 495 | path := binding.EncodeURL(pattern, in, true) 496 | opts = append(opts, http.Operation(OperationAppDeleteLesson)) 497 | opts = append(opts, http.PathTemplate(pattern)) 498 | err := c.cc.Invoke(ctx, "DELETE", path, nil, &out, opts...) 499 | if err != nil { 500 | return nil, err 501 | } 502 | return &out, err 503 | } 504 | 505 | func (c *AppHTTPClientImpl) DeleteTeacher(ctx context.Context, in *IDRequest, opts ...http.CallOption) (*emptypb.Empty, error) { 506 | var out emptypb.Empty 507 | pattern := "/v1/teacher/{id}" 508 | path := binding.EncodeURL(pattern, in, true) 509 | opts = append(opts, http.Operation(OperationAppDeleteTeacher)) 510 | opts = append(opts, http.PathTemplate(pattern)) 511 | err := c.cc.Invoke(ctx, "DELETE", path, nil, &out, opts...) 512 | if err != nil { 513 | return nil, err 514 | } 515 | return &out, err 516 | } 517 | 518 | func (c *AppHTTPClientImpl) GetBook(ctx context.Context, in *IDRequest, opts ...http.CallOption) (*GetBookReply, error) { 519 | var out GetBookReply 520 | pattern := "/v1/book/{id}" 521 | path := binding.EncodeURL(pattern, in, true) 522 | opts = append(opts, http.Operation(OperationAppGetBook)) 523 | opts = append(opts, http.PathTemplate(pattern)) 524 | err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) 525 | if err != nil { 526 | return nil, err 527 | } 528 | return &out, err 529 | } 530 | 531 | func (c *AppHTTPClientImpl) GetLesson(ctx context.Context, in *IDRequest, opts ...http.CallOption) (*GetLessonReply, error) { 532 | var out GetLessonReply 533 | pattern := "/v1/lesson/{id}" 534 | path := binding.EncodeURL(pattern, in, true) 535 | opts = append(opts, http.Operation(OperationAppGetLesson)) 536 | opts = append(opts, http.PathTemplate(pattern)) 537 | err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) 538 | if err != nil { 539 | return nil, err 540 | } 541 | return &out, err 542 | } 543 | 544 | func (c *AppHTTPClientImpl) GetTeacher(ctx context.Context, in *IDRequest, opts ...http.CallOption) (*GetTeacherReply, error) { 545 | var out GetTeacherReply 546 | pattern := "/v1/teacher/{id}" 547 | path := binding.EncodeURL(pattern, in, true) 548 | opts = append(opts, http.Operation(OperationAppGetTeacher)) 549 | opts = append(opts, http.PathTemplate(pattern)) 550 | err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) 551 | if err != nil { 552 | return nil, err 553 | } 554 | return &out, err 555 | } 556 | 557 | func (c *AppHTTPClientImpl) ListBook(ctx context.Context, in *PageRequest, opts ...http.CallOption) (*ListBookReply, error) { 558 | var out ListBookReply 559 | pattern := "/v1/book" 560 | path := binding.EncodeURL(pattern, in, true) 561 | opts = append(opts, http.Operation(OperationAppListBook)) 562 | opts = append(opts, http.PathTemplate(pattern)) 563 | err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) 564 | if err != nil { 565 | return nil, err 566 | } 567 | return &out, err 568 | } 569 | 570 | func (c *AppHTTPClientImpl) ListLesson(ctx context.Context, in *PageRequest, opts ...http.CallOption) (*ListLessonReply, error) { 571 | var out ListLessonReply 572 | pattern := "/v1/lesson" 573 | path := binding.EncodeURL(pattern, in, true) 574 | opts = append(opts, http.Operation(OperationAppListLesson)) 575 | opts = append(opts, http.PathTemplate(pattern)) 576 | err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) 577 | if err != nil { 578 | return nil, err 579 | } 580 | return &out, err 581 | } 582 | 583 | func (c *AppHTTPClientImpl) ListTeacher(ctx context.Context, in *PageRequest, opts ...http.CallOption) (*ListTeacherReply, error) { 584 | var out ListTeacherReply 585 | pattern := "/v1/teacher" 586 | path := binding.EncodeURL(pattern, in, true) 587 | opts = append(opts, http.Operation(OperationAppListTeacher)) 588 | opts = append(opts, http.PathTemplate(pattern)) 589 | err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...) 590 | if err != nil { 591 | return nil, err 592 | } 593 | return &out, err 594 | } 595 | 596 | func (c *AppHTTPClientImpl) UpdateBook(ctx context.Context, in *UpdateBookRequest, opts ...http.CallOption) (*emptypb.Empty, error) { 597 | var out emptypb.Empty 598 | pattern := "/v1/book/{id}" 599 | path := binding.EncodeURL(pattern, in, false) 600 | opts = append(opts, http.Operation(OperationAppUpdateBook)) 601 | opts = append(opts, http.PathTemplate(pattern)) 602 | err := c.cc.Invoke(ctx, "PUT", path, in, &out, opts...) 603 | if err != nil { 604 | return nil, err 605 | } 606 | return &out, err 607 | } 608 | 609 | func (c *AppHTTPClientImpl) UpdateLesson(ctx context.Context, in *UpdateLessonRequest, opts ...http.CallOption) (*emptypb.Empty, error) { 610 | var out emptypb.Empty 611 | pattern := "/v1/lesson/{id}" 612 | path := binding.EncodeURL(pattern, in, false) 613 | opts = append(opts, http.Operation(OperationAppUpdateLesson)) 614 | opts = append(opts, http.PathTemplate(pattern)) 615 | err := c.cc.Invoke(ctx, "PUT", path, in, &out, opts...) 616 | if err != nil { 617 | return nil, err 618 | } 619 | return &out, err 620 | } 621 | 622 | func (c *AppHTTPClientImpl) UpdateLessonStatus(ctx context.Context, in *UpdateLessonRequest, opts ...http.CallOption) (*emptypb.Empty, error) { 623 | var out emptypb.Empty 624 | pattern := "/v1/lesson/{id}/status" 625 | path := binding.EncodeURL(pattern, in, false) 626 | opts = append(opts, http.Operation(OperationAppUpdateLessonStatus)) 627 | opts = append(opts, http.PathTemplate(pattern)) 628 | err := c.cc.Invoke(ctx, "PUT", path, in, &out, opts...) 629 | if err != nil { 630 | return nil, err 631 | } 632 | return &out, err 633 | } 634 | 635 | func (c *AppHTTPClientImpl) UpdateTeacher(ctx context.Context, in *UpdateTeacherRequest, opts ...http.CallOption) (*emptypb.Empty, error) { 636 | var out emptypb.Empty 637 | pattern := "/v1/teacher/{id}" 638 | path := binding.EncodeURL(pattern, in, false) 639 | opts = append(opts, http.Operation(OperationAppUpdateTeacher)) 640 | opts = append(opts, http.PathTemplate(pattern)) 641 | err := c.cc.Invoke(ctx, "PUT", path, in, &out, opts...) 642 | if err != nil { 643 | return nil, err 644 | } 645 | return &out, err 646 | } 647 | -------------------------------------------------------------------------------- /api/cms.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package api; 3 | import "google/api/annotations.proto"; 4 | import "google/protobuf/empty.proto"; 5 | option go_package = "lin-cms-go/api"; 6 | 7 | service Cms { 8 | rpc Ping(google.protobuf.Empty) returns (PingReply) { 9 | option (google.api.http) = { 10 | get : "/ping" 11 | }; 12 | } 13 | rpc Login(LoginRequest) returns (LoginReply) { 14 | option (google.api.http) = { 15 | post : "/cms/user/login" 16 | body : "*" 17 | }; 18 | } 19 | 20 | rpc Upload(UploadRequest) returns (UploadReply) { 21 | option (google.api.http) = { 22 | post : "/cms/file" 23 | body : "*" 24 | }; 25 | } 26 | 27 | rpc CreateUser(CreateLinUserRequest) returns (google.protobuf.Empty) { 28 | option (google.api.http) = { 29 | post : "/cms/user/register" 30 | body : "*" 31 | }; 32 | } 33 | rpc UpdateMe(UpdateMeRequest) returns (google.protobuf.Empty) { 34 | option (google.api.http) = { 35 | put : "/cms/user" 36 | body : "*" 37 | }; 38 | } 39 | rpc UpdateMyPassword(UpdateMyPasswordRequest) 40 | returns (google.protobuf.Empty) { 41 | option (google.api.http) = { 42 | put : "/cms/user/change_password" 43 | body : "*" 44 | }; 45 | } 46 | rpc ListMyPermission(google.protobuf.Empty) returns (ListMyPermissionReply) { 47 | option (google.api.http) = { 48 | get : "/cms/user/permissions" 49 | }; 50 | } 51 | rpc GetMyInfomation(google.protobuf.Empty) returns (GetMyInfomationReply) { 52 | option (google.api.http) = { 53 | get : "/cms/user/information" 54 | }; 55 | } 56 | 57 | rpc ListPermission(google.protobuf.Empty) returns (ListPermissionReply) { 58 | option (google.api.http) = { 59 | get : "/cms/admin/permissions" 60 | }; 61 | } 62 | rpc ListUser(ListLinUserRequest) returns (ListLinUserReply) { 63 | option (google.api.http) = { 64 | get : "/cms/admin/users" 65 | }; 66 | } 67 | rpc UpdateUserPassword(UpdateUserPasswordRequest) 68 | returns (google.protobuf.Empty) { 69 | option (google.api.http) = { 70 | put : "/cms/admin/user/{id}/password" 71 | body : "*" 72 | }; 73 | } 74 | rpc DeleteUser(IDRequest) returns (google.protobuf.Empty) { 75 | option (google.api.http) = { 76 | delete : "/cms/admin/user/{id}" 77 | }; 78 | } 79 | rpc UpdateUser(UpdateUserRequest) returns (google.protobuf.Empty) { 80 | option (google.api.http) = { 81 | put : "/cms/admin/user/{id}" 82 | body : "*" 83 | }; 84 | } 85 | rpc GetUser(IDRequest) returns (GetLinUserReply) { 86 | option (google.api.http) = { 87 | get : "/cms/admin/user/{id}" 88 | }; 89 | } 90 | rpc GetGroup(IDRequest) returns (GetGroupReply) { 91 | option (google.api.http) = { 92 | get : "/cms/admin/group/{id}" 93 | }; 94 | } 95 | rpc UpdateGroup(UpdateGroupRequest) returns (google.protobuf.Empty) { 96 | option (google.api.http) = { 97 | put : "/cms/admin/group/{id}" 98 | body : "*" 99 | }; 100 | } 101 | 102 | rpc DeleteGroup(IDRequest) returns (google.protobuf.Empty) { 103 | option (google.api.http) = { 104 | delete : "/cms/admin/group/{id}" 105 | }; 106 | } 107 | rpc CreateGroup(CreateGroupRequest) returns (google.protobuf.Empty) { 108 | option (google.api.http) = { 109 | post : "/cms/admin/group" 110 | body : "*" 111 | }; 112 | } 113 | rpc ListGroup(google.protobuf.Empty) returns (ListGroupReply) { 114 | option (google.api.http) = { 115 | get : "/cms/admin/groups" 116 | }; 117 | } 118 | 119 | rpc DispatchPermission(DispatchPermissionRequest) 120 | returns (google.protobuf.Empty) { 121 | option (google.api.http) = { 122 | post : "/cms/admin/permission/dispatch" 123 | body : "*" 124 | }; 125 | } 126 | rpc DispatchPermissions(DispatchPermissionsRequest) 127 | returns (google.protobuf.Empty) { 128 | option (google.api.http) = { 129 | post : "/cms/admin/permissions/dispatch" 130 | body : "*" 131 | }; 132 | } 133 | rpc RemovePermission(RemovePermissionRequest) 134 | returns (google.protobuf.Empty) { 135 | option (google.api.http) = { 136 | post : "/cms/admin/permissions/remove" 137 | body : "*" 138 | }; 139 | } 140 | rpc ListLog(PageRequest) returns (ListLogReply) { 141 | option (google.api.http) = { 142 | get : "/cms/log" 143 | }; 144 | } 145 | rpc SearchLog(SearchLogRequest) returns (ListLogReply) { 146 | option (google.api.http) = { 147 | get : "/cms/log/search" 148 | }; 149 | } 150 | rpc ListLogUser(PageRequest) returns (ListLogUserReply) { 151 | option (google.api.http) = { 152 | get : "/cms/log/users" 153 | }; 154 | } 155 | } 156 | message DispatchPermissionsRequest { 157 | string groupId = 1; 158 | repeated int32 permissionIds = 2; 159 | } 160 | message DispatchPermissionRequest { 161 | int32 groupId = 1; 162 | int32 permissionId = 2; 163 | } 164 | message RemovePermissionRequest { 165 | int32 groupId = 1; 166 | repeated int32 permissionIds = 2; 167 | } 168 | 169 | message LoginRequest { 170 | string username = 1; 171 | string password = 2; 172 | } 173 | message CreateLinUserRequest { 174 | string username = 1; 175 | string phone = 2; 176 | string password = 3; 177 | int32 groupId = 5; 178 | } 179 | message UpdateMeRequest { 180 | string nickname = 1; 181 | string avatar = 2; 182 | string email = 3; 183 | } 184 | message UpdateUserPasswordRequest { 185 | int32 id = 1; 186 | string oldPassword = 2; 187 | string newPassword = 3; 188 | } 189 | 190 | message ListLogRequest { 191 | string start = 1; 192 | string end = 2; 193 | int32 page = 3; 194 | int32 size = 4; 195 | string name = 5; 196 | } 197 | message SearchLogRequest { 198 | string keyword = 1; 199 | string start = 2; 200 | string end = 3; 201 | int32 page = 4; 202 | int32 size = 5; 203 | string name = 6; 204 | } 205 | 206 | message ListLinUserRequest { 207 | int64 groupId = 1; 208 | int32 page = 2; 209 | int32 size = 3; 210 | } 211 | 212 | message UpdateGroupRequest { 213 | int64 id = 1; 214 | string name = 2; 215 | string info = 3; 216 | } 217 | message GetGroupReply {} 218 | message GetLinUserReply {} 219 | message GetMyInfomationReply {} 220 | message ListMyPermissionReply {} 221 | 222 | message UpdateUserRequest { 223 | int64 id = 1; 224 | repeated int64 group_ids = 2; 225 | } 226 | 227 | message UpdateMyPasswordRequest {} 228 | 229 | message ListLinUserReply { 230 | repeated LinUser list = 1; 231 | uint32 total = 2; 232 | } 233 | 234 | message ListGroupReply {} 235 | message LinUser { 236 | int64 id = 1; 237 | string username = 2; 238 | string phone = 3; 239 | } 240 | message Permission { int64 id = 1; } 241 | message ListPermissionReply { repeated Permission permissions = 1; } 242 | 243 | message UploadRequest { string file = 1; } 244 | message UploadReply { string url = 1; } 245 | 246 | message ListLogUserReply { repeated string users = 1; } 247 | message CreateGroupRequest { 248 | string name = 1; 249 | string info = 2; 250 | repeated int64 permission_ids = 3; 251 | } 252 | message Log { uint32 id = 1; } 253 | message ListLogReply { 254 | repeated Log list = 1; 255 | uint32 total = 2; 256 | } 257 | 258 | message PageRequest { 259 | int32 page = 1; 260 | int32 size = 2; 261 | } 262 | message IDRequest { int64 id = 1; } 263 | message PingReply { string message = 1; } 264 | 265 | message LoginReply { 266 | string accessToken = 1; 267 | string refreshToken = 2; 268 | } 269 | -------------------------------------------------------------------------------- /cmd/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "io" 6 | "os" 7 | "time" 8 | 9 | "lin-cms-go/internal/conf" 10 | 11 | "github.com/go-kratos/kratos/v2/config" 12 | "github.com/go-kratos/kratos/v2/config/file" 13 | 14 | kzap "github.com/go-kratos/kratos/contrib/log/zap/v2" 15 | "github.com/go-kratos/kratos/v2" 16 | "github.com/go-kratos/kratos/v2/log" 17 | "github.com/go-kratos/kratos/v2/transport/http" 18 | "go.uber.org/zap" 19 | "go.uber.org/zap/zapcore" 20 | ) 21 | 22 | var ( 23 | id, _ = os.Hostname() 24 | Name = "lin-cms" 25 | flagconf string 26 | ) 27 | 28 | func init() { 29 | flag.StringVar(&flagconf, "conf", "../../configs/config.yaml", "config path, eg: -conf config.yaml") 30 | } 31 | 32 | func newApp(logger log.Logger, hs *http.Server) *kratos.App { 33 | return kratos.New( 34 | kratos.ID(id), 35 | kratos.Name(Name), 36 | 37 | kratos.Logger(logger), 38 | kratos.Server(hs)) 39 | } 40 | 41 | func main() { 42 | os.RemoveAll("./log") 43 | conf := newConfig() 44 | logger := log.With(kzap.NewLogger(newLogger()), 45 | "service.id", id, 46 | "service.name", Name, 47 | 48 | "caller", log.DefaultCaller, 49 | ) 50 | 51 | app, cleanup, err := NewWire(conf.Server, conf.Data, logger) 52 | if err != nil { 53 | panic(err) 54 | } 55 | defer cleanup() 56 | 57 | if err = app.Run(); err != nil { 58 | panic(err) 59 | } 60 | } 61 | 62 | func newLogger() *zap.Logger { 63 | f, err := os.OpenFile("./app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, os.ModePerm) 64 | if err != nil { 65 | panic(err) 66 | } 67 | writeSyncer := zapcore.AddSync(io.MultiWriter(f, os.Stdout)) 68 | cfg := zap.NewProductionEncoderConfig() 69 | cfg.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { 70 | enc.AppendString(t.Format("2006-01-02 15:04:05.000")) 71 | } 72 | encoder := zapcore.NewJSONEncoder(cfg) 73 | core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel) 74 | 75 | return zap.New(core) 76 | } 77 | 78 | func newConfig() *conf.Bootstrap { 79 | c := config.New( 80 | config.WithSource( 81 | file.NewSource(flagconf), 82 | ), 83 | ) 84 | defer c.Close() 85 | 86 | if err := c.Load(); err != nil { 87 | panic(err) 88 | } 89 | var bc conf.Bootstrap 90 | if err := c.Scan(&bc); err != nil { 91 | panic(err) 92 | } 93 | return &bc 94 | } 95 | -------------------------------------------------------------------------------- /cmd/server/wire.go: -------------------------------------------------------------------------------- 1 | //go:build wireinject 2 | // +build wireinject 3 | 4 | package main 5 | 6 | import ( 7 | "lin-cms-go/internal/biz" 8 | "lin-cms-go/internal/conf" 9 | "lin-cms-go/internal/data" 10 | "lin-cms-go/internal/server" 11 | "lin-cms-go/internal/service" 12 | 13 | "github.com/go-kratos/kratos/v2" 14 | "github.com/go-kratos/kratos/v2/log" 15 | "github.com/google/wire" 16 | ) 17 | 18 | // NewWire init kratos application. 19 | func NewWire(*conf.Server, *conf.Data, log.Logger) (*kratos.App, func(), error) { 20 | panic(wire.Build(server.ProviderSet, 21 | data.ProviderSet, 22 | biz.ProviderSet, 23 | service.ProviderSet, 24 | newApp)) 25 | } 26 | -------------------------------------------------------------------------------- /cmd/server/wire_gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Wire. DO NOT EDIT. 2 | 3 | //go:generate go run -mod=mod github.com/google/wire/cmd/wire 4 | //go:build !wireinject 5 | // +build !wireinject 6 | 7 | package main 8 | 9 | import ( 10 | "github.com/go-kratos/kratos/v2" 11 | "github.com/go-kratos/kratos/v2/log" 12 | "lin-cms-go/internal/biz" 13 | "lin-cms-go/internal/conf" 14 | "lin-cms-go/internal/data" 15 | "lin-cms-go/internal/server" 16 | "lin-cms-go/internal/service" 17 | ) 18 | 19 | // Injectors from wire.go: 20 | 21 | // NewWire init kratos application. 22 | func NewWire(confServer *conf.Server, confData *conf.Data, logger log.Logger) (*kratos.App, func(), error) { 23 | dataData, cleanup, err := data.NewData(confData) 24 | if err != nil { 25 | return nil, nil, err 26 | } 27 | linUserRepo := data.NewLinUserRepo(dataData, logger) 28 | linUserusecase := biz.NewLinUserUsecase(linUserRepo, logger) 29 | cmsService := service.NewCmsService(linUserusecase) 30 | bookRepo := data.NewBookRepo(dataData, logger) 31 | bookUsecase := biz.NewBookUsecase(bookRepo, logger) 32 | lessonRepo := data.NewLessonRepo(dataData, logger) 33 | lessonUsecase := biz.NewLessonUsecase(lessonRepo, logger) 34 | teacherRepo := data.NewTeacherRepo(dataData, logger) 35 | teacherUsecase := biz.NewTeacherUsecase(teacherRepo, logger) 36 | appService := service.NewAppService(bookUsecase, lessonUsecase, teacherUsecase) 37 | httpServer := server.NewHTTPServer(confServer, cmsService, appService, logger) 38 | app := newApp(logger, httpServer) 39 | return app, func() { 40 | cleanup() 41 | }, nil 42 | } 43 | -------------------------------------------------------------------------------- /configs/example.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | http: 3 | addr: 0.0.0.0:3000 4 | timeout: 1 5 | 6 | data: 7 | database: 8 | main: test:pass@tcp(1.1.1.1:3306)/test?charset=utf8mb4&parseTime=True 9 | redis: 10 | addr: 127.0.0.1:6379 11 | read_timeout: 2 12 | write_timeout: 2 13 | -------------------------------------------------------------------------------- /deploy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine AS build 2 | 3 | # 设置环境变量 4 | ENV CGO_ENABLED 0 5 | ENV GOOS linux 6 | ENV GOPROXY https://goproxy.cn,direct 7 | 8 | # 项目代码存放的目录 9 | WORKDIR /home/www/lin-cms-go 10 | 11 | ADD go.mod . 12 | ADD go.sum . 13 | 14 | COPY . . 15 | 16 | # 编译成二进制可执行文件名 app 17 | RUN go build -o app . 18 | 19 | 20 | FROM alpine AS prod 21 | 22 | COPY --from=build /home/www/lin-cms-go/ . 23 | COPY --from=build /home/www/lin-cms-go/configs/config.yaml ./configs/ 24 | 25 | # 端口 26 | EXPOSE 3000 27 | 28 | CMD ["./app"] 29 | 30 | 31 | # docker build -t lin-cms:v1 -f Dockerfile . 32 | # docker run -it -p 8080:3000 lin-cms:v1 -------------------------------------------------------------------------------- /docs/app.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS teacher; 2 | 3 | CREATE TABLE 4 | teacher ( 5 | id bigint (20) unsigned NOT NULL AUTO_INCREMENT, 6 | name varchar(10) NOT NULL DEFAULT '' COMMENT '姓名', 7 | nickname varchar(30) NOT NULL DEFAULT '' COMMENT '昵称', 8 | introduce varchar(200) NOT NULL DEFAULT '' COMMENT '简介', 9 | avatar varchar(100) NOT NULL DEFAULT '' COMMENT '头像', 10 | domain varchar(10) NOT NULL DEFAULT '' COMMENT '擅长领域', 11 | area varchar(10) NOT NULL DEFAULT '' COMMENT '地区', 12 | remark varchar(10) NOT NULL DEFAULT '' COMMENT '备注', 13 | class_hour varchar(20) NOT NULL DEFAULT '' COMMENT '上课时间', 14 | phone varchar(15) NOT NULL DEFAULT '' COMMENT '手机号', 15 | created_at TIMESTAMP DEFAULT NULL, 16 | updated_at TIMESTAMP DEFAULT NULL, 17 | deleted_at TIMESTAMP DEFAULT NULL, 18 | PRIMARY KEY (id) 19 | ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci; 20 | 21 | DROP TABLE IF EXISTS user; 22 | 23 | CREATE TABLE 24 | user ( 25 | id bigint (20) NOT NULL AUTO_INCREMENT, 26 | phone varchar(15) NOT NULL DEFAULT '' COMMENT '手机号', 27 | `openid` varchar(50) DEFAULT NULL, 28 | `nickname` varchar(60) DEFAULT NULL, 29 | `wx_profile` json DEFAULT NULL, 30 | created_at TIMESTAMP DEFAULT NULL, 31 | updated_at TIMESTAMP DEFAULT NULL, 32 | deleted_at TIMESTAMP DEFAULT NULL, 33 | PRIMARY KEY (id) 34 | ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci; 35 | 36 | DROP TABLE IF EXISTS lesson; 37 | 38 | CREATE TABLE 39 | lesson ( 40 | id bigint (20) unsigned NOT NULL AUTO_INCREMENT, 41 | teacher_id bigint (20) unsigned NOT NULL, 42 | title varchar(10) NOT NULL DEFAULT '' COMMENT '标题', 43 | introduce varchar(200) NOT NULL DEFAULT '' COMMENT '简介', 44 | `start_at` datetime NOT NULL DEFAULT '' COMMENT '上课时间', 45 | `end_at` datetime NOT NULL DEFAULT '' COMMENT '上课时间', 46 | `lesson_status` tinyint (1) NOT NULL DEFAULT 0 COMMENT '状态 0 未开始 1 正在上课 2 已结束', 47 | `is_paid` tinyint (1) NOT NULL DEFAULT 0 COMMENT '类型 0 免费 1 收费', 48 | `price` decimal(8, 2) NOT NULL DEFAULT 0 COMMENT '价格', 49 | province varchar(10) NOT NULL DEFAULT '' COMMENT '省', 50 | city varchar(10) NOT NULL DEFAULT '' COMMENT '市', 51 | area varchar(10) NOT NULL DEFAULT '' COMMENT '区', 52 | address varchar(10) NOT NULL DEFAULT '' COMMENT '地址', 53 | created_at TIMESTAMP DEFAULT NULL, 54 | updated_at TIMESTAMP DEFAULT NULL, 55 | deleted_at TIMESTAMP DEFAULT NULL, 56 | PRIMARY KEY (id) 57 | ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci; 58 | 59 | DROP TABLE IF EXISTS lesson_signup; 60 | 61 | CREATE TABLE 62 | lesson_signup ( 63 | id bigint (20) unsigned NOT NULL AUTO_INCREMENT, 64 | user_id bigint (20) unsigned NOT NULL, 65 | lesson_id bigint (20) unsigned NOT NULL, 66 | created_at TIMESTAMP DEFAULT NULL, 67 | updated_at TIMESTAMP DEFAULT NULL, 68 | deleted_at TIMESTAMP DEFAULT NULL, 69 | PRIMARY KEY (id) 70 | ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '课程报名'; 71 | 72 | DROP TABLE IF EXISTS lesson_signin; 73 | 74 | CREATE TABLE 75 | `lesson_signin` ( 76 | id bigint (20) unsigned NOT NULL AUTO_INCREMENT, 77 | user_id bigint (20) unsigned NOT NULL, 78 | lesson_id bigint (20) unsigned NOT NULL, 79 | created_at TIMESTAMP DEFAULT NULL, 80 | updated_at TIMESTAMP DEFAULT NULL, 81 | deleted_at TIMESTAMP DEFAULT NULL, 82 | PRIMARY KEY (id) 83 | ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '课程签到'; 84 | 85 | CREATE TABLE 86 | `lesson_comment` ( 87 | id bigint (20) unsigned NOT NULL AUTO_INCREMENT, 88 | user_id bigint (20) unsigned NOT NULL, 89 | teacher_id bigint (20) unsigned NOT NULL, 90 | lesson_id bigint (20) unsigned NOT NULL, 91 | created_at TIMESTAMP DEFAULT NULL, 92 | updated_at TIMESTAMP DEFAULT NULL, 93 | deleted_at TIMESTAMP DEFAULT NULL, 94 | PRIMARY KEY (id) 95 | ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '课程评论'; -------------------------------------------------------------------------------- /docs/rest.http: -------------------------------------------------------------------------------- 1 | 2 | # @name login 3 | POST {{host}}/cms/user/login 4 | Content-Type: application/json 5 | 6 | { 7 | "username": "root", 8 | "password": "123456" 9 | } 10 | 11 | ### 12 | POST {{host}}/cms/user/register 13 | Content-Type: application/json 14 | 15 | { 16 | "username": "guest", 17 | "email": "guest@cms.com", 18 | "confirm_password": "123456", 19 | "group_id": 1, 20 | "password": "123456" 21 | } 22 | ### 23 | POST {{host}}/cms/user/login 24 | Content-Type: application/json 25 | 26 | { 27 | "username": "guest", 28 | "password": "123456" 29 | } 30 | ### 31 | 32 | @token = {{login.response.body.$.accessToken}} 33 | 34 | GET {{host}}/cms/admin/permissions 35 | Content-Type: application/json 36 | Authorization: Bearer {{token}} 37 | 38 | ### 39 | POST {{host}}/cms/admin/permissions/remove 40 | Content-Type: application/json 41 | Authorization: Bearer {{token}} 42 | 43 | { 44 | "group_id": 1, 45 | "permission_ids": [1,2] 46 | } 47 | 48 | ### 49 | POST {{host}}/cms/admin/permissions/dispatch 50 | Content-Type: application/json 51 | Authorization: Bearer {{token}} 52 | 53 | { 54 | "group_id": 1, 55 | "permission_ids": [1,2,3] 56 | } 57 | ### 58 | GET {{host}}/cms/user/permissions 59 | Content-Type: application/json 60 | Authorization: Bearer {{token}} 61 | ### 62 | DELETE {{host}}/cms/admin/group/1 63 | Content-Type: application/json 64 | Authorization: Bearer {{token}} 65 | ### 66 | GET {{host}}/v1/book 67 | Content-Type: application/json 68 | Authorization: Bearer {{token}} 69 | ### 70 | GET {{host}}/v1/teacher 71 | Content-Type: application/json 72 | Authorization: Bearer {{token}} 73 | ### 74 | GET {{host}}/v1/teacher/1 75 | Content-Type: application/json 76 | Authorization: Bearer {{token}} 77 | ### 78 | POST {{host}}/v1/teacher 79 | Content-Type: application/json 80 | Authorization: Bearer {{token}} 81 | 82 | { 83 | "name": "teacher1" 84 | 85 | } 86 | ### 87 | PUT {{host}}/v1/teacher/1 88 | Content-Type: application/json 89 | Authorization: Bearer {{token}} 90 | 91 | { 92 | 93 | } 94 | ### 95 | DELETE {{host}}/v1/teacher/1 96 | Content-Type: application/json 97 | Authorization: Bearer {{token}} 98 | 99 | ### 100 | GET {{host}}/v1/lesson 101 | Content-Type: application/json 102 | Authorization: Bearer {{token}} 103 | 104 | ### 105 | GET {{host}}/v1/lesson/1 106 | Content-Type: application/json 107 | Authorization: Bearer {{token}} 108 | ### 109 | POST {{host}}/v1/lesson 110 | Content-Type: application/json 111 | Authorization: Bearer {{token}} 112 | 113 | { 114 | "name": "teacher1" 115 | 116 | } 117 | ### 118 | PUT {{host}}/v1/lesson/1 119 | Content-Type: application/json 120 | Authorization: Bearer {{token}} 121 | 122 | { 123 | 124 | } 125 | ### 126 | DELETE {{host}}/v1/lesson/{id} 127 | Content-Type: application/json 128 | Authorization: Bearer {{token}} 129 | -------------------------------------------------------------------------------- /docs/schema.sql: -------------------------------------------------------------------------------- 1 | SET NAMES utf8mb4; 2 | SET FOREIGN_KEY_CHECKS = 0; 3 | 4 | -- ---------------------------- 5 | -- 文件表 6 | -- ---------------------------- 7 | DROP TABLE IF EXISTS lin_file; 8 | CREATE TABLE lin_file 9 | ( 10 | id bigint(20) unsigned NOT NULL AUTO_INCREMENT, 11 | path varchar(500) NOT NULL, 12 | type tinyint(1) NOT NULL DEFAULT 1 COMMENT '1 LOCAL 本地,2 REMOTE 远程', 13 | name varchar(100) NOT NULL, 14 | extension varchar(50) DEFAULT NULL, 15 | size int(11) DEFAULT NULL, 16 | md5 varchar(40) DEFAULT NULL COMMENT 'md5值,防止上传重复文件', 17 | created_at TIMESTAMP DEFAULT NULL, 18 | updated_at TIMESTAMP DEFAULT NULL, 19 | deleted_at TIMESTAMP DEFAULT NULL, 20 | PRIMARY KEY (id), 21 | UNIQUE KEY md5_del (md5, deleted_at) 22 | ) ENGINE = InnoDB 23 | DEFAULT CHARSET = utf8mb4 24 | COLLATE = utf8mb4_general_ci; 25 | ALTER TABLE lin_file MODIFY created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; 26 | ALTER TABLE lin_file MODIFY updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; 27 | -- ---------------------------- 28 | -- 日志表 29 | -- ---------------------------- 30 | DROP TABLE IF EXISTS lin_log; 31 | CREATE TABLE lin_log 32 | ( 33 | id bigint(20) unsigned NOT NULL AUTO_INCREMENT, 34 | message varchar(450) DEFAULT NULL, 35 | user_id int(10) unsigned NOT NULL, 36 | username varchar(24) DEFAULT NULL, 37 | status_code bigint(20) DEFAULT NULL, 38 | method varchar(20) DEFAULT NULL, 39 | path varchar(50) DEFAULT NULL, 40 | permission varchar(100) DEFAULT NULL, 41 | created_at TIMESTAMP DEFAULT NULL, 42 | updated_at TIMESTAMP DEFAULT NULL, 43 | deleted_at TIMESTAMP DEFAULT NULL, 44 | PRIMARY KEY (id) 45 | ) ENGINE = InnoDB 46 | DEFAULT CHARSET = utf8mb4 47 | COLLATE = utf8mb4_general_ci; 48 | ALTER TABLE lin_log MODIFY created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; 49 | ALTER TABLE lin_log MODIFY updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; 50 | -- ---------------------------- 51 | -- 权限表 52 | -- ---------------------------- 53 | DROP TABLE IF EXISTS lin_permission; 54 | CREATE TABLE lin_permission 55 | ( 56 | id bigint(20) unsigned NOT NULL AUTO_INCREMENT, 57 | name varchar(60) NOT NULL COMMENT '权限名称,例如:访问首页', 58 | module varchar(50) NOT NULL COMMENT '权限所属模块,例如:人员管理', 59 | mount tinyint(1) NOT NULL DEFAULT 1 COMMENT '0:关闭 1:开启', 60 | created_at TIMESTAMP DEFAULT NULL, 61 | updated_at TIMESTAMP DEFAULT NULL, 62 | deleted_at TIMESTAMP DEFAULT NULL, 63 | PRIMARY KEY (id) 64 | ) ENGINE = InnoDB 65 | DEFAULT CHARSET = utf8mb4 66 | COLLATE = utf8mb4_general_ci; 67 | ALTER TABLE lin_permission MODIFY created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; 68 | ALTER TABLE lin_permission MODIFY updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; 69 | -- ---------------------------- 70 | -- 分组表 71 | -- ---------------------------- 72 | DROP TABLE IF EXISTS lin_group; 73 | CREATE TABLE lin_group 74 | ( 75 | id bigint(20) unsigned NOT NULL AUTO_INCREMENT, 76 | name varchar(60) NOT NULL COMMENT '分组名称,例如:搬砖者', 77 | info varchar(255) DEFAULT NULL COMMENT '分组信息:例如:搬砖的人', 78 | level tinyint(2) NOT NULL DEFAULT 3 COMMENT '分组级别 1:root 2:guest 3:user(root、guest分组只能存在一个)', 79 | created_at TIMESTAMP DEFAULT NULL, 80 | updated_at TIMESTAMP DEFAULT NULL, 81 | deleted_at TIMESTAMP DEFAULT NULL, 82 | PRIMARY KEY (id), 83 | UNIQUE KEY name_del (name, deleted_at) 84 | ) ENGINE = InnoDB 85 | DEFAULT CHARSET = utf8mb4 86 | COLLATE = utf8mb4_general_ci; 87 | ALTER TABLE lin_group MODIFY created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; 88 | ALTER TABLE lin_group MODIFY updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; 89 | -- ---------------------------- 90 | -- 分组-权限表 91 | -- ---------------------------- 92 | DROP TABLE IF EXISTS lin_group_permission; 93 | CREATE TABLE lin_group_permission 94 | ( 95 | id bigint(20)unsigned NOT NULL AUTO_INCREMENT, 96 | group_id bigint(20) unsigned NOT NULL COMMENT '分组id', 97 | permission_id bigint(20)unsigned NOT NULL COMMENT '权限id', 98 | PRIMARY KEY (id), 99 | KEY group_id_permission_id (group_id, permission_id) USING BTREE COMMENT '联合索引' 100 | ) ENGINE = InnoDB 101 | DEFAULT CHARSET = utf8mb4 102 | COLLATE = utf8mb4_general_ci; 103 | 104 | -- ---------------------------- 105 | -- 用户基本信息表 106 | -- ---------------------------- 107 | DROP TABLE IF EXISTS lin_user; 108 | CREATE TABLE lin_user 109 | ( 110 | id bigint(20) unsigned NOT NULL AUTO_INCREMENT, 111 | username varchar(24) NOT NULL COMMENT '用户名,唯一', 112 | nickname varchar(24) DEFAULT NULL COMMENT '用户昵称', 113 | avatar varchar(500) DEFAULT NULL COMMENT '头像url', 114 | phone char(20) DEFAULT NULL COMMENT '手机', 115 | created_at TIMESTAMP DEFAULT NULL, 116 | updated_at TIMESTAMP DEFAULT NULL, 117 | deleted_at TIMESTAMP DEFAULT NULL, 118 | PRIMARY KEY (id), 119 | UNIQUE KEY username_del (username, deleted_at), 120 | UNIQUE KEY email_del (email, deleted_at) 121 | ) ENGINE = InnoDB 122 | DEFAULT CHARSET = utf8mb4 123 | COLLATE = utf8mb4_general_ci; 124 | ALTER TABLE lin_user MODIFY created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; 125 | ALTER TABLE lin_user MODIFY updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; 126 | -- ---------------------------- 127 | -- ---------------------------- 128 | -- 用户授权信息表 129 | # id 130 | # user_id 131 | # identity_type 登录类型(手机号 邮箱 用户名)或第三方应用名称(微信 微博等) 132 | # identifier 标识(手机号 邮箱 用户名或第三方应用的唯一标识) 133 | # credential 密码凭证(站内的保存密码,站外的不保存或保存token) 134 | -- ---------------------------- 135 | DROP TABLE IF EXISTS lin_user_identiy; 136 | CREATE TABLE lin_user_identiy 137 | ( 138 | id bigint(20) unsigned NOT NULL AUTO_INCREMENT, 139 | user_id bigint(20) unsigned NOT NULL COMMENT '用户id', 140 | identity_type varchar(100) NOT NULL, 141 | identifier varchar(100), 142 | credential varchar(100), 143 | created_at TIMESTAMP DEFAULT NULL, 144 | updated_at TIMESTAMP DEFAULT NULL, 145 | deleted_at TIMESTAMP DEFAULT NULL, 146 | PRIMARY KEY (id) 147 | ) ENGINE = InnoDB 148 | DEFAULT CHARSET = utf8mb4 149 | COLLATE = utf8mb4_general_ci; 150 | ALTER TABLE lin_user_identiy MODIFY created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; 151 | ALTER TABLE lin_user_identiy MODIFY updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; 152 | DROP TABLE IF EXISTS book; 153 | CREATE TABLE book 154 | ( 155 | id bigint(20) NOT NULL AUTO_INCREMENT, 156 | title varchar(50) NOT NULL, 157 | author varchar(30) DEFAULT NULL, 158 | summary varchar(1000) DEFAULT NULL, 159 | image varchar(100) DEFAULT NULL, 160 | created_at TIMESTAMP DEFAULT NULL, 161 | updated_at TIMESTAMP DEFAULT NULL, 162 | deleted_at TIMESTAMP DEFAULT NULL, 163 | PRIMARY KEY (id) 164 | ) ENGINE = InnoDB 165 | DEFAULT CHARSET = utf8mb4 166 | COLLATE = utf8mb4_general_ci; 167 | ALTER TABLE book MODIFY created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; 168 | ALTER TABLE book MODIFY updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; 169 | 170 | -- ---------------------------- 171 | -- 用户-分组表 172 | -- ---------------------------- 173 | DROP TABLE IF EXISTS lin_user_group; 174 | CREATE TABLE lin_user_group 175 | ( 176 | id bigint(20)unsigned NOT NULL AUTO_INCREMENT, 177 | user_id bigint(20) unsigned NOT NULL COMMENT '用户id', 178 | group_id bigint(20)unsigned NOT NULL COMMENT '分组id', 179 | PRIMARY KEY (id), 180 | KEY user_id_group_id (user_id, group_id) USING BTREE COMMENT '联合索引' 181 | ) ENGINE = InnoDB 182 | DEFAULT CHARSET = utf8mb4 183 | COLLATE = utf8mb4_general_ci; 184 | 185 | SET FOREIGN_KEY_CHECKS = 1; 186 | 187 | -- ---------------------------- 188 | -- 插入超级管理员 189 | -- 插入root分组 190 | -- ---------------------------- 191 | BEGIN; 192 | INSERT INTO lin_user(id, username, nickname) 193 | VALUES (1, 'root', 'root'); 194 | 195 | INSERT INTO lin_user_identiy (id, user_id, identity_type, identifier, credential) 196 | 197 | VALUES (1, 1, 'USERNAME_PASSWORD', 'root', 198 | '$2a$10$Subt/mCLem8axyivSN4BBeSLUtdPPEhDJJTWpGQVWJst1aVa9TzQq'); 199 | 200 | INSERT INTO lin_group(id, name, info, level) 201 | VALUES (1, 'root', '超级用户组', 1); 202 | 203 | INSERT INTO lin_group(id, name, info, level) 204 | VALUES (2, 'guest', '游客组', 2); 205 | 206 | INSERT INTO lin_user_group(id, user_id, group_id) 207 | VALUES (1, 1, 1); 208 | INSERT INTO `lin_permission` VALUES (1, '查看lin的信息', '信息',1, '2020-04-23 09:11:16', '2020-04-23 09:11:16', NULL); 209 | INSERT INTO `lin_permission` VALUES (2, '查询自己信息', '用户',1, '2020-04-23 09:11:16.531', '2020-04-23 09:11:16.531', NULL); 210 | INSERT INTO `lin_permission` VALUES (3, '查询自己拥有的权限', '用户',1, '2020-04-23 09:11:16.544', '2020-04-23 09:11:16.544', NULL); 211 | INSERT INTO `lin_permission` VALUES (4, '查询日志记录的用户', '日志',1, '2020-04-23 09:11:16.554', '2020-04-23 09:11:16.554', NULL); 212 | INSERT INTO `lin_permission` VALUES (5, '删除图书', '图书',1, '2020-04-23 09:11:16.562', '2020-04-23 09:11:16.562', NULL); 213 | INSERT INTO `lin_permission` VALUES (6, '查询所有日志', '日志',1, '2020-04-23 09:11:16.571', '2020-04-23 09:11:16.571', NULL); 214 | INSERT INTO `lin_permission` VALUES (7, '测试日志记录', '信息',1, '2020-04-23 09:11:16.580', '2020-04-23 09:11:16.580', NULL); 215 | INSERT INTO `lin_permission` VALUES (8, '搜索日志', '日志',1, '2020-04-23 09:11:16.590', '2020-04-23 09:11:16.590', NULL); 216 | 217 | COMMIT; -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module lin-cms-go 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/go-kratos/kratos/contrib/log/zap/v2 v2.0.0-20240627104009-3198e0b83bf2 7 | github.com/go-kratos/kratos/v2 v2.7.3 8 | github.com/gofiber/fiber/v2 v2.50.0 9 | github.com/golang-jwt/jwt/v4 v4.1.0 10 | github.com/google/wire v0.6.0 11 | github.com/gorilla/handlers v1.5.2 12 | github.com/pkg/errors v0.9.1 13 | github.com/spf13/cast v1.6.0 14 | go.uber.org/zap v1.26.0 15 | golang.org/x/crypto v0.18.0 16 | google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529 17 | google.golang.org/grpc v1.56.3 18 | google.golang.org/protobuf v1.31.0 19 | gorm.io/driver/mysql v1.5.7 20 | gorm.io/gorm v1.25.10 21 | ) 22 | 23 | require ( 24 | github.com/andybalholm/brotli v1.0.6 // indirect 25 | github.com/felixge/httpsnoop v1.0.3 // indirect 26 | github.com/fsnotify/fsnotify v1.6.0 // indirect 27 | github.com/go-kratos/aegis v0.2.0 // indirect 28 | github.com/go-playground/form/v4 v4.2.0 // indirect 29 | github.com/go-sql-driver/mysql v1.7.0 // indirect 30 | github.com/golang/protobuf v1.5.3 // indirect 31 | github.com/google/uuid v1.4.0 // indirect 32 | github.com/gorilla/mux v1.8.1 // indirect 33 | github.com/imdario/mergo v0.3.16 // indirect 34 | github.com/jinzhu/inflection v1.0.0 // indirect 35 | github.com/jinzhu/now v1.1.5 // indirect 36 | github.com/klauspost/compress v1.17.2 // indirect 37 | github.com/mattn/go-colorable v0.1.13 // indirect 38 | github.com/mattn/go-isatty v0.0.20 // indirect 39 | github.com/mattn/go-runewidth v0.0.15 // indirect 40 | github.com/rivo/uniseg v0.4.4 // indirect 41 | github.com/stretchr/testify v1.8.3 // indirect 42 | github.com/valyala/bytebufferpool v1.0.0 // indirect 43 | github.com/valyala/fasthttp v1.50.0 // indirect 44 | github.com/valyala/tcplisten v1.0.0 // indirect 45 | go.uber.org/multierr v1.11.0 // indirect 46 | golang.org/x/net v0.20.0 // indirect 47 | golang.org/x/sync v0.6.0 // indirect 48 | golang.org/x/sys v0.16.0 // indirect 49 | golang.org/x/text v0.14.0 // indirect 50 | google.golang.org/genproto v0.0.0-20230629202037-9506855d4529 // indirect 51 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529 // indirect 52 | gopkg.in/yaml.v3 v3.0.1 // indirect 53 | ) 54 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= 2 | github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= 3 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 4 | github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= 5 | github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= 6 | github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= 7 | github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= 8 | github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= 9 | github.com/go-kratos/aegis v0.2.0 h1:dObzCDWn3XVjUkgxyBp6ZeWtx/do0DPZ7LY3yNSJLUQ= 10 | github.com/go-kratos/aegis v0.2.0/go.mod h1:v0R2m73WgEEYB3XYu6aE2WcMwsZkJ/Rzuf5eVccm7bI= 11 | github.com/go-kratos/kratos/contrib/log/zap/v2 v2.0.0-20240627104009-3198e0b83bf2 h1:eus3W3SXhDUO6+Zo40mPn2XPXaUxjlxbO5xmnKEGKes= 12 | github.com/go-kratos/kratos/contrib/log/zap/v2 v2.0.0-20240627104009-3198e0b83bf2/go.mod h1:eD/bSXiReDHdcaE5Mk1RqUCMYpYjEmV39sHxCa/o/II= 13 | github.com/go-kratos/kratos/v2 v2.7.3 h1:T9MS69qk4/HkVUuHw5GS9PDVnOfzn+kxyF0CL5StqxA= 14 | github.com/go-kratos/kratos/v2 v2.7.3/go.mod h1:CQZ7V0qyVPwrotIpS5VNNUJNzEbcyRUl5pRtxLOIvn4= 15 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= 16 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 17 | github.com/go-playground/form/v4 v4.2.0 h1:N1wh+Goz61e6w66vo8vJkQt+uwZSoLz50kZPJWR8eic= 18 | github.com/go-playground/form/v4 v4.2.0/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U= 19 | github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= 20 | github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= 21 | github.com/gofiber/fiber/v2 v2.50.0 h1:ia0JaB+uw3GpNSCR5nvC5dsaxXjRU5OEu36aytx+zGw= 22 | github.com/gofiber/fiber/v2 v2.50.0/go.mod h1:21eytvay9Is7S6z+OgPi7c7n4++tnClWmhpimVHMimw= 23 | github.com/golang-jwt/jwt/v4 v4.1.0 h1:XUgk2Ex5veyVFVeLm0xhusUTQybEbexJXrvPNOKkSY0= 24 | github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= 25 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 26 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= 27 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 28 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 29 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 30 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 31 | github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE= 32 | github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= 33 | github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= 34 | github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 35 | github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= 36 | github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= 37 | github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= 38 | github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= 39 | github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= 40 | github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= 41 | github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= 42 | github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= 43 | github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= 44 | github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= 45 | github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= 46 | github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= 47 | github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= 48 | github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= 49 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 50 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 51 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 52 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 53 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 54 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 55 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 56 | github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= 57 | github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 58 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 59 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 60 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 61 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 62 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 63 | github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= 64 | github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 65 | github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= 66 | github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= 67 | github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= 68 | github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= 69 | github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 70 | github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 71 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 72 | github.com/valyala/fasthttp v1.50.0 h1:H7fweIlBm0rXLs2q0XbalvJ6r0CUPFWK3/bB4N13e9M= 73 | github.com/valyala/fasthttp v1.50.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= 74 | github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= 75 | github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= 76 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 77 | go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= 78 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 79 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 80 | go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= 81 | go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= 82 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 83 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 84 | golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= 85 | golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= 86 | golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= 87 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 88 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 89 | golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 90 | golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= 91 | golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 92 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 93 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 94 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 95 | golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 96 | golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= 97 | golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= 98 | golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= 99 | golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= 100 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 101 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 102 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 103 | golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= 104 | golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= 105 | golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 106 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 107 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 108 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 109 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 110 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 111 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 112 | golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 113 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 114 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 115 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 116 | golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 117 | golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= 118 | golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 119 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 120 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 121 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 122 | golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= 123 | golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= 124 | golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= 125 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 126 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 127 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 128 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 129 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 130 | golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 131 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 132 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 133 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 134 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 135 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 136 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 137 | golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= 138 | golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= 139 | golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= 140 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 141 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 142 | google.golang.org/genproto v0.0.0-20230629202037-9506855d4529 h1:9JucMWR7sPvCxUFd6UsOUNmA5kCcWOfORaT3tpAsKQs= 143 | google.golang.org/genproto v0.0.0-20230629202037-9506855d4529/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= 144 | google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529 h1:s5YSX+ZH5b5vS9rnpGymvIyMpLRJizowqDlOuyjXnTk= 145 | google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= 146 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529 h1:DEH99RbiLZhMxrpEJCZ0A+wdTe0EOgou/poSLx9vWf4= 147 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= 148 | google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= 149 | google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= 150 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 151 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 152 | google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= 153 | google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 154 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 155 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 156 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 157 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 158 | gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= 159 | gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= 160 | gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= 161 | gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= 162 | gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= 163 | -------------------------------------------------------------------------------- /internal/biz/admin.go: -------------------------------------------------------------------------------- 1 | package biz 2 | 3 | import ( 4 | "context" 5 | "lin-cms-go/api" 6 | 7 | "github.com/go-kratos/kratos/v2/errors" 8 | "golang.org/x/crypto/bcrypt" 9 | "gorm.io/gorm" 10 | ) 11 | 12 | type LinUserRepo interface { 13 | ListUser(ctx context.Context, page, size int32, groupId int64) ([]*LinUser, int64, error) 14 | GetUser(ctx context.Context, userId int) (*LinUser, error) 15 | CreateUser(ctx context.Context, user *LinUser) error 16 | ChangeUserPassword(ctx context.Context, userId int, password string) error 17 | UpdateUser(ctx context.Context, user *LinUser) error 18 | GetUserByUsername(ctx context.Context, username string) (*LinUser, error) 19 | // userIdentityModel, err := data.GetLinUserIdentityByIdentifier(ctx, username) 20 | } 21 | type LinUser struct { 22 | ID int64 23 | Username string 24 | Password string 25 | Phone string 26 | } 27 | 28 | func outLinUser(v *LinUser) *api.LinUser { 29 | return &api.LinUser{ 30 | Id: v.ID, 31 | Username: v.Username, 32 | Phone: v.Phone, 33 | } 34 | 35 | } 36 | func outLinUsers(list []*LinUser) []*api.LinUser { 37 | items := make([]*api.LinUser, 0) 38 | for _, v := range list { 39 | items = append(items, outLinUser(v)) 40 | } 41 | return items 42 | } 43 | func (u *LinUserusecase) ListUser(ctx context.Context, req *api.ListLinUserRequest) (*api.ListLinUserReply, error) { 44 | list, total, err := u.ur.ListUser(ctx, req.Page, req.Size, req.GroupId) 45 | if err != nil { 46 | return nil, err 47 | } 48 | 49 | return &api.ListLinUserReply{ 50 | List: outLinUsers(list), 51 | Total: uint32(total), 52 | }, nil 53 | 54 | } 55 | func (u *LinUserusecase) CreateUser(ctx context.Context, req *api.CreateLinUserRequest) error { 56 | userIdentity, err := u.ur.GetUserByUsername(ctx, req.Username) 57 | if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { 58 | return errors.InternalServer("INTERNAL_ERROR", "服务器内部错误") 59 | } 60 | 61 | if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { 62 | err = nil 63 | } 64 | if userIdentity != nil && userIdentity.ID > 0 { 65 | return errors.InternalServer("INTERNAL_ERROR", "用户已经存在") 66 | } 67 | hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) 68 | if err != nil { 69 | return errors.InternalServer("INTERNAL_ERROR", "服务器内部错误") 70 | } 71 | user := &LinUser{ 72 | Username: req.Username, 73 | Password: string(hash), 74 | Phone: req.Phone, 75 | } 76 | err = u.ur.CreateUser(ctx, user) 77 | if err != nil { 78 | return errors.InternalServer("INTERNAL_ERROR", "服务器内部错误") 79 | } 80 | 81 | return nil 82 | } 83 | 84 | func ChangeUserPassword(ctx context.Context, userId int, password string) error { 85 | // user, err := data.GetLinUserIdentityByUserId(ctx, userId) 86 | // if err != nil { 87 | // return 88 | // } 89 | // hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) 90 | // if err != nil { 91 | // return 92 | // } 93 | // err = data.UpdateLinUserIdentityPassword(ctx, user.Identifier, string(hash)) 94 | // if err != nil { 95 | // return 96 | // } 97 | return nil 98 | } 99 | 100 | func DeleteUser(ctx context.Context, userId int) error { 101 | //_, err = data.GetLinUserById(ctx, userId) 102 | // if model.IsNotFound(err) { 103 | // err = core.NotFoundError(errcode.UserNotFound) 104 | // return 105 | // } 106 | //err = data.SoftDeleteUser(ctx, userId) 107 | return nil 108 | } 109 | 110 | func UpdateUser(ctx context.Context, userId int, groupId []int32) (err error) { 111 | //_, err = data.GetLinUserById(ctx, userId) 112 | // if model.IsNotFound(err) { 113 | // err = core.NotFoundError(errcode.UserNotFound) 114 | // return 115 | // } 116 | // err = data.AddLinUserGroupIDs(ctx, userId, groupId) 117 | return nil 118 | } 119 | -------------------------------------------------------------------------------- /internal/biz/biz.go: -------------------------------------------------------------------------------- 1 | package biz 2 | 3 | import ( 4 | "github.com/google/wire" 5 | 6 | "github.com/gofiber/fiber/v2" 7 | ) 8 | const ROOT int8 = 1 9 | const GUEST int8 = 2 10 | const USER int8 = 3 11 | var ProviderSet = wire.NewSet(NewBookUsecase,NewLinUserUsecase,NewTeacherUsecase,NewLessonUsecase) 12 | 13 | // func LocalUser(c *fiber.Ctx) (user model.LinUser) { 14 | // local := c.Locals("user") 15 | // if local == nil { 16 | // return 17 | // } 18 | // jwtToken := local.(*jwt.Token) 19 | // claims := jwtToken.Claims.(jwt.MapClaims) 20 | // bytes, _ := utils.JSONEncode(claims["user"]) 21 | 22 | // utils.JSONDecode(bytes, &user) 23 | // return 24 | // } 25 | 26 | func IsAdmin(c *fiber.Ctx) (is bool, err error) { 27 | // user := LocalUser(c) 28 | // if user.ID == 0 { 29 | // err = core.UnAuthenticatedError(errcode.ErrorAuthToken) 30 | // return 31 | // } 32 | // u, err := data.GetLinUserWithGroupById(c.Context(), user.ID) 33 | // if err != nil { 34 | // return 35 | // } 36 | 37 | // for _, v := range u.Edges.LinGroup { 38 | // if v.Level == enum.ROOT { 39 | // is = true 40 | // } 41 | // } 42 | return 43 | } 44 | 45 | type Permission struct { 46 | Name string `json:"name"` 47 | Module string `json:"module"` 48 | } 49 | 50 | func UserHasPermission(c *fiber.Ctx) (has bool, err error) { 51 | // user := LocalUser(c) 52 | 53 | // u, err := data.GetLinUserWithGroupById(context.Background(), user.ID) 54 | // if model.IsNotFound(err) { 55 | // err = core.NotFoundError(errcode.UserNotFound) 56 | // return 57 | // } 58 | 59 | // local := c.Locals("permission") 60 | // if local == nil { 61 | // return false, core.UnAuthenticatedError(errcode.UserPermissionRequired) 62 | // } 63 | // userPermission := local.(Permission) 64 | // var ps []model.LinPermission 65 | // for _, v := range u.Edges.LinGroup { 66 | // for _, p := range v.Edges.LinPermission { 67 | // ps = append(ps, *p) 68 | // } 69 | // } 70 | // for _, p := range ps { 71 | // if p.Module == userPermission.Module && p.Name == userPermission.Name { 72 | // has = true 73 | // } 74 | // } 75 | return 76 | } 77 | -------------------------------------------------------------------------------- /internal/biz/book.go: -------------------------------------------------------------------------------- 1 | package biz 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "github.com/pkg/errors" 8 | 9 | "lin-cms-go/api" 10 | 11 | "github.com/go-kratos/kratos/v2/log" 12 | ) 13 | 14 | type ( 15 | BookRepo interface { 16 | GetBook(ctx context.Context, id int64) (*Book, error) 17 | ListBook(ctx context.Context, page, size int) ([]*Book, int64, error) 18 | CreateBook(ctx context.Context, req *api.CreateBookRequest) error 19 | UpdateBook(ctx context.Context, req *api.UpdateBookRequest) error 20 | DeleteBook(ctx context.Context, id int64) error 21 | } 22 | Book struct { 23 | ID int64 24 | CreatedAt time.Time 25 | Title string 26 | Author string 27 | Summary string 28 | Image string 29 | } 30 | ) 31 | 32 | type BookUsecase struct { 33 | log *log.Helper 34 | br BookRepo 35 | } 36 | 37 | func NewBookUsecase(br BookRepo, logger log.Logger) *BookUsecase { 38 | return &BookUsecase{ 39 | log: log.NewHelper(logger), 40 | br: br, 41 | } 42 | } 43 | 44 | func outBook(b *Book) *api.Book { 45 | return &api.Book{ 46 | Id: uint32(b.ID), 47 | Title: b.Title, 48 | Author: b.Author, 49 | Summary: b.Summary, 50 | Image: b.Image, 51 | } 52 | } 53 | 54 | func outBooks(bs []*Book) []*api.Book { 55 | res := make([]*api.Book, len(bs)) 56 | for i := range bs { 57 | res[i] = outBook(bs[i]) 58 | } 59 | return res 60 | } 61 | 62 | func (u *BookUsecase) ListBook(ctx context.Context, page, size int) ([]*api.Book, int64, error) { 63 | books, total, err := u.br.ListBook(ctx, int(page), int(size)) 64 | if err != nil { 65 | return nil, 0, err 66 | } 67 | 68 | return outBooks(books), total, nil 69 | } 70 | 71 | func (u *BookUsecase) UpdateBook(ctx context.Context, req *api.UpdateBookRequest) error { 72 | _, err := u.br.GetBook(ctx, req.Id) 73 | if err != nil { 74 | return errors.Wrap(err, "GetBookError") 75 | } 76 | 77 | err = u.br.UpdateBook(ctx, req) 78 | return err 79 | } 80 | 81 | func (u *BookUsecase) CreateBook(ctx context.Context, req *api.CreateBookRequest) error { 82 | err := u.br.CreateBook(ctx, req) 83 | return err 84 | } 85 | 86 | func (u *BookUsecase) DeleteBook(ctx context.Context, id int64) error { 87 | _, err := u.br.GetBook(ctx, id) 88 | if err != nil { 89 | return errors.Wrap(err, "GetBookError") 90 | } 91 | err = u.DeleteBook(ctx, id) 92 | if err != nil { 93 | return errors.Wrap(err, "DeleteBookError") 94 | } 95 | return nil 96 | } 97 | 98 | func (u *BookUsecase) GetBook(ctx context.Context, id int64) (*api.Book, error) { 99 | book, err := u.br.GetBook(ctx, id) 100 | if err != nil { 101 | return nil, errors.Wrap(err, "GetBookError") 102 | } 103 | 104 | return outBook(book), nil 105 | } 106 | -------------------------------------------------------------------------------- /internal/biz/group.go: -------------------------------------------------------------------------------- 1 | package biz 2 | 3 | import ( 4 | "context" 5 | 6 | "lin-cms-go/api" 7 | ) 8 | 9 | type ( 10 | GroupRepo interface { 11 | CreateGroup(ctx context.Context, g *Group) error 12 | GetGroup(ctx context.Context, id int) (*Group, error) 13 | UpdateGroup(ctx context.Context, g *Group) error 14 | DeleteGroup(ctx context.Context, id int) error 15 | ListGroup(ctx context.Context, page, size int) ([]*Group, error) 16 | } 17 | Group struct { 18 | Id int64 19 | Name string 20 | Info string 21 | Level int8 22 | } 23 | ) 24 | 25 | 26 | func GetGroups(ctx context.Context) (res interface{}, err error) { 27 | // var linGroupModel []*model.LinGroup 28 | // linGroupModel, err = data.GetAllGroup(ctx) 29 | // res = simplifyGroup(linGroupModel) 30 | return 31 | } 32 | 33 | func GetGroup(ctx context.Context, id int) (res interface{}, err error) { 34 | // var linGroupModel *model.LinGroup 35 | // linGroupModel, err = data.GetLinGroupById(ctx, id) 36 | // if model.IsNotFound(err) { 37 | // err = core.NotFoundError(errcode.GroupNotFound) 38 | // return 39 | // } 40 | 41 | // res = Group{Id: linGroupModel.ID, Name: linGroupModel.Name, Info: linGroupModel.Info, Level: linGroupModel.Level} 42 | return 43 | } 44 | 45 | // func simplifyGroup(groupModel []*model.LinGroup) []Group { 46 | // res := make([]Group, 0, len(groupModel)) 47 | // for _, v := range groupModel { 48 | // res = append(res, Group{Id: v.ID, Name: v.Name, Info: v.Info, Level: v.Level}) 49 | // } 50 | // return res 51 | // } 52 | 53 | func CreateGroup(ctx context.Context, name string, info string, permissionIds []int) (err error) { 54 | // group, _ := data.GetLinGroupByName(ctx, name) 55 | // if group != nil { 56 | // err = core.ParamsError(errcode.GroupFound) 57 | // return 58 | // } 59 | // for _, v := range permissionIds { 60 | // _, err = data.GetLinPermissionById(ctx, v) 61 | // if model.IsNotFound(err) { 62 | // err = core.NotFoundError(errcode.PermissionNotFound) 63 | // return 64 | // } 65 | // if err != nil { 66 | // err = errors.Wrap(err, "GetLinPermissionById err") 67 | // return 68 | // } 69 | // } 70 | // groupModel, err := data.CreateGroup(ctx, name, info, enum.USER) 71 | // if err != nil { 72 | // err = errors.Wrap(err, "CreateGroup err") 73 | // return 74 | // } 75 | 76 | // err = data.BatchCreateGroupPermission(ctx, groupModel.ID, permissionIds) 77 | // if err != nil { 78 | // err = errors.Wrap(err, "BatchCreateGroupPermission err") 79 | // return 80 | // } 81 | return 82 | } 83 | 84 | func UpdateGroup(ctx context.Context, id int, req *api.UpdateGroupRequest) (err error) { 85 | // _, err = data.GetLinGroupById(ctx, id) 86 | // if model.IsNotFound(err) { 87 | // err = core.NotFoundError(errcode.GroupNotFound) 88 | // return 89 | // } 90 | // if err != nil { 91 | // err = errors.Wrap(err, "GetLinGroupById") 92 | // return 93 | // } 94 | // err = data.UpdateGroup(ctx, id, req.Name, req.Info) 95 | // if err != nil { 96 | // err = errors.Wrap(err, "UpdateGroup") 97 | // return 98 | // } 99 | return 100 | } 101 | 102 | func DeleteGroup(ctx context.Context, id int) (err error) { 103 | // var linGroup *model.LinGroup 104 | // linGroup, err = data.GetLinGroupById(ctx, id) 105 | // if model.IsNotFound(err) { 106 | // err = core.NotFoundError(errcode.GroupNotFound) 107 | // return 108 | // } 109 | // if err != nil { 110 | // err = errors.Wrap(err, "GetLinGroupById ") 111 | // return 112 | // } 113 | // if linGroup.Level == enum.ROOT { 114 | // err = core.ParamsError(errcode.RootGroupNotAllowDelete) 115 | // return 116 | // } 117 | // 118 | // if linGroup.Level == enum.GUEST { 119 | // err = core.ParamsError(errcode.GuestGroupNotAllowDelete) 120 | // return 121 | // } 122 | // 123 | // err = data.DeleteGroup(ctx, id) 124 | // if err != nil { 125 | // err = errors.Wrap(err, "DeleteGroup ") 126 | // return 127 | // } 128 | return 129 | } 130 | -------------------------------------------------------------------------------- /internal/biz/lesson.go: -------------------------------------------------------------------------------- 1 | package biz 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "github.com/pkg/errors" 8 | 9 | "lin-cms-go/api" 10 | 11 | "github.com/go-kratos/kratos/v2/log" 12 | ) 13 | 14 | type ( 15 | LessonRepo interface { 16 | GetLesson(ctx context.Context, id int64) (*Lesson, error) 17 | ListLesson(ctx context.Context, page, size int) ([]*Lesson, int64, error) 18 | CreateLesson(ctx context.Context, req *api.CreateLessonRequest) error 19 | UpdateLesson(ctx context.Context, req *api.UpdateLessonRequest) error 20 | DeleteLesson(ctx context.Context, id int64) error 21 | } 22 | Lesson struct { 23 | ID int64 24 | CreatedAt time.Time 25 | Title string 26 | } 27 | ) 28 | 29 | type LessonUsecase struct { 30 | log *log.Helper 31 | br LessonRepo 32 | } 33 | 34 | func NewLessonUsecase(br LessonRepo, logger log.Logger) *LessonUsecase { 35 | return &LessonUsecase{ 36 | log: log.NewHelper(logger), 37 | br: br, 38 | } 39 | } 40 | 41 | func outLesson(b *Lesson) *api.Lesson { 42 | return &api.Lesson{ 43 | Id: uint32(b.ID), 44 | Title: b.Title, 45 | } 46 | } 47 | 48 | func outLessons(bs []*Lesson) []*api.Lesson { 49 | res := make([]*api.Lesson, len(bs)) 50 | for i := range bs { 51 | res[i] = outLesson(bs[i]) 52 | } 53 | return res 54 | } 55 | 56 | func (u *LessonUsecase) ListLesson(ctx context.Context, page, size int) ([]*api.Lesson, int64, error) { 57 | lessons, total, err := u.br.ListLesson(ctx, int(page), int(size)) 58 | if err != nil { 59 | return nil, 0, err 60 | } 61 | 62 | return outLessons(lessons), total, nil 63 | } 64 | 65 | func (u *LessonUsecase) UpdateLesson(ctx context.Context, req *api.UpdateLessonRequest) error { 66 | _, err := u.br.GetLesson(ctx, req.Id) 67 | if err != nil { 68 | return errors.Wrap(err, "GetLessonError") 69 | } 70 | 71 | err = u.br.UpdateLesson(ctx, req) 72 | return err 73 | } 74 | 75 | func (u *LessonUsecase) CreateLesson(ctx context.Context, req *api.CreateLessonRequest) error { 76 | err := u.br.CreateLesson(ctx, req) 77 | return err 78 | } 79 | 80 | func (u *LessonUsecase) DeleteLesson(ctx context.Context, id int64) error { 81 | _, err := u.br.GetLesson(ctx, id) 82 | if err != nil { 83 | return errors.Wrap(err, "GetLessonError") 84 | } 85 | err = u.DeleteLesson(ctx, id) 86 | if err != nil { 87 | return errors.Wrap(err, "DeleteLessonError") 88 | } 89 | return nil 90 | } 91 | 92 | func (u *LessonUsecase) GetLesson(ctx context.Context, id int64) (*api.Lesson, error) { 93 | lesson, err := u.br.GetLesson(ctx, id) 94 | if err != nil { 95 | return nil, errors.Wrap(err, "GetLessonError") 96 | } 97 | 98 | return outLesson(lesson), nil 99 | } 100 | -------------------------------------------------------------------------------- /internal/biz/log.go: -------------------------------------------------------------------------------- 1 | package biz 2 | 3 | import ( 4 | "context" 5 | 6 | "lin-cms-go/api" 7 | ) 8 | 9 | type LogRepo interface { 10 | ListLog(ctx context.Context, page, size int) ([]*Log, int64, error) 11 | SearchLog(ctx context.Context, req api.SearchLogRequest) ([]*Log, int64, error) 12 | } 13 | type Log struct{} 14 | 15 | func GetLogs(ctx context.Context, req *api.ListLogRequest) (res interface{}, total int, err error) { 16 | // var logs []*model.LinLog 17 | // 18 | // paging := data.NewPaging(page, size) 19 | // var query []predicate.LinLog 20 | // if req.Name != "" { 21 | // query = append(query, data.WithUsername(req.Name)) 22 | // } 23 | // if req.Start != "" && req.End != "" { 24 | // start := utils.String2time(req.Start) 25 | // end := utils.String2time(req.End) 26 | // q := linlog.And(linlog.CreatedAtGT(start), linlog.CreatedAtLT(end)) 27 | // query = append(query, q) 28 | // } 29 | // logs, err = paging.Search(ctx, query) 30 | // if err != nil { 31 | // err = errors.Wrap(err, "Search ") 32 | // return 33 | // } 34 | // total = data.GetSearchTotal(ctx, query) 35 | // 36 | // res = logs 37 | return 38 | } 39 | 40 | func SearchLogs(ctx context.Context, req api.SearchLogRequest, page int, size int) (res interface{}, total int, err error) { 41 | // var logs []*model.LinLog 42 | // 43 | // paging := data.NewPaging(page, size) 44 | // var query []predicate.LinLog 45 | // if req.Name != "" { 46 | // query = append(query, data.WithUsername(req.Name)) 47 | // } 48 | // if req.Start != "" && req.End != "" { 49 | // start := utils.String2time(req.Start) 50 | // end := utils.String2time(req.End) 51 | // q := linlog.And(linlog.CreatedAtGT(start), linlog.CreatedAtLT(end)) 52 | // query = append(query, q) 53 | // } 54 | // if req.Keyword != "" { 55 | // query = append(query, data.WithKeyword(req.Name)) 56 | // } 57 | // logs, err = paging.Search(ctx, query) 58 | // if err != nil { 59 | // err = errors.Wrap(err, "Search ") 60 | // return 61 | // } 62 | // total = data.GetSearchTotal(ctx, query) 63 | // res = logs 64 | return 65 | } 66 | 67 | func GetLogUsers(ctx context.Context, page, size int) (res interface{}, total int, err error) { 68 | // paging := data.NewPaging(page, size) 69 | // res, err = paging.GetLogUsers(ctx) 70 | // if err != nil { 71 | // err = errors.Wrap(err, "GetLogUsers ") 72 | // return 73 | // } 74 | // total, err = data.GetLogUsersTotal(ctx) 75 | // if err != nil { 76 | // err = errors.Wrap(err, "GetLogUsersTotal ") 77 | // return 78 | // } 79 | return 80 | } 81 | -------------------------------------------------------------------------------- /internal/biz/permission.go: -------------------------------------------------------------------------------- 1 | package biz 2 | 3 | type PermissionRepo interface{} 4 | 5 | // func GetAllPermissions(ctx context.Context) (res interface{}, err error) { 6 | // list, err := data.ListAllPermissions(ctx) 7 | // if err != nil { 8 | // return 9 | // } 10 | // m := make(map[string][]model.LinPermission) 11 | // for _, v := range list { 12 | // m[v.Module] = append(m[v.Module], *v) 13 | // } 14 | // res = m 15 | // return 16 | // } 17 | 18 | // func DispatchPermission(req api.DispatchPermissionRequest) (err error) { 19 | // return 20 | // } 21 | 22 | // func DispatchPermissions(ctx context.Context, groupId int, permissionIds []int) (err error) { 23 | // err = data.BatchCreateGroupPermission(ctx, groupId, permissionIds) 24 | 25 | // return 26 | // } 27 | 28 | //func RemovePermissions(ctx context.Context, groupId int, permissionIds []int) (err error) { 29 | // _, err = data.GetGroupPermissionByGroupId(ctx, groupId) 30 | // if err != nil { 31 | // return 32 | // } 33 | // err = data.DeleteGroupPermission(ctx, groupId, permissionIds) 34 | //return 35 | //} 36 | 37 | // func CreateIfNoPermissions(ctx context.Context, p Permission) (err error) { 38 | // _, err = data.GetPermission(ctx, p.Name, p.Module) 39 | // if model.IsNotFound(err) { 40 | // err = data.CreatePermission(context.Background(), p.Name, p.Module) 41 | // } 42 | 43 | //return 44 | //} 45 | -------------------------------------------------------------------------------- /internal/biz/teacher.go: -------------------------------------------------------------------------------- 1 | package biz 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "github.com/pkg/errors" 8 | 9 | "lin-cms-go/api" 10 | 11 | "github.com/go-kratos/kratos/v2/log" 12 | ) 13 | 14 | type ( 15 | TeacherRepo interface { 16 | GetTeacher(ctx context.Context, id int64) (*Teacher, error) 17 | ListTeacher(ctx context.Context, page, size int) ([]*Teacher, int64, error) 18 | CreateTeacher(ctx context.Context, req *api.CreateTeacherRequest) error 19 | UpdateTeacher(ctx context.Context, req *api.UpdateTeacherRequest) error 20 | DeleteTeacher(ctx context.Context, id int64) error 21 | } 22 | Teacher struct { 23 | ID int64 24 | Nickname string 25 | CreatedAt time.Time 26 | Name string 27 | Domain string 28 | Area string 29 | Introduce string 30 | Avatar string 31 | Remark string 32 | Phone string 33 | ClassHour string 34 | } 35 | ) 36 | 37 | type TeacherUsecase struct { 38 | log *log.Helper 39 | br TeacherRepo 40 | } 41 | 42 | func NewTeacherUsecase(br TeacherRepo, logger log.Logger) *TeacherUsecase { 43 | return &TeacherUsecase{ 44 | log: log.NewHelper(logger), 45 | br: br, 46 | } 47 | } 48 | 49 | func outTeacher(b *Teacher) *api.Teacher { 50 | return &api.Teacher{ 51 | Id: uint32(b.ID), 52 | Name: b.Name, 53 | Domain: b.Domain, 54 | Area: b.Area, 55 | } 56 | } 57 | 58 | func outTeachers(bs []*Teacher) []*api.Teacher { 59 | res := make([]*api.Teacher, len(bs)) 60 | for i := range bs { 61 | res[i] = outTeacher(bs[i]) 62 | } 63 | return res 64 | } 65 | 66 | func (u *TeacherUsecase) ListTeacher(ctx context.Context, page, size int) ([]*api.Teacher, int64, error) { 67 | teachers, total, err := u.br.ListTeacher(ctx, int(page), int(size)) 68 | if err != nil { 69 | return nil, 0, err 70 | } 71 | 72 | return outTeachers(teachers), total, nil 73 | } 74 | 75 | func (u *TeacherUsecase) UpdateTeacher(ctx context.Context, req *api.UpdateTeacherRequest) error { 76 | _, err := u.br.GetTeacher(ctx, req.Id) 77 | if err != nil { 78 | return errors.Wrap(err, "GetTeacherError") 79 | } 80 | 81 | err = u.br.UpdateTeacher(ctx, req) 82 | return err 83 | } 84 | 85 | func (u *TeacherUsecase) CreateTeacher(ctx context.Context, req *api.CreateTeacherRequest) error { 86 | err := u.br.CreateTeacher(ctx, req) 87 | return err 88 | } 89 | 90 | func (u *TeacherUsecase) DeleteTeacher(ctx context.Context, id int64) error { 91 | _, err := u.br.GetTeacher(ctx, id) 92 | if err != nil { 93 | return errors.Wrap(err, "GetTeacherError") 94 | } 95 | err = u.br.DeleteTeacher(ctx, id) 96 | if err != nil { 97 | return errors.Wrap(err, "DeleteTeacherError") 98 | } 99 | return nil 100 | } 101 | 102 | func (u *TeacherUsecase) GetTeacher(ctx context.Context, id int64) (*api.GetTeacherReply, error) { 103 | teacher, err := u.br.GetTeacher(ctx, id) 104 | if err != nil { 105 | return nil, errors.Wrap(err, "GetTeacherError") 106 | } 107 | 108 | return &api.GetTeacherReply{ 109 | Id: uint32(teacher.ID), 110 | Name: teacher.Name, 111 | Nickname: teacher.Nickname, 112 | Domain: teacher.Domain, 113 | Area: teacher.Area, 114 | Introduce: teacher.Introduce, 115 | Avatar: teacher.Avatar, 116 | Remark: teacher.Remark, 117 | ClassHour: teacher.ClassHour, 118 | Phone: teacher.Phone, 119 | }, nil 120 | } 121 | -------------------------------------------------------------------------------- /internal/biz/user.go: -------------------------------------------------------------------------------- 1 | package biz 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "lin-cms-go/api" 8 | 9 | "github.com/go-kratos/kratos/v2/errors" 10 | "github.com/go-kratos/kratos/v2/log" 11 | "github.com/spf13/cast" 12 | 13 | jwtv4 "github.com/golang-jwt/jwt/v4" 14 | "golang.org/x/crypto/bcrypt" 15 | ) 16 | 17 | type LinUserusecase struct { 18 | log *log.Helper 19 | ur LinUserRepo 20 | } 21 | type UserClaims struct { 22 | *jwtv4.RegisteredClaims 23 | UserID string `json:"user_id"` 24 | } 25 | 26 | func NewLinUserUsecase(ur LinUserRepo, logger log.Logger) *LinUserusecase { 27 | return &LinUserusecase{ur: ur, log: log.NewHelper(logger)} 28 | } 29 | 30 | func (u *LinUserusecase) Login(ctx context.Context, req *api.LoginRequest) (*api.LoginReply, error) { 31 | userIdentity, err := u.ur.GetUserByUsername(ctx, req.Username) 32 | if err != nil { 33 | return nil, errors.Unauthorized("USER_NOT_FOUND", "用户不存在") 34 | } 35 | if err = bcrypt.CompareHashAndPassword([]byte(userIdentity.Password), []byte(req.Password)); err != nil { 36 | if err == bcrypt.ErrMismatchedHashAndPassword { 37 | return nil, errors.Unauthorized("PASSWORD_INCORRECT", "密码错误") 38 | } 39 | return nil, errors.InternalServer("INTERNAL_ERROR", "密码验证时发生内部错误") 40 | } 41 | 42 | accessToken, refreshToken, err := generateToken(ctx, userIdentity.ID) 43 | if err != nil { 44 | return nil, err 45 | } 46 | return &api.LoginReply{ 47 | AccessToken: accessToken, 48 | RefreshToken: refreshToken, 49 | }, nil 50 | } 51 | 52 | func generateToken(ctx context.Context, userID int64) (string, string, error) { 53 | secret := "lincms" 54 | refreshToken, err := jwtv4.NewWithClaims(jwtv4.SigningMethodHS256, &jwtv4.RegisteredClaims{ 55 | ExpiresAt: jwtv4.NewNumericDate(time.Now().Add(time.Hour * 24)), 56 | }).SignedString([]byte(secret)) 57 | if err != nil { 58 | return "", "", errors.InternalServer(err.Error(), "服务器内部错误") 59 | } 60 | 61 | accessToken, err := jwtv4.NewWithClaims(jwtv4.SigningMethodHS256, &UserClaims{ 62 | UserID: cast.ToString(userID), 63 | RegisteredClaims: &jwtv4.RegisteredClaims{ 64 | ExpiresAt: jwtv4.NewNumericDate(time.Now().Add(time.Hour * 72)), 65 | Issuer: "lincms", 66 | Subject: "user", 67 | }, 68 | }).SignedString([]byte(secret)) 69 | if err != nil { 70 | return "", "", errors.InternalServer(err.Error(), "服务器内部错误") 71 | } 72 | 73 | return accessToken, refreshToken, nil 74 | } 75 | 76 | func UpdateMe(ctx context.Context, req *api.UpdateMeRequest, uid int) (err error) { 77 | // _, err = data.GetLinUserById(ctx, uid) 78 | // if model.IsNotFound(err) { 79 | // err = core.NotFoundError(errcode.UserNotFound) 80 | // return 81 | // } 82 | // if err != nil { 83 | // err = errors.Wrap(err, "GetLinUserById ") 84 | // return 85 | // } 86 | // err = data.UpdateLinUser(ctx, uid, req.Avatar, req.Nickname, req.Email) 87 | // if err != nil { 88 | // err = errors.Wrap(err, "UpdateLinUser ") 89 | // return 90 | // } 91 | return 92 | } 93 | 94 | func ChangeMyPassword(ctx context.Context, req *api.UpdateMyPasswordRequest, username string) (err error) { 95 | // userIdentityModel, err := data.GetLinUserIdentityByIdentifier(ctx, username) 96 | // if err != nil { 97 | // err = errors.Wrap(err, "GetLinUserIdentityByIdentifier ") 98 | // return err 99 | // } 100 | // err = bcrypt.CompareHashAndPassword([]byte(userIdentityModel.Credential), []byte(req.OldPassword)) 101 | // if err == bcrypt.ErrMismatchedHashAndPassword { 102 | // err = core.ParamsError(errcode.ErrorPassWord) 103 | // return 104 | // } 105 | // if err != nil { 106 | // err = errors.Wrap(err, "CompareHashAndPassword ") 107 | // return 108 | // } 109 | // hash, err := bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost) 110 | // if err != nil { 111 | // err = errors.Wrap(err, "GenerateFromPassword ") 112 | // return 113 | // } 114 | // err = data.UpdateLinUserIdentityPassword(ctx, username, string(hash)) 115 | // if err != nil { 116 | // err = errors.Wrap(err, "UpdateLinUserIdentityPassword ") 117 | // return 118 | // } 119 | 120 | return 121 | } 122 | 123 | func GetMyPermissions(ctx context.Context, uid int) (res map[string]interface{}, err error) { 124 | // user, err := data.GetLinUserById(ctx, uid) 125 | // if model.IsNotFound(err) { 126 | // err = core.NotFoundError(errcode.UserNotFound) 127 | // return 128 | // } 129 | // if err != nil { 130 | // err = errors.Wrap(err, "GetLinUserById ") 131 | // return 132 | // } 133 | // groupModel, err := user.QueryLinGroup().First(ctx) 134 | // if err != nil { 135 | // err = errors.Wrap(err, "user.QueryLinGroup ") 136 | // return 137 | // } 138 | // var isRoot bool 139 | // if groupModel.Level == 1 { 140 | // isRoot = true 141 | // } 142 | // 143 | // res = make(map[string]interface{}) 144 | // res["is_admin"] = isRoot 145 | // data["permissions"] = permissions 146 | return 147 | } 148 | 149 | func GetMyInfomation(ctx context.Context, uid int) (res LinUser, err error) { 150 | // usermodel, err := data.GetLinUserById(ctx, uid) 151 | // if model.IsNotFound(err) { 152 | // err = core.NotFoundError(errcode.UserNotFound) 153 | // return 154 | // } 155 | // if err != nil { 156 | // err = errors.Wrap(err, "GetLinUserById ") 157 | // return 158 | // } 159 | // res = LinUser{*usermodel} 160 | return 161 | } 162 | -------------------------------------------------------------------------------- /internal/conf/conf.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package conf; 3 | 4 | option go_package = "lin-cms-go/internal/conf;conf"; 5 | 6 | message Bootstrap { 7 | Server server = 1; 8 | Data data = 2; 9 | } 10 | 11 | message Server { 12 | message HTTP { 13 | string addr = 1; 14 | uint32 timeout = 3; 15 | } 16 | HTTP http = 1; 17 | } 18 | 19 | message Data { 20 | message Database { string main = 1; } 21 | message Redis { 22 | string addr = 1; 23 | string password = 2; 24 | int32 db = 3; 25 | } 26 | 27 | Database database = 1; 28 | Redis redis = 2; 29 | } 30 | -------------------------------------------------------------------------------- /internal/data/book.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "context" 5 | 6 | "lin-cms-go/api" 7 | "lin-cms-go/internal/biz" 8 | "lin-cms-go/internal/data/model" 9 | 10 | "github.com/go-kratos/kratos/v2/log" 11 | ) 12 | 13 | type bookRepo struct { 14 | data *Data 15 | log *log.Helper 16 | } 17 | 18 | // NewGreeterRepo . 19 | func NewBookRepo(data *Data, logger log.Logger) biz.BookRepo { 20 | return &bookRepo{ 21 | data: data, 22 | log: log.NewHelper(logger), 23 | } 24 | } 25 | 26 | func (r *bookRepo) GetBook(ctx context.Context, id int64) (*biz.Book, error) { 27 | var book model.Book 28 | err := r.data.db.Where("id = ?", id).First(&book).Error 29 | if err != nil { 30 | return nil, err 31 | } 32 | return toBook(&book), nil 33 | } 34 | 35 | func (r *bookRepo) ListBook(ctx context.Context, page, size int) ([]*biz.Book, int64, error) { 36 | var count int64 37 | err := r.data.db.Find(&model.Book{}).Count(&count).Error 38 | if err != nil { 39 | return nil, 0, err 40 | } 41 | var books []*model.Book 42 | err = r.data.db.Offset((page - 1) * size).Limit(size).Find(&books).Error 43 | if err != nil { 44 | return nil, 0, err 45 | } 46 | return toBooks(books), count, nil 47 | } 48 | 49 | func (r *bookRepo) CreateBook(ctx context.Context, req *api.CreateBookRequest) error { 50 | err := r.data.db.Create(&model.Book{ 51 | Title: req.GetTitle(), 52 | Author: req.GetAuthor(), 53 | Summary: req.GetSummary(), 54 | Image: req.GetImage(), 55 | }).Error 56 | if err != nil { 57 | return err 58 | } 59 | return nil 60 | } 61 | 62 | func (r *bookRepo) UpdateBook(ctx context.Context, req *api.UpdateBookRequest) error { 63 | err := r.data.db.Model(&model.Book{}).Where("id = ?", req.GetId()).Updates(map[string]interface{}{ 64 | "title": req.GetTitle(), 65 | "author": req.GetAuthor(), 66 | "summary": req.GetSummary(), 67 | "image": req.GetImage(), 68 | }).Error 69 | if err != nil { 70 | return err 71 | } 72 | return nil 73 | } 74 | 75 | func (r *bookRepo) DeleteBook(ctx context.Context, id int64) error { 76 | err := r.data.db.Delete(&model.Book{}, id).Error 77 | if err != nil { 78 | return err 79 | } 80 | return nil 81 | } 82 | 83 | func toBook(model *model.Book) *biz.Book { 84 | return &biz.Book{ 85 | ID: model.ID, 86 | Title: model.Title, 87 | Author: model.Author, 88 | Summary: model.Summary, 89 | Image: model.Image, 90 | CreatedAt: model.CreatedAt, 91 | } 92 | } 93 | 94 | func toBooks(models []*model.Book) []*biz.Book { 95 | books := make([]*biz.Book, len(models)) 96 | for i := range models { 97 | books[i] = toBook(models[i]) 98 | } 99 | return books 100 | } 101 | 102 | // func GetBookByTitle(ctx context.Context, title string) (model *model.Book, err error) { 103 | // model, err = GetDB().Book.Query().Where(book.Title(title)).First(ctx) 104 | // return 105 | // } 106 | -------------------------------------------------------------------------------- /internal/data/cache/init.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | // 初始化连接 4 | 5 | -------------------------------------------------------------------------------- /internal/data/data.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "lin-cms-go/internal/conf" 5 | 6 | "github.com/google/wire" 7 | "gorm.io/driver/mysql" 8 | "gorm.io/gorm" 9 | ) 10 | 11 | var ProviderSet = wire.NewSet(NewData, NewBookRepo,NewLinUserRepo,NewLessonRepo,NewTeacherRepo) 12 | 13 | type Data struct { 14 | db *gorm.DB 15 | } 16 | 17 | func NewData(conf *conf.Data) (*Data, func(), error) { 18 | d := &Data{ 19 | db: NewDB(conf), 20 | } 21 | main, _ := d.db.DB() 22 | 23 | return d, func() { 24 | main.Close() 25 | }, nil 26 | } 27 | 28 | func NewDB(conf *conf.Data) *gorm.DB { 29 | db, err := gorm.Open(mysql.Open(conf.Database.Main), &gorm.Config{}) 30 | if err != nil { 31 | panic(err) 32 | } 33 | return db.Debug() 34 | } 35 | -------------------------------------------------------------------------------- /internal/data/group.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "context" 5 | 6 | "lin-cms-go/internal/biz" 7 | 8 | "github.com/go-kratos/kratos/v2/log" 9 | ) 10 | 11 | type groupRepo struct { 12 | data *Data 13 | log *log.Helper 14 | } 15 | 16 | func NewGroupRepo(data *Data, logger log.Logger) biz.GroupRepo { 17 | return &groupRepo{ 18 | data: data, 19 | log: log.NewHelper(logger), 20 | } 21 | } 22 | 23 | func (r *groupRepo) CreateGroup(ctx context.Context, g *biz.Group) error { 24 | panic("not implemented") // TODO: Implement 25 | } 26 | 27 | func (r *groupRepo) GetGroup(ctx context.Context, id int) (*biz.Group, error) { 28 | panic("not implemented") // TODO: Implement 29 | } 30 | 31 | func (r *groupRepo) UpdateGroup(ctx context.Context, g *biz.Group) error { 32 | panic("not implemented") // TODO: Implement 33 | } 34 | 35 | func (r *groupRepo) DeleteGroup(ctx context.Context, id int) error { 36 | panic("not implemented") // TODO: Implement 37 | } 38 | 39 | func (r *groupRepo) ListGroup(ctx context.Context, page int, size int) ([]*biz.Group, error) { 40 | panic("not implemented") // TODO: Implement 41 | } 42 | 43 | // func GetAllGroup(ctx context.Context) (groups []*model.LinGroup, err error) { 44 | // groups, err = GetDB().LinGroup.Query().All(ctx) 45 | // return 46 | // } 47 | 48 | // func GetLinGroupById(ctx context.Context, groupId int) (group *model.LinGroup, err error) { 49 | // group, err = GetDB().LinGroup.Query().Where(lingroup.ID(groupId)).First(ctx) 50 | // return 51 | // } 52 | 53 | // func GetRootLinGroup(ctx context.Context, groupId int) (group *model.LinGroup, err error) { 54 | // group, err = GetDB().LinGroup.Query().Where(lingroup.ID(groupId)).Where(lingroup.And(lingroup.LevelGT(enum.ROOT))).First(ctx) 55 | // return 56 | // } 57 | 58 | // func GetLinGroupByName(ctx context.Context, name string) (group *model.LinGroup, err error) { 59 | // group, _ = GetDB().LinGroup.Query().Where(lingroup.Name(name)).First(ctx) 60 | // return 61 | // } 62 | 63 | // func CreateGroup(ctx context.Context, name string, info string, level int8) (res *model.LinGroup, err error) { 64 | // res, err = GetDB().LinGroup.Create().SetName(name).SetInfo(info).SetLevel(level).Save(ctx) 65 | // if err != nil { 66 | // return 67 | // } 68 | // return 69 | // } 70 | 71 | // func UpdateGroup(ctx context.Context, id int, name string, info string) (err error) { 72 | // _, err = GetDB().LinGroup.UpdateOneID(id).SetName(name).SetInfo(info).Save(ctx) 73 | // return 74 | // } 75 | 76 | // // update delete_time 77 | // func DeleteGroup(ctx context.Context, id int) (err error) { 78 | // _, err = GetDB().LinGroup.Update().SetDeleteTime(time.Now()).ClearLinPermission().ClearLinUser().Where(lingroup.ID(id)).Save(ctx) 79 | 80 | // return err 81 | // } 82 | -------------------------------------------------------------------------------- /internal/data/groupPermission.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | // func ListAllPermissions(ctx context.Context) (list []*model.LinPermission, err error) { 8 | // list, err = GetDB().LinPermission.Query().All(ctx) 9 | // return 10 | // } 11 | // func BatchCreateGroupPermission(ctx context.Context, groupId int, permissionId []int) (err error) { 12 | 13 | // _, err = GetDB().LinGroup.Update().Where(lingroup.ID(groupId)).AddLinPermissionIDs(permissionId...).Save(ctx) 14 | // return 15 | // } 16 | 17 | // func GetGroupPermissionByGroupId(ctx context.Context, groupId int) (groupPermission *model.LinGroup, err error) { 18 | // groupPermission, err = GetDB().LinGroup.Query().Where(lingroup.ID(groupId)).WithLinPermission().First(ctx) 19 | // return 20 | // } 21 | 22 | func DeleteGroupPermission(ctx context.Context, groupId int, permissionId []int) (err error) { 23 | //TODO 删除前判断数据是否存在放biz,不然error不好处理,职责不清晰,有可能别人调用的时候又查一次,从命名上看这个方法就是做删除,不用里面加其他操作 24 | //group, err := GetGroupPermissionByGroupId(ctx, groupId) 25 | //if err != nil { 26 | // return err 27 | //} 28 | 29 | // _, err = GetDB().LinGroup.Update().Where(lingroup.ID(groupId)).RemoveLinPermissionIDs(permissionId...).Save(ctx) 30 | //_, err = GetDB().LinGroupPermission.Delete().Where(lingrouppermission.GroupIDEQ(groupId)).Exec(ctx) 31 | return 32 | } 33 | 34 | // func ClearLinPermission(ctx context.Context, groupId int) (err error) { 35 | // _, err = GetDB().LinGroup.Update().Where(lingroup.ID(groupId)).ClearLinPermission().Save(ctx) 36 | // return 37 | // } 38 | -------------------------------------------------------------------------------- /internal/data/init.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | -------------------------------------------------------------------------------- /internal/data/lesson.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "context" 5 | 6 | "lin-cms-go/api" 7 | "lin-cms-go/internal/biz" 8 | "lin-cms-go/internal/data/model" 9 | 10 | "github.com/go-kratos/kratos/v2/log" 11 | ) 12 | 13 | type lessonRepo struct { 14 | data *Data 15 | log *log.Helper 16 | } 17 | 18 | // NewGreeterRepo . 19 | func NewLessonRepo(data *Data, logger log.Logger) biz.LessonRepo { 20 | return &lessonRepo{ 21 | data: data, 22 | log: log.NewHelper(logger), 23 | } 24 | } 25 | 26 | func (r *lessonRepo) GetLesson(ctx context.Context, id int64) (*biz.Lesson, error) { 27 | var lesson model.Lesson 28 | err := r.data.db.Where("id = ?", id).First(&lesson).Error 29 | if err != nil { 30 | return nil, err 31 | } 32 | return toLesson(&lesson), nil 33 | } 34 | 35 | func (r *lessonRepo) ListLesson(ctx context.Context, page, size int) ([]*biz.Lesson, int64, error) { 36 | var count int64 37 | err := r.data.db.Find(&model.Lesson{}).Count(&count).Error 38 | if err != nil { 39 | return nil, 0, err 40 | } 41 | var lessons []*model.Lesson 42 | err = r.data.db.Offset((page - 1) * size).Limit(size).Find(&lessons).Error 43 | if err != nil { 44 | return nil, 0, err 45 | } 46 | return toLessons(lessons), count, nil 47 | } 48 | 49 | func (r *lessonRepo) CreateLesson(ctx context.Context, req *api.CreateLessonRequest) error { 50 | err := r.data.db.Create(&model.Lesson{ 51 | Title: req.GetTitle(), 52 | }).Error 53 | if err != nil { 54 | return err 55 | } 56 | return nil 57 | } 58 | 59 | func (r *lessonRepo) UpdateLesson(ctx context.Context, req *api.UpdateLessonRequest) error { 60 | err := r.data.db.Model(&model.Lesson{}).Where("id = ?", req.GetId()).Updates(map[string]interface{}{ 61 | "title": req.GetTitle(), 62 | }).Error 63 | if err != nil { 64 | return err 65 | } 66 | return nil 67 | } 68 | 69 | func (r *lessonRepo) DeleteLesson(ctx context.Context, id int64) error { 70 | err := r.data.db.Delete(&model.Lesson{}, id).Error 71 | if err != nil { 72 | return err 73 | } 74 | return nil 75 | } 76 | 77 | func toLesson(model *model.Lesson) *biz.Lesson { 78 | return &biz.Lesson{ 79 | ID: model.ID, 80 | Title: model.Title, 81 | 82 | CreatedAt: model.CreatedAt, 83 | } 84 | } 85 | 86 | func toLessons(models []*model.Lesson) []*biz.Lesson { 87 | lessons := make([]*biz.Lesson, len(models)) 88 | for i := range models { 89 | lessons[i] = toLesson(models[i]) 90 | } 91 | return lessons 92 | } 93 | -------------------------------------------------------------------------------- /internal/data/log.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "context" 5 | 6 | "lin-cms-go/api" 7 | "lin-cms-go/internal/biz" 8 | 9 | "github.com/go-kratos/kratos/v2/log" 10 | 11 | "lin-cms-go/internal/data/model" 12 | ) 13 | 14 | type logRepo struct { 15 | data *Data 16 | log *log.Helper 17 | } 18 | 19 | func NewLogRepo(data *Data, logger log.Logger) biz.LogRepo { 20 | return &logRepo{data: data, log: log.NewHelper(logger)} 21 | } 22 | 23 | func (r *logRepo) ListLog(ctx context.Context, page int, size int) ([]*biz.Log, int64, error) { 24 | panic("not implemented") // TODO: Implement 25 | } 26 | 27 | func (r *logRepo) SearchLog(ctx context.Context, req api.SearchLogRequest) ([]*biz.Log, int64, error) { 28 | panic("not implemented") // TODO: Implement 29 | } 30 | 31 | func (r *logRepo) Search(ctx context.Context, page, size int, keyword, name string) (logs []*model.LinLog, err error) { 32 | db := r.data.db.Model(&model.LinLog{}) 33 | if keyword != "" { 34 | db = db.Where("message LIKE ?", "%"+keyword+"%") 35 | } 36 | if name != "" { 37 | db = db.Where("username = ?", name) 38 | } 39 | err = db.Order("created_at desc").Offset((page - 1) * size).Limit(size).Find(&logs).Error 40 | if err != nil { 41 | return nil, err 42 | } 43 | return 44 | } 45 | 46 | // func GetSearchTotal(ctx context.Context, query []predicate.LinLog) (total int) { 47 | // total, _ = GetDB().LinLog.Query().Where(query...).Count(ctx) 48 | // return 49 | // } 50 | 51 | // func (p *Paging) GetLogUsers(ctx context.Context) (model []string, err error) { 52 | // model, err = GetDB().LinLog.Query().Limit(p.Size).Offset(p.Offset).GroupBy(linlog.FieldUsername).Strings(ctx) 53 | // return 54 | // } 55 | 56 | // func GetLogUsersTotal(ctx context.Context) (total int, err error) { 57 | // total, err = GetDB().LinLog.Query().Select(linlog.FieldUsername).Count(ctx) 58 | // return 59 | // } 60 | 61 | // func CreateLog(ctx context.Context, statusCode, userId int, username, message, method, path, permission string) (err error) { 62 | // _, err = GetDB().LinLog.Create().SetStatusCode(statusCode).SetUserID(userId).SetUsername(username).SetMessage(message). 63 | // SetMethod(method).SetPath(path).SetPermission(permission).Save(ctx) 64 | // return 65 | // } 66 | -------------------------------------------------------------------------------- /internal/data/model/area.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameArea = "area" 14 | 15 | // Area mapped from table 16 | type Area struct { 17 | ID int32 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | Pid int32 `gorm:"column:pid;not null;comment:应用id" json:"pid"` // 应用id 19 | Name string `gorm:"column:name;not null;comment:地区名称" json:"name"` // 地区名称 20 | Letter string `gorm:"column:letter;not null;comment:地区字母" json:"letter"` // 地区字母 21 | Adcode string `gorm:"column:adcode;not null;comment:高德地区code" json:"adcode"` // 高德地区code 22 | Location string `gorm:"column:location;comment:经纬度" json:"location"` // 经纬度 23 | AreaType int32 `gorm:"column:area_type;not null;comment:0:国家,1:省,2:城市,3:区县" json:"area_type"` // 0:国家,1:省,2:城市,3:区县 24 | CityCode string `gorm:"column:city_code;not null;comment:城市编码" json:"city_code"` // 城市编码 25 | CreatedAt time.Time `gorm:"column:created_at;not null;comment:创建时间" json:"created_at"` // 创建时间 26 | UpdatedAt time.Time `gorm:"column:updated_at;not null;comment:更新时间" json:"updated_at"` // 更新时间 27 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间 28 | } 29 | 30 | // TableName Area's table name 31 | func (*Area) TableName() string { 32 | return TableNameArea 33 | } 34 | -------------------------------------------------------------------------------- /internal/data/model/book.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameBook = "book" 14 | 15 | // Book mapped from table 16 | type Book struct { 17 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | Title string `gorm:"column:title;not null" json:"title"` 19 | Author string `gorm:"column:author" json:"author"` 20 | Summary string `gorm:"column:summary" json:"summary"` 21 | Image string `gorm:"column:image" json:"image"` 22 | CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"` 23 | UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updated_at"` 24 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` 25 | } 26 | 27 | // TableName Book's table name 28 | func (*Book) TableName() string { 29 | return TableNameBook 30 | } 31 | -------------------------------------------------------------------------------- /internal/data/model/lesson.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameLesson = "lesson" 14 | 15 | // Lesson mapped from table 16 | type Lesson struct { 17 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | TeacherID int64 `gorm:"column:teacher_id;not null" json:"teacher_id"` 19 | Title string `gorm:"column:title;not null;comment:标题" json:"title"` // 标题 20 | Introduce string `gorm:"column:introduce;not null;comment:简介" json:"introduce"` // 简介 21 | StartAt time.Time `gorm:"column:start_at;comment:上课时间" json:"start_at"` // 上课时间 22 | EndAt time.Time `gorm:"column:end_at;comment:上课时间" json:"end_at"` // 上课时间 23 | LessonStatus int32 `gorm:"column:lesson_status;not null;comment:状态 0 未开始 1 正在上课 2 已结束" json:"lesson_status"` // 状态 0 未开始 1 正在上课 2 已结束 24 | IsPaid int32 `gorm:"column:is_paid;not null;comment:类型 0 免费 1 收费" json:"is_paid"` // 类型 0 免费 1 收费 25 | Price float64 `gorm:"column:price;not null;default:0.00;comment:价格" json:"price"` // 价格 26 | Province string `gorm:"column:province;not null;comment:省" json:"province"` // 省 27 | City string `gorm:"column:city;not null;comment:市" json:"city"` // 市 28 | Area string `gorm:"column:area;not null;comment:区" json:"area"` // 区 29 | Address string `gorm:"column:address;not null;comment:地址" json:"address"` // 地址 30 | CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` 31 | UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` 32 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` 33 | } 34 | 35 | // TableName Lesson's table name 36 | func (*Lesson) TableName() string { 37 | return TableNameLesson 38 | } 39 | -------------------------------------------------------------------------------- /internal/data/model/lesson_comment.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameLessonComment = "lesson_comment" 14 | 15 | // LessonComment mapped from table 16 | type LessonComment struct { 17 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | UserID int64 `gorm:"column:user_id;not null" json:"user_id"` 19 | TeacherID int64 `gorm:"column:teacher_id;not null" json:"teacher_id"` 20 | LessonID int64 `gorm:"column:lesson_id;not null" json:"lesson_id"` 21 | CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` 22 | UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` 23 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` 24 | } 25 | 26 | // TableName LessonComment's table name 27 | func (*LessonComment) TableName() string { 28 | return TableNameLessonComment 29 | } 30 | -------------------------------------------------------------------------------- /internal/data/model/lesson_signin.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameLessonSignin = "lesson_signin" 14 | 15 | // LessonSignin mapped from table 16 | type LessonSignin struct { 17 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | UserID int64 `gorm:"column:user_id;not null" json:"user_id"` 19 | LessonID int64 `gorm:"column:lesson_id;not null" json:"lesson_id"` 20 | CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` 21 | UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` 22 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` 23 | } 24 | 25 | // TableName LessonSignin's table name 26 | func (*LessonSignin) TableName() string { 27 | return TableNameLessonSignin 28 | } 29 | -------------------------------------------------------------------------------- /internal/data/model/lesson_signup.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameLessonSignup = "lesson_signup" 14 | 15 | // LessonSignup mapped from table 16 | type LessonSignup struct { 17 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | UserID int64 `gorm:"column:user_id;not null" json:"user_id"` 19 | LessonID int64 `gorm:"column:lesson_id;not null" json:"lesson_id"` 20 | CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` 21 | UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` 22 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` 23 | } 24 | 25 | // TableName LessonSignup's table name 26 | func (*LessonSignup) TableName() string { 27 | return TableNameLessonSignup 28 | } 29 | -------------------------------------------------------------------------------- /internal/data/model/lin_file.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameLinFile = "lin_file" 14 | 15 | // LinFile mapped from table 16 | type LinFile struct { 17 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | Path string `gorm:"column:path;not null" json:"path"` 19 | Type int32 `gorm:"column:type;not null;default:1;comment:1 LOCAL 本地,2 REMOTE 远程" json:"type"` // 1 LOCAL 本地,2 REMOTE 远程 20 | Name string `gorm:"column:name;not null" json:"name"` 21 | Extension string `gorm:"column:extension" json:"extension"` 22 | Size int32 `gorm:"column:size" json:"size"` 23 | Md5 string `gorm:"column:md5;comment:md5值,防止上传重复文件" json:"md5"` // md5值,防止上传重复文件 24 | CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"` 25 | UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updated_at"` 26 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` 27 | } 28 | 29 | // TableName LinFile's table name 30 | func (*LinFile) TableName() string { 31 | return TableNameLinFile 32 | } 33 | -------------------------------------------------------------------------------- /internal/data/model/lin_group.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameLinGroup = "lin_group" 14 | 15 | // LinGroup mapped from table 16 | type LinGroup struct { 17 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | Name string `gorm:"column:name;not null;comment:分组名称,例如:搬砖者" json:"name"` // 分组名称,例如:搬砖者 19 | Info string `gorm:"column:info;comment:分组信息:例如:搬砖的人" json:"info"` // 分组信息:例如:搬砖的人 20 | Level int32 `gorm:"column:level;not null;default:3;comment:分组级别 1:root 2:guest 3:user(root、guest分组只能存在一个)" json:"level"` // 分组级别 1:root 2:guest 3:user(root、guest分组只能存在一个) 21 | CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"` 22 | UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updated_at"` 23 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` 24 | } 25 | 26 | // TableName LinGroup's table name 27 | func (*LinGroup) TableName() string { 28 | return TableNameLinGroup 29 | } 30 | -------------------------------------------------------------------------------- /internal/data/model/lin_group_permission.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | const TableNameLinGroupPermission = "lin_group_permission" 8 | 9 | // LinGroupPermission mapped from table 10 | type LinGroupPermission struct { 11 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 12 | GroupID int64 `gorm:"column:group_id;not null;comment:分组id" json:"group_id"` // 分组id 13 | PermissionID int64 `gorm:"column:permission_id;not null;comment:权限id" json:"permission_id"` // 权限id 14 | } 15 | 16 | // TableName LinGroupPermission's table name 17 | func (*LinGroupPermission) TableName() string { 18 | return TableNameLinGroupPermission 19 | } 20 | -------------------------------------------------------------------------------- /internal/data/model/lin_log.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameLinLog = "lin_log" 14 | 15 | // LinLog mapped from table 16 | type LinLog struct { 17 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | Message string `gorm:"column:message" json:"message"` 19 | UserID int32 `gorm:"column:user_id;not null" json:"user_id"` 20 | Username string `gorm:"column:username" json:"username"` 21 | StatusCode int64 `gorm:"column:status_code" json:"status_code"` 22 | Method string `gorm:"column:method" json:"method"` 23 | Path string `gorm:"column:path" json:"path"` 24 | Permission string `gorm:"column:permission" json:"permission"` 25 | CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"` 26 | UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updated_at"` 27 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` 28 | } 29 | 30 | // TableName LinLog's table name 31 | func (*LinLog) TableName() string { 32 | return TableNameLinLog 33 | } 34 | -------------------------------------------------------------------------------- /internal/data/model/lin_permission.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameLinPermission = "lin_permission" 14 | 15 | // LinPermission mapped from table 16 | type LinPermission struct { 17 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | Name string `gorm:"column:name;not null;comment:权限名称,例如:访问首页" json:"name"` // 权限名称,例如:访问首页 19 | Module string `gorm:"column:module;not null;comment:权限所属模块,例如:人员管理" json:"module"` // 权限所属模块,例如:人员管理 20 | Mount int32 `gorm:"column:mount;not null;default:1;comment:0:关闭 1:开启" json:"mount"` // 0:关闭 1:开启 21 | CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"` 22 | UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updated_at"` 23 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` 24 | } 25 | 26 | // TableName LinPermission's table name 27 | func (*LinPermission) TableName() string { 28 | return TableNameLinPermission 29 | } 30 | -------------------------------------------------------------------------------- /internal/data/model/lin_user.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameLinUser = "lin_user" 14 | 15 | // LinUser mapped from table 16 | type LinUser struct { 17 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | Username string `gorm:"column:username;not null;comment:用户名,唯一" json:"username"` // 用户名,唯一 19 | Nickname string `gorm:"column:nickname;comment:用户昵称" json:"nickname"` // 用户昵称 20 | Avatar string `gorm:"column:avatar;comment:头像url" json:"avatar"` // 头像url 21 | Phone string `gorm:"column:phone;comment:邮箱" json:"phone"` // 邮箱 22 | CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"` 23 | UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updated_at"` 24 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` 25 | Password string `gorm:"column:password" json:"password"` 26 | } 27 | 28 | // TableName LinUser's table name 29 | func (*LinUser) TableName() string { 30 | return TableNameLinUser 31 | } 32 | -------------------------------------------------------------------------------- /internal/data/model/lin_user_group.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | const TableNameLinUserGroup = "lin_user_group" 8 | 9 | // LinUserGroup mapped from table 10 | type LinUserGroup struct { 11 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 12 | UserID int64 `gorm:"column:user_id;not null;comment:用户id" json:"user_id"` // 用户id 13 | GroupID int64 `gorm:"column:group_id;not null;comment:分组id" json:"group_id"` // 分组id 14 | } 15 | 16 | // TableName LinUserGroup's table name 17 | func (*LinUserGroup) TableName() string { 18 | return TableNameLinUserGroup 19 | } 20 | -------------------------------------------------------------------------------- /internal/data/model/lin_user_identiy.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameLinUserIdentiy = "lin_user_identiy" 14 | 15 | // LinUserIdentiy mapped from table 16 | type LinUserIdentiy struct { 17 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | UserID int64 `gorm:"column:user_id;not null;comment:用户id" json:"user_id"` // 用户id 19 | IdentityType string `gorm:"column:identity_type;not null" json:"identity_type"` 20 | Identifier string `gorm:"column:identifier" json:"identifier"` 21 | Credential string `gorm:"column:credential" json:"credential"` 22 | CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"` 23 | UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updated_at"` 24 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` 25 | } 26 | 27 | // TableName LinUserIdentiy's table name 28 | func (*LinUserIdentiy) TableName() string { 29 | return TableNameLinUserIdentiy 30 | } 31 | -------------------------------------------------------------------------------- /internal/data/model/teacher.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameTeacher = "teacher" 14 | 15 | // Teacher mapped from table 16 | type Teacher struct { 17 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | Name string `gorm:"column:name;not null;comment:姓名" json:"name"` // 姓名 19 | Nickname string `gorm:"column:nickname;not null;comment:昵称" json:"nickname"` // 昵称 20 | Introduce string `gorm:"column:introduce;not null;comment:简介" json:"introduce"` // 简介 21 | Avatar string `gorm:"column:avatar;not null;comment:头像" json:"avatar"` // 头像 22 | Domain string `gorm:"column:domain;not null;comment:擅长领域" json:"domain"` // 擅长领域 23 | Area string `gorm:"column:area;not null;comment:地区" json:"area"` // 地区 24 | Remark string `gorm:"column:remark;not null;comment:备注" json:"remark"` // 备注 25 | ClassHour string `gorm:"column:class_hour;not null;comment:上课时间" json:"class_hour"` // 上课时间 26 | Phone string `gorm:"column:phone;not null;comment:手机号" json:"phone"` // 手机号 27 | CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` 28 | UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` 29 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` 30 | } 31 | 32 | // TableName Teacher's table name 33 | func (*Teacher) TableName() string { 34 | return TableNameTeacher 35 | } 36 | -------------------------------------------------------------------------------- /internal/data/model/user.gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by gorm.io/gen. DO NOT EDIT. 2 | // Code generated by gorm.io/gen. DO NOT EDIT. 3 | // Code generated by gorm.io/gen. DO NOT EDIT. 4 | 5 | package model 6 | 7 | import ( 8 | "time" 9 | 10 | "gorm.io/gorm" 11 | ) 12 | 13 | const TableNameUser = "user" 14 | 15 | // User mapped from table 16 | type User struct { 17 | ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` 18 | Phone string `gorm:"column:phone;not null;comment:手机号" json:"phone"` // 手机号 19 | Openid string `gorm:"column:openid" json:"openid"` 20 | Nickname string `gorm:"column:nickname" json:"nickname"` 21 | WxProfile string `gorm:"column:wx_profile" json:"wx_profile"` 22 | CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` 23 | UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` 24 | DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` 25 | } 26 | 27 | // TableName User's table name 28 | func (*User) TableName() string { 29 | return TableNameUser 30 | } 31 | -------------------------------------------------------------------------------- /internal/data/permission.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "lin-cms-go/internal/biz" 5 | 6 | "github.com/go-kratos/kratos/v2/log" 7 | ) 8 | 9 | type permissionRepo struct { 10 | data *Data 11 | log *log.Helper 12 | } 13 | 14 | func NewPermissionRepo(data *Data, logger log.Logger) biz.PermissionRepo { 15 | return &permissionRepo{ 16 | data: data, 17 | log: log.NewHelper(logger), 18 | } 19 | } 20 | 21 | // func GetLinPermissionById(ctx context.Context, id int) (permission *model.LinPermission, err error) { 22 | // permission, err = GetDB().LinPermission.Query().Where(linpermission.ID(id)).First(ctx) 23 | // return 24 | // } 25 | 26 | // func GetPermission(ctx context.Context, name, module string) (p *model.LinPermission, err error) { 27 | // p, err = GetDB().LinPermission.Query().Where(linpermission.Module(module), linpermission.Name(name)).First(ctx) 28 | // return 29 | // } 30 | 31 | // func CreatePermission(ctx context.Context, name, module string) (err error) { 32 | // _, err = GetDB().LinPermission.Create().SetModule(module).SetName(name).SetMount(1).Save(ctx) 33 | // return 34 | // } 35 | -------------------------------------------------------------------------------- /internal/data/teacher.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "context" 5 | 6 | "lin-cms-go/api" 7 | "lin-cms-go/internal/biz" 8 | "lin-cms-go/internal/data/model" 9 | 10 | "github.com/go-kratos/kratos/v2/log" 11 | ) 12 | 13 | type teacherRepo struct { 14 | data *Data 15 | log *log.Helper 16 | } 17 | 18 | // NewGreeterRepo . 19 | func NewTeacherRepo(data *Data, logger log.Logger) biz.TeacherRepo { 20 | return &teacherRepo{ 21 | data: data, 22 | log: log.NewHelper(logger), 23 | } 24 | } 25 | 26 | func (r *teacherRepo) GetTeacher(ctx context.Context, id int64) (*biz.Teacher, error) { 27 | var teacher model.Teacher 28 | err := r.data.db.Where("id = ?", id).First(&teacher).Error 29 | if err != nil { 30 | return nil, err 31 | } 32 | return toTeacher(&teacher), nil 33 | } 34 | 35 | func (r *teacherRepo) ListTeacher(ctx context.Context, page, size int) ([]*biz.Teacher, int64, error) { 36 | var count int64 37 | err := r.data.db.Find(&model.Teacher{}).Count(&count).Error 38 | if err != nil { 39 | return nil, 0, err 40 | } 41 | var teachers []*model.Teacher 42 | err = r.data.db.Offset((page - 1) * size).Limit(size).Find(&teachers).Error 43 | if err != nil { 44 | return nil, 0, err 45 | } 46 | return toTeachers(teachers), count, nil 47 | } 48 | 49 | func (r *teacherRepo) CreateTeacher(ctx context.Context, req *api.CreateTeacherRequest) error { 50 | err := r.data.db.Create(&model.Teacher{ 51 | Name: req.Name, 52 | }).Error 53 | if err != nil { 54 | return err 55 | } 56 | return nil 57 | } 58 | 59 | func (r *teacherRepo) UpdateTeacher(ctx context.Context, req *api.UpdateTeacherRequest) error { 60 | err := r.data.db.Model(&model.Teacher{}).Where("id = ?", req.GetId()).Updates(map[string]interface{}{ 61 | "name": req.Name, 62 | }).Error 63 | if err != nil { 64 | return err 65 | } 66 | return nil 67 | } 68 | 69 | func (r *teacherRepo) DeleteTeacher(ctx context.Context, id int64) error { 70 | err := r.data.db.Delete(&model.Teacher{}, id).Error 71 | if err != nil { 72 | return err 73 | } 74 | return nil 75 | } 76 | 77 | func toTeacher(model *model.Teacher) *biz.Teacher { 78 | return &biz.Teacher{ 79 | ID: model.ID, 80 | Name: model.Name, 81 | Nickname: model.Nickname, 82 | Domain: model.Domain, 83 | Area: model.Area, 84 | Introduce: model.Introduce, 85 | Avatar: model.Avatar, 86 | ClassHour: model.ClassHour, 87 | Remark: model.Remark, 88 | Phone: model.Phone, 89 | CreatedAt: model.CreatedAt, 90 | } 91 | } 92 | 93 | func toTeachers(models []*model.Teacher) []*biz.Teacher { 94 | teachers := make([]*biz.Teacher, len(models)) 95 | for i := range models { 96 | teachers[i] = toTeacher(models[i]) 97 | } 98 | return teachers 99 | } 100 | -------------------------------------------------------------------------------- /internal/data/user.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "lin-cms-go/internal/biz" 8 | "lin-cms-go/internal/data/model" 9 | 10 | "github.com/go-kratos/kratos/v2/log" 11 | ) 12 | 13 | type linUserRepo struct { 14 | data *Data 15 | log *log.Helper 16 | } 17 | 18 | func NewLinUserRepo(data *Data, logger log.Logger) biz.LinUserRepo { 19 | return &linUserRepo{data: data, log: log.NewHelper(logger)} 20 | } 21 | 22 | func (r *linUserRepo) GetUserByUsername(ctx context.Context, username string)(*biz.LinUser, error) { 23 | var u model.LinUser 24 | err := r.data.db.First(&u, "username = ?", username).Error 25 | if err != nil { 26 | return nil, err 27 | } 28 | return &biz.LinUser{ 29 | ID: u.ID, 30 | Username: u.Username, 31 | Password: u.Password, 32 | Phone: u.Phone, 33 | }, nil 34 | } 35 | 36 | func (r *linUserRepo) ListUser(ctx context.Context, page, size int32, groupId int64) ([]*biz.LinUser, int64, error) { 37 | panic("not implemented") // TODO: Implement 38 | } 39 | 40 | func (r *linUserRepo) GetUser(ctx context.Context, userId int) (*biz.LinUser, error) { 41 | panic("not implemented") // TODO: Implement 42 | } 43 | 44 | func (r *linUserRepo) CreateUser(ctx context.Context, user *biz.LinUser) error { 45 | err := r.data.db.Create(&model.LinUser{ 46 | Username: user.Username, 47 | Password: user.Password, 48 | Phone: user.Phone, 49 | Nickname: user.Username, 50 | }).Error 51 | if err != nil { 52 | return fmt.Errorf("CreateUser failed %w ", err) 53 | } 54 | return nil 55 | } 56 | 57 | func (r *linUserRepo) ChangeUserPassword(ctx context.Context, userId int, password string) error { 58 | panic("not implemented") // TODO: Implement 59 | } 60 | 61 | func (r *linUserRepo) UpdateUser(ctx context.Context, user *biz.LinUser) error { 62 | panic("not implemented") // TODO: Implement 63 | } 64 | 65 | // func GetLinUserIdentityByIdentifier(ctx context.Context, identifier string) (model *model.LinUserIdentiy, err error) { 66 | // model, err = GetDB().LinUserIdentiy.Query().Where(linuseridentiy.Identifier(identifier)).First(ctx) 67 | // return 68 | // } 69 | 70 | // func GetLinUserIdentityByUserId(ctx context.Context, userId int) (model *model.LinUserIdentiy, err error) { 71 | // model, err = GetDB().LinUserIdentiy.Query().Where(linuseridentiy.UserID(userId)).First(ctx) 72 | // return 73 | // } 74 | 75 | // func CreateLinUser(ctx context.Context, username, password, email string, groupId int) (err error) { 76 | // userModel, err := GetDB().LinUser.Create(). 77 | // SetUsername(username). 78 | // SetNickname(username). 79 | // SetEmail(email). 80 | // AddLinGroupIDs(groupId). 81 | // Save(ctx) 82 | // if err != nil { 83 | // return err 84 | // } 85 | // _, err = GetDB().LinUserIdentiy.Create(). 86 | // SetUserID(userModel.ID). 87 | // SetIdentifier(username). 88 | // SetCredential(password). 89 | // SetIdentityType("USERNAME_PASSWORD"). 90 | // Save(ctx) 91 | 92 | // return 93 | // } 94 | 95 | // func GetLinUserById(ctx context.Context, uid int) (model *model.LinUser, err error) { 96 | // model, err = GetDB().LinUser.Query().Where(linuser.ID(uid)).First(ctx) 97 | 98 | // return 99 | // } 100 | 101 | // func GetLinUserWithGroupById(ctx context.Context, uid int) (users *model.LinUser, err error) { 102 | // users, err = GetDB().LinUser.Query().Where(linuser.ID(uid)).WithLinGroup(func(query *model.LinGroupQuery) { 103 | // query.WithLinPermission() 104 | // }).First(ctx) 105 | 106 | // return 107 | // } 108 | 109 | // func UpdateLinUser(ctx context.Context, uid int, avatar, nickname, email string) (err error) { 110 | // _, err = GetDB().LinUser.Update().Where(linuser.ID(uid)).SetEmail(email).SetAvatar(avatar).SetNickname(nickname). 111 | // Save(ctx) 112 | 113 | // return 114 | // } 115 | 116 | // func UpdateLinUserIdentityPassword(ctx context.Context, username, password string) (err error) { 117 | // _, err = GetDB().LinUserIdentiy.Update().Where(linuseridentiy.Identifier(username)). 118 | // SetCredential(password).Save(ctx) 119 | 120 | // return 121 | // } 122 | 123 | // func SoftDeleteUser(ctx context.Context, userId int) (err error) { 124 | // _, err = GetDB().LinUser.Update().Where(linuser.ID(userId)). 125 | // SetDeleteTime(time.Now()).Save(ctx) 126 | 127 | // return 128 | // } 129 | 130 | // func (p *Paging) ListUser(ctx context.Context) (users []*model.LinUser, err error) { 131 | // users, err = GetDB().LinUser.Query().WithLinGroup().Limit(p.Size).Offset(p.Offset).All(ctx) 132 | // return 133 | // } 134 | 135 | // func (p *Paging) ListUserByGroupId(ctx context.Context, groupId int) (users []*model.LinUser, err error) { 136 | // groups, err := GetDB().LinGroup.Query().Where(lingroup.ID(groupId)).WithLinUser(func(query *model.LinUserQuery) { 137 | // query.Limit(p.Size).Offset(p.Offset).WithLinGroup() 138 | // }).All(ctx) 139 | // if err != nil { 140 | // return 141 | // } 142 | // for _, g := range groups { 143 | // users = append(users, g.Edges.LinUser...) 144 | // } 145 | 146 | // return 147 | // } 148 | 149 | // func AddLinUserGroupIDs(ctx context.Context, userId int, groupIds []int) (err error) { 150 | // _, err = GetDB().LinUser.Update().Where(linuser.ID(userId)).ClearLinGroup().AddLinGroupIDs(groupIds...).Save(ctx) 151 | // return 152 | // } 153 | -------------------------------------------------------------------------------- /internal/server/http.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "encoding/json" 5 | "time" 6 | 7 | "lin-cms-go/api" 8 | "lin-cms-go/internal/conf" 9 | "lin-cms-go/internal/service" 10 | 11 | "github.com/go-kratos/kratos/v2/log" 12 | "github.com/go-kratos/kratos/v2/middleware/logging" 13 | "github.com/go-kratos/kratos/v2/middleware/recovery" 14 | "github.com/go-kratos/kratos/v2/transport/http" 15 | "github.com/gorilla/handlers" 16 | "google.golang.org/grpc/encoding" 17 | ) 18 | 19 | // MiddlewareCors 设置跨域请求头 20 | 21 | // NewHTTPServer new a HTTP server. 22 | func NewHTTPServer(c *conf.Server, cs *service.CmsService,as *service.AppService, logger log.Logger) *http.Server { 23 | opts := []http.ServerOption{ 24 | http.Middleware( 25 | 26 | recovery.Recovery(), 27 | 28 | logging.Server(logger), 29 | ), 30 | http.Filter(handlers.CORS( 31 | handlers.AllowedHeaders([]string{"X-Requested-With", "content-type", "Content-Type", "Authorization", "tag"}), 32 | handlers.AllowedMethods([]string{"GET", "POST", "PUT", "HEAD", "OPTIONS"}), 33 | handlers.AllowCredentials(), 34 | handlers.AllowedOrigins([]string{"*"}), 35 | )), 36 | // http.ResponseEncoder(DefaultResponseEncoder), 37 | } 38 | 39 | if c.Http.Addr != "" { 40 | opts = append(opts, http.Address(c.Http.Addr)) 41 | } 42 | if c.Http.Timeout > 0 { 43 | opts = append(opts, http.Timeout(5*time.Second)) 44 | } 45 | 46 | srv := http.NewServer(opts...) 47 | 48 | api.RegisterCmsHTTPServer(srv, cs) 49 | api.RegisterAppHTTPServer(srv, as) 50 | return srv 51 | } 52 | 53 | type Response struct { 54 | Code int `json:"code"` 55 | Message string `json:"message"` 56 | Data json.RawMessage `json:"data"` 57 | } 58 | 59 | func DefaultResponseEncoder(w http.ResponseWriter, r *http.Request, v any) error { 60 | if v == nil { 61 | return nil 62 | } 63 | 64 | data, err := encoding.GetCodec("json").Marshal(v) 65 | if err != nil { 66 | return err 67 | } 68 | 69 | bs, _ := json.Marshal(&Response{ 70 | Code: 0, 71 | Message: "ok", 72 | Data: data, 73 | }) 74 | 75 | w.Header().Set("Content-Type", "application/json") 76 | _, err = w.Write(bs) 77 | if err != nil { 78 | return err 79 | } 80 | return nil 81 | } 82 | -------------------------------------------------------------------------------- /internal/server/middleware.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | // func UserLog(c *fiber.Ctx) error { 4 | // err := c.Next() 5 | // if err != nil { 6 | // return err 7 | // } 8 | // user := biz.LocalUser(c) 9 | 10 | // msg := c.Locals("logMessage") 11 | // if msg == nil { 12 | // return nil 13 | // } 14 | // err = data.CreateLog(c.Context(), c.Response().StatusCode(), user.ID, user.Username, user.Username+msg.(string), c.Method(), c.Path(), "") 15 | 16 | // return err 17 | // } 18 | 19 | // func SetPermission(name, module string) fiber.Handler { 20 | // return func(c *fiber.Ctx) error { 21 | // p := biz.Permission{Name: name, Module: module} 22 | // err := biz.CreateIfNoPermissions(c.Context(), p) 23 | // if err != nil { 24 | // return err 25 | // } 26 | // c.Locals("permission", p) 27 | 28 | // return c.Next() 29 | // } 30 | // } 31 | 32 | // func AdminRequired(c *fiber.Ctx) error { 33 | // isAdmin, err := biz.IsAdmin(c) 34 | // if err != nil { 35 | // return err 36 | // } 37 | // if !isAdmin { 38 | // return core.UnAuthenticatedError(errcode.UserNoPermission) 39 | // } 40 | // return c.Next() 41 | // } 42 | 43 | // func LoginRequired(c *fiber.Ctx) error { 44 | // user := biz.LocalUser(c) 45 | // if user.ID == 0 { 46 | // return core.UnAuthenticatedError(errcode.AuthCheckTokenFail) 47 | // } 48 | 49 | // return c.Next() 50 | // } 51 | 52 | // func GroupRequired(c *fiber.Ctx) error { 53 | // isAdmin, err := biz.IsAdmin(c) 54 | // if err != nil { 55 | // return err 56 | // } 57 | // if isAdmin { 58 | // return c.Next() 59 | // } 60 | 61 | // has, err := biz.UserHasPermission(c) 62 | // if err != nil { 63 | // return err 64 | // } 65 | // if !has { 66 | // return core.UnAuthenticatedError(errcode.UserNoPermission) 67 | // } 68 | // return c.Next() 69 | // } 70 | 71 | // 72 | //func (a *Auth) RefreshRequired(ctx *gin.Context) { 73 | // refreshToken, tokenErr := getHeaderToken(ctx) 74 | // if tokenErr != nil { 75 | // ctx.Error(tokenErr) 76 | // ctx.Abort() 77 | // return 78 | // } 79 | // payload, err := a.JWT.VerifyRefreshToken(refreshToken) 80 | // if err != nil { 81 | // ctx.Error(err) 82 | // ctx.Abort() 83 | // } else { 84 | // userId := payload.Identity 85 | // user, errs := a.UserService.GetUserById(userId) 86 | // if errs != nil { 87 | // ctx.Error(response.UnifyResponse(10021, ctx)) 88 | // ctx.Abort() 89 | // } else { 90 | // ctx.Set("currentUser", user) 91 | // ctx.Next() 92 | // } 93 | // } 94 | //} 95 | 96 | //func getHeaderToken(ctx *gin.Context) (string, error) { 97 | // authorizationHeader := ctx.GetHeader(AuthorizationHeaderKey) 98 | // if authorizationHeader == "" { 99 | // return "", response.UnifyResponse(10012, ctx) 100 | // } 101 | // fields := strings.Fields(authorizationHeader) 102 | // if fields[0] != AuthorizationTypeBearer { 103 | // return "", response.UnifyResponse(10013, ctx) 104 | // } 105 | // tokenString := fields[1] 106 | // return tokenString, nil 107 | //} 108 | -------------------------------------------------------------------------------- /internal/server/router.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/go-kratos/kratos/v2/middleware/selector" 7 | ) 8 | 9 | func ListRoutes() map[string]struct{} { 10 | return map[string]struct{}{ 11 | "/api.Suggest/CreateSuggest": {}, 12 | "/api.Suggest/UpdateSuggestRead": {}, 13 | "/api.Suggest/Update": {}, 14 | "/api.Suggest/CreateDraft": {}, 15 | "/api.Suggest/ListDraft": {}, 16 | "/api.Suggest/GetDraft": {}, 17 | "/api.Suggest/ListChannel": {}, 18 | "/api.Suggest/UpdateRead": {}, 19 | "/api.Suggest/CreateLike": {}, 20 | "/api.Suggest/CreateFollow": {}, 21 | "/api.Suggest/CreateComment": {}, 22 | "/api.Suggest/CreateCommentLike": {}, 23 | "/api.Suggest/DeleteComment": {}, 24 | "/api.Suggest/ListFollow": {}, 25 | "/api.Suggest/ListNotifyLike": {}, 26 | "/api.Suggest/ListNotifyComment": {}, 27 | "/api.Suggest/ListMyCheck": {}, 28 | "/api.Suggest/ListMyRelease": {}, 29 | "/api.Suggest/GetMySuggest": {}, 30 | } 31 | } 32 | 33 | func MustAuthRoutersMatcher() selector.MatchFunc { 34 | return func(ctx context.Context, operation string) bool { 35 | if _, ok := ListRoutes()[operation]; ok { 36 | return true 37 | } 38 | return false 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /internal/server/server.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import "github.com/google/wire" 4 | 5 | var ProviderSet = wire.NewSet(NewHTTPServer) 6 | -------------------------------------------------------------------------------- /internal/service/admin.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | // func GetUsers(c *fiber.Ctx) error { 4 | // var req api.ListUserRequest 5 | // if err := core.ParseRequest(c, &req); err != nil { 6 | // return err 7 | // } 8 | 9 | // data, err := biz.GetUsers(c.Context(), int(req.GroupId), core.GetPage(c), core.GetSize(c)) 10 | // if err != nil { 11 | // return err 12 | // } 13 | // return core.SetData(c, data) 14 | // } 15 | 16 | // func ChangeUserPassword(c *fiber.Ctx) error { 17 | // var req api.UpdateUserPasswordRequest 18 | // if err := core.ParseRequest(c, &req); err != nil { 19 | // return err 20 | // } 21 | 22 | // err := biz.ChangeUserPassword(c.Context(), int(req.Id), req.NewPassword) 23 | // if err != nil { 24 | // return err 25 | // } 26 | // return core.SuccessResp(c) 27 | // } 28 | 29 | // func DeleteUser(c *fiber.Ctx) error { 30 | // id, err := utils.StringToInt(c.Params("id")) 31 | // if err != nil { 32 | // return err 33 | // } 34 | // err = biz.DeleteUser(c.Context(), id) 35 | // if err != nil { 36 | // return err 37 | // } 38 | // return core.SuccessResp(c) 39 | // } 40 | 41 | // func UpdateUser(c *fiber.Ctx) error { 42 | // var req api.UpdateUserRequest 43 | // if err := core.ParseRequest(c, &req); err != nil { 44 | // return err 45 | // } 46 | 47 | // err := biz.UpdateUser(c.Context(), int(req.Id), req.GroupIds) 48 | // if err != nil { 49 | // return err 50 | // } 51 | // return core.SuccessResp(c) 52 | // } 53 | -------------------------------------------------------------------------------- /internal/service/app.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/go-kratos/kratos/v2/errors" 8 | "google.golang.org/protobuf/types/known/emptypb" 9 | "gorm.io/gorm" 10 | 11 | pb "lin-cms-go/api" 12 | "lin-cms-go/internal/biz" 13 | ) 14 | 15 | type AppService struct { 16 | pb.UnimplementedAppServer 17 | bu *biz.BookUsecase 18 | lu *biz.LessonUsecase 19 | tu *biz.TeacherUsecase 20 | } 21 | 22 | func NewAppService(bu *biz.BookUsecase, lu *biz.LessonUsecase, tu *biz.TeacherUsecase) *AppService { 23 | return &AppService{ 24 | bu: bu, 25 | lu: lu, 26 | tu: tu, 27 | } 28 | } 29 | 30 | func (s *AppService) CreateLesson(ctx context.Context, req *pb.CreateLessonRequest) (*emptypb.Empty, error) { 31 | return &emptypb.Empty{}, nil 32 | } 33 | 34 | func (s *AppService) ListLesson(ctx context.Context, req *pb.PageRequest) (*pb.ListLessonReply, error) { 35 | return &pb.ListLessonReply{ 36 | Page: req.Page, 37 | Size: req.Size, 38 | }, nil 39 | } 40 | 41 | func (s *AppService) GetLesson(ctx context.Context, req *pb.IDRequest) (*pb.GetLessonReply, error) { 42 | return &pb.GetLessonReply{}, nil 43 | } 44 | 45 | func (s *AppService) UpdateLesson(ctx context.Context, req *pb.UpdateLessonRequest) (*emptypb.Empty, error) { 46 | return &emptypb.Empty{}, nil 47 | } 48 | 49 | func (s *AppService) DeleteLesson(ctx context.Context, req *pb.IDRequest) (*emptypb.Empty, error) { 50 | return &emptypb.Empty{}, nil 51 | } 52 | 53 | func (s *AppService) CreateTeacher(ctx context.Context, req *pb.CreateTeacherRequest) (*emptypb.Empty, error) { 54 | return &emptypb.Empty{}, nil 55 | } 56 | 57 | func (s *AppService) ListTeacher(ctx context.Context, req *pb.PageRequest) (*pb.ListTeacherReply, error) { 58 | page, size := defaultPageRequest(req.Page, req.Size) 59 | list, total, err := s.tu.ListTeacher(ctx, page, size) 60 | if err != nil { 61 | return nil, fmt.Errorf("ListTeacher failed %w ", err) 62 | } 63 | return &pb.ListTeacherReply{ 64 | List: list, 65 | Total: uint32(total), 66 | Page: req.Page, 67 | Size: req.Size, 68 | }, nil 69 | } 70 | 71 | func (s *AppService) GetTeacher(ctx context.Context, req *pb.IDRequest) (*pb.GetTeacherReply, error) { 72 | teacher, err := s.tu.GetTeacher(ctx, req.Id) 73 | if errors.Is(err, gorm.ErrRecordNotFound) { 74 | return nil, errors.NotFound(err.Error(), "teacher not found") 75 | } 76 | if err != nil { 77 | return nil, err 78 | } 79 | return teacher, nil 80 | } 81 | 82 | func (s *AppService) UpdateTeacher(ctx context.Context, req *pb.UpdateTeacherRequest) (*emptypb.Empty, error) { 83 | return &emptypb.Empty{}, nil 84 | } 85 | 86 | func (s *AppService) DeleteTeacher(ctx context.Context, req *pb.IDRequest) (*emptypb.Empty, error) { 87 | err := s.tu.DeleteTeacher(ctx, req.Id) 88 | if err != nil { 89 | return nil, err 90 | } 91 | return &emptypb.Empty{}, nil 92 | } 93 | -------------------------------------------------------------------------------- /internal/service/book.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "lin-cms-go/api" 7 | 8 | "google.golang.org/protobuf/types/known/emptypb" 9 | ) 10 | 11 | func (s *AppService) CreateBook(ctx context.Context, req *api.CreateBookRequest) (*emptypb.Empty, error) { 12 | if err := s.bu.CreateBook(ctx, req); err != nil { 13 | return nil, err 14 | } 15 | return &emptypb.Empty{}, nil 16 | } 17 | 18 | func (s *AppService) ListBook(ctx context.Context, req *api.PageRequest) (*api.ListBookReply, error) { 19 | // TODO 权限判断 20 | page, size := defaultPageRequest(req.Page, req.Size) 21 | list, total, err := s.bu.ListBook(ctx, page, size) 22 | if err != nil { 23 | return nil, err 24 | } 25 | return &api.ListBookReply{ 26 | List: list, 27 | Total: uint32(total), 28 | }, nil 29 | } 30 | 31 | func (s *AppService) GetBook(ctx context.Context, req *api.IDRequest) (*api.GetBookReply, error) { 32 | // TODO 权限判断 33 | book, err := s.bu.GetBook(ctx, req.Id) 34 | if err != nil { 35 | return nil, err 36 | } 37 | return &api.GetBookReply{ 38 | Book: book, 39 | }, nil 40 | } 41 | 42 | func (s *AppService) UpdateBook(ctx context.Context, req *api.UpdateBookRequest) (*emptypb.Empty, error) { 43 | if err := s.bu.UpdateBook(ctx, req); err != nil { 44 | return nil, err 45 | } 46 | return &emptypb.Empty{}, nil 47 | } 48 | 49 | func (s *AppService) DeleteBook(ctx context.Context, req *api.IDRequest) (*emptypb.Empty, error) { 50 | if err := s.bu.DeleteBook(ctx, req.Id); err != nil { 51 | return nil, err 52 | } 53 | return &emptypb.Empty{}, nil 54 | } 55 | 56 | // func GetBooks(c *fiber.Ctx) error { 57 | // // TODO book 接口少了权限判断 58 | 59 | // size := core.GetSize(c) 60 | // page := core.GetPage(c) 61 | // data, err := biz.GetBookAll(c.Context(), page, size) 62 | // if err != nil { 63 | // return err 64 | // } 65 | // total, err := biz.GetBookTotal(c.Context()) 66 | // if err != nil { 67 | // return err 68 | // } 69 | // core.SetPage(c, data, total) 70 | // return nil 71 | // } 72 | 73 | // func UpdateBook(c *fiber.Ctx) error { 74 | // var req api.UpdateBookRequest 75 | // if err := core.ParseRequest(c, &req); err != nil { 76 | // return err 77 | // } 78 | // id, err := utils.StringToInt(c.Params("id")) 79 | // if err != nil { 80 | // return err 81 | // } 82 | 83 | // err = biz.UpdateBook(c.Context(), id, &req) 84 | // if err != nil { 85 | // return err 86 | // } 87 | // return core.SuccessResp(c) 88 | // } 89 | 90 | // func CreateBook(c *fiber.Ctx) error { 91 | // var req api.CreateBookRequest 92 | // if err := core.ParseRequest(c, &req); err != nil { 93 | // return err 94 | // } 95 | // err := biz.CreateBook(c.Context(), &req) 96 | // if err != nil { 97 | // return err 98 | // } 99 | // return core.SuccessResp(c) 100 | // } 101 | 102 | // func DeleteBook(c *fiber.Ctx) error { 103 | // id, err := utils.StringToInt(c.Params("id")) 104 | // if err != nil { 105 | // return err 106 | // } 107 | // err = biz.DeleteBook(c.Context(), id) 108 | // if err != nil { 109 | // return err 110 | // } 111 | // return core.SuccessResp(c) 112 | // } 113 | 114 | // func GetBook(c *fiber.Ctx) error { 115 | // id, err := utils.StringToInt(c.Params("id")) 116 | // if err != nil { 117 | // return err 118 | // } 119 | // data, err := biz.GetBook(c.Context(), id) 120 | // if err != nil { 121 | // return err 122 | // } 123 | // core.SetData(c, data) 124 | // return nil 125 | // } 126 | -------------------------------------------------------------------------------- /internal/service/cms.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | pb "lin-cms-go/api" 7 | "lin-cms-go/internal/biz" 8 | 9 | "google.golang.org/protobuf/types/known/emptypb" 10 | ) 11 | 12 | type CmsService struct { 13 | pb.UnimplementedCmsServer 14 | uu *biz.LinUserusecase 15 | } 16 | 17 | func NewCmsService(uu *biz.LinUserusecase) *CmsService { 18 | return &CmsService{ 19 | uu: uu, 20 | } 21 | } 22 | 23 | func (s *CmsService) Ping(ctx context.Context, req *emptypb.Empty) (*pb.PingReply, error) { 24 | return &pb.PingReply{ 25 | Message: "pong", 26 | }, nil 27 | } 28 | 29 | func (s *CmsService) Login(ctx context.Context, req *pb.LoginRequest) (*pb.LoginReply, error) { 30 | r, err := s.uu.Login(ctx, req) 31 | if err != nil { 32 | return nil, err 33 | } 34 | return r, err 35 | } 36 | func (s *CmsService) CreateUser(ctx context.Context, req *pb.CreateLinUserRequest) (*emptypb.Empty, error) { 37 | err := s.uu.CreateUser(ctx, req) 38 | if err != nil { 39 | return nil, err 40 | } 41 | return &emptypb.Empty{}, nil 42 | } 43 | 44 | func (s *CmsService) Upload(ctx context.Context, req *pb.UploadRequest) (*pb.UploadReply, error) { 45 | return &pb.UploadReply{}, nil 46 | } 47 | 48 | func (s *CmsService) UpdateMe(ctx context.Context, req *pb.UpdateMeRequest) (*emptypb.Empty, error) { 49 | return &emptypb.Empty{}, nil 50 | } 51 | 52 | func (s *CmsService) UpdateMyPassword(ctx context.Context, req *pb.UpdateMyPasswordRequest) (*emptypb.Empty, error) { 53 | return &emptypb.Empty{}, nil 54 | } 55 | 56 | func (s *CmsService) ListMyPermission(ctx context.Context, req *emptypb.Empty) (*pb.ListMyPermissionReply, error) { 57 | return &pb.ListMyPermissionReply{}, nil 58 | } 59 | 60 | func (s *CmsService) GetMyInfomation(ctx context.Context, req *emptypb.Empty) (*pb.GetMyInfomationReply, error) { 61 | return &pb.GetMyInfomationReply{}, nil 62 | } 63 | 64 | func (s *CmsService) ListPermission(ctx context.Context, req *emptypb.Empty) (*pb.ListPermissionReply, error) { 65 | return &pb.ListPermissionReply{}, nil 66 | } 67 | 68 | func (s *CmsService) ListUser(ctx context.Context, req *pb.ListLinUserRequest) (*pb.ListLinUserReply, error) { 69 | return &pb.ListLinUserReply{}, nil 70 | } 71 | 72 | func (s *CmsService) UpdateUserPassword(ctx context.Context, req *pb.UpdateUserPasswordRequest) (*emptypb.Empty, error) { 73 | return &emptypb.Empty{}, nil 74 | } 75 | 76 | func (s *CmsService) DeleteUser(ctx context.Context, 77 | req *pb.IDRequest) (*emptypb.Empty, error) { 78 | return &emptypb.Empty{}, nil 79 | } 80 | 81 | func (s *CmsService) UpdateUser(ctx context.Context, req *pb.UpdateUserRequest) (*emptypb.Empty, error) { 82 | return &emptypb.Empty{}, nil 83 | } 84 | 85 | func (s *CmsService) GetUser(ctx context.Context, req *pb.IDRequest) (*pb.GetLinUserReply, error) { 86 | return &pb.GetLinUserReply{}, nil 87 | } 88 | 89 | func (s *CmsService) GetGroup(ctx context.Context, req *pb.IDRequest) (*pb.GetGroupReply, error) { 90 | return &pb.GetGroupReply{}, nil 91 | 92 | } 93 | 94 | func (s *CmsService) UpdateGroup(ctx context.Context, req *pb.UpdateGroupRequest) (*emptypb.Empty, error) { 95 | return &emptypb.Empty{}, nil 96 | } 97 | 98 | func (s *CmsService) DeleteGroup(ctx context.Context, req *pb.IDRequest) (*emptypb.Empty, error) { 99 | return &emptypb.Empty{}, nil 100 | } 101 | 102 | func (s *CmsService) CreateGroup(ctx context.Context, req *pb.CreateGroupRequest) (*emptypb.Empty, error) { 103 | return &emptypb.Empty{}, nil 104 | } 105 | 106 | func (s *CmsService) ListGroup(ctx context.Context, req *emptypb.Empty) (*pb.ListGroupReply, error) { 107 | return &pb.ListGroupReply{}, nil 108 | } 109 | 110 | func (s *CmsService) DispatchPermission(ctx context.Context, req *pb.DispatchPermissionRequest) (*emptypb.Empty, error) { 111 | return &emptypb.Empty{}, nil 112 | } 113 | 114 | func (s *CmsService) DispatchPermissions(ctx context.Context, req *pb.DispatchPermissionsRequest) (*emptypb.Empty, error) { 115 | return &emptypb.Empty{}, nil 116 | } 117 | 118 | func (s *CmsService) RemovePermission(ctx context.Context, req *pb.RemovePermissionRequest) (*emptypb.Empty, error) { 119 | return &emptypb.Empty{}, nil 120 | } 121 | 122 | func (s *CmsService) ListLog(ctx context.Context, req *pb.PageRequest) (*pb.ListLogReply, error) { 123 | return &pb.ListLogReply{}, nil 124 | } 125 | 126 | func (s *CmsService) SearchLog(ctx context.Context, req *pb.SearchLogRequest) (*pb.ListLogReply, error) { 127 | return &pb.ListLogReply{}, nil 128 | } 129 | 130 | func (s *CmsService) ListLogUser(ctx context.Context, req *pb.PageRequest) (*pb.ListLogUserReply, error) { 131 | return &pb.ListLogUserReply{}, nil 132 | } 133 | -------------------------------------------------------------------------------- /internal/service/group.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | // func GetGroups(c *fiber.Ctx) error { 4 | // data, err := biz.GetGroups(c.Context()) 5 | // if err != nil { 6 | // return err 7 | // } 8 | // return core.SetData(c, data) 9 | // } 10 | 11 | // func GetGroup(c *fiber.Ctx) error { 12 | // id, err := utils.StringToInt(c.Params("id")) 13 | // if err != nil { 14 | // return err 15 | // } 16 | // data, err := biz.GetGroup(c.Context(), id) 17 | // if err != nil { 18 | // return err 19 | // } 20 | // return core.SetData(c, data) 21 | // } 22 | 23 | // func CreateGroup(c *fiber.Ctx) error { 24 | // var req api.CreateGroupRequest 25 | // if err := core.ParseRequest(c, &req); err != nil { 26 | // return err 27 | // } 28 | // err := biz.CreateGroup(c.Context(), req.Name, req.Info, req.PermissionIds) 29 | // if err != nil { 30 | // return err 31 | // } 32 | // return core.SuccessResp(c) 33 | // } 34 | 35 | // func UpdateGroup(c *fiber.Ctx) error { 36 | // var req api.UpdateGroupRequest 37 | // if err := core.ParseRequest(c, &req); err != nil { 38 | // return err 39 | // } 40 | // id, err := utils.StringToInt(c.Params("id")) 41 | // if err != nil { 42 | // return err 43 | // } 44 | 45 | // err = biz.UpdateGroup(c.Context(), id, &req) 46 | // if err != nil { 47 | // return err 48 | // } 49 | // return core.SuccessResp(c) 50 | // } 51 | // func DeleteGroup(c *fiber.Ctx) error { 52 | // id, err := utils.StringToInt(c.Params("id")) 53 | // if err != nil { 54 | // return err 55 | // } 56 | 57 | // err = biz.DeleteGroup(c.Context(), id) 58 | // if err != nil { 59 | // return err 60 | // } 61 | // return core.SuccessResp(c) 62 | 63 | // } 64 | -------------------------------------------------------------------------------- /internal/service/log.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | // func Upload(c *fiber.Ctx) error { 4 | // return core.SuccessResp(c) 5 | // } 6 | 7 | // func GetLogs(c *fiber.Ctx) error { 8 | // var req api.ListLogRequest 9 | // page := core.GetPage(c) 10 | // size := core.GetSize(c) 11 | // if err := core.ParseQuery(c, &req); err != nil { 12 | // return err 13 | // } 14 | 15 | // data, total, err := biz.GetLogs(c.Context(), req, page, size) 16 | // if err != nil { 17 | // return err 18 | // } 19 | // return core.SetPage(c, data, total) 20 | // } 21 | 22 | // func SearchLogs(c *fiber.Ctx) error { 23 | // var req api.SearchLogRequest 24 | // if err := core.ParseQuery(c, &req); err != nil { 25 | // return err 26 | // } 27 | // page := core.GetPage(c) 28 | // size := core.GetSize(c) 29 | 30 | // data, total, err := biz.SearchLogs(c.Context(), req, page, size) 31 | // if err != nil { 32 | // return err 33 | // } 34 | // return core.SetPage(c, data, total) 35 | // } 36 | 37 | // func GetLogUsers(c *fiber.Ctx) error { 38 | // page := core.GetPage(c) 39 | // size := core.GetSize(c) 40 | // data, total, err := biz.GetLogUsers(c.Context(), page, size) 41 | // if err != nil { 42 | // return err 43 | // } 44 | // return core.SetPage(c, data, total) 45 | // } 46 | -------------------------------------------------------------------------------- /internal/service/permission.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | // func GetAllPermissions(c *fiber.Ctx) error { 4 | 5 | // data, err := biz.GetAllPermissions(c.Context()) 6 | // if err != nil { 7 | 8 | // return err 9 | // } 10 | // return core.SetData(c, data) 11 | 12 | // } 13 | 14 | // //TODO: 没找到必须实现该接口的业务场景,而且功能和分配多个权限重复,开发待定 15 | // func DispatchPermission(c *fiber.Ctx) error { 16 | 17 | // return nil 18 | // } 19 | 20 | // func DispatchPermissions(c *fiber.Ctx) error { 21 | // var req api.DispatchPermissionsRequest 22 | // if err := core.ParseRequest(c, &req); err != nil { 23 | // return err 24 | // } 25 | // err := biz.DispatchPermissions(c.Context(), req.GroupId, req.PermissionIds) 26 | // if err != nil { 27 | // return err 28 | // } 29 | // return core.SuccessResp(c) 30 | 31 | // } 32 | 33 | // func RemovePermissions(c *fiber.Ctx) error { 34 | // var req request.RemovePermissions 35 | // if err := core.ParseRequest(c, &req); err != nil { 36 | 37 | // return err 38 | // } 39 | // err := biz.RemovePermissions(c.Context(), req.GroupId, req.PermissionIds) 40 | // if err != nil { 41 | 42 | // return err 43 | // } 44 | // return core.SuccessResp(c) 45 | 46 | // } 47 | -------------------------------------------------------------------------------- /internal/service/service.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/google/wire" 7 | "github.com/spf13/cast" 8 | ) 9 | 10 | var ProviderSet = wire.NewSet(NewCmsService,NewAppService) 11 | 12 | func CurrentUserId(ctx context.Context) string { 13 | // if ginCtx, ok := ctx.(*gin.Context); ok { 14 | // return ginCtx.GetString("userId") 15 | // } 16 | 17 | return cast.ToString(ctx.Value("userID")) 18 | } 19 | 20 | func CurrentIP(ctx context.Context) string { 21 | // if ginCtx, ok := ctx.(*gin.Context); ok { 22 | // return ginCtx.GetString("ip") 23 | // } 24 | return cast.ToString(ctx.Value("ip")) 25 | } 26 | 27 | func getTotalPages(total int64, size int32) int32 { 28 | if total == 0 || size == 0 { 29 | return 0 30 | } 31 | if total%int64(size) == 0 { 32 | return int32(total / int64(size)) 33 | } 34 | return int32(total/int64(size)) + 1 35 | } 36 | 37 | func defaultPageRequest(page, size int32) (int, int) { 38 | 39 | if page <= 0 { 40 | page = 1 41 | } 42 | if size <= 0 { 43 | size = 10 44 | } 45 | return int(page), int(size) 46 | } 47 | -------------------------------------------------------------------------------- /internal/service/user.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | 4 | // func Hello(ctx *fiber.Ctx) error { 5 | // return ctx.JSON("Hello") 6 | // } 7 | // func Login(c *fiber.Ctx) error { 8 | // var req request.Login 9 | // if err := core.ParseRequest(c, &req); err != nil { 10 | // return err 11 | // } 12 | 13 | // data, err := biz.Login(c.Context(), req.Username, req.Password) 14 | // if err != nil { 15 | 16 | // return err 17 | // } 18 | 19 | // return core.SetData(c, data) 20 | 21 | // } 22 | 23 | // func Register(c *fiber.Ctx) error { 24 | // var req request.Register 25 | // if err := core.ParseRequest(c, &req); err != nil { 26 | 27 | // return err 28 | // } 29 | 30 | // err := biz.Register(c.Context(), req) 31 | // if err != nil { 32 | // return err 33 | // } 34 | // return core.SuccessResp(c) 35 | // } 36 | 37 | // func UpdateMe(c *fiber.Ctx) error { 38 | // var req request.UpdateMe 39 | // if err := core.ParseRequest(c, &req); err != nil { 40 | // return err 41 | // } 42 | // user := biz.LocalUser(c) 43 | // err := biz.UpdateMe(c.Context(), req, user.ID) 44 | // if err != nil { 45 | // return err 46 | // } 47 | // return core.SuccessResp(c) 48 | // } 49 | 50 | // func ChangeMyPassword(c *fiber.Ctx) error { 51 | 52 | // var req request.ChangeMyPassword 53 | // if err := core.ParseRequest(c, &req); err != nil { 54 | // return err 55 | // } 56 | // user := biz.LocalUser(c) 57 | 58 | // err := biz.ChangeMyPassword(c.Context(), req, user.Username) 59 | // if err != nil { 60 | 61 | // return err 62 | // } 63 | // return core.SuccessResp(c) 64 | 65 | // } 66 | 67 | // func GetMyPermissions(c *fiber.Ctx) error { 68 | // user := biz.LocalUser(c) 69 | 70 | // data, err := biz.GetMyPermissions(c.Context(), user.ID) 71 | // if err != nil { 72 | 73 | // return err 74 | // } 75 | // return core.SetData(c, data) 76 | 77 | // } 78 | 79 | // func GetMyInfomation(c *fiber.Ctx) error { 80 | // user := biz.LocalUser(c) 81 | // data, err := biz.GetMyInfomation(c.Context(), user.ID) 82 | // if err != nil { 83 | 84 | // return err 85 | // } 86 | // return core.SetData(c, data) 87 | 88 | // } 89 | 90 | // //TODO 对cms意义并不大,先不实现 91 | // func RefreshToken(c *fiber.Ctx) error { 92 | // return nil 93 | // } 94 | -------------------------------------------------------------------------------- /pkg/errcode/message.go: -------------------------------------------------------------------------------- 1 | package errcode 2 | 3 | 4 | 5 | const ( 6 | AuthCheckTokenFail = 10000 7 | AuthCheckTokenTimeout = 10001 8 | ErrorAuthToken = 10002 9 | TimeoutAuthToken = 10003 10 | ErrorPassWord = 10004 11 | UserFound = 10005 12 | UserNotFound = 10006 13 | BookNotFound = 20000 14 | BookTitleRepetition = 20001 15 | GroupNotFound = 30000 16 | GroupFound = 30001 17 | RootGroupNotAllowDelete = 30002 18 | GuestGroupNotAllowDelete = 30003 19 | PermissionNotFound = 30004 20 | UserPermissionRequired = 40000 21 | UserNoPermission = 40001 22 | ) 23 | 24 | func init() { 25 | // core.CodeMapping = map[int]string{ 26 | // AuthCheckTokenFail: "Token鉴权失败", 27 | // AuthCheckTokenTimeout: "Token已超时", 28 | // ErrorAuthToken: "Token错误", 29 | // ErrorPassWord: "密码错误", 30 | // UserFound: "用户已存在", 31 | // UserNotFound: "用户不存在", 32 | // BookNotFound: "书籍不存在", 33 | // BookTitleRepetition: "书籍标题重复", 34 | // GroupNotFound: "分组不存在", 35 | // RootGroupNotAllowDelete: "root分组不允许删除", 36 | // GuestGroupNotAllowDelete: "guest分组不允许删除", 37 | // GroupFound: "分组已存在", 38 | // PermissionNotFound: "权限不存在", 39 | // UserPermissionRequired: "用户权限必须存在", 40 | // UserNoPermission: "用户没有权限访问", 41 | // } 42 | } 43 | -------------------------------------------------------------------------------- /pkg/lib/upload.go: -------------------------------------------------------------------------------- 1 | package lib 2 | 3 | import ( 4 | "io" 5 | 6 | 7 | "mime/multipart" 8 | "os" 9 | "path" 10 | "strings" 11 | ) 12 | 13 | type FileType int 14 | 15 | const ( 16 | TypeImage FileType = iota + 1 17 | TypePng FileType = iota + 2 18 | ) 19 | 20 | func GetFileName(name string) string { 21 | ext := GetFileExt(name) 22 | fileName := strings.TrimSuffix(name, ext) 23 | //fileName = utils.EncodeMD5(fileName) 24 | return fileName + ext 25 | } 26 | 27 | func GetFileExt(name string) string { 28 | return path.Ext(name) 29 | } 30 | 31 | func CheckSavePath(dst string) bool { 32 | _, err := os.Stat(dst) 33 | return os.IsNotExist(err) 34 | } 35 | 36 | func CheckContainExt(t FileType, name string) bool { 37 | ext := GetFileExt(name) 38 | ext = strings.ToUpper(ext) 39 | switch t { 40 | case TypeImage: 41 | for _, allowExt := range []string{} { 42 | if strings.ToUpper(allowExt) == ext { 43 | return true 44 | } 45 | } 46 | 47 | } 48 | 49 | return false 50 | } 51 | 52 | func CheckMaxSize(t FileType, f multipart.File) bool { 53 | content, _ := io.ReadAll(f) 54 | size := len(content) 55 | switch t { 56 | case TypeImage: 57 | if size >= 1*1024*1024 { 58 | return true 59 | } 60 | } 61 | 62 | return false 63 | } 64 | 65 | func CheckPermission(dst string) bool { 66 | _, err := os.Stat(dst) 67 | 68 | return os.IsPermission(err) 69 | } 70 | 71 | func CreateSavePath(dst string, perm os.FileMode) error { 72 | err := os.MkdirAll(dst, perm) 73 | if err != nil { 74 | return err 75 | } 76 | 77 | return nil 78 | } 79 | 80 | func SaveFile(file *multipart.FileHeader, dst string) error { 81 | src, err := file.Open() 82 | if err != nil { 83 | return err 84 | } 85 | defer src.Close() 86 | 87 | out, err := os.Create(dst) 88 | if err != nil { 89 | return err 90 | } 91 | defer out.Close() 92 | 93 | _, err = io.Copy(out, src) 94 | return err 95 | } 96 | -------------------------------------------------------------------------------- /pkg/lib/wechat.go: -------------------------------------------------------------------------------- 1 | package lib 2 | 3 | import ( 4 | "crypto/aes" 5 | "crypto/cipher" 6 | "encoding/base64" 7 | "fmt" 8 | ) 9 | 10 | // DecodeWeAppUserInfo 解密微信小程序用户信息 11 | func DecodeWeAppUserInfo(encryptedData string, sessionKey string, iv string) (result []byte, err error) { 12 | bytes, err := base64.StdEncoding.DecodeString(encryptedData) 13 | if err != nil { 14 | fmt.Println("encryptedData: ", encryptedData, "\n", err.Error()) 15 | return nil, err 16 | } 17 | 18 | key, keyErr := base64.StdEncoding.DecodeString(sessionKey) 19 | if keyErr != nil { 20 | fmt.Println("sessionKey: ", sessionKey, "\n", keyErr.Error()) 21 | return nil, keyErr 22 | } 23 | 24 | theIV, ivErr := base64.StdEncoding.DecodeString(iv) 25 | if ivErr != nil { 26 | fmt.Println("iv: ", iv, "\n", ivErr.Error()) 27 | return nil, ivErr 28 | } 29 | 30 | result, err = AESDecrypt(bytes, key, theIV) 31 | return 32 | } 33 | 34 | func AESDecrypt(cipherText, key, iv []byte) ([]byte, error) { 35 | block, err := aes.NewCipher(key) //选择加密算法 36 | if err != nil { 37 | return nil, err 38 | } 39 | blockModel := cipher.NewCBCDecrypter(block, iv) 40 | plantText := make([]byte, len(cipherText)) 41 | blockModel.CryptBlocks(plantText, cipherText) 42 | //if len(plantText)==0{ 43 | // return nil,errors.New("invalid plantText") 44 | //} 45 | for i, ch := range plantText { 46 | if ch == '\x0e' { 47 | plantText[i] = ' ' 48 | } 49 | } 50 | //plantText = PKCS7UnPadding(plantText, block.BlockSize()) 51 | return plantText, nil 52 | } 53 | 54 | func PKCS7UnPadding(plantText []byte, blockSize int) []byte { 55 | length := len(plantText) 56 | unpadding := int(plantText[length-1]) 57 | return plantText[:(length - unpadding)] 58 | } 59 | -------------------------------------------------------------------------------- /test/helper.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "net/http" 7 | "net/http/httptest" 8 | ) 9 | 10 | type TestCase struct { 11 | code int // 状态码 12 | param string // 参数 13 | method string // 请求类型 14 | desc string // 描述 15 | showBody bool // 是否展示返回 16 | errMsg string // 错误信息 17 | url string // 链接 18 | contentType string // 19 | ext1 interface{} // 自定义1 20 | ext2 interface{} // 自定义2 21 | } 22 | 23 | func NewBufferString(body string) io.Reader { 24 | return bytes.NewBufferString(body) 25 | } 26 | 27 | func PerformRequest(mothod, url, contentType string, body string) (r *http.Request, w *httptest.ResponseRecorder) { 28 | return 29 | } 30 | -------------------------------------------------------------------------------- /test/log_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestGetLogUsers(t *testing.T) { 9 | fmt.Printf("\033[35mGoal run %s.\033[0m\n", "dir") 10 | // type args struct { 11 | // c *fiber.Ctx 12 | // } 13 | // tests := []struct { 14 | // name string 15 | // args args 16 | // wantErr bool 17 | // }{ 18 | // // TODO: Add test cases. 19 | // } 20 | // for _, tt := range tests { 21 | // t.Run(tt.name, func(t *testing.T) { 22 | // if err := api.GetLogUsers(tt.args.c); (err != nil) != tt.wantErr { 23 | // t.Errorf("GetLogUsers() error = %v, wantErr %v", err, tt.wantErr) 24 | // } 25 | // }) 26 | // } 27 | } 28 | -------------------------------------------------------------------------------- /test/main_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "fmt" 5 | 6 | "os" 7 | "testing" 8 | ) 9 | 10 | func setup() { 11 | 12 | 13 | //fmt.Println(global.JWTSetting.Secret) 14 | fmt.Println("Before all tests") 15 | } 16 | 17 | func teardown() { 18 | fmt.Println("After all tests") 19 | } 20 | func TestMain(m *testing.M) { 21 | setup() 22 | fmt.Println("Test begins....") 23 | code := m.Run() // 如果不加这句,只会执行Main 24 | teardown() 25 | os.Exit(code) 26 | } 27 | -------------------------------------------------------------------------------- /test/user_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io/ioutil" 7 | "net/http" 8 | "testing" 9 | ) 10 | 11 | type Categories struct { 12 | ID int 13 | Pid int 14 | Name string 15 | Children []Categories 16 | } 17 | 18 | func getNode(list []Categories, pid int) (l []Categories) { 19 | for _, val := range list { 20 | if val.Pid == pid { 21 | if pid == 0 { 22 | // 顶层 23 | l = append(l, val) 24 | } else { 25 | var children []Categories 26 | child := val 27 | children = append(children, child) 28 | } 29 | } 30 | } 31 | return 32 | } 33 | 34 | func Tree(list []Categories, pid int) (newList []Categories) { 35 | for _, v := range list { 36 | if v.Pid == pid { 37 | child := getNode(list, v.ID) 38 | node := Categories{ 39 | ID: v.ID, 40 | Name: v.Name, 41 | Pid: v.Pid, 42 | } 43 | node.Children = child 44 | newList = append(newList, node) 45 | } 46 | } 47 | return 48 | } 49 | 50 | func TestAddUsers(t *testing.T) { 51 | categories := []Categories{ 52 | {ID: 1, Pid: 0, Name: "电脑"}, 53 | {ID: 2, Pid: 0, Name: "手机"}, 54 | {ID: 3, Pid: 1, Name: "笔记本"}, 55 | {ID: 4, Pid: 1, Name: "台式机"}, 56 | {ID: 5, Pid: 2, Name: "智能机"}, 57 | {ID: 6, Pid: 2, Name: "功能机"}, 58 | {ID: 7, Pid: 3, Name: "超级本"}, 59 | {ID: 8, Pid: 3, Name: "游戏本"}, 60 | } 61 | m := Tree(categories, 0) 62 | 63 | fmt.Println(m) 64 | } 65 | 66 | type AlbumResponse struct { 67 | Id int64 `json:"id"` 68 | Name string `json:"name"` 69 | IssueDate string `json:"issue_date"` 70 | IssueTime string `json:"issue_time"` 71 | } 72 | 73 | type Response struct { 74 | Code int `json:"code"` 75 | Message string `json:"message"` 76 | Data PageResponse `json:"data"` 77 | } 78 | 79 | type PageResponse struct { 80 | Items []AlbumResponse `json:"items"` 81 | Total int64 `json:"total"` 82 | } 83 | 84 | func do(url string) []AlbumResponse { 85 | rsps, err := http.Get(url) 86 | if err != nil { 87 | fmt.Println("Request failed:", err) 88 | return nil 89 | } 90 | defer rsps.Body.Close() 91 | 92 | body, err := ioutil.ReadAll(rsps.Body) 93 | if err != nil { 94 | fmt.Println("Read body failed:", err) 95 | return nil 96 | } 97 | var resp Response 98 | json.Unmarshal(body, &resp) 99 | return resp.Data.Items 100 | } 101 | 102 | func TestUserAll(t *testing.T) { 103 | } 104 | --------------------------------------------------------------------------------