This commit is contained in:
ivamp 2024-11-23 01:53:33 +08:00
parent 611433e6bf
commit bd4223a58c
6 changed files with 286 additions and 146 deletions

View File

@ -17,7 +17,7 @@ debug:
database: database:
host: 127.0.0.1 host: 127.0.0.1
port: 3306 port: 5432
user: root user: root
password: root password: root
name: db_name name: db_name

View File

@ -40,7 +40,7 @@ const docTemplate = `{
"schema": { "schema": {
"allOf": [ "allOf": [
{ {
"$ref": "#/definitions/schema.ResponseBody" "$ref": "#/definitions/response.Body"
}, },
{ {
"type": "object", "type": "object",
@ -56,7 +56,7 @@ const docTemplate = `{
"400": { "400": {
"description": "Bad Request", "description": "Bad Request",
"schema": { "schema": {
"$ref": "#/definitions/schema.ResponseBody" "$ref": "#/definitions/response.Body"
} }
} }
} }
@ -64,6 +64,21 @@ const docTemplate = `{
} }
}, },
"definitions": { "definitions": {
"response.Body": {
"type": "object",
"properties": {
"data": {},
"error": {
"type": "string"
},
"message": {
"type": "string"
},
"success": {
"type": "boolean"
}
}
},
"schema.CurrentUserResponse": { "schema.CurrentUserResponse": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -83,21 +98,6 @@ const docTemplate = `{
"type": "boolean" "type": "boolean"
} }
} }
},
"schema.ResponseBody": {
"type": "object",
"properties": {
"data": {},
"error": {
"type": "string"
},
"message": {
"type": "string"
},
"success": {
"type": "boolean"
}
}
} }
}, },
"securityDefinitions": { "securityDefinitions": {

View File

@ -1,101 +1,101 @@
{ {
"swagger": "2.0", "swagger": "2.0",
"info": { "info": {
"title": "API Docs", "title": "API Docs",
"contact": {}, "contact": {},
"version": "1.0" "version": "1.0"
},
"paths": {
"/api/v1/ping": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "测试接口,将会返回当前用户的信息",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"ping"
],
"summary": "Greet",
"deprecated": true,
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/schema.ResponseBody"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/schema.CurrentUserResponse"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/schema.ResponseBody"
}
}
}
}
}
},
"definitions": {
"schema.CurrentUserResponse": {
"type": "object",
"properties": {
"ip": {
"type": "string"
},
"userEmail": {
"type": "string"
},
"userId": {
"type": "string"
},
"userName": {
"type": "string"
},
"valid": {
"type": "boolean"
}
}
}, },
"schema.ResponseBody": { "paths": {
"type": "object", "/api/v1/ping": {
"properties": { "get": {
"data": {}, "security": [
"error": { {
"type": "string" "ApiKeyAuth": []
}, }
"message": { ],
"type": "string" "description": "测试接口,将会返回当前用户的信息",
}, "consumes": [
"success": { "application/json"
"type": "boolean" ],
"produces": [
"application/json"
],
"tags": [
"ping"
],
"summary": "Greet",
"deprecated": true,
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.Body"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/schema.CurrentUserResponse"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.Body"
}
}
}
}
}
},
"definitions": {
"response.Body": {
"type": "object",
"properties": {
"data": {},
"error": {
"type": "string"
},
"message": {
"type": "string"
},
"success": {
"type": "boolean"
}
}
},
"schema.CurrentUserResponse": {
"type": "object",
"properties": {
"ip": {
"type": "string"
},
"userEmail": {
"type": "string"
},
"userId": {
"type": "string"
},
"userName": {
"type": "string"
},
"valid": {
"type": "boolean"
}
}
}
},
"securityDefinitions": {
"ApiKeyAuth": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
} }
}
} }
},
"securityDefinitions": {
"ApiKeyAuth": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
}
}
} }

View File

@ -1,4 +1,14 @@
definitions: definitions:
response.Body:
properties:
data: {}
error:
type: string
message:
type: string
success:
type: boolean
type: object
schema.CurrentUserResponse: schema.CurrentUserResponse:
properties: properties:
ip: ip:
@ -12,48 +22,38 @@ definitions:
valid: valid:
type: boolean type: boolean
type: object type: object
schema.ResponseBody:
properties:
data: { }
error:
type: string
message:
type: string
success:
type: boolean
type: object
info: info:
contact: { } contact: {}
title: API Docs title: API Docs
version: "1.0" version: "1.0"
paths: paths:
/api/v1/ping: /api/v1/ping:
get: get:
consumes: consumes:
- application/json - application/json
deprecated: true deprecated: true
description: 测试接口,将会返回当前用户的信息 description: 测试接口,将会返回当前用户的信息
produces: produces:
- application/json - application/json
responses: responses:
"200": "200":
description: OK description: OK
schema: schema:
allOf: allOf:
- $ref: '#/definitions/schema.ResponseBody' - $ref: '#/definitions/response.Body'
- properties: - properties:
data: data:
$ref: '#/definitions/schema.CurrentUserResponse' $ref: '#/definitions/schema.CurrentUserResponse'
type: object type: object
"400": "400":
description: Bad Request description: Bad Request
schema: schema:
$ref: '#/definitions/schema.ResponseBody' $ref: '#/definitions/response.Body'
security: security:
- ApiKeyAuth: [ ] - ApiKeyAuth: []
summary: Greet summary: Greet
tags: tags:
- ping - ping
securityDefinitions: securityDefinitions:
ApiKeyAuth: ApiKeyAuth:
in: header in: header

View File

@ -24,8 +24,8 @@ func NewUserController(authService *auth.Service) *UserController {
// @Produce json // @Produce json
// @Security ApiKeyAuth // @Security ApiKeyAuth
// @deprecated true // @deprecated true
// @Success 200 {object} schema.ResponseBody{data=schema.CurrentUserResponse} // @Success 200 {object} response.Body{data=schema.CurrentUserResponse}
// @Failure 400 {object} schema.ResponseBody // @Failure 400 {object} response.Body
// @Router /api/v1/ping [get] // @Router /api/v1/ping [get]
func (u *UserController) Test(c echo.Context) error { func (u *UserController) Test(c echo.Context) error {
user, ok := u.authService.GetUser(c) user, ok := u.authService.GetUser(c)

View File

@ -1,15 +1,155 @@
-- +goose Up -- +goose Up
CREATE TABLE IF NOT EXISTS users CREATE TABLE apis
( (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL, description TEXT,
password VARCHAR(255) NOT NULL, -- 后端地址
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, backend_url VARCHAR(255) NOT NULL,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP auth_token VARCHAR(255) NOT NULL,
-- 是否已经验证(验证时间)
ownership_verified_at TIMESTAMP DEFAULT Null,
-- 所有权验证 token
ownership_verification_token VARCHAR(255) NOT NULL,
-- user id string
user_id VARCHAR(255) NOT NULL,
-- 状态
status VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT now(),
updated_at TIMESTAMP DEFAULT now(),
deleted_at TIMESTAMP DEFAULT Null
); );
-- +goose Down -- index
CREATE INDEX idx_api_name ON apis (name);
CREATE INDEX idx_api_user_id ON apis (user_id);
CREATE INDEX idx_api_status ON apis (status);
CREATE INDEX idx_api_deleted_at ON apis (deleted_at);
CREATE INDEX idx_api_ownership_verified_at ON apis (ownership_verified_at);
DROP TABLE IF EXISTS users;
CREATE TABLE api_documents
(
id BIGSERIAL PRIMARY KEY,
api_id BIGINT NOT NULL,
openapi_url VARCHAR(255) NOT NULL,
content TEXT,
created_at TIMESTAMP DEFAULT now(),
updated_at TIMESTAMP DEFAULT now(),
CONSTRAINT fk_api_id
FOREIGN KEY (api_id) REFERENCES apis (id)
);
CREATE INDEX idx_api_documents_api_id ON api_documents (api_id);
CREATE INDEX idx_api_documents_openapi_url ON api_documents (openapi_url);
CREATE TABLE packages
(
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
api_id BIGINT NOT NULL,
price DECIMAL(10, 2),
-- hidden
is_hidden BOOLEAN DEFAULT false,
is_published BOOLEAN DEFAULT false,
call_limit BIGINT DEFAULT 10000,
-- 有效期(天)
duration INTEGER DEFAULT 30,
-- 是否为试用套餐
is_trial BOOLEAN DEFAULT false,
-- 每个用户的购买限制
purchase_limit INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT now(),
updated_at TIMESTAMP DEFAULT now(),
CONSTRAINT fk_api_id FOREIGN KEY (api_id) REFERENCES apis (id),
deleted_at TIMESTAMP DEFAULT Null
);
CREATE INDEX idx_package_name ON packages (name);
CREATE INDEX idx_package_api_id ON packages (api_id);
CREATE INDEX idx_package_price ON packages (price);
CREATE INDEX idx_package_is_published ON packages (is_published);
CREATE INDEX idx_package_is_hidden ON packages (is_hidden);
CREATE INDEX idx_package_is_trial ON packages (is_trial);
CREATE INDEX idx_package_call_limit ON packages (call_limit);
CREATE INDEX idx_package_duration ON packages (duration);
CREATE INDEX idx_package_purchase_limit ON packages (purchase_limit);
CREATE INDEX idx_package_deleted_at ON packages (deleted_at);
CREATE TABLE user_packages
(
id BIGSERIAL PRIMARY KEY,
user_id VARCHAR(255) NOT NULL,
package_id BIGINT NOT NULL,
calls_left INTEGER DEFAULT 0,
is_active BOOLEAN DEFAULT false,
expiration_at TIMESTAMP DEFAULT NULL,
purchase_at TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT now(),
updated_at TIMESTAMP DEFAULT now(),
CONSTRAINT fk_package_id FOREIGN KEY (package_id) REFERENCES packages (id)
);
CREATE INDEX idx_user_package_user_id ON user_packages (user_id);
CREATE INDEX idx_user_package_package_id ON user_packages (package_id);
CREATE INDEX idx_user_package_is_active ON user_packages (is_active);
CREATE INDEX idx_user_package_expiration_at ON user_packages (expiration_at);
CREATE INDEX idx_user_package_purchase_at ON user_packages (purchase_at);
CREATE INDEX idx_user_package_calls_left ON user_packages (calls_left);
CREATE TABLE promo_codes
(
id BIGSERIAL PRIMARY KEY,
code VARCHAR(255) NOT NULL,
discount_type VARCHAR(255) NOT NULL,
discount_value DECIMAL(10, 2) NOT NULL,
expiration_date TIMESTAMP,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT now(),
updated_at TIMESTAMP DEFAULT now(),
deleted_at TIMESTAMP DEFAULT Null
);
CREATE INDEX idx_promo_code_code ON promo_codes (code);
CREATE INDEX idx_promo_code_discount_type ON promo_codes (discount_type);
CREATE INDEX idx_promo_code_discount_value ON promo_codes (discount_value);
CREATE INDEX idx_promo_code_expiration_date ON promo_codes (expiration_date);
CREATE INDEX idx_promo_code_is_active ON promo_codes (is_active);
CREATE INDEX idx_promo_code_deleted_at ON promo_codes (deleted_at);
CREATE TABLE orders
(
id BIGSERIAL PRIMARY KEY,
user_id VARCHAR(255) NOT NULL,
promo_code_id BIGINT DEFAULT NULL,
price DECIMAL(10, 2) NOT NULL,
order_date TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT now(),
updated_at TIMESTAMP DEFAULT now(),
CONSTRAINT fk_promo_code_id FOREIGN KEY (promo_code_id) REFERENCES promo_codes (id) ON DELETE SET NULL
);
CREATE INDEX idx_order_user_id ON orders (user_id);
CREATE INDEX idx_order_promo_code_id ON orders (promo_code_id);
CREATE INDEX idx_order_price ON orders (price);
CREATE INDEX idx_order_order_date ON orders (order_date);
CREATE TABLE order_items
(
id BIGSERIAL PRIMARY KEY,
order_id BIGINT NOT NULL,
package_id BIGINT NOT NULL,
created_at TIMESTAMP DEFAULT now(),
updated_at TIMESTAMP DEFAULT now(),
CONSTRAINT fk_order_id FOREIGN KEY (order_id) REFERENCES orders (id)
);
CREATE INDEX idx_order_item_order_id ON order_items (order_id);
CREATE INDEX idx_order_item_package_id ON order_items (package_id);
-- +goose Down
DROP TABLE IF EXISTS order_items;
DROP TABLE IF EXISTS orders;
DROP TABLE IF EXISTS promo_codes;
DROP TABLE IF EXISTS user_packages;
DROP TABLE IF EXISTS packages;
DROP TABLE IF EXISTS api_documents;
DROP TABLE IF EXISTS apis;