feat: add login page
This commit is contained in:
commit
513a290031
|
@ -0,0 +1,8 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true" />
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="MaterialThemeProjectNewConfig">
|
||||||
|
<option name="metadata">
|
||||||
|
<MTProjectMetadataState>
|
||||||
|
<option name="migrated" value="true" />
|
||||||
|
<option name="pristineConfig" value="false" />
|
||||||
|
<option name="userId" value="-31530129:19584ea2536:-7ff9" />
|
||||||
|
</MTProjectMetadataState>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/backend.iml" filepath="$PROJECT_DIR$/.idea/backend.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings" defaultProject="true" />
|
||||||
|
</project>
|
|
@ -0,0 +1,76 @@
|
||||||
|
GO_CTL_NAME=goctl
|
||||||
|
GO_ZERO_STYLE=go_zero
|
||||||
|
GO ?= go
|
||||||
|
GOFMT ?= gofmt "-s"
|
||||||
|
GOFILES := $(shell find . -name "*.go")
|
||||||
|
LDFLAGS := -s -w
|
||||||
|
VERSION="v1.0.0"
|
||||||
|
DOCKER_REPO="refactor-service"
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test: # 進行測試
|
||||||
|
go test -v --cover ./...
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: gen-api
|
||||||
|
gen-api: # 產生 api
|
||||||
|
goctl api go -api ./generate/api/gateway.api -dir . -style go_zero
|
||||||
|
|
||||||
|
.PHONY: gen-doc
|
||||||
|
gen-doc: # 生成 Swagger 文檔
|
||||||
|
# go-doc openapi --api ./generate/api/gateway.api --filename gateway.json --host dev-api.truheart.com.tw --basepath /api/v1
|
||||||
|
go-doc -a generate/api/gateway.api -d ./ -f gateway -s openapi3.0
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: fmt
|
||||||
|
fmt: # 格式優化
|
||||||
|
$(GOFMT) -w $(GOFILES)
|
||||||
|
goimports -w ./
|
||||||
|
golangci-lint run
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
build: # 編譯專案
|
||||||
|
go build -ldflags "$(LDFLAGS)" -o bin/gateway cmd/gateway/main.go
|
||||||
|
|
||||||
|
.PHONY: run
|
||||||
|
run: # 運行專案
|
||||||
|
go run cmd/gateway/main.go
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean: # 清理編譯文件
|
||||||
|
rm -rf bin/
|
||||||
|
|
||||||
|
.PHONY: docker-build
|
||||||
|
docker-build: # 構建 Docker 映像
|
||||||
|
docker build -t $(DOCKER_REPO):$(VERSION) .
|
||||||
|
|
||||||
|
.PHONY: docker-run
|
||||||
|
docker-run: # 運行 Docker 容器
|
||||||
|
docker run -p 8888:8888 $(DOCKER_REPO):$(VERSION)
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
install: # 安裝依賴
|
||||||
|
go mod tidy
|
||||||
|
go mod download
|
||||||
|
|
||||||
|
.PHONY: lint
|
||||||
|
lint: # 代碼檢查
|
||||||
|
golangci-lint run
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
help: # 顯示幫助信息
|
||||||
|
@echo "Available commands:"
|
||||||
|
@echo " test - 運行測試"
|
||||||
|
@echo " gen-api - 產生 api"
|
||||||
|
@echo " gen-swagger - 生成 JSON 格式 Swagger 文檔"
|
||||||
|
@echo " gen-swagger-yaml - 生成 YAML 格式 Swagger 文檔"
|
||||||
|
@echo " fmt - 格式化代碼"
|
||||||
|
@echo " build - 編譯專案"
|
||||||
|
@echo " run - 運行專案"
|
||||||
|
@echo " clean - 清理編譯文件"
|
||||||
|
@echo " docker-build - 構建 Docker 映像"
|
||||||
|
@echo " docker-run - 運行 Docker 容器"
|
||||||
|
@echo " install - 安裝依賴"
|
||||||
|
@echo " lint - 代碼檢查"
|
||||||
|
@echo " help - 顯示幫助信息"
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
# 🏛️ Cursor Rules: Go Kernel Mode 1.24.2
|
||||||
|
|
||||||
|
**最高指導原則:** 以 Linus Torvalds 的實用主義為核心,融合 Go 語言三巨頭 (Pike, Thompson, Griesemer) 的簡潔與併發哲學。
|
||||||
|
|
||||||
|
**核心目標:** 構建極致高效 (Performance-First)、極度簡潔 (Simplicity)、且完全受控 (Control) 的 Go 後端服務。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 最小化原則 (Minimization Principle)
|
||||||
|
|
||||||
|
**核心:保持規模的簡潔、專注、易於理解。**
|
||||||
|
|
||||||
|
| 規則 ID | 規則內容 (Go 實踐) | 哲學依據 |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| **M1** | **Stdlib-First:** **強制優先** 使用 Go 標準庫 (`net/http`, `context`, `sync`, `io`, `database/sql`)。任何外部依賴的引入必須有不可替代的理由。 | **Pike/Thompson:** 簡潔與正交性。 |
|
||||||
|
| **M2** | **No-Fat-Frameworks:** **禁止** 使用大型、功能過載的 Web 框架。僅允許使用 Go 標準庫或極輕量的路由/工具庫 (如 `go-chi/chi`),以維持對 **性能瓶頸的完全控制**。 | **Linus Torvalds:** 實用與控制。 |
|
||||||
|
| **M3** | **Small Interfaces:** 介面 (Interfaces) 必須 **小且專一** (`er` 慣例,如 `io.Reader`)。介面應定義在使用者 (Consumer) 端,以促進模組間的低耦合。 | **Robert Griesemer:** 語言設計的嚴謹。 |
|
||||||
|
| **M4** | **Explicit Errors:** 錯誤處理必須使用 **Go 慣用的多回傳值 (`value, error`)** 模式。**嚴禁** 使用 `panic` 或 `recover` 來控制正常的業務流程錯誤。 | **Go 慣例:** 錯誤是流程的一部分。 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 結構化原則 (Structural Principle)
|
||||||
|
|
||||||
|
**核心:使用分層架構管理職責邊界,促進可測試性和可維護性。**
|
||||||
|
|
||||||
|
| 規則 ID | 規則內容 (Go 實踐) | 哲學依據 |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| **S1** | **Internal-First Layout:** 核心業務邏輯必須放置在 **`internal/`** 目錄中,不允許被外部專案直接導入。執行入口點必須在 **`cmd/{servicename}`**。 | **Griesemer/Go 慣例:** 嚴謹的專案封裝。 |
|
||||||
|
| **S2** | **Clean Architecture Layers:** 服務應至少分為 **`transport`** (I/O, 如 `net/http` Handler)、**`service`** (核心業務邏輯) 和 **`repository`** (數據存取)。層次間透過 **介面** 隔離。 | **Pike/Thompson:** 關注點分離 (Separation of Concerns)。 |
|
||||||
|
| **S3** | **Concurrency Management:** 併發操作 (如背景任務、Worker Pool) 必須明確使用 **Goroutine 和 Channel** 封裝。**Goroutine 的生命週期** 必須使用 **`context.Context`** 進行取消與超時控制。 | **Rob Pike:** Go 併發模型的正確實踐。 |
|
||||||
|
| **S4** | **Config Isolation:** 設定檔 (`.env`, 環境變數) 只能在 **`cmd`** 或專門的 **`config`** 套件中讀取。核心業務邏輯 (Service Layer) 絕不允許直接存取環境變數。 | **Linus Torvalds:** 清晰的邊界控制。 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 精準引用原則 (Precise Reference Principle)
|
||||||
|
|
||||||
|
**核心:所有依賴必須顯式、高效、可追溯。**
|
||||||
|
|
||||||
|
| 規則 ID | 規則內容 (Go 實踐) | 哲學依據 |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| **P1** | **Raw SQL Control:** 數據層存取必須使用 **原生 SQL** 語句,並搭配 **`sqlx`** 或 **`sqlc`** 輔助。**嚴禁** 使用大型、會自動生成複雜查詢的 ORM,以確保對效能的完全控制。 | **Linus Torvalds:** 控制數據流與效率。 |
|
||||||
|
| **P2** | **Dependency Injection (DI):** 所有依賴(例如 `service` 依賴 `repository`)必須通過 **建構函式** (例如 `NewUserService(repo Repository)`) 顯式注入,避免使用全局變數。 | **Griesemer/Go 慣例:** 顯式的依賴關係。 |
|
||||||
|
| **P3** | **I/O Context Passing:** 任何涉及 I/O (網路、DB) 的函式,其第一個參數必須是 **`context.Context`**,以便傳播截止時間和取消訊號。 | **Go 慣例:** 資源管理的標準。 |
|
||||||
|
| **P4** | **Structured Logging:** 使用 **`log/slog`** 進行結構化日誌記錄。日誌中必須包含 Request ID 或 Trace ID,以實現 **可觀察性 (Observability)**。 | **Linus/實用主義:** 快速診斷問題的能力。 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 一致性原則 (Consistency Principle)
|
||||||
|
|
||||||
|
**核心:保持專案的程式碼風格、命名方式、結構的統一,減少團隊摩擦。**
|
||||||
|
|
||||||
|
| 規則 ID | 規則內容 (Go 實踐) | 哲學依據 |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| **C1** | **Mandatory Formatting:** 所有提交的程式碼必須通過 **`gofmt`** 或 **`goimports`** 格式化。**禁止** 違反官方程式碼風格的程式碼。 | **Robert Griesemer:** 語言設計的嚴謹性與工程規範。 |
|
||||||
|
| **C2** | **Go Naming Conventions:** 變數和函式應**簡短**。未導出的私有成員使用**小寫開頭**。簡寫必須保持一致(如 HTTP 寫成 `http`,而非 `Http`)。 | **Rob Pike:** 簡潔與慣例。 |
|
||||||
|
| **C3** | **Testing In-Package:** 單元測試程式碼 (e.g., `_test.go`) 應與被測試程式碼保持在 **同一套件**,以實現對私有函式和變數的全面測試。 | **Linus/Go 慣例:** 穩定性與可靠性。 |
|
||||||
|
| **C4** | **Go Modules & Version:** 專案必須使用 **Go Modules** 進行依賴管理,並且針對 **Go 1.25** 版本進行編寫和測試。| **Linus/Griesemer:** 版本控制的嚴格性與相容性。 |
|
||||||
|
|
||||||
|
---
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: gateway
|
||||||
|
Host: 0.0.0.0
|
||||||
|
Port: 8888
|
|
@ -0,0 +1,31 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"backend/internal/config"
|
||||||
|
"backend/internal/handler"
|
||||||
|
"backend/internal/svc"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/conf"
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
var configFile = flag.String("f", "etc/gateway.yaml", "the config file")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
var c config.Config
|
||||||
|
conf.MustLoad(*configFile, &c)
|
||||||
|
|
||||||
|
server := rest.MustNewServer(c.RestConf)
|
||||||
|
defer server.Stop()
|
||||||
|
|
||||||
|
ctx := svc.NewServiceContext(c)
|
||||||
|
handler.RegisterHandlers(server, ctx)
|
||||||
|
|
||||||
|
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
||||||
|
server.Start()
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -0,0 +1,33 @@
|
||||||
|
syntax = "v1"
|
||||||
|
|
||||||
|
// ================ 通用響應 ================
|
||||||
|
type (
|
||||||
|
// 成功響應
|
||||||
|
OKResp {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Msg string `json:"msg"`
|
||||||
|
Data interface{} `json:"data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分頁響應
|
||||||
|
PagerResp {
|
||||||
|
Total int64 `json:"total"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
Index int64 `json:"index"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 錯誤響應
|
||||||
|
ErrorResp {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Msg string `json:"msg"`
|
||||||
|
Details string `json:"details,omitempty"`
|
||||||
|
Error interface{} `json:"error,omitempty"` // 可選的錯誤信息
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseReq {}
|
||||||
|
|
||||||
|
VerifyHeader {
|
||||||
|
Token string `header:"token" validate:"required"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
syntax = "v1"
|
||||||
|
|
||||||
|
info (
|
||||||
|
title: "Digimon Platform API Gateway"
|
||||||
|
description: "This is Digimon Platform "
|
||||||
|
version: "v1"
|
||||||
|
contactName: "Daniel Wang"
|
||||||
|
contactEmail: "igs170911@gmail.com"
|
||||||
|
consumes: "application/json"
|
||||||
|
produces: "application/json"
|
||||||
|
schemes: "http,https"
|
||||||
|
host: "127.0.0.1:8888"
|
||||||
|
)
|
||||||
|
|
||||||
|
import (
|
||||||
|
"common.api"
|
||||||
|
"ping.api"
|
||||||
|
"member.api"
|
||||||
|
)
|
||||||
|
|
|
@ -0,0 +1,554 @@
|
||||||
|
syntax = "v1"
|
||||||
|
|
||||||
|
// ================ 請求/響應結構 ================
|
||||||
|
type (
|
||||||
|
// 創建帳號請求
|
||||||
|
CreateUserAccountReq {
|
||||||
|
LoginID string `json:"login_id" validate:"required,min=3,max=50"`
|
||||||
|
Platform string `json:"platform" validate:"required,oneof=platform google line apple"`
|
||||||
|
Token string `json:"token" validate:"required,min=8,max=128"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 綁定用戶請求
|
||||||
|
BindingUserReq {
|
||||||
|
UID string `json:"uid" validate:"required,min=1,max=50"`
|
||||||
|
LoginID string `json:"login_id" validate:"required,min=3,max=50"`
|
||||||
|
Type int `json:"type" validate:"required,oneof=1 2 3"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 綁定用戶響應
|
||||||
|
BindingUserResp {
|
||||||
|
UID string `json:"uid"`
|
||||||
|
LoginID string `json:"login_id"`
|
||||||
|
Type int `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 創建用戶資料請求
|
||||||
|
CreateUserInfoReq {
|
||||||
|
UID string `json:"uid" validate:"required,min=1,max=50"`
|
||||||
|
AlarmType int `json:"alarm_type" validate:"required,oneof=0 1 2"`
|
||||||
|
Status int `json:"status" validate:"required,oneof=0 1 2 3"`
|
||||||
|
Language string `json:"language" validate:"required,min=2,max=10"`
|
||||||
|
Currency string `json:"currency" validate:"required,min=3,max=3"`
|
||||||
|
Avatar *string `json:"avatar,omitempty"`
|
||||||
|
NickName *string `json:"nick_name,omitempty" validate:"omitempty,min=1,max=50"`
|
||||||
|
FullName *string `json:"full_name,omitempty" validate:"omitempty,min=1,max=100"`
|
||||||
|
Gender *int64 `json:"gender,omitempty" validate:"omitempty,oneof=0 1 2"`
|
||||||
|
Birthdate *int64 `json:"birthdate,omitempty" validate:"omitempty,min=19000101,max=21001231"`
|
||||||
|
PhoneNumber *string `json:"phone_number,omitempty" validate:"omitempty,min=10,max=20"`
|
||||||
|
Email *string `json:"email,omitempty" validate:"omitempty,email"`
|
||||||
|
Address *string `json:"address,omitempty" validate:"omitempty,max=200"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 獲取帳號資訊響應
|
||||||
|
GetAccountInfoResp {
|
||||||
|
Data CreateUserAccountReq `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新用戶資料請求
|
||||||
|
UpdateUserInfoReq {
|
||||||
|
UID string `json:"uid" validate:"required,min=1,max=50"`
|
||||||
|
Language *string `json:"language,omitempty" validate:"omitempty,min=2,max=10"`
|
||||||
|
Currency *string `json:"currency,omitempty" validate:"omitempty,min=3,max=3"`
|
||||||
|
NickName *string `json:"nick_name,omitempty" validate:"omitempty,min=1,max=50"`
|
||||||
|
Avatar *string `json:"avatar,omitempty"`
|
||||||
|
AlarmType *int `json:"alarm_type,omitempty" validate:"omitempty,oneof=0 1 2"`
|
||||||
|
Status *int `json:"status,omitempty" validate:"omitempty,oneof=0 1 2 3"`
|
||||||
|
FullName *string `json:"full_name,omitempty" validate:"omitempty,min=1,max=100"`
|
||||||
|
Gender *int64 `json:"gender,omitempty" validate:"omitempty,oneof=0 1 2"`
|
||||||
|
Birthdate *int64 `json:"birthdate,omitempty" validate:"omitempty,min=19000101,max=21001231"`
|
||||||
|
Address *string `json:"address,omitempty" validate:"omitempty,max=200"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 獲取 UID 請求
|
||||||
|
GetUIDByAccountReq {
|
||||||
|
Account string `json:"account" validate:"required,min=3,max=50"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 獲取 UID 響應
|
||||||
|
GetUIDByAccountResp {
|
||||||
|
UID string `json:"uid"`
|
||||||
|
Account string `json:"account"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新密碼請求
|
||||||
|
UpdateTokenReq {
|
||||||
|
Account string `json:"account" validate:"required,min=3,max=50"`
|
||||||
|
Token string `json:"token" validate:"required,min=8,max=128"`
|
||||||
|
Platform int `json:"platform" validate:"required,oneof=1 2 3 4"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成驗證碼請求
|
||||||
|
GenerateRefreshCodeReq {
|
||||||
|
Account string `json:"account" validate:"required,min=3,max=50"`
|
||||||
|
CodeType int `json:"code_type" validate:"required,oneof=1 2 3"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 驗證碼響應
|
||||||
|
VerifyCodeResp {
|
||||||
|
VerifyCode string `json:"verify_code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成驗證碼響應
|
||||||
|
GenerateRefreshCodeResp {
|
||||||
|
Data VerifyCodeResp `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 驗證碼請求
|
||||||
|
VerifyRefreshCodeReq {
|
||||||
|
Account string `json:"account" validate:"required,min=3,max=50"`
|
||||||
|
CodeType int `json:"code_type" validate:"required,oneof=1 2 3"`
|
||||||
|
VerifyCode string `json:"verify_code" validate:"required,min=4,max=10"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新狀態請求
|
||||||
|
UpdateStatusReq {
|
||||||
|
UID string `json:"uid" validate:"required,min=1,max=50"`
|
||||||
|
Status int `json:"status" validate:"required,oneof=0 1 2 3"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 獲取用戶資訊請求
|
||||||
|
GetUserInfoReq {
|
||||||
|
UID string `json:"uid,omitempty" validate:"omitempty,min=1,max=50"`
|
||||||
|
NickName *string `json:"nick_name,omitempty" validate:"omitempty,min=1,max=50"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用戶資訊
|
||||||
|
UserInfo {
|
||||||
|
UID string `json:"uid"`
|
||||||
|
AvatarURL *string `json:"avatar_url,omitempty"`
|
||||||
|
FullName *string `json:"full_name,omitempty"`
|
||||||
|
NickName *string `json:"nick_name,omitempty"`
|
||||||
|
GenderCode *int64 `json:"gender_code,omitempty"`
|
||||||
|
Birthday *int64 `json:"birthday,omitempty"`
|
||||||
|
Phone *string `json:"phone,omitempty"`
|
||||||
|
Email *string `json:"email,omitempty"`
|
||||||
|
Address *string `json:"address,omitempty"`
|
||||||
|
AlarmType int `json:"alarm_type"`
|
||||||
|
Status int `json:"status"`
|
||||||
|
Language string `json:"language"`
|
||||||
|
Currency string `json:"currency"`
|
||||||
|
CreateTime int64 `json:"create_time"`
|
||||||
|
UpdateTime int64 `json:"update_time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 獲取用戶資訊響應
|
||||||
|
GetUserInfoResp {
|
||||||
|
Data UserInfo `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用戶列表請求
|
||||||
|
ListUserInfoReq {
|
||||||
|
AlarmType *int `json:"alarm_type,omitempty" validate:"omitempty,oneof=0 1 2"`
|
||||||
|
Status *int `json:"status,omitempty" validate:"omitempty,oneof=0 1 2 3"`
|
||||||
|
CreateStartTime *int64 `json:"create_start_time,omitempty"`
|
||||||
|
CreateEndTime *int64 `json:"create_end_time,omitempty"`
|
||||||
|
PageSize int `json:"page_size" validate:"required,min=1,max=100"`
|
||||||
|
PageIndex int `json:"page_index" validate:"required,min=1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用戶列表響應
|
||||||
|
ListUserInfoResp {
|
||||||
|
Data []UserInfo `json:"data"`
|
||||||
|
Pager PagerResp `json:"pager"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 驗證認證結果請求
|
||||||
|
VerifyAuthResultReq {
|
||||||
|
Token string `json:"token" validate:"required,min=1"`
|
||||||
|
Account *string `json:"account,omitempty" validate:"omitempty,min=3,max=50"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 驗證認證結果響應
|
||||||
|
VerifyAuthResultResp {
|
||||||
|
Status bool `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Google 認證結果響應
|
||||||
|
VerifyGoogleAuthResultResp {
|
||||||
|
Status bool `json:"status"`
|
||||||
|
Iss *string `json:"iss,omitempty"`
|
||||||
|
Sub *string `json:"sub,omitempty"`
|
||||||
|
Aud *string `json:"aud,omitempty"`
|
||||||
|
Exp *string `json:"exp,omitempty"`
|
||||||
|
Iat *string `json:"iat,omitempty"`
|
||||||
|
Email *string `json:"email,omitempty"`
|
||||||
|
EmailVerified *string `json:"email_verified,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Picture *string `json:"picture,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 綁定驗證 Email 請求
|
||||||
|
BindVerifyEmailReq {
|
||||||
|
UID string `json:"uid" validate:"required,min=1,max=50"`
|
||||||
|
Email string `json:"email" validate:"required,email"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 綁定驗證 Phone 請求
|
||||||
|
BindVerifyPhoneReq {
|
||||||
|
UID string `json:"uid" validate:"required,min=1,max=50"`
|
||||||
|
Phone string `json:"phone" validate:"required,min=10,max=20"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LINE 獲取 Token 請求
|
||||||
|
LineGetTokenReq {
|
||||||
|
Code string `json:"code" validate:"required,min=1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LINE Access Token 響應
|
||||||
|
LineAccessTokenResp {
|
||||||
|
Token string `json:"token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LINE 用戶資料
|
||||||
|
LineUserProfile {
|
||||||
|
DisplayName string `json:"display_name"`
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
PictureURL string `json:"picture_url"`
|
||||||
|
StatusMessage string `json:"status_message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LINE 獲取用戶資訊請求
|
||||||
|
LineGetUserInfoReq {
|
||||||
|
Token string `json:"token" validate:"required,min=1"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// ================ API 路由 ================
|
||||||
|
@server(
|
||||||
|
group: account
|
||||||
|
prefix: /api/v1/account
|
||||||
|
)
|
||||||
|
service gateway {
|
||||||
|
@doc(
|
||||||
|
summary: "創建帳號"
|
||||||
|
description: "創建新的帳號,支援多平台登入"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-201 () // 創建成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40001: (ErrorResp) 帳號格式錯誤
|
||||||
|
40002: (ErrorResp) 密碼強度不足
|
||||||
|
40003: (ErrorResp) 平台類型無效
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-409 (ErrorResp) // 帳號已存在
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler CreateUserAccount
|
||||||
|
post /create (CreateUserAccountReq) returns ()
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "獲取帳號資訊"
|
||||||
|
description: "根據帳號獲取用戶的帳號資訊"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (GetAccountInfoResp) // 獲取成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40001: (ErrorResp) 帳號格式錯誤
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-404 (ErrorResp) // 帳號不存在
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler GetUserAccountInfo
|
||||||
|
post /info (GetUIDByAccountReq) returns (GetAccountInfoResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "更新用戶密碼"
|
||||||
|
description: "更新指定帳號的密碼"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (OKResp) // 更新成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40001: (ErrorResp) 帳號格式錯誤
|
||||||
|
40002: (ErrorResp) 密碼強度不足
|
||||||
|
40003: (ErrorResp) 平台類型無效
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-404 (ErrorResp) // 帳號不存在
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler UpdateUserToken
|
||||||
|
post /update-token (UpdateTokenReq) returns (OKResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "獲取用戶 UID"
|
||||||
|
description: "根據帳號獲取對應的用戶 UID"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (GetUIDByAccountResp) // 獲取成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40001: (ErrorResp) 帳號格式錯誤
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-404 (ErrorResp) // 帳號不存在
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler GetUIDByAccount
|
||||||
|
post /uid (GetUIDByAccountReq) returns (GetUIDByAccountResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "綁定帳號"
|
||||||
|
description: "將帳號綁定到指定的用戶 UID"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (BindingUserResp) // 綁定成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40001: (ErrorResp) 帳號格式錯誤
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
40005: (ErrorResp) UID 格式錯誤
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-404 (ErrorResp) // 帳號不存在
|
||||||
|
@respdoc-409 (ErrorResp) // 帳號已綁定
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler BindAccount
|
||||||
|
post /bind (BindingUserReq) returns (BindingUserResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "綁定用戶資料"
|
||||||
|
description: "初次綁定用戶的詳細資料"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (OKResp) // 綁定成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
40005: (ErrorResp) UID 格式錯誤
|
||||||
|
40006: (ErrorResp) 郵箱格式錯誤
|
||||||
|
40007: (ErrorResp) 電話格式錯誤
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-404 (ErrorResp) // 用戶不存在
|
||||||
|
@respdoc-409 (ErrorResp) // 用戶資料已存在
|
||||||
|
@respdoc-422 (ErrorResp) // 用戶資料不完整
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler BindUserInfo
|
||||||
|
post /bind-info (CreateUserInfoReq) returns (OKResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "綁定驗證 Email"
|
||||||
|
description: "綁定並驗證用戶的 Email 地址"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (OKResp) // 綁定成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40005: (ErrorResp) UID 格式錯誤
|
||||||
|
40006: (ErrorResp) 郵箱格式錯誤
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-404 (ErrorResp) // 用戶不存在
|
||||||
|
@respdoc-409 (ErrorResp) // 郵箱已綁定
|
||||||
|
@respdoc-422 (ErrorResp) // 郵箱未驗證
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler BindVerifyEmail
|
||||||
|
post /bind-email (BindVerifyEmailReq) returns (OKResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "綁定驗證 Phone"
|
||||||
|
description: "綁定並驗證用戶的電話號碼"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (OKResp) // 綁定成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40005: (ErrorResp) UID 格式錯誤
|
||||||
|
40007: (ErrorResp) 電話格式錯誤
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-404 (ErrorResp) // 用戶不存在
|
||||||
|
@respdoc-409 (ErrorResp) // 電話已綁定
|
||||||
|
@respdoc-422 (ErrorResp) // 電話未驗證
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler BindVerifyPhone
|
||||||
|
post /bind-phone (BindVerifyPhoneReq) returns (OKResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "更新用戶資料"
|
||||||
|
description: "更新用戶的個人資料資訊"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (OKResp) // 更新成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
40005: (ErrorResp) UID 格式錯誤
|
||||||
|
40006: (ErrorResp) 郵箱格式錯誤
|
||||||
|
40007: (ErrorResp) 電話格式錯誤
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-404 (ErrorResp) // 用戶不存在
|
||||||
|
@respdoc-422 (ErrorResp) // 用戶資料無效
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler UpdateUserInfo
|
||||||
|
post /update-info (UpdateUserInfoReq) returns (OKResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "更新用戶狀態"
|
||||||
|
description: "更新用戶的帳號狀態"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (OKResp) // 更新成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
40005: (ErrorResp) UID 格式錯誤
|
||||||
|
40008: (ErrorResp) 狀態值無效
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-404 (ErrorResp) // 用戶不存在
|
||||||
|
@respdoc-422 (ErrorResp) // 狀態更新無效
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler UpdateStatus
|
||||||
|
post /update-status (UpdateStatusReq) returns (OKResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "獲取用戶資訊"
|
||||||
|
description: "根據 UID 或暱稱獲取用戶詳細資訊"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (GetUserInfoResp) // 獲取成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
40005: (ErrorResp) UID 格式錯誤
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-404 (ErrorResp) // 用戶不存在
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler GetUserInfo
|
||||||
|
post /user-info (GetUserInfoReq) returns (GetUserInfoResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "獲取用戶列表"
|
||||||
|
description: "分頁獲取用戶列表,支援篩選條件"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (ListUserInfoResp) // 獲取成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
40009: (ErrorResp) 分頁參數無效
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler ListMember
|
||||||
|
post /list (ListUserInfoReq) returns (ListUserInfoResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "生成驗證碼"
|
||||||
|
description: "為指定帳號生成驗證碼,用於忘記密碼等功能"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (GenerateRefreshCodeResp) // 生成成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40001: (ErrorResp) 帳號格式錯誤
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
40010: (ErrorResp) 驗證碼類型無效
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-404 (ErrorResp) // 帳號不存在
|
||||||
|
@respdoc-429 (ErrorResp) // 請求過於頻繁
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler GenerateRefreshCode
|
||||||
|
post /generate-code (GenerateRefreshCodeReq) returns (GenerateRefreshCodeResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "驗證驗證碼"
|
||||||
|
description: "驗證並使用驗證碼,驗證後會刪除驗證碼"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (OKResp) // 驗證成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40001: (ErrorResp) 帳號格式錯誤
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
40010: (ErrorResp) 驗證碼類型無效
|
||||||
|
40011: (ErrorResp) 驗證碼格式錯誤
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-404 (ErrorResp) // 驗證碼不存在
|
||||||
|
@respdoc-422 (ErrorResp) // 驗證碼無效或已過期
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler VerifyRefreshCode
|
||||||
|
post /verify-code (VerifyRefreshCodeReq) returns (OKResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "檢查驗證碼"
|
||||||
|
description: "檢查驗證碼是否正確,但不刪除驗證碼"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (OKResp) // 檢查成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40001: (ErrorResp) 帳號格式錯誤
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
40010: (ErrorResp) 驗證碼類型無效
|
||||||
|
40011: (ErrorResp) 驗證碼格式錯誤
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-404 (ErrorResp) // 驗證碼不存在
|
||||||
|
@respdoc-422 (ErrorResp) // 驗證碼無效或已過期
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler CheckRefreshCode
|
||||||
|
post /check-code (VerifyRefreshCodeReq) returns (OKResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "驗證 Google 認證"
|
||||||
|
description: "驗證 Google OAuth 登入是否有效"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (VerifyGoogleAuthResultResp) // 驗證成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
40012: (ErrorResp) Token 格式錯誤
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-401 (ErrorResp) // Token 無效或過期
|
||||||
|
@respdoc-422 (ErrorResp) // Google 認證失敗
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler VerifyGoogleAuthResult
|
||||||
|
post /verify-google (VerifyAuthResultReq) returns (VerifyGoogleAuthResultResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "驗證平台認證"
|
||||||
|
description: "驗證平台登入認證是否有效"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (VerifyAuthResultResp) // 驗證成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
40012: (ErrorResp) Token 格式錯誤
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-401 (ErrorResp) // Token 無效或過期
|
||||||
|
@respdoc-422 (ErrorResp) // 平台認證失敗
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler VerifyPlatformAuthResult
|
||||||
|
post /verify-platform (VerifyAuthResultReq) returns (VerifyAuthResultResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "LINE 獲取 Access Token"
|
||||||
|
description: "使用 LINE 授權碼獲取 Access Token"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (LineAccessTokenResp) // 獲取成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
40013: (ErrorResp) 授權碼格式錯誤
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-401 (ErrorResp) // 授權碼無效或過期
|
||||||
|
@respdoc-422 (ErrorResp) // LINE 認證失敗
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler LineCodeToAccessToken
|
||||||
|
post /line/token (LineGetTokenReq) returns (LineAccessTokenResp)
|
||||||
|
|
||||||
|
@doc(
|
||||||
|
summary: "LINE 獲取用戶資料"
|
||||||
|
description: "使用 LINE Access Token 獲取用戶資料"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
@respdoc-200 (LineUserProfile) // 獲取成功
|
||||||
|
@respdoc-400 (
|
||||||
|
40004: (ErrorResp) 參數驗證失敗
|
||||||
|
40012: (ErrorResp) Token 格式錯誤
|
||||||
|
) // 客戶端錯誤
|
||||||
|
@respdoc-401 (ErrorResp) // Token 無效或過期
|
||||||
|
@respdoc-422 (ErrorResp) // LINE 用戶資料獲取失敗
|
||||||
|
@respdoc-500 (ErrorResp) // 服務器錯誤
|
||||||
|
*/
|
||||||
|
@handler LineGetProfileByAccessToken
|
||||||
|
post /line/profile (LineGetUserInfoReq) returns (LineUserProfile)
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
syntax = "v1"
|
||||||
|
|
||||||
|
// ===========================================
|
||||||
|
// 系統健康檢查 API 端點定義
|
||||||
|
// ===========================================
|
||||||
|
|
||||||
|
@server(
|
||||||
|
group: ping
|
||||||
|
prefix: /api/v1
|
||||||
|
schemes: https
|
||||||
|
timeout: 10s
|
||||||
|
)
|
||||||
|
|
||||||
|
service gateway {
|
||||||
|
@doc(
|
||||||
|
summary: "系統健康檢查"
|
||||||
|
description: "檢查系統服務狀態,用於監控和負載均衡器健康檢查。返回系統運行狀態信息。"
|
||||||
|
)
|
||||||
|
@handler Ping
|
||||||
|
get /health () returns ()
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
||||||
|
use digimon_member
|
||||||
|
db.count.dropIndex("name_1");
|
|
@ -0,0 +1,2 @@
|
||||||
|
use digimon_member
|
||||||
|
db.count.createIndex({ "name": 1 }, { unique: true });
|
|
@ -0,0 +1,3 @@
|
||||||
|
use digimon_member;
|
||||||
|
db.account.createIndex({ "login_id": 1, "platform": 1}, {unique: true})
|
||||||
|
db.account.createIndex({"create_at": 1})
|
|
@ -0,0 +1,4 @@
|
||||||
|
use digimon_member;
|
||||||
|
db.account_uid_binding.createIndex({"login_id": 1}, {unique: true})
|
||||||
|
db.account_uid_binding.createIndex({"uid": 1})
|
||||||
|
db.account_uid_binding.createIndex({"create_at": 1})
|
|
@ -0,0 +1,3 @@
|
||||||
|
use digimon_member;
|
||||||
|
db.user_info.createIndex({"uid": 1},{unique: true})
|
||||||
|
db.user_info.createIndex({"create_at": 1})
|
|
@ -0,0 +1,22 @@
|
||||||
|
use digimon_product;
|
||||||
|
|
||||||
|
# 精確查詢索引(針對 owner_uid, is_published, is_visible, created_at)
|
||||||
|
db.product.createIndex({"owner_uid": 1, "is_published": 1, "is_visible": 1, "created_at": -1})
|
||||||
|
|
||||||
|
# 範圍查詢索引(針對 start_time, end_time, created_at)
|
||||||
|
db.product.createIndex({"start_time": 1, "end_time": 1, "created_at": -1})
|
||||||
|
|
||||||
|
# 金額範圍索引(針對 target_amount, created_at)
|
||||||
|
db.product.createIndex({"target_amount": 1, "created_at": -1})
|
||||||
|
|
||||||
|
# 成功排序專用索引(針對 finished, updated_at)
|
||||||
|
db.product.createIndex({"finished": 1, "updated_at": -1})
|
||||||
|
|
||||||
|
# URL 精確查詢索引(針對 url_slug)
|
||||||
|
db.product.createIndex({"url_slug": 1})
|
||||||
|
|
||||||
|
# 基礎排序索引(針對 created_at 單列)
|
||||||
|
db.product.createIndex({"created_at": -1})
|
||||||
|
|
||||||
|
# URL 精確查詢索引(針對 url_slug)
|
||||||
|
db.product.createIndex({"category": 1})
|
|
@ -0,0 +1,9 @@
|
||||||
|
use digimon_product;
|
||||||
|
|
||||||
|
# 精確查詢與範圍條件組合索引
|
||||||
|
db.product_item.createIndex({"reference_id": 1}) # 精確匹配 reference_id
|
||||||
|
db.product_item.createIndex({"sale_start_time": 1, "sale_end_time": 1}) # 範圍查詢索引,提升 SaleStartTime 與 SaleEndTime 查詢效率
|
||||||
|
db.product_item.createIndex({"status": 1}) # 精確查詢 status
|
||||||
|
|
||||||
|
# 排序索引
|
||||||
|
db.product_item.createIndex({"created_at": -1}) # 用於按 created_at 倒序排序
|
|
@ -0,0 +1,8 @@
|
||||||
|
use digimon_product;
|
||||||
|
|
||||||
|
# 精確查詢與範圍條件組合索引
|
||||||
|
db.supplementary_info.createIndex({"reference_id": 1}) # 精確匹配 reference_id
|
||||||
|
db.supplementary_info.createIndex({"info_type": 1}) # 精確查詢 status
|
||||||
|
|
||||||
|
# 排序索引
|
||||||
|
db.supplementary_info.createIndex({"created_at": -1}) # 用於按 created_at 倒序排序
|
|
@ -0,0 +1,6 @@
|
||||||
|
use digimon_cart;
|
||||||
|
|
||||||
|
# 精確查詢與範圍條件組合索引
|
||||||
|
db.cart.createIndex({ "uid": 1, "product_id": 1 }, { unique: true })
|
||||||
|
# 排序索引
|
||||||
|
db.supplementary_info.createIndex({"created_at": -1}) # 用於按 created_at 倒序排序
|
|
@ -0,0 +1,50 @@
|
||||||
|
module backend
|
||||||
|
|
||||||
|
go 1.25.1
|
||||||
|
|
||||||
|
require github.com/zeromicro/go-zero v1.9.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
|
github.com/fatih/color v1.18.0 // indirect
|
||||||
|
github.com/go-logr/logr v1.4.2 // indirect
|
||||||
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/grafana/pyroscope-go v1.2.4 // indirect
|
||||||
|
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
|
||||||
|
github.com/klauspost/compress v1.17.11 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
|
github.com/openzipkin/zipkin-go v0.4.3 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
|
github.com/prometheus/client_golang v1.21.1 // indirect
|
||||||
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
|
github.com/prometheus/common v0.62.0 // indirect
|
||||||
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
|
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/zipkin v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/sdk v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||||
|
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||||
|
golang.org/x/net v0.35.0 // indirect
|
||||||
|
golang.org/x/sys v0.30.0 // indirect
|
||||||
|
golang.org/x/text v0.22.0 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||||
|
google.golang.org/grpc v1.65.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.36.5 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
)
|
|
@ -0,0 +1,132 @@
|
||||||
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||||
|
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||||
|
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||||
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
|
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||||
|
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||||
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/grafana/pyroscope-go v1.2.4 h1:B22GMXz+O0nWLatxLuaP7o7L9dvP0clLvIpmeEQQM0Q=
|
||||||
|
github.com/grafana/pyroscope-go v1.2.4/go.mod h1:zzT9QXQAp2Iz2ZdS216UiV8y9uXJYQiGE1q8v1FyhqU=
|
||||||
|
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg=
|
||||||
|
github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
|
||||||
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||||
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||||
|
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||||
|
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
|
github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg=
|
||||||
|
github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||||
|
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||||
|
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
|
||||||
|
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||||
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
|
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||||
|
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||||
|
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||||
|
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||||
|
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||||
|
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||||
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/zeromicro/go-zero v1.9.0 h1:hlVtQCSHPszQdcwZTawzGwTej1G2mhHybYzMRLuwCt4=
|
||||||
|
github.com/zeromicro/go-zero v1.9.0/go.mod h1:TMyCxiaOjLQ3YxyYlJrejaQZF40RlzQ3FVvFu5EbcV4=
|
||||||
|
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||||
|
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||||
|
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4=
|
||||||
|
go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0/go.mod h1:iSDOcsnSA5INXzZtwaBPrKp/lWu/V14Dd+llD0oI2EA=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 h1:Mw5xcxMwlqoJd97vwPxA8isEaIoxsta9/Q51+TTJLGE=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0/go.mod h1:CQNu9bj7o7mC6U7+CA/schKEYakYXWr79ucDHTMGhCM=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 h1:Xw8U6u2f8DK2XAkGRFV7BBLENgnTGX9i4rQRxJf+/vs=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0/go.mod h1:6KW1Fm6R/s6Z3PGXwSJN2K4eT6wQB3vXX6CVnYX9NmM=
|
||||||
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 h1:s0PHtIkN+3xrbDOpt2M8OTG92cWqUESvzh2MxiR5xY8=
|
||||||
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0/go.mod h1:hZlFbDbRt++MMPCCfSJfmhkGIWnX1h3XjkfxZUjLrIA=
|
||||||
|
go.opentelemetry.io/otel/exporters/zipkin v1.24.0 h1:3evrL5poBuh1KF51D9gO/S+N/1msnm4DaBqs/rpXUqY=
|
||||||
|
go.opentelemetry.io/otel/exporters/zipkin v1.24.0/go.mod h1:0EHgD8R0+8yRhUYJOGR8Hfg2dpiJQxDOszd5smVO9wM=
|
||||||
|
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||||
|
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
|
||||||
|
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||||
|
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||||
|
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||||
|
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||||
|
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||||
|
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||||
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
|
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||||
|
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||||
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||||
|
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||||
|
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||||
|
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
|
||||||
|
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
|
||||||
|
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||||
|
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
|
||||||
|
gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
|
||||||
|
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
|
@ -0,0 +1,7 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import "github.com/zeromicro/go-zero/rest"
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
rest.RestConf
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package ping
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"backend/internal/logic/ping"
|
||||||
|
"backend/internal/svc"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 系統健康檢查
|
||||||
|
func PingHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
l := ping.NewPingLogic(r.Context(), svcCtx)
|
||||||
|
err := l.Ping()
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.Ok(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// goctl 1.8.1
|
||||||
|
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
ping "backend/internal/handler/ping"
|
||||||
|
"backend/internal/svc"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||||
|
server.AddRoutes(
|
||||||
|
[]rest.Route{
|
||||||
|
{
|
||||||
|
// 系統健康檢查
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/health",
|
||||||
|
Handler: ping.PingHandler(serverCtx),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rest.WithPrefix("/api/v1"),
|
||||||
|
rest.WithTimeout(10000*time.Millisecond),
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package ping
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"backend/internal/svc"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PingLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
// 系統健康檢查
|
||||||
|
func NewPingLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PingLogic {
|
||||||
|
return &PingLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *PingLogic) Ping() error {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package svc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"backend/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServiceContext struct {
|
||||||
|
Config config.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
return &ServiceContext{
|
||||||
|
Config: c,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// goctl 1.8.1
|
||||||
|
|
||||||
|
package types
|
||||||
|
|
||||||
|
type BaseReq struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type BaseResponse struct {
|
||||||
|
Status Status `json:"status"` // 狀態
|
||||||
|
Data interface{} `json:"data"` // 資料
|
||||||
|
}
|
||||||
|
|
||||||
|
type Pager struct {
|
||||||
|
Total int64 `json:"total"`
|
||||||
|
PageSize int64 `json:"page_size"`
|
||||||
|
PageIndex int64 `json:"page_index"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RespOK struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type Status struct {
|
||||||
|
Code int64 `json:"code"` // 狀態碼
|
||||||
|
Message string `json:"message"` // 訊息
|
||||||
|
Data interface{} `json:"data,omitempty"` // 可選的資料,當有返回時才出現
|
||||||
|
Error interface{} `json:"error,omitempty"` // 可選的錯誤信息
|
||||||
|
}
|
||||||
|
|
||||||
|
type VerifyHeader struct {
|
||||||
|
Token string `header:"token" validate:"required"`
|
||||||
|
}
|
Loading…
Reference in New Issue