refactor: reorganize modules and add Linux build tooling

This commit is contained in:
2026-08-09 12:41:08 +08:00
parent 86024fa81d
commit 5cc5fd92ed
1461 changed files with 4054 additions and 4724 deletions

View File

@@ -0,0 +1,542 @@
# Feedback Service
[![Go Version](https://img.shields.io/badge/Go-1.25.1-blue.svg)](https://golang.org/)
[![License](https://img.shields.io/badge/License-Internal-red.svg)](LICENSE)
[![Build Status](https://img.shields.io/badge/Build-Passing-green.svg)](https://bsm/full/module/base/feedback)
一个高性能、可扩展的微服务,基于 gRPC 和 HTTP Gateway 架构,提供用户反馈管理、问题跟踪、附件处理等完整的反馈系统功能。
## 🚀 特性
- **📝 反馈管理**: 完整的用户反馈创建、查询、修改、删除功能
- **📎 附件支持**: 图片和文件附件上传与管理
- **🏷️ 分类管理**: 灵活的反馈分类和状态管理
- **👥 用户关联**: 支持多用户、多机构的反馈管理
- **📊 状态跟踪**: 反馈处理状态跟踪和备注管理
- **⚡ 高性能**: Redis缓存 + 数据库优化
- **🐳 容器化**: 完整的Docker支持
- **📊 监控**: 健康检查和APM集成
- **🔒 安全**: 完善的错误处理和输入验证
## 📋 目录
- [快速开始](#-快速开始)
- [项目结构](#-项目结构)
- [核心功能](#-核心功能)
- [API文档](#-api文档)
- [开发指南](#-开发指南)
- [部署说明](#-部署说明)
- [性能优化](#-性能优化)
- [故障排除](#-故障排除)
## 🚀 快速开始
### 环境要求
- **Go**: 1.25.1+
- **PostgreSQL**: 12+
- **Redis**: 6+
- **Docker**: 20.10+ (可选)
- **Protocol Buffers**: 3.15+ (开发需要)
### 快速安装
```bash
# 克隆项目
git clone bsm/full/module/base/feedback.git
cd feedback
# 安装依赖
go mod download
# 生成代码
make proto
# 构建应用
go build -o bin/feedback cmd/main/main.go
# 运行服务
./bin/feedback
```
### Docker 快速启动
```bash
# 启动完整服务栈
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f feedback-service
```
## 📁 项目结构
```
feedback/
├── 📁 cmd/ # 应用程序入口
│ ├── 📁 main/ # 主服务入口
│ └── 📁 cli/ # 命令行工具
├── 📁 internal/ # 内部包
│ ├── 📁 config/ # 配置管理
│ ├── 📁 impl/ # 实现层
│ ├── 📁 logic/ # 业务逻辑
│ │ └── 📁 method/ # 反馈相关逻辑
│ ├── 📁 models/ # 数据模型
│ └── 📁 server/ # 服务器实现
├── 📁 pb/ # Protocol Buffers 生成代码
├── 📁 proto/ # Protocol Buffers 定义文件
├── 📁 swagger/ # API 文档
├── 📁 scripts/ # 脚本文件
├── 📁 test/ # 测试文件
├── 📁 etc/ # 配置文件
├── 🐳 Dockerfile # Docker 镜像构建
├── 🐳 docker-compose.yml # Docker 编排
├── 🔧 Makefile # 构建脚本
└── 📖 README.md # 项目文档
```
## 🔧 核心功能
### 1. 反馈管理服务 (Method Service)
#### 📝 添加反馈 (Add)
```protobuf
rpc Add(AddRequest) returns (AddReply)
```
- **功能**: 创建新的用户反馈记录
- **特性**:
- 支持图片和附件上传
- 自动生成唯一标识
- 用户身份关联
- 分类和状态管理
#### 📋 获取反馈列表 (List)
```protobuf
rpc List(ListRequest) returns (ListReply)
```
- **功能**: 分页查询反馈记录列表
- **特性**:
- 支持多条件筛选(用户、状态、分类、机构)
- 分页查询优化
- 按创建时间排序
- 预加载关联图片
#### 🔍 获取反馈详情 (Get)
```protobuf
rpc Get(GetRequest) returns (GetReply)
```
- **功能**: 根据ID获取反馈记录详情
- **特性**: 完整记录信息、关联图片和附件
#### ✏️ 修改反馈 (Modify)
```protobuf
rpc Modify(ModifyRequest) returns (StatusReply)
```
- **功能**: 更新反馈记录信息
- **特性**:
- 支持部分字段更新
- 关联数据同步更新
- 事务性操作保证
#### 🗑️ 删除反馈 (Delete)
```protobuf
rpc Delete(DeleteRequest) returns (StatusReply)
```
- **功能**: 删除反馈记录
- **特性**: 级联删除关联的图片和附件
#### 📝 添加备注 (Remark)
```protobuf
rpc Remark(RemarkRequest) returns (StatusReply)
```
- **功能**: 为反馈记录添加备注和更新状态
- **特性**: 支持状态变更和备注记录
## 📚 API文档
### gRPC 服务
| 服务 | 方法 | 描述 | 端口 |
|------|------|------|------|
| Method | Add | 添加反馈 | 12101 |
| Method | List | 获取列表 | 12101 |
| Method | Get | 获取详情 | 12101 |
| Method | Modify | 修改反馈 | 12101 |
| Method | Delete | 删除反馈 | 12101 |
| Method | Remark | 添加备注 | 12101 |
### HTTP Gateway
| 端点 | 方法 | 描述 |
|------|------|------|
| `/feedback.Method/Add` | POST | 添加反馈 |
| `/feedback.Method/List` | POST | 获取列表 |
| `/feedback.Method/Get` | POST | 获取详情 |
| `/feedback.Method/Modify` | POST | 修改反馈 |
| `/feedback.Method/Delete` | POST | 删除反馈 |
| `/feedback.Method/Remark` | POST | 添加备注 |
### Swagger 文档
- **本地**: http://localhost:12102/feedback.swagger.json
- **在线**: 通过 HTTP Gateway 访问完整的 API 文档
## 🛠️ 开发指南
### 开发环境设置
```bash
# 安装开发工具
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
# 设置Git钩子
git config core.hooksPath .githooks
# 启动开发模式
go run cmd/main/main.go
```
### 代码生成
```bash
# 生成 protobuf 代码
make proto
# 生成 Swagger 文档
make swagger
```
### 测试
```bash
# 运行所有测试
go test ./...
# 测试覆盖率
go test -cover ./...
# 代码检查
make lint
# 安全扫描
make security
```
### 数据库管理
```bash
# 初始化数据库
make init-db
# 备份数据库
make backup-db
```
## 🚀 部署说明
### Docker 部署
```bash
# 构建镜像
make docker-build
# 启动服务栈
make docker-compose-up
# 查看日志
make docker-compose-logs
# 停止服务
make docker-compose-down
```
### 生产环境部署
1. **环境准备**
```bash
# 创建生产配置
cp etc/feedback_dev.yaml etc/feedback_prod.yaml
# 编辑生产配置...
```
2. **数据库初始化**
```bash
# 执行数据库迁移
go run cmd/main/main.go migrate
```
3. **服务启动**
```bash
# 构建生产版本
make build-linux
# 启动服务
./build/feedback-linux-amd64
```
### Kubernetes 部署
```yaml
# k8s-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: feedback-service
spec:
replicas: 3
selector:
matchLabels:
app: feedback-service
template:
metadata:
labels:
app: feedback-service
spec:
containers:
- name: feedback-service
image: feedback:latest
ports:
- containerPort: 12101
- containerPort: 12102
env:
- name: SERVICE_ENV
value: "production"
```
## ⚡ 性能优化
### 缓存策略
| 数据类型 | 缓存时间 | 策略 |
|----------|----------|------|
| 反馈列表 | 5分钟 | 按用户+条件缓存 |
| 反馈详情 | 10分钟 | 按ID缓存 |
| 用户信息 | 30分钟 | 按用户ID缓存 |
### 数据库优化
- **索引优化**: 关键字段建立复合索引
- **查询优化**: 使用预加载减少N+1查询
- **连接池**: 配置合适的连接池大小
- **读写分离**: 支持主从数据库配置
### 监控指标
```bash
# 服务健康检查
curl http://localhost:12102/health
# 性能指标
curl http://localhost:12102/metrics
```
## 🔧 配置说明
### 环境配置文件
```yaml
# etc/feedback_prod.yaml
Service: feedback
Port: 12101
# 数据库配置
Databases:
Driver: postgres
Source:
- host=db-host user=postgres password=*** dbname=feedback_db port=5432 sslmode=require
# 缓存配置
Cache: redis://username:password@redis-host:6379/0
# 网关配置
Gateway:
Enable: true
Port: 12102
# 微服务配置
MicroService:
Enable: true
Registry: etcd://etcd-cluster:2379
# APM监控
APM:
Platform: elasticAPM
Endpoint: http://apm-server:8200
```
### 环境变量
| 变量名 | 描述 | 默认值 |
|--------|------|--------|
| `SERVICE_ENV` | 运行环境 | `development` |
| `CONFIG_FILE` | 配置文件路径 | `etc/feedback_dev.yaml` |
| `LOG_LEVEL` | 日志级别 | `info` |
| `TZ` | 时区设置 | `Asia/Shanghai` |
## 🐛 故障排除
### 常见问题
1. **服务启动失败**
```bash
# 检查端口占用
netstat -tlnp | grep :12101
# 检查配置文件
make lint
```
2. **数据库连接失败**
```bash
# 测试数据库连接
psql -h your-db-host -U postgres -d feedback_db -c "SELECT 1;"
```
3. **Redis连接失败**
```bash
# 测试Redis连接
redis-cli -h your-redis-host ping
```
### 日志分析
```bash
# 查看服务日志
tail -f logs/feedback.log
# 查看错误日志
grep ERROR logs/feedback.log
# 查看性能日志
grep "slow query" logs/feedback.log
```
### 性能调优
1. **内存优化**
```bash
# 监控内存使用
go tool pprof http://localhost:6060/debug/pprof/heap
```
2. **CPU优化**
```bash
# CPU性能分析
go tool pprof http://localhost:6060/debug/pprof/profile
```
## 📊 数据模型
### 核心表结构
#### feedback_item - 反馈主表
```sql
CREATE TABLE feedback_item (
id SERIAL PRIMARY KEY,
identity VARCHAR(255) NOT NULL,
passport_id VARCHAR(255) DEFAULT '',
passport_identity VARCHAR(255) DEFAULT '',
category VARCHAR(255) DEFAULT '',
user_name VARCHAR(20) DEFAULT '',
email VARCHAR(255) DEFAULT '',
phone VARCHAR(20) DEFAULT '',
status INTEGER DEFAULT 1,
title VARCHAR(255) DEFAULT '',
content VARCHAR(500) DEFAULT '',
remark VARCHAR(500) DEFAULT '',
agency VARCHAR(255) DEFAULT '',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
#### feedback_images - 反馈图片表
```sql
CREATE TABLE feedback_images (
id SERIAL PRIMARY KEY,
identity VARCHAR(255) NOT NULL,
item_identity VARCHAR(36) DEFAULT '',
url VARCHAR(255) DEFAULT '',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
#### feedback_accessory - 反馈附件表
```sql
CREATE TABLE feedback_accessory (
id SERIAL PRIMARY KEY,
identity VARCHAR(255) NOT NULL,
item_identity VARCHAR(36) DEFAULT '',
title VARCHAR(255) DEFAULT '',
file_path VARCHAR(500) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
## 🤝 贡献指南
### 开发流程
1. **Fork 项目**
2. **创建特性分支**: `git checkout -b feature/amazing-feature`
3. **提交更改**: `git commit -m 'Add amazing feature'`
4. **推送分支**: `git push origin feature/amazing-feature`
5. **创建 Pull Request**
### 代码规范
- 遵循 Go 官方代码规范
- 使用 `gofmt` 格式化代码
- 添加必要的中文注释和文档
- 编写单元测试
### 提交规范
```
type(scope): description
[optional body]
[optional footer]
```
类型:
- `feat`: 新功能
- `fix`: 修复bug
- `docs`: 文档更新
- `style`: 代码格式
- `refactor`: 重构
- `test`: 测试
- `chore`: 构建过程或辅助工具的变动
## 📄 许可证
本项目采用内部许可证,仅供 BSM 内部使用。
## 👥 团队
- **作者**: David Yan (david.yan@qq.com)
- **维护者**: BSM 开发团队
- **项目地址**: [bsm/full/module/base/feedback](https://bsm/full/module/base/feedback)
## 🔗 相关链接
- [BSM SDK](https://git.apinb.com/bsm-sdk)
- [API 文档](https://docs.apinb.com/feedback)
- [问题反馈](https://bsm/full/module/base/feedback/issues)
---
<div align="center">
**⭐ 如果这个项目对你有帮助,请给它一个星标!**
Made with ❤️ by BSM Team
</div>

View File

@@ -0,0 +1,7 @@
package main
import "log"
func main() {
log.Println("Hello World!")
}

View File

@@ -0,0 +1,50 @@
/**
* @Author: david.yan(david.yan@qq.com)
* @Date: 2021-11-26 15:25:03
* @Description: 反馈服务主程序入口
*/
package service
import (
"bsm/full/module/base/feedback/internal/config"
"bsm/full/module/base/feedback/internal/impl"
"bsm/full/module/base/feedback/internal/server"
"git.apinb.com/bsm-sdk/core/service"
)
var (
ServiceKey = "Feedback" // 服务标识符
)
// main 程序入口函数
// 负责初始化配置、服务连接启动gRPC服务和HTTP网关
func Run() {
// 初始化配置
config.New(ServiceKey)
// 初始化各种服务连接
impl.NewImpl()
// 初始化服务
s := server.New(config.Spec.Addr)
srv := service.New(
s.Grpc,
&service.Options{
Addr: config.Spec.Addr, // 服务地址
MsConf: config.Spec.MicroService, // 微服务配置
EtcdClient: impl.EtcdService, // Etcd客户端
GatewayCtx: s.Ctx, // 网关上下文
GatewayConf: config.Spec.Gateway, // 网关配置
GatewayMux: s.Mux, // 网关路由
},
)
// 停止服务
defer srv.Stop()
// 启动服务
srv.Start()
}
func main() {
Run()
}

View File

@@ -0,0 +1,6 @@
Name: feedback.rpc
ListenOn: 0.0.0.0:8080
Etcd:
Hosts:
- 127.0.0.1:2379
Key: feedback.rpc

View File

@@ -0,0 +1,49 @@
Name: {ServiceKey}
ListenOn: 0.0.0.0:12210
Dsn: postgres://postgres:CHANGE_ME@47.109.77.183:5432/milu?sslmode=disable&TimeZone=Asia/Shanghai
# cache DB的选择请在后面直接带参数不带会自动HASH计算选择DB库。
# DB库设置例redis://null:Weidong1214@139.159.232.50:6379/12代表DB12
Cache: redis://null:CHANGE_ME@47.109.77.183:6379/
#
#Etcd:
# Hosts:
# - 127.0.0.1:2379
# Key: service.{Workspace}.{ServiceKey}.rpc
# 匿名访问清单,自动注入网关层
Anonymous:
Key: anonymous.{Workspace}
Urls:
- feedback.Check.Hello
- feedback.Check.Updates
- feedback.Data.Configure
- feedback.Data.Areas
- feedback.Data.Tags
# 日志记录
Log:
ServiceName: {ServiceKey}
Mode: file
Path: logs/{ServiceKey}
Stat: false
# 性能监控
# Prometheus:
# Host: 127.0.0.1
# Port: 22210
# Path: /metrics
# 链路追踪
# Telemetry:
# Name: {Workspace}.{ServiceKey}.{RuntimeMode}
# Endpoint: http://139.159.232.50:14268/api/traces
# Sampler: 1.0
# Batcher: jaeger
# MQ Pulsar
#Pulsar:
# Endpoints: 127.0.0.1
# Token: 9091
# Namespaces: {Workspace}

View File

@@ -0,0 +1,48 @@
Name: {ServiceKey}
ListenOn: 0.0.0.0:12210
Dsn: postgres://prod:MakeW2023~PROD@192.168.0.224:5432/scf?sslmode=disable&TimeZone=Asia/Shanghai
# cache DB的选择请在后面直接带参数不带会自动HASH计算选择DB库。
Cache: redis://null:CHANGE_ME@192.168.0.43:6379/
Etcd:
Hosts:
- 192.168.0.83:2379
Key: service.{Workspace}.{ServiceKey}.rpc
# 匿名访问清单,自动注入网关层
Anonymous:
Key: anonymous.{Workspace}
Urls:
- feedback.Check.Hello
- feedback.Check.Updates
- feedback.Data.Configure
- feedback.Data.Areas
- feedback.Data.Tags
# 日志记录
Log:
ServiceName: {ServiceKey}
Mode: file
Path: logs/{ServiceKey}
Stat: false
# 性能监控
Prometheus:
Host: 127.0.0.1
Port: 22210
Path: /metrics
# 链路追踪
Telemetry:
Name: {Workspace}.{ServiceKey}.{RuntimeMode}
Endpoint: http://139.159.232.50:14268/api/traces
Sampler: 1.0
Batcher: jaeger
# MQ Pulsar
#Pulsar:
# Endpoints: 127.0.0.1
# Token: 9091
# Namespaces: {Workspace}

View File

@@ -0,0 +1,49 @@
Name: {ServiceKey}
ListenOn: 0.0.0.0:12210
Dsn: postgres://postgres:CHANGE_ME@47.108.57.74:5432/milu?sslmode=disable&TimeZone=Asia/Shanghai
# cache DB的选择请在后面直接带参数不带会自动HASH计算选择DB库。
# DB库设置例redis://null:Weidong1214@139.159.232.50:6379/12代表DB12
Cache: redis://null:CHANGE_ME@127.0.0.1:6379/
Etcd:
Hosts:
- 127.0.0.1:2379
Key: service.{Workspace}.{ServiceKey}.rpc
# 匿名访问清单,自动注入网关层
Anonymous:
Key: anonymous.{Workspace}
Urls:
- feedback.Check.Hello
- feedback.Check.Updates
- feedback.Data.Configure
- feedback.Data.Areas
- feedback.Data.Tags
# 日志记录
Log:
ServiceName: {ServiceKey}
Mode: file
Path: logs/{ServiceKey}
Stat: false
# 性能监控
Prometheus:
Host: 127.0.0.1
Port: 22210
Path: /metrics
# 链路追踪
Telemetry:
Name: {Workspace}.{ServiceKey}.{RuntimeMode}
Endpoint: http://139.159.232.50:14268/api/traces
Sampler: 1.0
Batcher: jaeger
# MQ Pulsar
#Pulsar:
# Endpoints: 127.0.0.1
# Token: 9091
# Namespaces: {Workspace}

View File

@@ -0,0 +1,69 @@
module bsm/full/module/base/feedback
go 1.26.5
tool (
git.apinb.com/bsm-tools/protoc-gen-markdown
git.apinb.com/bsm-tools/protoc-gen-slc
git.apinb.com/bsm-tools/protoc-gen-ts
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2
github.com/pepabo/protoc-gen-go-client
google.golang.org/grpc/cmd/protoc-gen-go-grpc
google.golang.org/protobuf/cmd/protoc-gen-go
)
require (
git.apinb.com/bsm-sdk/core v0.2.0
git.apinb.com/bsm-sdk/engine v1.3.2
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0
github.com/patrickmn/go-cache v2.1.0+incompatible
go.etcd.io/etcd/client/v3 v3.7.1
google.golang.org/grpc v1.83.0
google.golang.org/protobuf v1.36.11
gorm.io/gorm v1.31.2
)
require (
filippo.io/edwards25519 v1.2.0 // indirect
git.apinb.com/bsm-tools/protoc-gen-markdown v0.0.0-20250907131213-6c1694ce6bcb // indirect
git.apinb.com/bsm-tools/protoc-gen-slc v0.0.13 // indirect
git.apinb.com/bsm-tools/protoc-gen-ts v0.0.2 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.7.0 // indirect
github.com/ditashi/jsbeautifier-go v0.0.0-20141206144643-2520a8026a9c // indirect
github.com/go-sql-driver/mysql v1.10.0 // indirect
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.10.0 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/oklog/ulid/v2 v2.1.2 // indirect
github.com/pepabo/protoc-gen-go-client v0.3.0 // indirect
github.com/redis/go-redis/v9 v9.22.0 // indirect
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
go.etcd.io/etcd/api/v3 v3.7.1 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.7.1 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.28.0 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/mod v0.37.0 // indirect
golang.org/x/net v0.57.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/text v0.40.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260807164820-c8921c73eeea // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260807164820-c8921c73eeea // indirect
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/driver/mysql v1.6.0 // indirect
gorm.io/driver/postgres v1.6.2 // indirect
)
replace git.apinb.com/bsm-sdk/core => D:/work/bsm-sdk/core

150
module/base/feedback/go.sum Normal file
View File

@@ -0,0 +1,150 @@
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
git.apinb.com/bsm-sdk/engine v1.3.2 h1:QJ20jveUIHcn3Tu0ktrkZI9zGRaPuJRZ+YTbSa1Zj1w=
git.apinb.com/bsm-sdk/engine v1.3.2/go.mod h1:OXRlO6Cdidqagw+LJjCngvpuuX1rwhxDwZlL/MhwiKQ=
git.apinb.com/bsm-tools/protoc-gen-markdown v0.0.0-20250907131213-6c1694ce6bcb h1:GoXhkGzI5vZ9JMXCVsSRw/AGsJY0tM2aEv76YaUg2wM=
git.apinb.com/bsm-tools/protoc-gen-markdown v0.0.0-20250907131213-6c1694ce6bcb/go.mod h1:l+84zWPM4F40Ppar+jLapgjRNt6XWDsr+l0vN4Jjlm4=
git.apinb.com/bsm-tools/protoc-gen-slc v0.0.13 h1:RGg2R2kHz6IAD7scH6So2FlZYctFUDxqWR8i/+fMfOU=
git.apinb.com/bsm-tools/protoc-gen-slc v0.0.13/go.mod h1:NpJaupVAxmyBleRMAug4mGS6BQV2E32rtuiqQzj1b+A=
git.apinb.com/bsm-tools/protoc-gen-ts v0.0.2 h1:T9C1kY6iIHl5cZ7xyNgV2xlPNWxXmaWfTbD8AzpBB9M=
git.apinb.com/bsm-tools/protoc-gen-ts v0.0.2/go.mod h1:5kAPyKSSLL7HcdZvyJa+ICnOiit/O/Z963nQpGJRrao=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
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/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj9KI28KA=
github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ditashi/jsbeautifier-go v0.0.0-20141206144643-2520a8026a9c h1:+Zo5Ca9GH0RoeVZQKzFJcTLoAixx5s5Gq3pTIS+n354=
github.com/ditashi/jsbeautifier-go v0.0.0-20141206144643-2520a8026a9c/go.mod h1:HJGU9ULdREjOcVGZVPB5s6zYmHi1RxzT71l2wQyLmnE=
github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8=
github.com/go-logr/logr v1.4.4/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/go-sql-driver/mysql v1.10.0 h1:Q+1LV8DkHJvSYAdR83XzuhDaTykuDx0l6fkXxoWCWfw=
github.com/go-sql-driver/mysql v1.10.0/go.mod h1:M+cqaI7+xxXGG9swrdeUIoPG3Y3KCkF0pZej+SK+nWk=
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
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/grpc-ecosystem/grpc-gateway/v2 v2.30.0 h1:/Tnpcb2E0Pz/tN9s3bfEY2Q8ePCEX9iuS+cneUwncnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0/go.mod h1:zOBXOsUaBSjKgmH4OGzV1esUpR3oUSCPYVd2cUBjKYY=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0=
github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw=
github.com/klauspost/cpuid/v2 v2.4.0/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU=
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/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/oklog/ulid/v2 v2.1.2 h1:IEclFb9JNvzYA6MW2SCxbLzcHTVsfqm3PrqGQJH5zec=
github.com/oklog/ulid/v2 v2.1.2/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
github.com/pepabo/protoc-gen-go-client v0.3.0 h1:BUlzqqgMXWaEYzGXw1vqLIShP18JV7BMDm45OSLr/AU=
github.com/pepabo/protoc-gen-go-client v0.3.0/go.mod h1:NvHW7/gsmZUK2UxafqzUzWD8zEMY0lMmm+2kLVxx8Jc=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis/v9 v9.22.0 h1:laDvpYXTJtZLloinw1fA5Kqd6HAEH2XKxOkG/PDq2F0=
github.com/redis/go-redis/v9 v9.22.0/go.mod h1:y2g0Wj8rQvuK0ELM+oxSudcLtC09JScs98I/X9gRWY4=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs=
github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s=
go.etcd.io/etcd/api/v3 v3.7.1 h1:KJG0/DcWGfe3Y1otDf/fsBf0TSSgpxZ5RO/L8SFt73E=
go.etcd.io/etcd/api/v3 v3.7.1/go.mod h1:8bXIpCMeV7E3/XL0Ix123ATn3dB+0V7d9zklHbB0m78=
go.etcd.io/etcd/client/pkg/v3 v3.7.1 h1:rKYsj3pRkR0eK3yjT3XOgrhqfmIfj9pzNgxjh7mfFv4=
go.etcd.io/etcd/client/pkg/v3 v3.7.1/go.mod h1:cnzZGIUzSfjEwLC6UBVsSXlEK1eepS/JUD7wE6PLRT0=
go.etcd.io/etcd/client/v3 v3.7.1 h1:0PEMMC0KuZmVIN+RAbdqfkZ45pYTgKVtmBEbRCvZFUg=
go.etcd.io/etcd/client/v3 v3.7.1/go.mod h1:ffNqALa8tRCYhYo1F9oR489y23K39Gz+BSR3ApAGYq0=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU=
go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ=
go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M=
go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s=
go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw=
go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA=
go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag=
go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo=
go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q=
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/genproto/googleapis/api v0.0.0-20260807164820-c8921c73eeea h1:Jifw/kjs/r3B0uszvls/m3c3tmZs2YHGM9C+rvxP9gY=
google.golang.org/genproto/googleapis/api v0.0.0-20260807164820-c8921c73eeea/go.mod h1:K/+WGbmBY7aNW1HDw1fJnKYo10i0DkAX6pows00dLig=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260807164820-c8921c73eeea h1:kVhQEPTpKQahD5+JSBTfBB19wcgQTTjAIn45MBqnyHk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260807164820-c8921c73eeea/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.83.0 h1:JeNZEKJFbQxArAMl+hiytHauacDNqJUllNfmIMmpqnQ=
google.golang.org/grpc v1.83.0/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2 h1:rgSNvqscFZ1JgV/4wH5GOsZFSFkR2Eua9As3KIr2LlM=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2/go.mod h1:iMEtFwDlAhjDU9L5mY6U1XLwlIId/G3h+QcBHDIvrJ8=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
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/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=
gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg=
gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo=
gorm.io/driver/postgres v1.6.2 h1:BvXQ/cNUg63q5TFNg672DmDcowZSFrNLkkA3Xe6GXq4=
gorm.io/driver/postgres v1.6.2/go.mod h1:0c4fQA44XhOklXDkgtuKqysHCycTa5i9e3EIpDGCwXk=
gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
gorm.io/gorm v1.31.2 h1:3o8FXNo9v9S858gil+3LlZA1LkCOzgb4g5BL64FgaCo=
gorm.io/gorm v1.31.2/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=

View File

@@ -0,0 +1,45 @@
// Package config 配置管理包,负责服务的配置初始化和管理
package config
import (
"net"
"git.apinb.com/bsm-sdk/core/conf"
"git.apinb.com/bsm-sdk/core/crypto/encipher"
"git.apinb.com/bsm-sdk/core/env"
)
var (
Spec SrvConfig // 全局服务配置实例
)
// SrvConfig 服务配置结构体
type SrvConfig struct {
conf.Base `yaml:",inline"` // 基础配置
Databases *conf.DBConf `yaml:"Databases"` // 数据库配置
MicroService *conf.MicroServiceConf `yaml:"MicroService"` // 微服务配置
Rpc map[string]conf.RpcConf `yaml:"Rpc"` // RPC配置
Gateway *conf.GatewayConf `yaml:"Gateway"` // 网关配置
Apm *conf.ApmConf `yaml:"APM"` // APM监控配置
Etcd *conf.EtcdConf `yaml:"Etcd"` // Etcd配置
}
// New 初始化服务配置
// srvKey: 服务标识符,用于配置文件的命名
func New(srvKey string) {
// 初始化配置 创建一个新的配置实例,用于服务配置
conf.New(srvKey, &Spec)
// 配置校验 服务IP,端口; 端口如果不合规,则随机分配端口
Spec.Port = conf.CheckPort(Spec.Port)
Spec.BindIP = conf.CheckIP(Spec.BindIP)
Spec.Addr = net.JoinHostPort(Spec.BindIP, Spec.Port)
// 配置校验 服务名称地址及监听地址不能为空
conf.NotNil(Spec.Service, Spec.Cache)
// 初始化加密SecretKey
encipher.New(env.Runtime.JwtSecretKey)
conf.PrintInfo(Spec.Addr)
}

View File

@@ -0,0 +1,31 @@
// Package impl 实现层,负责初始化各种服务连接
package impl
import (
"bsm/full/module/base/feedback/internal/config"
"git.apinb.com/bsm-sdk/core/cache/redis"
"git.apinb.com/bsm-sdk/core/with"
cache "github.com/patrickmn/go-cache"
clientv3 "go.etcd.io/etcd/client/v3"
"gorm.io/gorm"
)
var (
RedisService *redis.RedisClient // Redis缓存服务
EtcdService *clientv3.Client // Etcd服务发现客户端
DBService *gorm.DB // 数据库服务
MemorySerice *cache.Cache // 内存缓存服务
)
// NewImpl 初始化各种服务连接
// 包括内存缓存、Redis缓存、数据库连接和Etcd服务发现
func NewImpl() {
// 初始化内存缓存服务
MemorySerice = with.Memory(nil)
// 初始化Redis缓存服务
RedisService = with.RedisCache(config.Spec.Cache)
// 初始化数据库连接
DBService = with.Databases(config.Spec.Databases, nil)
// 初始化Etcd服务发现客户端
EtcdService = with.Etcd(config.Spec.Etcd)
}

View File

@@ -0,0 +1,75 @@
// Package method 业务逻辑方法包,实现反馈相关的业务操作
package method
import (
"context"
"bsm/full/module/base/feedback/internal/impl"
"bsm/full/module/base/feedback/internal/models"
pb "bsm/full/module/base/feedback/pb"
"git.apinb.com/bsm-sdk/core/service"
"git.apinb.com/bsm-sdk/core/types"
"git.apinb.com/bsm-sdk/core/utils"
)
// Add 添加新的反馈记录
// ctx: 上下文,包含用户认证信息
// in: 添加请求参数
// 返回: 添加结果包含新创建的记录ID
func Add(ctx context.Context, in *pb.AddRequest) (reply *pb.AddReply, err error) {
// 解析用户认证信息
auth, err := service.ParseMetaCtx(ctx, nil)
if err != nil {
return nil, err
}
// 构建反馈记录
record := &models.FeedbackItem{
Std_IICUDS: types.Std_IICUDS{
Identity: utils.UUID(), // 生成唯一标识
},
Std_Passport: types.Std_Passport{
PassportID: auth.ID, // 用户ID
PassportIdentity: auth.Identity, // 用户身份标识
},
UserName: in.GetUserName(), // 用户名
Status: in.GetStatus(), // 状态
Email: in.GetEmail(), // 邮箱
Phone: in.GetPhone(), // 手机号
Title: in.GetTitle(), // 标题
Content: in.GetContent(), // 内容
Images: make([]models.FeedbackImage, 0, len(in.GetImages())), // 图片列表
Accessories: make([]models.FeedbackAccessory, 0, len(in.GetAccessories())), // 附件列表
}
// 处理图片信息
for _, v := range in.GetImages() {
record.Images = append(record.Images, models.FeedbackImage{
Std_IICUDS: types.Std_IICUDS{
Identity: utils.UUID(), // 生成图片唯一标识
},
ItemIdentity: record.Identity, // 关联的反馈记录ID
URL: v.GetUrl(), // 图片URL
})
}
// 处理附件信息
for _, v := range in.GetAccessories() {
record.Accessories = append(record.Accessories, models.FeedbackAccessory{
Std_IICUDS: types.Std_IICUDS{
Identity: utils.UUID(), // 生成附件唯一标识
},
ItemIdentity: record.Identity, // 关联的反馈记录ID
Title: v.Title, // 附件标题
FilePath: v.FilePath, // 附件文件路径
})
}
// 保存到数据库
err = impl.DBService.Create(record).Error
if err != nil {
return nil, err
}
return &pb.AddReply{Identity: record.Identity}, nil
}

View File

@@ -0,0 +1,35 @@
// Package method 业务逻辑方法包,实现反馈相关的业务操作
package method
import (
"context"
"time"
"bsm/full/module/base/feedback/internal/impl"
"bsm/full/module/base/feedback/internal/models"
pb "bsm/full/module/base/feedback/pb"
"git.apinb.com/bsm-sdk/core/vars"
"git.apinb.com/bsm-sdk/engine/exception"
)
// Delete 删除反馈记录
// ctx: 上下文
// in: 删除请求参数包含记录ID
// 返回: 删除操作结果
func Delete(ctx context.Context, in *pb.DeleteRequest) (reply *pb.StatusReply, err error) {
// 验证请求参数
if in.GetIdentity() == "" {
return nil, exception.ErrInvalidArgument
}
// 删除记录GORM会自动处理关联的图片和附件删除
err = impl.DBService.Where("identity = ?", in.GetIdentity()).Delete(new(models.FeedbackItem)).Error
if err != nil {
return nil, err
}
return &pb.StatusReply{
Message: vars.OK,
Timeseq: time.Now().UnixMilli(),
}, nil
}

View File

@@ -0,0 +1,42 @@
// Package method 业务逻辑方法包,实现反馈相关的业务操作
package method
import (
"context"
"errors"
"bsm/full/module/base/feedback/internal/impl"
"bsm/full/module/base/feedback/internal/models"
pb "bsm/full/module/base/feedback/pb"
"git.apinb.com/bsm-sdk/engine/exception"
"gorm.io/gorm"
)
// Get 根据ID获取反馈记录详情
// ctx: 上下文
// in: 查询请求参数包含记录ID
// 返回: 反馈记录详情
func Get(ctx context.Context, in *pb.GetRequest) (reply *pb.GetReply, err error) {
// 验证请求参数
if in.GetIdentity() == "" {
return nil, exception.ErrInvalidArgument
}
out := new(pb.GetReply)
record := new(models.FeedbackItem)
// 查询记录,预加载关联的图片信息
err = impl.DBService.Preload("Images").Where("identity = ?", in.GetIdentity()).First(record).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, exception.ErrNotFound
}
return nil, err
}
// 转换为响应格式
item := convert(*record)
out.Record = item
out.Exists = true
return out, nil
}

View File

@@ -0,0 +1,87 @@
// Package method 业务逻辑方法包,实现反馈相关的业务操作
package method
import (
"context"
"bsm/full/module/base/feedback/internal/impl"
"bsm/full/module/base/feedback/internal/models"
pb "bsm/full/module/base/feedback/pb"
"git.apinb.com/bsm-sdk/core/service"
)
// List 获取反馈记录列表
// ctx: 上下文,包含用户认证信息
// in: 查询请求参数,包含分页、筛选条件等
// 返回: 反馈记录列表和总数
func List(ctx context.Context, in *pb.ListRequest) (reply *pb.ListReply, err error) {
// 解析用户认证信息
auth, err := service.ParseMetaCtx(ctx, nil)
if err != nil {
return nil, err
}
// 分页参数校验和设置
if in.GetPage() < 1 {
in.Page = 1
}
size := in.GetSize()
if size < 1 || size > 50 {
in.Size = 10
}
offset := (in.Page - 1) * in.GetSize()
// 构建查询会话,预加载图片信息
sess := impl.DBService.Preload("Images")
// 根据机构筛选或用户身份筛选
if in.GetAgency() != "" {
sess = sess.Where("agency = ?", in.GetAgency())
} else {
userIdentity := auth.Identity
if userIdentity != "" {
sess = sess.Where("passport_identity = ?", userIdentity)
}
}
// 用户名筛选
username := in.GetUserName()
if username != "" {
sess = sess.Where("username = ?", username)
}
// 状态筛选
status := in.GetStatus()
if status != 0 {
sess = sess.Where("status = ?", status)
}
// 分类筛选
category := in.GetCategory()
if category != "" {
sess = sess.Where("category = ?", category)
}
var (
list []models.FeedbackItem
count int64
)
// 执行查询,按创建时间倒序排列
if err := sess.Limit(int(in.GetSize())).Offset(int(offset)).Order("created_at desc").Find(&list).Count(&count).Error; err != nil {
return nil, err
}
// 构建响应结果
out := &pb.ListReply{
Count: count,
List: make([]*pb.FeedbackItem, 0, len(list)),
}
// 转换数据格式
for _, v := range list {
item := convert(v)
out.List = append(out.List, item)
}
return out, nil
}

View File

@@ -0,0 +1,112 @@
// Package method 业务逻辑方法包,实现反馈相关的业务操作
package method
import (
"context"
"time"
"bsm/full/module/base/feedback/internal/impl"
"bsm/full/module/base/feedback/internal/models"
pb "bsm/full/module/base/feedback/pb"
"git.apinb.com/bsm-sdk/core/service"
"git.apinb.com/bsm-sdk/core/types"
"git.apinb.com/bsm-sdk/core/utils"
"git.apinb.com/bsm-sdk/core/vars"
"git.apinb.com/bsm-sdk/engine/exception"
)
// Modify 修改反馈记录
// ctx: 上下文,包含用户认证信息
// in: 修改请求参数包含记录ID和要修改的字段
// 返回: 修改操作结果
func Modify(ctx context.Context, in *pb.ModifyRequest) (reply *pb.StatusReply, err error) {
// 解析用户认证信息
auth, err := service.ParseMetaCtx(ctx, nil)
if err != nil {
return nil, err
}
// 验证请求参数
if in.GetIdentity() == "" {
return nil, exception.ErrInvalidArgument
}
// 构建更新记录
record := &models.FeedbackItem{
Std_IICUDS: types.Std_IICUDS{
Identity: utils.UUID(),
},
Std_Passport: types.Std_Passport{
PassportID: auth.ID, // 用户ID
PassportIdentity: auth.Identity, // 用户身份标识
},
UserName: in.GetUserName(), // 用户名
Email: in.GetEmail(), // 邮箱
Phone: in.GetPhone(), // 手机号
Status: in.GetStatus(), // 状态
Title: in.GetTitle(), // 标题
Content: in.GetContent(), // 内容
Category: in.GetCategory(), // 分类
Images: make([]models.FeedbackImage, 0, len(in.GetImages())), // 图片列表
Accessories: make([]models.FeedbackAccessory, 0, len(in.GetAccessories())), // 附件列表
}
// 处理图片信息
for _, v := range in.GetImages() {
identity := v.GetIdentity()
if identity == "" {
identity = utils.UUID() // 生成新的图片ID
}
record.Images = append(record.Images, models.FeedbackImage{
Std_IICUDS: types.Std_IICUDS{
Identity: identity,
},
ItemIdentity: in.GetIdentity(), // 关联的反馈记录ID
URL: v.GetUrl(), // 图片URL
})
}
// 处理附件信息
for _, v := range in.GetAccessories() {
record.Accessories = append(record.Accessories, models.FeedbackAccessory{
ItemIdentity: in.GetIdentity(), // 关联的反馈记录ID
Title: v.Title, // 附件标题
FilePath: v.FilePath, // 附件文件路径
})
}
// 先删除关联的图片和附件
err = impl.DBService.Where("item_identity = ?", in.GetIdentity()).Delete(&models.FeedbackImage{}).Error
if err != nil {
return nil, err
}
err = impl.DBService.Where("item_identity = ?", in.GetIdentity()).Delete(&models.FeedbackAccessory{}).Error
if err != nil {
return nil, err
}
// 更新主记录
err = impl.DBService.Where("identity = ?", in.GetIdentity()).Updates(record).Error
if err != nil {
return nil, err
}
// 重新创建关联的图片和附件
if len(record.Images) > 0 {
err = impl.DBService.Create(&record.Images).Error
if err != nil {
return nil, err
}
}
if len(record.Accessories) > 0 {
err = impl.DBService.Create(&record.Accessories).Error
if err != nil {
return nil, err
}
}
return &pb.StatusReply{
Message: vars.OK,
Timeseq: time.Now().UnixMilli(),
}, nil
}

View File

@@ -0,0 +1,48 @@
// Package method 业务逻辑方法包,实现反馈相关的业务操作
package method
import (
"bsm/full/module/base/feedback/internal/models"
pb "bsm/full/module/base/feedback/pb"
"git.apinb.com/bsm-sdk/core/vars"
)
// convert 将数据库模型转换为protobuf响应格式
// item: 数据库中的反馈记录模型
// 返回: protobuf格式的反馈记录指针
func convert(item models.FeedbackItem) *pb.FeedbackItem {
reply := &pb.FeedbackItem{
Identity: item.Identity, // 记录唯一标识
UserName: item.UserName, // 用户名
Email: item.Email, // 邮箱
Phone: item.Phone, // 手机号
Status: item.Status, // 状态
Title: item.Title, // 标题
Content: item.Content, // 内容
Remark: item.Remark, // 备注
Category: item.Category, // 分类
CreatedAt: item.CreatedAt.Format(vars.YYYY_MM_DD_HH_MM_SS), // 创建时间
UpdatedAt: item.UpdatedAt.Format(vars.YYYY_MM_DD_HH_MM_SS), // 更新时间
}
// 转换图片信息
for _, image := range item.Images {
reply.Images = append(reply.Images, &pb.FeedbackImage{
Identity: image.Identity, // 图片唯一标识
ItemIdentity: image.ItemIdentity, // 关联的反馈记录ID
Url: image.URL, // 图片URL
})
}
// 转换附件信息
for _, accessory := range item.Accessories {
reply.Accessories = append(reply.Accessories, &pb.FeedbackAccessory{
Identity: accessory.Identity, // 附件唯一标识
ItemIdentity: accessory.ItemIdentity, // 关联的反馈记录ID
Title: accessory.Title, // 附件标题
FilePath: accessory.FilePath, // 附件文件路径
})
}
return reply
}

View File

@@ -0,0 +1,41 @@
// Package method 业务逻辑方法包,实现反馈相关的业务操作
package method
import (
"context"
"time"
"bsm/full/module/base/feedback/internal/impl"
"bsm/full/module/base/feedback/internal/models"
pb "bsm/full/module/base/feedback/pb"
"git.apinb.com/bsm-sdk/core/vars"
"git.apinb.com/bsm-sdk/engine/exception"
)
// Remark 添加或更新反馈记录的备注和状态
// ctx: 上下文
// in: 备注请求参数包含记录ID、备注内容和状态
// 返回: 操作结果
func Remark(ctx context.Context, in *pb.RemarkRequest) (reply *pb.StatusReply, err error) {
// 验证请求参数
if in.GetIdentity() == "" {
return nil, exception.ErrInvalidArgument
}
// 构建更新记录
record := &models.FeedbackItem{
Remark: in.GetRemark(), // 备注内容
Status: in.GetStatus(), // 状态
}
// 更新记录的备注和状态
err = impl.DBService.Where("identity = ?", in.GetIdentity()).Updates(record).Error
if err != nil {
return nil, err
}
return &pb.StatusReply{
Message: vars.OK,
Timeseq: time.Now().UnixMilli(),
}, nil
}

View File

@@ -0,0 +1,26 @@
// Package models 数据模型包,定义反馈相关的数据库模型
package models
import (
"git.apinb.com/bsm-sdk/core/database"
"git.apinb.com/bsm-sdk/core/types"
)
// FeedbackAccessory 反馈附件模型
// 用于存储反馈记录关联的附件信息
type FeedbackAccessory struct {
types.Std_IICUDS // 标准IICUDS字段ID、Identity、CreatedAt、UpdatedAt、Status
ItemIdentity string `gorm:"column:item_identity;type:varchar(36);default:'';" json:"item_identity"` // 关联的反馈记录ID
Title string `gorm:"column:title;type:varchar(255);default:''" json:"title"` // 附件标题
FilePath string `gorm:"column:file_path;type:varchar(500);not null" json:"file_path"` // 附件文件地址
}
func init() {
// 注册模型到数据库迁移表
database.MigrateTables = append(database.MigrateTables, &FeedbackAccessory{})
}
// TableName 返回数据库表名
func (c *FeedbackAccessory) TableName() string {
return "feedback_accessory" // 对应数据库表名
}

View File

@@ -0,0 +1,25 @@
// Package models 数据模型包,定义反馈相关的数据库模型
package models
import (
"git.apinb.com/bsm-sdk/core/database"
"git.apinb.com/bsm-sdk/core/types"
)
// FeedbackImage 反馈图片模型
// 用于存储反馈记录关联的图片信息
type FeedbackImage struct {
types.Std_IICUDS // 标准IICUDS字段ID、Identity、CreatedAt、UpdatedAt、Status
ItemIdentity string `gorm:"column:item_identity;type:varchar(36);default:'';" json:"item_identity"` // 关联的反馈记录ID
URL string `gorm:"column:url;type:varchar(255);default:'';" json:"url"` // 图片URL地址
}
func init() {
// 注册模型到数据库迁移表
database.MigrateTables = append(database.MigrateTables, &FeedbackImage{})
}
// TableName 返回数据库表名
func (FeedbackImage) TableName() string {
return "feedback_images" // 对应数据库表名
}

View File

@@ -0,0 +1,35 @@
// Package models 数据模型包,定义反馈相关的数据库模型
package models
import (
"git.apinb.com/bsm-sdk/core/database"
"git.apinb.com/bsm-sdk/core/types"
)
// FeedbackItem 反馈记录模型
// 用于存储用户反馈的基本信息和关联数据
type FeedbackItem struct {
types.Std_IICUDS // 标准IICUDS字段ID、Identity、CreatedAt、UpdatedAt、Status
types.Std_Passport // 标准Passport字段用户身份信息
Category string `gorm:"column:category;type:varchar(255);default:'';" json:"category"` // 分类
UserName string `gorm:"column:user_name;type:varchar(20);default:'';" json:"user_name"` // 用户名
Email string `gorm:"column:email;type:varchar(255);default:'';" json:"email"` // 邮箱
Phone string `gorm:"column:phone;type:varchar(20);default:'';" json:"phone"` // 手机号码
Status int32 `gorm:"column:status;default:1;" json:"status"` // 状态,1未处理,2已处理,也可以调用方自行设置,如果未设置则默认是1
Title string `gorm:"column:title;type:varchar(255);default:'';" json:"title"` // 标题
Content string `gorm:"column:content;type:varchar(500);" json:"content"` // 内容
Remark string `gorm:"column:remark;type:varchar(500);" json:"remark"` // 备注
Agency string `gorm:"column:agency;type:varchar(255);default:'';" json:"agency"` // 机构
Images []FeedbackImage `gorm:"foreignKey:ItemIdentity;references:Identity" json:"images"` // 图片列表
Accessories []FeedbackAccessory `gorm:"foreignKey:ItemIdentity;references:Identity" json:"accessories"` // 附件列表
}
func init() {
// 注册模型到数据库迁移表
database.MigrateTables = append(database.MigrateTables, &FeedbackItem{})
}
// TableName 返回数据库表名
func (FeedbackItem) TableName() string {
return "feedback_item" // 对应数据库表名
}

View File

@@ -0,0 +1,40 @@
// Code generated by protoc-gen-slc. DO NOT EDIT.
package server
import (
"context"
"bsm/full/module/base/feedback/internal/logic/method"
pb "bsm/full/module/base/feedback/pb"
)
type MethodServer struct {
pb.UnimplementedMethodServer
}
func NewMethodServer() *MethodServer {
return &MethodServer{}
}
func (s *MethodServer) List(ctx context.Context, in *pb.ListRequest) (*pb.ListReply, error) {
return method.List(ctx, in)
}
func (s *MethodServer) Get(ctx context.Context, in *pb.GetRequest) (*pb.GetReply, error) {
return method.Get(ctx, in)
}
func (s *MethodServer) Add(ctx context.Context, in *pb.AddRequest) (*pb.AddReply, error) {
return method.Add(ctx, in)
}
func (s *MethodServer) Modify(ctx context.Context, in *pb.ModifyRequest) (*pb.StatusReply, error) {
return method.Modify(ctx, in)
}
func (s *MethodServer) Delete(ctx context.Context, in *pb.DeleteRequest) (*pb.StatusReply, error) {
return method.Delete(ctx, in)
}
func (s *MethodServer) Remark(ctx context.Context, in *pb.RemarkRequest) (*pb.StatusReply, error) {
return method.Remark(ctx, in)
}

View File

@@ -0,0 +1,91 @@
// Code generated by protoc-gen-slc. DO NOT EDIT.
package server
import (
"context"
pb "bsm/full/module/base/feedback/pb"
"git.apinb.com/bsm-sdk/core/vars"
gwRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"
"google.golang.org/protobuf/proto"
"net/http"
"os"
"strings"
"time"
)
type Server struct {
Grpc *grpc.Server
Ctx context.Context
Mux *gwRuntime.ServeMux
grpcConns map[string]*grpc.ClientConn // 连接池
}
func New(addr string) *Server {
srv := &Server{
Ctx: context.Background(),
Grpc: grpc.NewServer(),
Mux: gwRuntime.NewServeMux(gwRuntime.WithForwardResponseRewriter(responseEnvelope)),
grpcConns: make(map[string]*grpc.ClientConn),
}
// register service to grpc.Server
pb.RegisterMethodServer(srv.Grpc, NewMethodServer())
reflection.Register(srv.Grpc)
// 连接池: 只创建一次连接并复用
conn, ok := srv.grpcConns[addr]
if !ok {
var err error
conn, err = grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
panic("failed to dial grpc server: " + err.Error())
}
srv.grpcConns[addr] = conn
}
// 将服务注册到Gateway
if err := pb.RegisterMethodHandler(srv.Ctx, srv.Mux, conn); err != nil {
panic("Failed to register Method handler: " + err.Error())
}
// Register services swagger
srv.RegisterSwagger()
return srv
}
// RegisterSwagger 注册swagger
func (s *Server) RegisterSwagger() {
srvKey := strings.ToLower(vars.ServiceKey)
s.Mux.HandlePath("GET", "/"+srvKey+".swagger.json", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
w.Header().Set("Content-Type", "application/json")
bytes, err := os.ReadFile("./swagger/" + srvKey + ".swagger.json")
if err != nil {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(err.Error()))
return
}
w.Write(bytes)
return
})
}
// response envelope
func responseEnvelope(_ context.Context, response proto.Message) (interface{}, error) {
name := string(response.ProtoReflect().Descriptor().Name())
if name == "Status" || name == "Error" || name == "StatusReply" {
return response, nil
}
return map[string]any{
"code": 0,
"message": vars.OK,
"details": response,
"timeseq": time.Now().Unix(),
}, nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,487 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: feedback.proto
/*
Package feedback is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package feedback
import (
"context"
"errors"
"io"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)
// Suppress "imported and not used" errors
var (
_ codes.Code
_ io.Reader
_ status.Status
_ = errors.New
_ = runtime.String
_ = utilities.NewDoubleArray
_ = metadata.Join
)
func request_Method_List_0(ctx context.Context, marshaler runtime.Marshaler, client MethodClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq ListRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.List(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Method_List_0(ctx context.Context, marshaler runtime.Marshaler, server MethodServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq ListRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.List(ctx, &protoReq)
return msg, metadata, err
}
func request_Method_Get_0(ctx context.Context, marshaler runtime.Marshaler, client MethodClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Get(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Method_Get_0(ctx context.Context, marshaler runtime.Marshaler, server MethodServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Get(ctx, &protoReq)
return msg, metadata, err
}
func request_Method_Add_0(ctx context.Context, marshaler runtime.Marshaler, client MethodClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq AddRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Add(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Method_Add_0(ctx context.Context, marshaler runtime.Marshaler, server MethodServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq AddRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Add(ctx, &protoReq)
return msg, metadata, err
}
func request_Method_Modify_0(ctx context.Context, marshaler runtime.Marshaler, client MethodClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq ModifyRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Modify(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Method_Modify_0(ctx context.Context, marshaler runtime.Marshaler, server MethodServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq ModifyRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Modify(ctx, &protoReq)
return msg, metadata, err
}
func request_Method_Delete_0(ctx context.Context, marshaler runtime.Marshaler, client MethodClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq DeleteRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Delete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Method_Delete_0(ctx context.Context, marshaler runtime.Marshaler, server MethodServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq DeleteRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Delete(ctx, &protoReq)
return msg, metadata, err
}
func request_Method_Remark_0(ctx context.Context, marshaler runtime.Marshaler, client MethodClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq RemarkRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Remark(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Method_Remark_0(ctx context.Context, marshaler runtime.Marshaler, server MethodServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq RemarkRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Remark(ctx, &protoReq)
return msg, metadata, err
}
// RegisterMethodHandlerServer registers the http handlers for service Method to "mux".
// UnaryRPC :call MethodServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterMethodHandlerFromEndpoint instead.
// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call.
func RegisterMethodHandlerServer(ctx context.Context, mux *runtime.ServeMux, server MethodServer) error {
mux.Handle(http.MethodPost, pattern_Method_List_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/feedback.Method/List", runtime.WithHTTPPathPattern("/feedback.Method/List"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Method_List_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Method_List_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_Method_Get_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/feedback.Method/Get", runtime.WithHTTPPathPattern("/feedback.Method/Get"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Method_Get_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Method_Get_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_Method_Add_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/feedback.Method/Add", runtime.WithHTTPPathPattern("/feedback.Method/Add"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Method_Add_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Method_Add_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_Method_Modify_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/feedback.Method/Modify", runtime.WithHTTPPathPattern("/feedback.Method/Modify"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Method_Modify_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Method_Modify_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_Method_Delete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/feedback.Method/Delete", runtime.WithHTTPPathPattern("/feedback.Method/Delete"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Method_Delete_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Method_Delete_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_Method_Remark_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/feedback.Method/Remark", runtime.WithHTTPPathPattern("/feedback.Method/Remark"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Method_Remark_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Method_Remark_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterMethodHandlerFromEndpoint is same as RegisterMethodHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterMethodHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.NewClient(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterMethodHandler(ctx, mux, conn)
}
// RegisterMethodHandler registers the http handlers for service Method to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterMethodHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterMethodHandlerClient(ctx, mux, NewMethodClient(conn))
}
// RegisterMethodHandlerClient registers the http handlers for service Method
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "MethodClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "MethodClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "MethodClient" to call the correct interceptors. This client ignores the HTTP middlewares.
func RegisterMethodHandlerClient(ctx context.Context, mux *runtime.ServeMux, client MethodClient) error {
mux.Handle(http.MethodPost, pattern_Method_List_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/feedback.Method/List", runtime.WithHTTPPathPattern("/feedback.Method/List"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Method_List_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Method_List_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_Method_Get_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/feedback.Method/Get", runtime.WithHTTPPathPattern("/feedback.Method/Get"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Method_Get_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Method_Get_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_Method_Add_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/feedback.Method/Add", runtime.WithHTTPPathPattern("/feedback.Method/Add"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Method_Add_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Method_Add_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_Method_Modify_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/feedback.Method/Modify", runtime.WithHTTPPathPattern("/feedback.Method/Modify"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Method_Modify_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Method_Modify_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_Method_Delete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/feedback.Method/Delete", runtime.WithHTTPPathPattern("/feedback.Method/Delete"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Method_Delete_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Method_Delete_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_Method_Remark_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/feedback.Method/Remark", runtime.WithHTTPPathPattern("/feedback.Method/Remark"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Method_Remark_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Method_Remark_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_Method_List_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"feedback.Method", "List"}, ""))
pattern_Method_Get_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"feedback.Method", "Get"}, ""))
pattern_Method_Add_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"feedback.Method", "Add"}, ""))
pattern_Method_Modify_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"feedback.Method", "Modify"}, ""))
pattern_Method_Delete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"feedback.Method", "Delete"}, ""))
pattern_Method_Remark_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"feedback.Method", "Remark"}, ""))
)
var (
forward_Method_List_0 = runtime.ForwardResponseMessage
forward_Method_Get_0 = runtime.ForwardResponseMessage
forward_Method_Add_0 = runtime.ForwardResponseMessage
forward_Method_Modify_0 = runtime.ForwardResponseMessage
forward_Method_Delete_0 = runtime.ForwardResponseMessage
forward_Method_Remark_0 = runtime.ForwardResponseMessage
)

View File

@@ -0,0 +1,315 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc (unknown)
// source: feedback.proto
package feedback
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.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
Method_List_FullMethodName = "/feedback.Method/List"
Method_Get_FullMethodName = "/feedback.Method/Get"
Method_Add_FullMethodName = "/feedback.Method/Add"
Method_Modify_FullMethodName = "/feedback.Method/Modify"
Method_Delete_FullMethodName = "/feedback.Method/Delete"
Method_Remark_FullMethodName = "/feedback.Method/Remark"
)
// MethodClient is the client API for Method 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.
//
// Feedback-建议反馈模块
type MethodClient interface {
List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListReply, error)
Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetReply, error)
Add(ctx context.Context, in *AddRequest, opts ...grpc.CallOption) (*AddReply, error)
Modify(ctx context.Context, in *ModifyRequest, opts ...grpc.CallOption) (*StatusReply, error)
Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*StatusReply, error)
Remark(ctx context.Context, in *RemarkRequest, opts ...grpc.CallOption) (*StatusReply, error)
}
type methodClient struct {
cc grpc.ClientConnInterface
}
func NewMethodClient(cc grpc.ClientConnInterface) MethodClient {
return &methodClient{cc}
}
func (c *methodClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListReply, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListReply)
err := c.cc.Invoke(ctx, Method_List_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *methodClient) Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetReply, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetReply)
err := c.cc.Invoke(ctx, Method_Get_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *methodClient) Add(ctx context.Context, in *AddRequest, opts ...grpc.CallOption) (*AddReply, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AddReply)
err := c.cc.Invoke(ctx, Method_Add_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *methodClient) Modify(ctx context.Context, in *ModifyRequest, opts ...grpc.CallOption) (*StatusReply, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(StatusReply)
err := c.cc.Invoke(ctx, Method_Modify_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *methodClient) Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*StatusReply, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(StatusReply)
err := c.cc.Invoke(ctx, Method_Delete_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *methodClient) Remark(ctx context.Context, in *RemarkRequest, opts ...grpc.CallOption) (*StatusReply, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(StatusReply)
err := c.cc.Invoke(ctx, Method_Remark_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// MethodServer is the server API for Method service.
// All implementations must embed UnimplementedMethodServer
// for forward compatibility.
//
// Feedback-建议反馈模块
type MethodServer interface {
List(context.Context, *ListRequest) (*ListReply, error)
Get(context.Context, *GetRequest) (*GetReply, error)
Add(context.Context, *AddRequest) (*AddReply, error)
Modify(context.Context, *ModifyRequest) (*StatusReply, error)
Delete(context.Context, *DeleteRequest) (*StatusReply, error)
Remark(context.Context, *RemarkRequest) (*StatusReply, error)
mustEmbedUnimplementedMethodServer()
}
// UnimplementedMethodServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedMethodServer struct{}
func (UnimplementedMethodServer) List(context.Context, *ListRequest) (*ListReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method List not implemented")
}
func (UnimplementedMethodServer) Get(context.Context, *GetRequest) (*GetReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Get not implemented")
}
func (UnimplementedMethodServer) Add(context.Context, *AddRequest) (*AddReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Add not implemented")
}
func (UnimplementedMethodServer) Modify(context.Context, *ModifyRequest) (*StatusReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Modify not implemented")
}
func (UnimplementedMethodServer) Delete(context.Context, *DeleteRequest) (*StatusReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented")
}
func (UnimplementedMethodServer) Remark(context.Context, *RemarkRequest) (*StatusReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Remark not implemented")
}
func (UnimplementedMethodServer) mustEmbedUnimplementedMethodServer() {}
func (UnimplementedMethodServer) testEmbeddedByValue() {}
// UnsafeMethodServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to MethodServer will
// result in compilation errors.
type UnsafeMethodServer interface {
mustEmbedUnimplementedMethodServer()
}
func RegisterMethodServer(s grpc.ServiceRegistrar, srv MethodServer) {
// If the following call pancis, it indicates UnimplementedMethodServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&Method_ServiceDesc, srv)
}
func _Method_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MethodServer).List(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Method_List_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MethodServer).List(ctx, req.(*ListRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Method_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MethodServer).Get(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Method_Get_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MethodServer).Get(ctx, req.(*GetRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Method_Add_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AddRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MethodServer).Add(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Method_Add_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MethodServer).Add(ctx, req.(*AddRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Method_Modify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ModifyRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MethodServer).Modify(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Method_Modify_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MethodServer).Modify(ctx, req.(*ModifyRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Method_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MethodServer).Delete(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Method_Delete_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MethodServer).Delete(ctx, req.(*DeleteRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Method_Remark_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(RemarkRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MethodServer).Remark(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Method_Remark_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MethodServer).Remark(ctx, req.(*RemarkRequest))
}
return interceptor(ctx, in, info, handler)
}
// Method_ServiceDesc is the grpc.ServiceDesc for Method service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Method_ServiceDesc = grpc.ServiceDesc{
ServiceName: "feedback.Method",
HandlerType: (*MethodServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "List",
Handler: _Method_List_Handler,
},
{
MethodName: "Get",
Handler: _Method_Get_Handler,
},
{
MethodName: "Add",
Handler: _Method_Add_Handler,
},
{
MethodName: "Modify",
Handler: _Method_Modify_Handler,
},
{
MethodName: "Delete",
Handler: _Method_Delete_Handler,
},
{
MethodName: "Remark",
Handler: _Method_Remark_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "feedback.proto",
}

View File

@@ -0,0 +1,130 @@
syntax = "proto3";
package feedback;
option go_package = ".;feedback";
// Feedback-建议反馈模块
service Method{
rpc List(ListRequest) returns (ListReply) {}
rpc Get(GetRequest) returns (GetReply) {}
rpc Add(AddRequest) returns (AddReply) {}
rpc Modify(ModifyRequest) returns (StatusReply) {}
rpc Delete(DeleteRequest) returns (StatusReply) {}
rpc Remark(RemarkRequest) returns (StatusReply) {}
}
message ListRequest {
int64 page = 1; // 页码,默认第一页
int64 size = 2; // 单页显示数量,默认10,最多50
string user_identity = 3 [json_name = "user_identity"]; //用户唯一`标识,可选
string user_name = 4 [json_name = "user_name"]; // 用户名称,可选
int32 status = 5;// 条目状态,可选,默认0,全部查找
string category = 6; //业务类型: 1,意见/2,反馈/3,申述等,默认0 调用方传
string email = 7;// 邮箱
string phone = 8;// 手机号码
string store_identity = 9 [json_name = "store_identity"];// 店铺标识
string agency = 10;// 代理
}
message ListReply {
int64 count = 1;
repeated FeedbackItem list = 2;
}
message FeedbackItem{
string identity = 1;
string user_identity = 2 [json_name = "user_identity"];// 用户唯一标识
string user_name = 3 [json_name = "user_name"];// 用户名称
int32 status = 4; //状态,1未处理,2已处理,也可以调用方自行设置,如果未设置则默认是1
string created_at = 5 [json_name = "created_at"];// 创建时间
string updated_at = 6 [json_name = "updated_at"];// 更新时间
string title = 7; // 标题
string content = 8; // 内容
repeated FeedbackImage images = 9;// 图片
string remark = 10; //反馈信息
string category = 11;// 类型: 1:pre_sales 2:after_sales
repeated FeedbackAccessory accessories = 12;
string email = 13;// 邮箱
string phone = 14;// 手机号码
string store_identity = 15 [json_name = "store_identity"];// 店铺标识
string agency = 16;// 代理
}
message FeedbackAccessory{
string identity = 1;
string item_identity = 2 [json_name = "item_identity"];
string title = 3;// 附件标题
string file_path = 4 [json_name = "file_path"];// 附件地址
}
message FeedbackImage{
string identity = 1;
string item_identity = 2;
string url = 3;
}
message GetRequest{
string identity = 1;
}
message GetReply{
FeedbackItem record = 1;
bool exists = 2;
}
message AddRequest {
string user_identity = 1 [json_name = "user_identity"];// 用户唯一标识
string user_name = 2 [json_name = "user_name"];// 用户名称
int32 status = 3; //状态,1未处理,2已处理,也可以调用方自行设置,如果未设置则默认是1
string title = 7; // 标题
string content = 8; // 内容
repeated FeedbackImage images = 9;// 图片
string category = 10;// 类型: 1:pre_sales 2:after_sales
repeated FeedbackAccessory accessories =11;// 附件
string email = 12;// 邮箱
string phone = 13;// 手机号码
string store_identity = 14[json_name = "store_identity"];// 店铺标识
string agency = 15;// 代理
}
message AddReply {
string identity = 1;
}
message ModifyRequest {
string identity = 1;
string user_identity = 2 [json_name = "user_identity"];// 用户唯一标识
string user_name = 3 [json_name = "user_name"];// 用户名称
int32 status = 4; //状态,1未处理,2已处理,也可以调用方自行设置,如果未设置则默认是1
string title = 7; // 标题
string content = 8; // 内容
repeated FeedbackImage images = 9;// 图片
string category = 10;// 类型: 1:pre_sales 2:after_sales
repeated FeedbackAccessory accessories =11;// 附件
string email = 12;// 邮箱
string phone = 13;// 手机号码
string store_identity = 14[json_name = "store_identity"];// 店铺标识
string agency = 15;// 代理
}
message DeleteRequest {
string identity = 1;
}
message RemarkRequest {
string identity = 1;
string remark = 2;
int32 status = 3;
}
message IdentRequest{
int64 id = 1; // 唯一ID
string identity = 2; // 唯一码
}
message StatusReply{
int32 code=1; // 状态码
string message=2; // 状态说明
string details=3; // 数据
int64 timeseq=4; // 响应时间序列
}

View File

@@ -0,0 +1,27 @@
# 微服务相关配置
service:
key: feedback
origin: bsm
describe: system feedback microservice
# 编译选项二进制文件docker镜像
build:
- binary
- docker
# docker 环境镜像
docker_image: golang:1.26.5
# docker 私有仓库
docker_registry:
endpoint: cid.apinb.com
account: op
password: 123456
# 微服务系统变量,docker或宿主机
start:
- export BlocksMesh_Workspace=scf
- export BlocksMesh_Prefix=/usr/local/bsm/
- export BlocksMesh_RuntimeMode=dev
- export BlocksMesh_JwtSecretKey=Cblocksmesh2022C

View File

@@ -0,0 +1,32 @@
filebeat.inputs:
- type: log
enabled: true
# 开启json解析
json.keys_under_root: true
json.add_error_key: true
# 日志文件路径
paths:
- ./logs/feedback/error.log
- ./logs/feedback/slow.log
setup.template.settings:
index.number_of_shards: 1
# 定义kafka topic field
fields:
log_topic: scf.feedback.dev
# 输出到kafka
output.kafka:
hosts: ["127.0.0.1:9092"]
topic: '%{[fields.log_topic]}'
partition.round_robin:
reachable_only: false
required_acks: 1
keep_alive: 10s
# ================================= Processors =================================
processors:
- decode_json_fields:
fields: ['@timestamp','level','content','trace','span','duration']
target: ""

View File

@@ -0,0 +1,5 @@
#install
go install github.com/securego/gosec/v2/cmd/gosec@latest
#run
gosec -fmt=json -out=./test/lint/gosec.json ./...

View File

@@ -0,0 +1,216 @@
{
"swagger": "2.0",
"info": {
"title": "feedback.proto",
"version": "version not set"
},
"tags": [
{
"name": "Method"
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {},
"definitions": {
"feedbackAddReply": {
"type": "object",
"properties": {
"identity": {
"type": "string"
}
}
},
"feedbackFeedbackAccessory": {
"type": "object",
"properties": {
"identity": {
"type": "string"
},
"item_identity": {
"type": "string"
},
"title": {
"type": "string",
"title": "附件标题"
},
"file_path": {
"type": "string",
"title": "附件地址"
}
}
},
"feedbackFeedbackImage": {
"type": "object",
"properties": {
"identity": {
"type": "string"
},
"itemIdentity": {
"type": "string"
},
"url": {
"type": "string"
}
}
},
"feedbackFeedbackItem": {
"type": "object",
"properties": {
"identity": {
"type": "string"
},
"user_identity": {
"type": "string",
"title": "用户唯一标识"
},
"user_name": {
"type": "string",
"title": "用户名称"
},
"status": {
"type": "integer",
"format": "int32",
"title": "状态,1未处理,2已处理,也可以调用方自行设置,如果未设置则默认是1"
},
"created_at": {
"type": "string",
"title": "创建时间"
},
"updated_at": {
"type": "string",
"title": "更新时间"
},
"title": {
"type": "string",
"title": "标题"
},
"content": {
"type": "string",
"title": "内容"
},
"images": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/feedbackFeedbackImage"
},
"title": "图片"
},
"remark": {
"type": "string",
"title": "反馈信息"
},
"category": {
"type": "string",
"title": "类型: 1:pre_sales 2:after_sales"
},
"accessories": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/feedbackFeedbackAccessory"
}
},
"email": {
"type": "string",
"title": "邮箱"
},
"phone": {
"type": "string",
"title": "手机号码"
},
"store_identity": {
"type": "string",
"title": "店铺标识"
},
"agency": {
"type": "string",
"title": "代理"
}
}
},
"feedbackGetReply": {
"type": "object",
"properties": {
"record": {
"$ref": "#/definitions/feedbackFeedbackItem"
},
"exists": {
"type": "boolean"
}
}
},
"feedbackListReply": {
"type": "object",
"properties": {
"count": {
"type": "string",
"format": "int64"
},
"list": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/feedbackFeedbackItem"
}
}
}
},
"feedbackStatusReply": {
"type": "object",
"properties": {
"code": {
"type": "integer",
"format": "int32",
"title": "状态码"
},
"message": {
"type": "string",
"title": "状态说明"
},
"details": {
"type": "string",
"title": "数据"
},
"timeseq": {
"type": "string",
"format": "int64",
"title": "响应时间序列"
}
}
},
"protobufAny": {
"type": "object",
"properties": {
"@type": {
"type": "string"
}
},
"additionalProperties": {}
},
"rpcStatus": {
"type": "object",
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
},
"details": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/protobufAny"
}
}
}
}
}
}

View File

@@ -0,0 +1,17 @@
POST http://127.0.0.1:12210/feedback.Method/Add
Content-Type: application/json
Authorization: {{BSM_TOKEN}}
{
"user_name": "张三" ,
"title": "测试" ,
"content": "测试内容" ,
"type": "1" ,
"images": [] ,
"accessories": [
{
"title": "附件1",
"file_path": "http://127.0.0.1:22210/file/download/1"
}
],
}

View File

@@ -0,0 +1,23 @@
package rpc
func main() {
/*
md := metadata.New(map[string]string{"request_id": utils.UUID(), "workspace": "scf"})
ctx := metadata.NewOutgoingContext(context.Background(), md)
// 建立GRPC连接
conn, err := grpc.Dial("127.0.0.1:12201", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
panic(err)
}
defer conn.Close()
c := pb.NewMethodClient(conn)
r, err := c.List()(ctx, &pb.Crc{
Code: "david",
})
if err != nil {
panic(err)
}
fmt.Printf("返回的消息: %s", r.Message)
*/
}