add: user module
This commit is contained in:
parent
bf7c262d78
commit
57f071922e
11
README.md
11
README.md
|
@ -1,7 +1,7 @@
|
|||
<!--
|
||||
* @Date: 2021-03-21 19:54:57
|
||||
* @LastEditors: viletyy
|
||||
* @LastEditTime: 2021-06-15 00:19:24
|
||||
* @LastEditTime: 2021-07-09 14:48:06
|
||||
* @FilePath: /potato/README.md
|
||||
-->
|
||||
# Potato
|
||||
|
@ -10,13 +10,13 @@
|
|||
|
||||
Go项目脚手架
|
||||
|
||||
基于gin、gorm、zap的脚手架
|
||||
基于gin、gorm、zap、cron的脚手架
|
||||
|
||||
本脚手架包含以下内容:
|
||||
|
||||
1. mvc结构。
|
||||
2. swagger接口文档。
|
||||
3. 配置、数据库、redis、日志、工具库封装。
|
||||
3. 配置、数据库、redis、日志、工具库、后台任务封装。
|
||||
4. 单点登陆(jwt)。
|
||||
|
||||
## 内容列表
|
||||
|
@ -40,6 +40,7 @@ potato
|
|||
├── internal(内部模块)
|
||||
│ ├── controller(控制器层,用于存放控制器)
|
||||
│ ├── dao(数据访问层,所有与数据相关等操作都会在dao层进行)
|
||||
│ ├── job(后台任务)
|
||||
│ ├── middleware(HTTP中间件)
|
||||
│ ├── model(模型层,用于存放model对象)
|
||||
│ ├── routers(路由相关逻辑处理)
|
||||
|
@ -82,8 +83,11 @@ jaegertracing/all-in-one:1.16
|
|||
## 使用说明
|
||||
|
||||
```sh
|
||||
# 启动项目
|
||||
$ go build -o potato main.go
|
||||
$ ./potato
|
||||
# 生成api文档
|
||||
$ swag init
|
||||
```
|
||||
|
||||
## 相关仓库
|
||||
|
@ -91,6 +95,7 @@ $ ./potato
|
|||
- [Gin](https://github.com/gin-gonic/gin) — Web Framework
|
||||
- [Gorm](https://github.com/jinzhu/gorm) — ORM
|
||||
- [Swag](https://github.com/swaggo/swag) - RESTful API Doc
|
||||
- [Cron](https://github.com/robfig/cron) - A cron library
|
||||
|
||||
## 如何贡献
|
||||
|
||||
|
|
354
docs/docs.go
354
docs/docs.go
|
@ -59,6 +59,82 @@ var doc = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/user/login": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"summary": "用户登录",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "用户名",
|
||||
"name": "username",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "密码",
|
||||
"name": "password",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errcode.Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/register": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"summary": "用户注册",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "用户名",
|
||||
"name": "username",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "密码",
|
||||
"name": "password",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "昵称",
|
||||
"name": "nickname",
|
||||
"in": "formData"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errcode.Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/upload": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
|
@ -101,6 +177,248 @@ var doc = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/v1/users": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"users"
|
||||
],
|
||||
"summary": "用户列表",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "auth token",
|
||||
"name": "token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "页码",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "每页数量",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"maxLength": 30,
|
||||
"type": "string",
|
||||
"description": "用户名",
|
||||
"name": "username",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"maxLength": 30,
|
||||
"type": "string",
|
||||
"description": "昵称",
|
||||
"name": "nickname",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.User"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"users"
|
||||
],
|
||||
"summary": "新增用户",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "auth token",
|
||||
"name": "token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"maxLength": 30,
|
||||
"minLength": 1,
|
||||
"type": "string",
|
||||
"description": "用户名",
|
||||
"name": "username",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"maxLength": 18,
|
||||
"minLength": 1,
|
||||
"type": "string",
|
||||
"description": "密码",
|
||||
"name": "password",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"maxLength": 30,
|
||||
"type": "string",
|
||||
"description": "昵称",
|
||||
"name": "nickname",
|
||||
"in": "formData"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.User"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/users/{id}": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"users"
|
||||
],
|
||||
"summary": "用户",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "auth token",
|
||||
"name": "token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "用户 ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.User"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"users"
|
||||
],
|
||||
"summary": "删除用户",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "auth token",
|
||||
"name": "token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "用户ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.User"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"users"
|
||||
],
|
||||
"summary": "更新用户",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "auth token",
|
||||
"name": "token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "用户ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"maxLength": 30,
|
||||
"type": "string",
|
||||
"description": "用户名",
|
||||
"name": "username",
|
||||
"in": "formData"
|
||||
},
|
||||
{
|
||||
"maxLength": 18,
|
||||
"type": "string",
|
||||
"description": "密码",
|
||||
"name": "password",
|
||||
"in": "formData"
|
||||
},
|
||||
{
|
||||
"maxLength": 30,
|
||||
"type": "string",
|
||||
"description": "昵称",
|
||||
"name": "nickname",
|
||||
"in": "formData"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.User"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/vendors": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
|
@ -328,7 +646,18 @@ var doc = `{
|
|||
},
|
||||
"definitions": {
|
||||
"basic.Vendor": {
|
||||
"type": "object"
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"uuid": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"errcode.Error": {
|
||||
"type": "object",
|
||||
|
@ -343,6 +672,29 @@ var doc = `{
|
|||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.User": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"is_admin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"nickname": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
|
|
@ -43,6 +43,82 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/user/login": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"summary": "用户登录",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "用户名",
|
||||
"name": "username",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "密码",
|
||||
"name": "password",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errcode.Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/register": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"summary": "用户注册",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "用户名",
|
||||
"name": "username",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "密码",
|
||||
"name": "password",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "昵称",
|
||||
"name": "nickname",
|
||||
"in": "formData"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errcode.Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/upload": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
|
@ -85,6 +161,248 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/v1/users": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"users"
|
||||
],
|
||||
"summary": "用户列表",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "auth token",
|
||||
"name": "token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "页码",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "每页数量",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"maxLength": 30,
|
||||
"type": "string",
|
||||
"description": "用户名",
|
||||
"name": "username",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"maxLength": 30,
|
||||
"type": "string",
|
||||
"description": "昵称",
|
||||
"name": "nickname",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.User"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"users"
|
||||
],
|
||||
"summary": "新增用户",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "auth token",
|
||||
"name": "token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"maxLength": 30,
|
||||
"minLength": 1,
|
||||
"type": "string",
|
||||
"description": "用户名",
|
||||
"name": "username",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"maxLength": 18,
|
||||
"minLength": 1,
|
||||
"type": "string",
|
||||
"description": "密码",
|
||||
"name": "password",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"maxLength": 30,
|
||||
"type": "string",
|
||||
"description": "昵称",
|
||||
"name": "nickname",
|
||||
"in": "formData"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.User"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/users/{id}": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"users"
|
||||
],
|
||||
"summary": "用户",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "auth token",
|
||||
"name": "token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "用户 ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.User"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"users"
|
||||
],
|
||||
"summary": "删除用户",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "auth token",
|
||||
"name": "token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "用户ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.User"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"users"
|
||||
],
|
||||
"summary": "更新用户",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "auth token",
|
||||
"name": "token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "用户ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"maxLength": 30,
|
||||
"type": "string",
|
||||
"description": "用户名",
|
||||
"name": "username",
|
||||
"in": "formData"
|
||||
},
|
||||
{
|
||||
"maxLength": 18,
|
||||
"type": "string",
|
||||
"description": "密码",
|
||||
"name": "password",
|
||||
"in": "formData"
|
||||
},
|
||||
{
|
||||
"maxLength": 30,
|
||||
"type": "string",
|
||||
"description": "昵称",
|
||||
"name": "nickname",
|
||||
"in": "formData"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "请求成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.User"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/vendors": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
|
@ -312,7 +630,18 @@
|
|||
},
|
||||
"definitions": {
|
||||
"basic.Vendor": {
|
||||
"type": "object"
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"uuid": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"errcode.Error": {
|
||||
"type": "object",
|
||||
|
@ -327,6 +656,29 @@
|
|||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.User": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"is_admin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"nickname": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,13 @@
|
|||
basePath: /api
|
||||
definitions:
|
||||
basic.Vendor:
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
uuid:
|
||||
type: integer
|
||||
type: object
|
||||
errcode.Error:
|
||||
properties:
|
||||
|
@ -11,6 +18,21 @@ definitions:
|
|||
msg:
|
||||
type: string
|
||||
type: object
|
||||
model.User:
|
||||
properties:
|
||||
created_at:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
is_admin:
|
||||
type: boolean
|
||||
nickname:
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
type: object
|
||||
info:
|
||||
contact: {}
|
||||
description: This is a potato use golang
|
||||
|
@ -40,6 +62,56 @@ paths:
|
|||
schema:
|
||||
$ref: '#/definitions/errcode.Error'
|
||||
summary: 鉴权验证
|
||||
/user/login:
|
||||
post:
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
parameters:
|
||||
- description: 用户名
|
||||
in: formData
|
||||
name: username
|
||||
required: true
|
||||
type: string
|
||||
- description: 密码
|
||||
in: formData
|
||||
name: password
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 请求成功
|
||||
schema:
|
||||
$ref: '#/definitions/errcode.Error'
|
||||
summary: 用户登录
|
||||
/user/register:
|
||||
post:
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
parameters:
|
||||
- description: 用户名
|
||||
in: formData
|
||||
name: username
|
||||
required: true
|
||||
type: string
|
||||
- description: 密码
|
||||
in: formData
|
||||
name: password
|
||||
required: true
|
||||
type: string
|
||||
- description: 昵称
|
||||
in: formData
|
||||
name: nickname
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 请求成功
|
||||
schema:
|
||||
$ref: '#/definitions/errcode.Error'
|
||||
summary: 用户注册
|
||||
/v1/upload:
|
||||
post:
|
||||
consumes:
|
||||
|
@ -68,6 +140,170 @@ paths:
|
|||
schema:
|
||||
$ref: '#/definitions/errcode.Error'
|
||||
summary: 上传文件
|
||||
/v1/users:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: auth token
|
||||
in: header
|
||||
name: token
|
||||
required: true
|
||||
type: string
|
||||
- description: 页码
|
||||
in: query
|
||||
name: page
|
||||
type: integer
|
||||
- description: 每页数量
|
||||
in: query
|
||||
name: page_size
|
||||
type: integer
|
||||
- description: 用户名
|
||||
in: query
|
||||
maxLength: 30
|
||||
name: username
|
||||
type: string
|
||||
- description: 昵称
|
||||
in: query
|
||||
maxLength: 30
|
||||
name: nickname
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 请求成功
|
||||
schema:
|
||||
$ref: '#/definitions/model.User'
|
||||
summary: 用户列表
|
||||
tags:
|
||||
- users
|
||||
post:
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
parameters:
|
||||
- description: auth token
|
||||
in: header
|
||||
name: token
|
||||
required: true
|
||||
type: string
|
||||
- description: 用户名
|
||||
in: formData
|
||||
maxLength: 30
|
||||
minLength: 1
|
||||
name: username
|
||||
required: true
|
||||
type: string
|
||||
- description: 密码
|
||||
in: formData
|
||||
maxLength: 18
|
||||
minLength: 1
|
||||
name: password
|
||||
required: true
|
||||
type: string
|
||||
- description: 昵称
|
||||
in: formData
|
||||
maxLength: 30
|
||||
name: nickname
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 请求成功
|
||||
schema:
|
||||
$ref: '#/definitions/model.User'
|
||||
summary: 新增用户
|
||||
tags:
|
||||
- users
|
||||
/v1/users/{id}:
|
||||
delete:
|
||||
consumes:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: auth token
|
||||
in: header
|
||||
name: token
|
||||
required: true
|
||||
type: string
|
||||
- description: 用户ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 请求成功
|
||||
schema:
|
||||
$ref: '#/definitions/model.User'
|
||||
summary: 删除用户
|
||||
tags:
|
||||
- users
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: auth token
|
||||
in: header
|
||||
name: token
|
||||
required: true
|
||||
type: string
|
||||
- description: 用户 ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 请求成功
|
||||
schema:
|
||||
$ref: '#/definitions/model.User'
|
||||
summary: 用户
|
||||
tags:
|
||||
- users
|
||||
patch:
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
parameters:
|
||||
- description: auth token
|
||||
in: header
|
||||
name: token
|
||||
required: true
|
||||
type: string
|
||||
- description: 用户ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
- description: 用户名
|
||||
in: formData
|
||||
maxLength: 30
|
||||
name: username
|
||||
type: string
|
||||
- description: 密码
|
||||
in: formData
|
||||
maxLength: 18
|
||||
name: password
|
||||
type: string
|
||||
- description: 昵称
|
||||
in: formData
|
||||
maxLength: 30
|
||||
name: nickname
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 请求成功
|
||||
schema:
|
||||
$ref: '#/definitions/model.User'
|
||||
summary: 更新用户
|
||||
tags:
|
||||
- users
|
||||
/v1/vendors:
|
||||
get:
|
||||
consumes:
|
||||
|
|
1
go.mod
1
go.mod
|
@ -22,7 +22,6 @@ require (
|
|||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/robfig/cron/v3 v3.0.0
|
||||
github.com/smacker/opentracing-gorm v0.0.0-20181207094635-cd4974441042 // indirect
|
||||
github.com/soheilhy/cmux v0.1.5
|
||||
github.com/spf13/viper v1.7.1
|
||||
github.com/swaggo/gin-swagger v1.3.0
|
||||
github.com/swaggo/swag v1.7.0
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @Date: 2021-03-22 10:12:38
|
||||
* @LastEditors: viletyy
|
||||
* @LastEditTime: 2021-06-14 21:11:29
|
||||
* @LastEditTime: 2021-07-09 14:27:45
|
||||
* @FilePath: /potato/initialize/gorm.go
|
||||
*/
|
||||
package initialize
|
||||
|
@ -60,8 +60,9 @@ func GormSet(db *gorm.DB) {
|
|||
|
||||
// 设置迁移
|
||||
db.AutoMigrate(
|
||||
basic.Vendor{},
|
||||
model.Auth{},
|
||||
&basic.Vendor{},
|
||||
&model.User{},
|
||||
&model.Auth{},
|
||||
)
|
||||
|
||||
// 设置空闲连接池中的最大连接数
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* @Date: 2021-07-09 14:44:50
|
||||
* @LastEditors: viletyy
|
||||
* @LastEditTime: 2021-07-09 14:45:52
|
||||
* @FilePath: /potato/internal/controller/api/user.go
|
||||
*/
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/viletyy/potato/global"
|
||||
"github.com/viletyy/potato/internal/service"
|
||||
"github.com/viletyy/potato/pkg/app"
|
||||
"github.com/viletyy/potato/pkg/errcode"
|
||||
)
|
||||
|
||||
// @Summary 用户注册
|
||||
// @Description
|
||||
// @Accept mpfd
|
||||
// @Produce json
|
||||
// @Param username formData string true "用户名"
|
||||
// @Param password formData string true "密码"
|
||||
// @Param nickname formData string false "昵称"
|
||||
// @Success 200 {object} errcode.Error "请求成功"
|
||||
// @Router /user/register [post]
|
||||
func UserRegister(c *gin.Context) {
|
||||
param := service.UserRegisterRequest{}
|
||||
response := app.NewResponse(c)
|
||||
valid, errs := app.BindAndValid(c, ¶m)
|
||||
if !valid {
|
||||
global.GO_LOG.Sugar().Errorf("app.BindAndValid errs: %v", errs)
|
||||
response.ToResponseErrors(errs.Errors())
|
||||
return
|
||||
}
|
||||
|
||||
svc := service.New(c.Request.Context())
|
||||
dbUser, err := svc.RegisterUser(¶m)
|
||||
if err != nil {
|
||||
global.GO_LOG.Sugar().Errorf("svc.RegisterUser err: %v", err)
|
||||
response.ToErrorResponse(errcode.ErrorRegisterUserError)
|
||||
return
|
||||
}
|
||||
|
||||
response.ToResponse(dbUser)
|
||||
}
|
||||
|
||||
// @Summary 用户登录
|
||||
// @Description
|
||||
// @Accept mpfd
|
||||
// @Produce json
|
||||
// @Param username formData string true "用户名"
|
||||
// @Param password formData string true "密码"
|
||||
// @Success 200 {object} errcode.Error "请求成功"
|
||||
// @Router /user/login [post]
|
||||
func UserLogin(c *gin.Context) {
|
||||
param := service.UserLoginRequest{}
|
||||
response := app.NewResponse(c)
|
||||
valid, errs := app.BindAndValid(c, ¶m)
|
||||
if !valid {
|
||||
global.GO_LOG.Sugar().Errorf("app.BindAndValid errs: %v", errs)
|
||||
response.ToResponseErrors(errs.Errors())
|
||||
return
|
||||
}
|
||||
|
||||
svc := service.New(c.Request.Context())
|
||||
dbUser, err := svc.LoginUser(¶m)
|
||||
if err != nil {
|
||||
global.GO_LOG.Sugar().Errorf("svc.LoginUser err: %v", err)
|
||||
response.ToErrorResponse(errcode.ErrorLoginUserError)
|
||||
return
|
||||
}
|
||||
|
||||
token, err := app.GenerateToken(dbUser.Username, dbUser.Password)
|
||||
if err != nil {
|
||||
global.GO_LOG.Sugar().Errorf("app.GenerateToken err: %v", err)
|
||||
response.ToErrorResponse(errcode.UnauthorizedTokenGenerate)
|
||||
return
|
||||
}
|
||||
|
||||
response.ToResponse(gin.H{
|
||||
"username": dbUser.Username,
|
||||
"is_admin": dbUser.IsAdmin,
|
||||
"token": token,
|
||||
})
|
||||
}
|
|
@ -1,7 +1,214 @@
|
|||
/*
|
||||
* @Date: 2021-03-21 19:54:57
|
||||
* @LastEditors: viletyy
|
||||
* @LastEditTime: 2021-06-10 19:02:24
|
||||
* @LastEditTime: 2021-07-09 14:32:27
|
||||
* @FilePath: /potato/internal/controller/api/v1/user.go
|
||||
*/
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/viletyy/potato/global"
|
||||
"github.com/viletyy/potato/internal/service"
|
||||
"github.com/viletyy/potato/pkg/app"
|
||||
"github.com/viletyy/potato/pkg/errcode"
|
||||
"github.com/viletyy/yolk/convert"
|
||||
)
|
||||
|
||||
type User struct{}
|
||||
|
||||
func NewUser() User {
|
||||
return User{}
|
||||
}
|
||||
|
||||
// @Summary 用户列表
|
||||
// @Tags users
|
||||
// @Description
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param token header string true "auth token"
|
||||
// @Param page query int false "页码"
|
||||
// @Param page_size query int false "每页数量"
|
||||
// @Param username query string false "用户名" maxlength(30)
|
||||
// @Param nickname query string false "昵称" maxlength(30)
|
||||
// @Success 200 {object} model.User "请求成功"
|
||||
// @Router /v1/users [get]
|
||||
func (user User) List(c *gin.Context) {
|
||||
param := service.UserListRequest{}
|
||||
response := app.NewResponse(c)
|
||||
valid, errs := app.BindAndValid(c, ¶m)
|
||||
if !valid {
|
||||
global.GO_LOG.Sugar().Errorf("app.BindAndValid errs: %v", errs)
|
||||
response.ToResponseErrors(errs.Errors())
|
||||
return
|
||||
}
|
||||
|
||||
svc := service.New(c.Request.Context())
|
||||
paper := app.Pager{Page: app.GetPage(c), PageSize: app.GetPageSize(c)}
|
||||
total, err := svc.CountUser(&service.CountUserRequest{Username: param.Username, Nickname: param.Nickname})
|
||||
if err != nil {
|
||||
global.GO_LOG.Sugar().Errorf("svc.CountUser err: %v", err)
|
||||
response.ToErrorResponse(errcode.ErrorCountUserFail)
|
||||
return
|
||||
}
|
||||
|
||||
users, err := svc.GetUserList(¶m, &paper)
|
||||
if err != nil {
|
||||
global.GO_LOG.Sugar().Errorf("svc.GetUserList err: %v", err)
|
||||
response.ToErrorResponse(errcode.ErrorGetUserListFail)
|
||||
return
|
||||
}
|
||||
|
||||
response.ToResponseList(users, total)
|
||||
}
|
||||
|
||||
// @Summary 用户
|
||||
// @Tags users
|
||||
// @Description
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param token header string true "auth token"
|
||||
// @Param id path int true "用户 ID"
|
||||
// @Success 200 {object} model.User "请求成功"
|
||||
// @Router /v1/users/{id} [get]
|
||||
func (user User) Get(c *gin.Context) {
|
||||
userID, err := convert.StrTo(c.Param("id")).Int64()
|
||||
response := app.NewResponse(c)
|
||||
if err != nil {
|
||||
global.GO_LOG.Sugar().Errorf("convert.StrTo err: %v", err)
|
||||
response.ToErrorResponse(errcode.InvalidParams)
|
||||
return
|
||||
}
|
||||
param := service.UserRequest{ID: userID}
|
||||
valid, errs := app.BindAndValid(c, ¶m)
|
||||
if !valid {
|
||||
global.GO_LOG.Sugar().Errorf("app.BindAndValid errs: %v", errs)
|
||||
response.ToResponseErrors(errs.Errors())
|
||||
return
|
||||
}
|
||||
|
||||
svc := service.New(c.Request.Context())
|
||||
dbUser, err := svc.GetUser(¶m)
|
||||
if err != nil {
|
||||
global.GO_LOG.Sugar().Errorf("svc.GetUser err: %v", err)
|
||||
response.ToErrorResponse(errcode.ErrorGetUserFail)
|
||||
return
|
||||
}
|
||||
|
||||
response.ToResponse(dbUser)
|
||||
}
|
||||
|
||||
// @Summary 新增用户
|
||||
// @Tags users
|
||||
// @Description
|
||||
// @Accept mpfd
|
||||
// @Produce json
|
||||
// @Param token header string true "auth token"
|
||||
// @Param username formData string true "用户名" minlength(1) maxlength(30)
|
||||
// @Param password formData string true "密码" minlength(1) maxlength(18)
|
||||
// @param nickname formData string false "昵称" maxlength(30)
|
||||
// @Success 200 {object} model.User "请求成功"
|
||||
// @Router /v1/users [post]
|
||||
func (user User) Create(c *gin.Context) {
|
||||
param := service.CreateUserRequest{}
|
||||
response := app.NewResponse(c)
|
||||
valid, errs := app.BindAndValid(c, ¶m)
|
||||
if !valid {
|
||||
global.GO_LOG.Sugar().Errorf("app.BindAndValid errs: %v", errs)
|
||||
response.ToResponseErrors(errs.Errors())
|
||||
return
|
||||
}
|
||||
|
||||
svc := service.New(c.Request.Context())
|
||||
dbUser, err := svc.CreateUser(¶m)
|
||||
if err != nil {
|
||||
global.GO_LOG.Sugar().Errorf("svc.CreateUser err: %v", err)
|
||||
response.ToErrorResponse(errcode.ErrorCreateUserFail)
|
||||
return
|
||||
}
|
||||
|
||||
response.ToResponse(dbUser)
|
||||
}
|
||||
|
||||
// @Summary 更新用户
|
||||
// @Tags users
|
||||
// @Description
|
||||
// @Accept mpfd
|
||||
// @Produce json
|
||||
// @Param token header string true "auth token"
|
||||
// @Param id path int true "用户ID"
|
||||
// @Param username formData string false "用户名" maxlength(30)
|
||||
// @Param password formData string false "密码" maxlength(18)
|
||||
// @param nickname formData string false "昵称" maxlength(30)
|
||||
// @Success 200 {object} model.User "请求成功"
|
||||
// @Router /v1/users/{id} [patch]
|
||||
func (user User) Update(c *gin.Context) {
|
||||
userID, err := convert.StrTo(c.Param("id")).Int64()
|
||||
response := app.NewResponse(c)
|
||||
if err != nil {
|
||||
global.GO_LOG.Sugar().Errorf("convert.StrTo err: %v", err)
|
||||
response.ToErrorResponse(errcode.InvalidParams)
|
||||
return
|
||||
}
|
||||
|
||||
param := service.UpdateUserRequest{ID: userID}
|
||||
valid, errs := app.BindAndValid(c, ¶m)
|
||||
if !valid {
|
||||
global.GO_LOG.Sugar().Errorf("app.BindAndValid errs: %v", errs)
|
||||
response.ToResponseErrors(errs)
|
||||
return
|
||||
}
|
||||
svc := service.New(c.Request.Context())
|
||||
dbUser, err := svc.UpdateUser(¶m)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
global.GO_LOG.Sugar().Errorf("svc.UpdateUser err: %v", err)
|
||||
response.ToErrorResponse(errcode.ErrorGetUserFail)
|
||||
return
|
||||
} else {
|
||||
global.GO_LOG.Sugar().Errorf("svc.UpdateUser err: %v", err)
|
||||
response.ToErrorResponse(errcode.ErrorUpdateUserFail)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
response.ToResponse(dbUser)
|
||||
}
|
||||
|
||||
// @Summary 删除用户
|
||||
// @Tags users
|
||||
// @Description
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param token header string true "auth token"
|
||||
// @Param id path int true "用户ID"
|
||||
// @Success 200 {object} model.User "请求成功"
|
||||
// @Router /v1/users/{id} [delete]
|
||||
func (user User) Delete(c *gin.Context) {
|
||||
userID, err := convert.StrTo(c.Param("id")).Int64()
|
||||
response := app.NewResponse(c)
|
||||
if err != nil {
|
||||
global.GO_LOG.Sugar().Errorf("convert.StrTo err: %v", err)
|
||||
response.ToErrorResponse(errcode.InvalidParams)
|
||||
return
|
||||
}
|
||||
|
||||
param := service.DeleteUserRequest{ID: userID}
|
||||
svc := service.New(c.Request.Context())
|
||||
dbUser, err := svc.DeleteUser(¶m)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
global.GO_LOG.Sugar().Errorf("svc.DeleteUser err: %v", err)
|
||||
response.ToErrorResponse(errcode.ErrorGetUserFail)
|
||||
return
|
||||
} else {
|
||||
global.GO_LOG.Sugar().Errorf("svc.DeleteUser err: %v", err)
|
||||
response.ToErrorResponse(errcode.ErrorDeleteUserFail)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
errcode.Success.Data = dbUser
|
||||
response.ToErrorResponse(errcode.Success)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* @Date: 2021-07-09 14:30:19
|
||||
* @LastEditors: viletyy
|
||||
* @LastEditTime: 2021-07-09 14:30:40
|
||||
* @FilePath: /potato/internal/dao/user.go
|
||||
*/
|
||||
package dao
|
||||
|
||||
import (
|
||||
"github.com/viletyy/potato/internal/model"
|
||||
"github.com/viletyy/potato/pkg/app"
|
||||
"github.com/viletyy/yolk/crypt"
|
||||
)
|
||||
|
||||
func (d *Dao) RegisterUser(username string, password string, nickname string) (model.User, error) {
|
||||
user := model.User{
|
||||
Username: username,
|
||||
Password: crypt.Md5Encode(password),
|
||||
Nickname: nickname,
|
||||
}
|
||||
|
||||
return user, user.Create(d.Engine)
|
||||
}
|
||||
|
||||
func (d *Dao) LoginUser(username string, password string) (model.User, error) {
|
||||
user := model.User{
|
||||
Username: username,
|
||||
Password: crypt.Md5Encode(password),
|
||||
}
|
||||
|
||||
return user.GetByUsernameAndPassword(d.Engine)
|
||||
}
|
||||
|
||||
func (d *Dao) CountUser(username, nickname string) (int, error) {
|
||||
vendor := model.User{Username: username, Nickname: nickname}
|
||||
return vendor.Count(d.Engine)
|
||||
}
|
||||
|
||||
func (d *Dao) GetUserList(username, nickname string, page, pageSize int) ([]model.User, error) {
|
||||
user := model.User{Username: username, Nickname: nickname}
|
||||
pageOffset := app.GetPageOffset(page, pageSize)
|
||||
return user.List(d.Engine, pageOffset, pageSize)
|
||||
}
|
||||
|
||||
func (d *Dao) GetUser(id int64) (model.User, error) {
|
||||
user := model.User{
|
||||
Model: &model.Model{ID: id},
|
||||
}
|
||||
|
||||
return user.Get(d.Engine)
|
||||
}
|
||||
|
||||
func (d *Dao) CreateUser(username, password, nickname string) (model.User, error) {
|
||||
user := model.User{
|
||||
Username: username,
|
||||
Password: crypt.Md5Encode(password),
|
||||
Nickname: nickname,
|
||||
}
|
||||
|
||||
return user, user.Create(d.Engine)
|
||||
}
|
||||
|
||||
func (d *Dao) UpdateUser(id int64, username, password, nickname string) (model.User, error) {
|
||||
|
||||
user := model.User{
|
||||
Username: username,
|
||||
Nickname: nickname,
|
||||
Model: &model.Model{ID: id},
|
||||
}
|
||||
|
||||
dbUser, err := user.Get(d.Engine)
|
||||
|
||||
if password == "" {
|
||||
user.Password = dbUser.Password
|
||||
} else {
|
||||
user.Password = crypt.Md5Encode(password)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return user, err
|
||||
}
|
||||
|
||||
return dbUser, user.Update(d.Engine)
|
||||
}
|
||||
|
||||
func (d *Dao) DeleteUser(id int64) (model.User, error) {
|
||||
user := model.User{
|
||||
Model: &model.Model{ID: id},
|
||||
}
|
||||
|
||||
dbUser, err := user.Get(d.Engine)
|
||||
|
||||
if err != nil {
|
||||
return user, err
|
||||
}
|
||||
|
||||
return dbUser, dbUser.Delete(d.Engine)
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
/*
|
||||
* @Date: 2021-03-21 19:54:57
|
||||
* @LastEditors: viletyy
|
||||
* @LastEditTime: 2021-06-11 10:38:24
|
||||
* @LastEditTime: 2021-07-09 14:31:04
|
||||
* @FilePath: /potato/internal/model/user.go
|
||||
*/
|
||||
package model
|
||||
|
||||
import "github.com/jinzhu/gorm"
|
||||
|
||||
type User struct {
|
||||
*Model
|
||||
|
||||
|
@ -14,3 +16,65 @@ type User struct {
|
|||
Nickname string `json:"nickname"`
|
||||
IsAdmin bool `json:"is_admin" gorm:"default: false"`
|
||||
}
|
||||
|
||||
func (u User) Count(db *gorm.DB) (int, error) {
|
||||
var count int
|
||||
if u.Username != "" {
|
||||
db = db.Where("username = ?", u.Username)
|
||||
}
|
||||
if u.Nickname != "" {
|
||||
db = db.Where("nickname = ?", u.Nickname)
|
||||
}
|
||||
if err := db.Model(&u).Count(&count).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (u User) List(db *gorm.DB, pageOffset, pageSize int) (users []User, err error) {
|
||||
if pageOffset >= 0 && pageSize > 0 {
|
||||
db = db.Offset(pageOffset).Limit(pageSize)
|
||||
}
|
||||
if u.Username != "" {
|
||||
db = db.Where("name = ?", u.Username)
|
||||
}
|
||||
if u.Nickname != "" {
|
||||
db = db.Where("nickname = ?", u.Nickname)
|
||||
}
|
||||
|
||||
if err = db.Find(&users).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (u User) GetByUsernameAndPassword(db *gorm.DB) (user User, err error) {
|
||||
if notFound := db.Where("username = ? AND password = ?", u.Username, u.Password).First(&user).RecordNotFound(); notFound {
|
||||
return u, gorm.ErrRecordNotFound
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (u User) Get(db *gorm.DB) (user User, err error) {
|
||||
if notFound := db.Where("id = ?", u.ID).First(&user).RecordNotFound(); notFound {
|
||||
return u, gorm.ErrRecordNotFound
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (u *User) Create(db *gorm.DB) error {
|
||||
return db.Create(u).Error
|
||||
}
|
||||
|
||||
func (u *User) Update(db *gorm.DB) error {
|
||||
err := db.Model(&User{}).Update(u).Error
|
||||
return err
|
||||
}
|
||||
|
||||
func (u *User) Delete(db *gorm.DB) error {
|
||||
return db.Where("id = ?", u.ID).Delete(u).Error
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @Date: 2021-03-21 19:54:57
|
||||
* @LastEditors: viletyy
|
||||
* @LastEditTime: 2021-06-14 23:32:23
|
||||
* @LastEditTime: 2021-07-09 14:44:37
|
||||
* @FilePath: /potato/internal/routers/router.go
|
||||
*/
|
||||
package routers
|
||||
|
@ -52,6 +52,8 @@ func InitRouter() *gin.Engine {
|
|||
Engine.StaticFS("/static", http.Dir(global.GO_CONFIG.App.UploadSavePath))
|
||||
|
||||
Engine.POST("/api/auth", api.GetAuth)
|
||||
Engine.POST("/api/user/register", api.UserRegister)
|
||||
Engine.POST("/api/user/login", api.UserLogin)
|
||||
Engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
|
||||
v1RouterGroup := Engine.Group("../api/v1")
|
||||
|
@ -59,6 +61,16 @@ func InitRouter() *gin.Engine {
|
|||
|
||||
upload := v1.NewUpload()
|
||||
v1RouterGroup.POST("/upload", upload.Create)
|
||||
|
||||
users := v1RouterGroup.Group("/users")
|
||||
user := v1.NewUser()
|
||||
{
|
||||
users.GET("", user.List)
|
||||
users.POST("", user.Create)
|
||||
users.GET("/:id", user.Get)
|
||||
users.PATCH("/:id", user.Update)
|
||||
users.DELETE("/:id", user.Delete)
|
||||
}
|
||||
V1InitBasicRouter()
|
||||
|
||||
return Engine
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* @Date: 2021-07-09 14:29:44
|
||||
* @LastEditors: viletyy
|
||||
* @LastEditTime: 2021-07-09 14:30:11
|
||||
* @FilePath: /potato/internal/service/user.go
|
||||
*/
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/viletyy/potato/internal/model"
|
||||
"github.com/viletyy/potato/pkg/app"
|
||||
)
|
||||
|
||||
type UserRegisterRequest struct {
|
||||
Username string `form:"username" json:"username" validate:"max=30"`
|
||||
Password string `form:"password" json:"password" validate:"max=18"`
|
||||
Nickname string `form:"nickname" json:"nickname" validate:"max=30"`
|
||||
}
|
||||
|
||||
type UserLoginRequest struct {
|
||||
Username string `form:"username" json:"username" validate:"max=30"`
|
||||
Password string `form:"password" json:"password" validate:"max=18"`
|
||||
}
|
||||
|
||||
type UserListRequest struct {
|
||||
Username string `form:"username" json:"username" validate:"max=30"`
|
||||
Nickname string `form:"nickname" json:"nickname" validate:"max=30"`
|
||||
}
|
||||
|
||||
type CountUserRequest struct {
|
||||
Username string `form:"username" json:"username" validate:"max=30"`
|
||||
Password string `form:"password" json:"password" validate:"max=18"`
|
||||
Nickname string `form:"nickname" json:"nickname" validate:"max=30"`
|
||||
}
|
||||
|
||||
type UserRequest struct {
|
||||
ID int64 `form:"id" json:"id" validate:"required,gte=1"`
|
||||
}
|
||||
|
||||
type CreateUserRequest struct {
|
||||
Username string `form:"username" json:"username" validate:"required,max=30"`
|
||||
Password string `form:"password" json:"password" validate:"required,max=18"`
|
||||
Nickname string `form:"nickname" json:"nickname" validate:"max=30"`
|
||||
}
|
||||
|
||||
type UpdateUserRequest struct {
|
||||
ID int64 `form:"id" json:"id" validate:"required,gte=1"`
|
||||
Username string `form:"username" json:"username" validate:"max=30"`
|
||||
Password string `form:"password" json:"password" validate:"max=18"`
|
||||
Nickname string `form:"nickname" json:"nickname" validate:"max=30"`
|
||||
}
|
||||
|
||||
type DeleteUserRequest struct {
|
||||
ID int64 `form:"id" json:"id" validate:"required,gte=1"`
|
||||
}
|
||||
|
||||
func (svc *Service) RegisterUser(param *UserRegisterRequest) (model.User, error) {
|
||||
return svc.Dao.RegisterUser(param.Username, param.Password, param.Nickname)
|
||||
}
|
||||
|
||||
func (svc *Service) LoginUser(param *UserLoginRequest) (model.User, error) {
|
||||
return svc.Dao.LoginUser(param.Username, param.Password)
|
||||
}
|
||||
|
||||
func (svc *Service) CountUser(param *CountUserRequest) (int, error) {
|
||||
return svc.Dao.CountUser(param.Username, param.Nickname)
|
||||
}
|
||||
|
||||
func (svc *Service) GetUserList(param *UserListRequest, pager *app.Pager) ([]model.User, error) {
|
||||
return svc.Dao.GetUserList(param.Username, param.Nickname, pager.Page, pager.PageSize)
|
||||
}
|
||||
|
||||
func (svc *Service) GetUser(param *UserRequest) (model.User, error) {
|
||||
return svc.Dao.GetUser(param.ID)
|
||||
}
|
||||
|
||||
func (svc *Service) CreateUser(param *CreateUserRequest) (model.User, error) {
|
||||
return svc.Dao.CreateUser(param.Username, param.Password, param.Nickname)
|
||||
}
|
||||
|
||||
func (svc *Service) UpdateUser(param *UpdateUserRequest) (model.User, error) {
|
||||
return svc.Dao.UpdateUser(param.ID, param.Username, param.Password, param.Nickname)
|
||||
}
|
||||
|
||||
func (svc *Service) DeleteUser(param *DeleteUserRequest) (model.User, error) {
|
||||
return svc.Dao.DeleteUser(param.ID)
|
||||
}
|
47
main.go
47
main.go
|
@ -1,16 +1,14 @@
|
|||
/*
|
||||
* @Date: 2021-03-21 19:54:57
|
||||
* @LastEditors: viletyy
|
||||
* @LastEditTime: 2021-07-08 13:59:06
|
||||
* @LastEditTime: 2021-07-09 14:37:35
|
||||
* @FilePath: /potato/main.go
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"net"
|
||||
|
||||
"github.com/soheilhy/cmux"
|
||||
"github.com/viletyy/potato/global"
|
||||
"github.com/viletyy/potato/initialize"
|
||||
"github.com/viletyy/yolk/convert"
|
||||
|
@ -20,12 +18,8 @@ import (
|
|||
// @version 1.0
|
||||
// @description This is a potato use golang
|
||||
// @BasePath /api
|
||||
|
||||
var port string
|
||||
|
||||
func runTcpServer(port string) (net.Listener, error) {
|
||||
return net.Listen("tcp", ":"+port)
|
||||
}
|
||||
var grpcPort string
|
||||
var httpPort string
|
||||
|
||||
func main() {
|
||||
global.GO_VP = initialize.Viper()
|
||||
|
@ -33,35 +27,32 @@ func main() {
|
|||
global.GO_DB = initialize.Gorm()
|
||||
global.GO_REDIS = initialize.Redis()
|
||||
global.GO_TRACER = initialize.Tracer()
|
||||
initialize.Cron()
|
||||
go initialize.Cron()
|
||||
|
||||
defer global.GO_DB.Close()
|
||||
defer global.GO_REDIS.Close()
|
||||
|
||||
flag.StringVar(&port, "port", convert.ToString(global.GO_CONFIG.Server.Port), "启动端口号")
|
||||
flag.StringVar(&grpcPort, "grpc_port", convert.ToString(global.GO_CONFIG.Server.GrpcPort), "启动grpc服务端口号")
|
||||
flag.StringVar(&httpPort, "http_port", convert.ToString(global.GO_CONFIG.Server.HttpPort), "启动http服务端口号")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
l, err := runTcpServer(port)
|
||||
errs := make(chan error)
|
||||
go func() {
|
||||
err := initialize.RunHttpServer(httpPort)
|
||||
if err != nil {
|
||||
global.GO_LOG.Sugar().Fatalf("Run Tcp Server err: %v", err)
|
||||
errs <- err
|
||||
}
|
||||
m := cmux.New(l)
|
||||
grpcL := m.MatchWithWriters(
|
||||
cmux.HTTP2MatchHeaderFieldSendSettings(
|
||||
"content-type",
|
||||
"application/grpc",
|
||||
),
|
||||
)
|
||||
httpL := m.Match(cmux.HTTP1Fast())
|
||||
}()
|
||||
|
||||
grpcS := initialize.RunGrpcServer()
|
||||
httpS := initialize.RunServer(port)
|
||||
go grpcS.Serve(grpcL)
|
||||
go httpS.Serve(httpL)
|
||||
|
||||
err = m.Serve()
|
||||
go func() {
|
||||
err := initialize.RunGrpcServer(grpcPort)
|
||||
if err != nil {
|
||||
errs <- err
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case err := <-errs:
|
||||
global.GO_LOG.Sugar().Fatalf("Run Server err: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,17 +1,25 @@
|
|||
/*
|
||||
* @Date: 2021-06-10 23:09:09
|
||||
* @LastEditors: viletyy
|
||||
* @LastEditTime: 2021-06-11 17:25:58
|
||||
* @LastEditTime: 2021-07-09 14:32:17
|
||||
* @FilePath: /potato/pkg/errcode/module_code.go
|
||||
*/
|
||||
package errcode
|
||||
|
||||
var (
|
||||
ErrorUploadFileFail = NewError(20001, "上传文件失败")
|
||||
ErrorGetVendorListFail = NewError(20101, "获取系统厂商列表失败")
|
||||
ErrorGetVendorFail = NewError(20102, "获取系统厂商失败")
|
||||
ErrorCreateVendorFail = NewError(20103, "创建系统厂商失败")
|
||||
ErrorUpdateVendorFail = NewError(20104, "更新系统厂商失败")
|
||||
ErrorDeleteVendorFail = NewError(20105, "删除系统厂商失败")
|
||||
ErrorCountVendorFail = NewError(20106, "统计系统厂商失败")
|
||||
ErrorRegisterUserError = NewError(20010, "用户注册失败")
|
||||
ErrorLoginUserError = NewError(20011, "用户登录失败")
|
||||
ErrorGetUserListFail = NewError(20101, "获取用户列表失败")
|
||||
ErrorGetUserFail = NewError(20102, "获取用户失败")
|
||||
ErrorCreateUserFail = NewError(20103, "创建用户失败")
|
||||
ErrorUpdateUserFail = NewError(20104, "更新用户失败")
|
||||
ErrorDeleteUserFail = NewError(20105, "删除用户失败")
|
||||
ErrorCountUserFail = NewError(20106, "统计用户失败")
|
||||
ErrorGetVendorListFail = NewError(20201, "获取系统厂商列表失败")
|
||||
ErrorGetVendorFail = NewError(20202, "获取系统厂商失败")
|
||||
ErrorCreateVendorFail = NewError(20203, "创建系统厂商失败")
|
||||
ErrorUpdateVendorFail = NewError(20204, "更新系统厂商失败")
|
||||
ErrorDeleteVendorFail = NewError(20205, "删除系统厂商失败")
|
||||
ErrorCountVendorFail = NewError(20206, "统计系统厂商失败")
|
||||
)
|
||||
|
|
|
@ -0,0 +1,357 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc v3.17.1
|
||||
// source: proto/user.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type GetUserListRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
|
||||
Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname,omitempty"`
|
||||
Page int64 `protobuf:"varint,3,opt,name=page,proto3" json:"page,omitempty"`
|
||||
PageSize int64 `protobuf:"varint,4,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetUserListRequest) Reset() {
|
||||
*x = GetUserListRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_user_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetUserListRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetUserListRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetUserListRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_user_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetUserListRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetUserListRequest) Descriptor() ([]byte, []int) {
|
||||
return file_proto_user_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *GetUserListRequest) GetUsername() string {
|
||||
if x != nil {
|
||||
return x.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetUserListRequest) GetNickname() string {
|
||||
if x != nil {
|
||||
return x.Nickname
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetUserListRequest) GetPage() int64 {
|
||||
if x != nil {
|
||||
return x.Page
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *GetUserListRequest) GetPageSize() int64 {
|
||||
if x != nil {
|
||||
return x.PageSize
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type User struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
|
||||
Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"`
|
||||
Nickname string `protobuf:"bytes,4,opt,name=nickname,proto3" json:"nickname,omitempty"`
|
||||
IsAdmin bool `protobuf:"varint,5,opt,name=is_admin,json=isAdmin,proto3" json:"is_admin,omitempty"`
|
||||
}
|
||||
|
||||
func (x *User) Reset() {
|
||||
*x = User{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_user_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *User) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*User) ProtoMessage() {}
|
||||
|
||||
func (x *User) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_user_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use User.ProtoReflect.Descriptor instead.
|
||||
func (*User) Descriptor() ([]byte, []int) {
|
||||
return file_proto_user_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *User) GetId() int64 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *User) GetUsername() string {
|
||||
if x != nil {
|
||||
return x.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *User) GetPassword() string {
|
||||
if x != nil {
|
||||
return x.Password
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *User) GetNickname() string {
|
||||
if x != nil {
|
||||
return x.Nickname
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *User) GetIsAdmin() bool {
|
||||
if x != nil {
|
||||
return x.IsAdmin
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type GetUserListReply struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
List []*User `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"`
|
||||
Pager *Pager `protobuf:"bytes,2,opt,name=pager,proto3" json:"pager,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetUserListReply) Reset() {
|
||||
*x = GetUserListReply{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_user_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetUserListReply) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetUserListReply) ProtoMessage() {}
|
||||
|
||||
func (x *GetUserListReply) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_user_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetUserListReply.ProtoReflect.Descriptor instead.
|
||||
func (*GetUserListReply) Descriptor() ([]byte, []int) {
|
||||
return file_proto_user_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *GetUserListReply) GetList() []*User {
|
||||
if x != nil {
|
||||
return x.List
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *GetUserListReply) GetPager() *Pager {
|
||||
if x != nil {
|
||||
return x.Pager
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_proto_user_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_proto_user_proto_rawDesc = []byte{
|
||||
0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x1a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x7d, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65,
|
||||
0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08,
|
||||
0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
|
||||
0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65,
|
||||
0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x61, 0x67,
|
||||
0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x85, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e,
|
||||
0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a,
|
||||
0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61,
|
||||
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61,
|
||||
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0x4b, 0x0a,
|
||||
0x10, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c,
|
||||
0x79, 0x12, 0x19, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x05, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x05,
|
||||
0x70, 0x61, 0x67, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x06, 0x2e, 0x50, 0x61,
|
||||
0x67, 0x65, 0x72, 0x52, 0x05, 0x70, 0x61, 0x67, 0x65, 0x72, 0x32, 0x46, 0x0a, 0x0b, 0x55, 0x73,
|
||||
0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x47, 0x65, 0x74,
|
||||
0x55, 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x13, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73,
|
||||
0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e,
|
||||
0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79,
|
||||
0x22, 0x00, 0x42, 0x21, 0x5a, 0x1f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x76, 0x69, 0x6c, 0x65, 0x74, 0x79, 0x79, 0x2f, 0x70, 0x6f, 0x74, 0x61, 0x74, 0x6f, 0x2f,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_proto_user_proto_rawDescOnce sync.Once
|
||||
file_proto_user_proto_rawDescData = file_proto_user_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_proto_user_proto_rawDescGZIP() []byte {
|
||||
file_proto_user_proto_rawDescOnce.Do(func() {
|
||||
file_proto_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_user_proto_rawDescData)
|
||||
})
|
||||
return file_proto_user_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_proto_user_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_proto_user_proto_goTypes = []interface{}{
|
||||
(*GetUserListRequest)(nil), // 0: GetUserListRequest
|
||||
(*User)(nil), // 1: User
|
||||
(*GetUserListReply)(nil), // 2: GetUserListReply
|
||||
(*Pager)(nil), // 3: Pager
|
||||
}
|
||||
var file_proto_user_proto_depIdxs = []int32{
|
||||
1, // 0: GetUserListReply.list:type_name -> User
|
||||
3, // 1: GetUserListReply.pager:type_name -> Pager
|
||||
0, // 2: UserService.GetUserList:input_type -> GetUserListRequest
|
||||
2, // 3: UserService.GetUserList:output_type -> GetUserListReply
|
||||
3, // [3:4] is the sub-list for method output_type
|
||||
2, // [2:3] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_user_proto_init() }
|
||||
func file_proto_user_proto_init() {
|
||||
if File_proto_user_proto != nil {
|
||||
return
|
||||
}
|
||||
file_proto_common_proto_init()
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_proto_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetUserListRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*User); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetUserListReply); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_proto_user_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_proto_user_proto_goTypes,
|
||||
DependencyIndexes: file_proto_user_proto_depIdxs,
|
||||
MessageInfos: file_proto_user_proto_msgTypes,
|
||||
}.Build()
|
||||
File_proto_user_proto = out.File
|
||||
file_proto_user_proto_rawDesc = nil
|
||||
file_proto_user_proto_goTypes = nil
|
||||
file_proto_user_proto_depIdxs = nil
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
syntax = "proto3";
|
||||
|
||||
option go_package= "github.com/viletyy/potato/proto";
|
||||
|
||||
import "proto/common.proto";
|
||||
|
||||
service UserService {
|
||||
rpc GetUserList(GetUserListRequest) returns (GetUserListReply) {}
|
||||
}
|
||||
|
||||
message GetUserListRequest {
|
||||
string username = 1;
|
||||
string nickname = 2;
|
||||
int64 page = 3;
|
||||
int64 page_size = 4;
|
||||
}
|
||||
|
||||
message User {
|
||||
int64 id = 1;
|
||||
string username = 2;
|
||||
string password = 3;
|
||||
string nickname = 4;
|
||||
bool is_admin = 5;
|
||||
}
|
||||
|
||||
message GetUserListReply {
|
||||
repeated User list = 1;
|
||||
Pager pager = 2;
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
// UserServiceClient is the client API for UserService service.
|
||||
//
|
||||
// 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.
|
||||
type UserServiceClient interface {
|
||||
GetUserList(ctx context.Context, in *GetUserListRequest, opts ...grpc.CallOption) (*GetUserListReply, error)
|
||||
}
|
||||
|
||||
type userServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient {
|
||||
return &userServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *userServiceClient) GetUserList(ctx context.Context, in *GetUserListRequest, opts ...grpc.CallOption) (*GetUserListReply, error) {
|
||||
out := new(GetUserListReply)
|
||||
err := c.cc.Invoke(ctx, "/UserService/GetUserList", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// UserServiceServer is the server API for UserService service.
|
||||
// All implementations must embed UnimplementedUserServiceServer
|
||||
// for forward compatibility
|
||||
type UserServiceServer interface {
|
||||
GetUserList(context.Context, *GetUserListRequest) (*GetUserListReply, error)
|
||||
mustEmbedUnimplementedUserServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedUserServiceServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedUserServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceServer) GetUserList(context.Context, *GetUserListRequest) (*GetUserListReply, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetUserList not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {}
|
||||
|
||||
// UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to UserServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeUserServiceServer interface {
|
||||
mustEmbedUnimplementedUserServiceServer()
|
||||
}
|
||||
|
||||
func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) {
|
||||
s.RegisterService(&UserService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _UserService_GetUserList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetUserListRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(UserServiceServer).GetUserList(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/UserService/GetUserList",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(UserServiceServer).GetUserList(ctx, req.(*GetUserListRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// UserService_ServiceDesc is the grpc.ServiceDesc for UserService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var UserService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "UserService",
|
||||
HandlerType: (*UserServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "GetUserList",
|
||||
Handler: _UserService_GetUserList_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "proto/user.proto",
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* @Date: 2021-07-09 14:33:26
|
||||
* @LastEditors: viletyy
|
||||
* @LastEditTime: 2021-07-09 14:34:16
|
||||
* @FilePath: /potato/server/user.go
|
||||
*/
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/viletyy/potato/internal/service"
|
||||
"github.com/viletyy/potato/pkg/app"
|
||||
"github.com/viletyy/potato/pkg/errcode/rpc"
|
||||
pb "github.com/viletyy/potato/proto"
|
||||
)
|
||||
|
||||
type UserServer struct {
|
||||
pb.UnimplementedUserServiceServer
|
||||
}
|
||||
|
||||
func NewVendorServer() *UserServer {
|
||||
return &UserServer{}
|
||||
}
|
||||
|
||||
func (t *UserServer) GetUserList(ctx context.Context, r *pb.GetUserListRequest) (*pb.GetUserListReply, error) {
|
||||
svc := service.New(ctx)
|
||||
dbUserList, err := svc.Dao.GetUserList(r.GetUsername(), r.GetNickname(), int(r.GetPage()), int(r.GetPageSize()))
|
||||
if err != nil {
|
||||
return nil, rpc.ToRpcError(rpc.RpcErrorGetVendorListFail)
|
||||
}
|
||||
total, err := svc.Dao.CountUser(r.GetUsername(), r.GetNickname())
|
||||
if err != nil {
|
||||
return nil, rpc.ToRpcError(rpc.RpcErrorCountVendorFail)
|
||||
}
|
||||
data := map[string]interface{}{
|
||||
"list": dbUserList,
|
||||
"pager": app.Pager{
|
||||
Page: int(r.GetPage()),
|
||||
PageSize: int(r.GetPageSize()),
|
||||
Total: total,
|
||||
},
|
||||
}
|
||||
byteData, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, rpc.ToRpcError(rpc.RpcInvalidParams)
|
||||
}
|
||||
userList := pb.GetUserListReply{}
|
||||
err = json.Unmarshal(byteData, &userList)
|
||||
if err != nil {
|
||||
return nil, rpc.ToRpcError(rpc.RpcInvalidParams)
|
||||
}
|
||||
|
||||
return &userList, nil
|
||||
}
|
Loading…
Reference in New Issue