feat 拆出qgdzs
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.idea
|
||||||
|
*/.idea
|
||||||
58
app/app.go
Normal file
58
app/app.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/discover"
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/log"
|
||||||
|
"git.hlsq.asia/mmorpg/service-qgdzs/config"
|
||||||
|
"github.com/judwhite/go-svc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Program struct {
|
||||||
|
moduleList []Module // 模块列表
|
||||||
|
}
|
||||||
|
|
||||||
|
type Module interface {
|
||||||
|
init() error
|
||||||
|
start() error
|
||||||
|
stop() error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Program) Init(_ svc.Environment) error {
|
||||||
|
p.moduleList = append(p.moduleList, &ModuleBase{})
|
||||||
|
p.moduleList = append(p.moduleList, &ModuleDB{})
|
||||||
|
p.moduleList = append(p.moduleList, &ModuleGrpcServer{})
|
||||||
|
|
||||||
|
for _, module := range p.moduleList {
|
||||||
|
if err := module.init(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Infof(fmt.Sprintf("%v Init successful...", config.Get().App.Name))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Program) Start() error {
|
||||||
|
for _, module := range p.moduleList {
|
||||||
|
if err := module.start(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
discover.Listen()
|
||||||
|
|
||||||
|
log.Infof(fmt.Sprintf("%v Start successful...", config.Get().App.Name))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Program) Stop() error {
|
||||||
|
discover.Close()
|
||||||
|
for i := len(p.moduleList) - 1; i >= 0; i-- {
|
||||||
|
module := p.moduleList[i]
|
||||||
|
if err := module.stop(); err != nil {
|
||||||
|
log.Errorf("module stop error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof(fmt.Sprintf("%v Stop successful...", config.Get().App.Name))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
33
app/base.go
Normal file
33
app/base.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/log"
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/utils"
|
||||||
|
"git.hlsq.asia/mmorpg/service-qgdzs/config"
|
||||||
|
"math/rand"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ModuleBase 基础模块,或者一些零散的模块
|
||||||
|
type ModuleBase struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ModuleBase) init() error {
|
||||||
|
// 配置
|
||||||
|
if err := config.LoadConfig(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cfg := config.Get()
|
||||||
|
// 日志
|
||||||
|
log.Init(cfg.Log.Debug, cfg.Log.MaxSize, cfg.Log.MaxBackups, cfg.Log.MaxAge, cfg.Log.Level)
|
||||||
|
// 雪花
|
||||||
|
utils.InitSnowflake(int64(rand.Intn(1000)))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ModuleBase) start() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ModuleBase) stop() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
23
app/db.go
Normal file
23
app/db.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/db"
|
||||||
|
"git.hlsq.asia/mmorpg/service-qgdzs/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ModuleDB 数据库模块
|
||||||
|
type ModuleDB struct {
|
||||||
|
dbModule *db.ModuleDB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ModuleDB) init() error {
|
||||||
|
return p.dbModule.Init(config.Get().DB)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ModuleDB) start() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ModuleDB) stop() error {
|
||||||
|
return p.dbModule.Stop()
|
||||||
|
}
|
||||||
27
app/grpc.go
Normal file
27
app/grpc.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/net/grpc/service"
|
||||||
|
"git.hlsq.asia/mmorpg/service-qgdzs/config"
|
||||||
|
"git.hlsq.asia/mmorpg/service-qgdzs/internal/grpc_server/server"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ModuleGrpcServer Grpc服务模块
|
||||||
|
type ModuleGrpcServer struct {
|
||||||
|
server service.IService
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ModuleGrpcServer) init() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ModuleGrpcServer) start() error {
|
||||||
|
m.server = server.NewServer(config.Get().Serve.Grpc.TTL)
|
||||||
|
m.server.Init(config.Get().Serve.Grpc.Address, config.Get().Serve.Grpc.Port)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ModuleGrpcServer) stop() error {
|
||||||
|
m.server.Close()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
31
config/config.dev.yaml
Normal file
31
config/config.dev.yaml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
app:
|
||||||
|
name: "qgdzs-dev"
|
||||||
|
|
||||||
|
log:
|
||||||
|
debug: true
|
||||||
|
level: "debug"
|
||||||
|
maxSize: 10
|
||||||
|
maxBackups: 100
|
||||||
|
maxAge: 7
|
||||||
|
|
||||||
|
db:
|
||||||
|
etcd:
|
||||||
|
endpoints: [ "10.0.40.9:2379" ]
|
||||||
|
mysql:
|
||||||
|
qgdzs_db:
|
||||||
|
dsn: "root:gR9pV4tY7zR6qL3e@tcp(47.108.184.184:3306)/qgdzs_db?charset=utf8mb4&parseTime=True&loc=Local"
|
||||||
|
maxOpenConn: 50
|
||||||
|
maxIdleConn: 20
|
||||||
|
connMaxLifetimeSec: 600
|
||||||
|
connMaxIdleTimeSec: 180
|
||||||
|
logLevel: "warn"
|
||||||
|
redis:
|
||||||
|
addr: "47.108.184.184:6379"
|
||||||
|
password: "lQ7aM8oB6lK0iD5k"
|
||||||
|
db: 0
|
||||||
|
|
||||||
|
serve:
|
||||||
|
grpc:
|
||||||
|
address: "10.0.40.199"
|
||||||
|
port: 8603
|
||||||
|
ttl: 20
|
||||||
25
config/config.go
Normal file
25
config/config.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import "git.hlsq.asia/mmorpg/service-common/config"
|
||||||
|
|
||||||
|
const path = "./config"
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
App *config.AppConfig `yaml:"app"`
|
||||||
|
Log *config.LogConfig `yaml:"log"`
|
||||||
|
DB *config.DBConfig `yaml:"db"`
|
||||||
|
Serve *config.ServeConfig `yaml:"serve"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var cfg *Config
|
||||||
|
|
||||||
|
// LoadConfig 加载应用配置
|
||||||
|
func LoadConfig() error {
|
||||||
|
c, err := config.LoadConfig(path, cfg)
|
||||||
|
cfg = c
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func Get() *Config {
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
31
config/config.prod.yaml
Normal file
31
config/config.prod.yaml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
app:
|
||||||
|
name: "qgdzs-prod"
|
||||||
|
|
||||||
|
log:
|
||||||
|
debug: false
|
||||||
|
level: "debug"
|
||||||
|
maxSize: 10
|
||||||
|
maxBackups: 100
|
||||||
|
maxAge: 7
|
||||||
|
|
||||||
|
db:
|
||||||
|
etcd:
|
||||||
|
endpoints: [ "172.18.28.0:2379" ]
|
||||||
|
mysql:
|
||||||
|
qgdzs_db:
|
||||||
|
dsn: "root:gR9pV4tY7zR6qL3e@tcp(172.18.28.0:3306)/qgdzs_db?charset=utf8mb4&parseTime=True&loc=Local"
|
||||||
|
maxOpenConn: 50
|
||||||
|
maxIdleConn: 20
|
||||||
|
connMaxLifetimeSec: 600
|
||||||
|
connMaxIdleTimeSec: 180
|
||||||
|
logLevel: "warn"
|
||||||
|
redis:
|
||||||
|
addr: "172.18.28.0:6379"
|
||||||
|
password: "lQ7aM8oB6lK0iD5k"
|
||||||
|
db: 0
|
||||||
|
|
||||||
|
serve:
|
||||||
|
grpc:
|
||||||
|
address: "172.18.28.0"
|
||||||
|
port: 8603
|
||||||
|
ttl: 20
|
||||||
12
deploy/Dockerfile
Normal file
12
deploy/Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
FROM alpine:3.23.2
|
||||||
|
|
||||||
|
RUN apk add --no-cache tzdata && \
|
||||||
|
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
||||||
|
echo "Asia/Shanghai" > /etc/timezone
|
||||||
|
|
||||||
|
COPY service-qgdzs /app/service-qgdzs
|
||||||
|
COPY config /app/config
|
||||||
|
RUN chmod 777 /app/service-qgdzs
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
CMD ["./service-qgdzs"]
|
||||||
133
deploy/Jenkinsfile
vendored
Normal file
133
deploy/Jenkinsfile
vendored
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
pipeline {
|
||||||
|
agent none
|
||||||
|
|
||||||
|
environment {
|
||||||
|
// 仓库
|
||||||
|
REPO_URL = 'https://git.hlsq.asia/mmorpg/service-qgdzs.git'
|
||||||
|
REPO_CREDENTIALS_ID = '80805ba2-f4ac-4d84-aee6-d4cce5fc0a96'
|
||||||
|
|
||||||
|
// Registry
|
||||||
|
REGISTRY_URL = 'registry.hlsq.asia'
|
||||||
|
REGISTRY_CREDENTIALS_ID = '0d79fc0b-a150-470b-bd0d-2639b2826031'
|
||||||
|
|
||||||
|
// 部署目标服务器
|
||||||
|
SERVER_HOST = 'www.hlsq.asia'
|
||||||
|
SERVER_USER = 'root'
|
||||||
|
SSH_CREDENTIALS_ID = '10e0830d-4d03-4879-9ee4-03a4c55513ad'
|
||||||
|
|
||||||
|
// 基础信息
|
||||||
|
APP_NAME = 'service-qgdzs'
|
||||||
|
GO_MOD_CACHE_DIR = '/home/pi/Desktop/docker/jenkins/caches/go-mod'
|
||||||
|
GO_BUILD_CACHE_DIR = '/home/pi/Desktop/docker/jenkins/caches/go-build'
|
||||||
|
}
|
||||||
|
|
||||||
|
options {
|
||||||
|
skipDefaultCheckout true
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Checkout') {
|
||||||
|
agent any
|
||||||
|
steps {
|
||||||
|
checkout([
|
||||||
|
$class: 'GitSCM',
|
||||||
|
branches: [[name: '*/master']],
|
||||||
|
doGenerateSubmoduleConfigurations: false,
|
||||||
|
extensions: [],
|
||||||
|
userRemoteConfigs: [[
|
||||||
|
credentialsId: env.REPO_CREDENTIALS_ID,
|
||||||
|
url: env.REPO_URL
|
||||||
|
]]
|
||||||
|
])
|
||||||
|
// 立刻保存Git的Commit,避免并发问题
|
||||||
|
script {
|
||||||
|
def shortCommit = sh(script: 'git rev-parse --short=8 HEAD', returnStdout: true).trim()
|
||||||
|
env.IMAGE_TAG = "${env.REGISTRY_URL}/${env.APP_NAME}:${shortCommit}"
|
||||||
|
echo "Checked out commit: ${env.IMAGE_TAG}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Build Go Binary') {
|
||||||
|
agent {
|
||||||
|
docker {
|
||||||
|
image 'golang:1.23.1-alpine'
|
||||||
|
reuseNode true
|
||||||
|
args '-u root:root -v $GO_MOD_CACHE_DIR:/go/pkg/mod -v $GO_BUILD_CACHE_DIR:/root/.cache/go-build'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
sh """
|
||||||
|
export GOPROXY=https://goproxy.cn,direct
|
||||||
|
export CGO_ENABLED=0
|
||||||
|
export GOOS=linux
|
||||||
|
export GOARCH=amd64
|
||||||
|
|
||||||
|
go build -o ${env.APP_NAME} .
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Push Docker Image') {
|
||||||
|
agent any
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
withCredentials([usernamePassword(
|
||||||
|
credentialsId: env.REGISTRY_CREDENTIALS_ID,
|
||||||
|
usernameVariable: 'DOCKER_USER',
|
||||||
|
passwordVariable: 'DOCKER_PASS'
|
||||||
|
)]) {
|
||||||
|
sh """
|
||||||
|
echo "$DOCKER_PASS" | docker login --username "$DOCKER_USER" --password-stdin ${env.REGISTRY_URL}
|
||||||
|
docker buildx build --platform linux/amd64 -t ${env.IMAGE_TAG} -f deploy/Dockerfile . --push
|
||||||
|
docker logout ${env.REGISTRY_URL}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Deploy to Server') {
|
||||||
|
agent any
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
withCredentials([
|
||||||
|
usernamePassword(
|
||||||
|
credentialsId: env.REGISTRY_CREDENTIALS_ID,
|
||||||
|
usernameVariable: 'DOCKER_USER',
|
||||||
|
passwordVariable: 'DOCKER_PASS'
|
||||||
|
)
|
||||||
|
]) {
|
||||||
|
sshagent (credentials: [env.SSH_CREDENTIALS_ID]) {
|
||||||
|
sh """
|
||||||
|
ssh -o StrictHostKeyChecking=no ${env.SERVER_USER}@${env.SERVER_HOST} << EOF
|
||||||
|
set -e
|
||||||
|
echo '${DOCKER_PASS}' | docker login --username '${DOCKER_USER}' --password-stdin ${env.REGISTRY_URL}
|
||||||
|
docker pull ${env.IMAGE_TAG}
|
||||||
|
docker stop ${env.APP_NAME} 2>/dev/null || true
|
||||||
|
docker rm ${env.APP_NAME} 2>/dev/null || true
|
||||||
|
docker run -d \\
|
||||||
|
--name ${env.APP_NAME} \\
|
||||||
|
--restart unless-stopped \\
|
||||||
|
-p 8603:8603 \\
|
||||||
|
--env XH_G_ENV=prod \\
|
||||||
|
-v /root/service/logs/qgdzs_log/:/app/logs \\
|
||||||
|
${env.IMAGE_TAG}
|
||||||
|
docker logout ${env.REGISTRY_URL}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
success {
|
||||||
|
echo '✅ 构建、推送镜像与部署成功!'
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
echo '❌ 构建失败,请检查日志。'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
89
go.mod
Normal file
89
go.mod
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
module git.hlsq.asia/mmorpg/service-qgdzs
|
||||||
|
|
||||||
|
go 1.23.1
|
||||||
|
|
||||||
|
require (
|
||||||
|
git.hlsq.asia/mmorpg/service-common v0.0.0-20260112082258-b1e7d33940d7
|
||||||
|
github.com/judwhite/go-svc v1.2.1
|
||||||
|
google.golang.org/grpc v1.71.1
|
||||||
|
gorm.io/gen v0.3.27
|
||||||
|
gorm.io/gorm v1.31.1
|
||||||
|
gorm.io/plugin/dbresolver v1.6.2
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
|
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
||||||
|
github.com/bytedance/sonic v1.14.0 // indirect
|
||||||
|
github.com/bytedance/sonic/loader v0.3.0 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
|
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||||
|
github.com/coreos/go-semver v0.3.1 // indirect
|
||||||
|
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
|
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||||
|
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||||
|
github.com/gin-gonic/gin v1.11.0 // indirect
|
||||||
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
|
github.com/go-playground/validator/v10 v10.27.0 // indirect
|
||||||
|
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||||
|
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||||
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
|
github.com/goccy/go-yaml v1.18.0 // indirect
|
||||||
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.4 // indirect
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
|
||||||
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||||
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/natefinch/lumberjack v2.0.0+incompatible // indirect
|
||||||
|
github.com/panjf2000/gnet/v2 v2.9.7 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/quic-go/qpack v0.5.1 // indirect
|
||||||
|
github.com/quic-go/quic-go v0.54.0 // indirect
|
||||||
|
github.com/redis/go-redis/v9 v9.10.0 // indirect
|
||||||
|
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||||
|
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||||
|
github.com/spf13/afero v1.15.0 // indirect
|
||||||
|
github.com/spf13/cast v1.10.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.10 // indirect
|
||||||
|
github.com/spf13/viper v1.21.0 // indirect
|
||||||
|
github.com/stretchr/testify v1.11.1 // indirect
|
||||||
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.3.0 // indirect
|
||||||
|
go.etcd.io/etcd/api/v3 v3.6.1 // indirect
|
||||||
|
go.etcd.io/etcd/client/pkg/v3 v3.6.1 // indirect
|
||||||
|
go.etcd.io/etcd/client/v3 v3.6.1 // indirect
|
||||||
|
go.uber.org/mock v0.5.0 // indirect
|
||||||
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
|
golang.org/x/arch v0.20.0 // indirect
|
||||||
|
golang.org/x/crypto v0.40.0 // indirect
|
||||||
|
golang.org/x/mod v0.26.0 // indirect
|
||||||
|
golang.org/x/net v0.42.0 // indirect
|
||||||
|
golang.org/x/sync v0.16.0 // indirect
|
||||||
|
golang.org/x/sys v0.35.0 // indirect
|
||||||
|
golang.org/x/text v0.28.0 // indirect
|
||||||
|
golang.org/x/tools v0.35.0 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||||
|
google.golang.org/protobuf v1.36.9 // indirect
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
gorm.io/datatypes v1.2.4 // indirect
|
||||||
|
gorm.io/driver/mysql v1.6.0 // indirect
|
||||||
|
gorm.io/hints v1.1.0 // indirect
|
||||||
|
)
|
||||||
271
go.sum
Normal file
271
go.sum
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
|
git.hlsq.asia/mmorpg/service-common v0.0.0-20260112082258-b1e7d33940d7 h1:C3quCA54dyFgmlCVgJXx+0rNqa+JZgGggdotbvHAsnA=
|
||||||
|
git.hlsq.asia/mmorpg/service-common v0.0.0-20260112082258-b1e7d33940d7/go.mod h1:xv6m1I2jUA6mudKVznygpnzMoshBQarthHD1QnkW4qc=
|
||||||
|
github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=
|
||||||
|
github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
|
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/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
|
||||||
|
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
|
||||||
|
github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ=
|
||||||
|
github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA=
|
||||||
|
github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=
|
||||||
|
github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||||
|
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/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
|
||||||
|
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
|
||||||
|
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.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||||
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
|
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/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
|
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||||
|
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||||
|
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||||
|
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||||
|
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
|
||||||
|
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
|
||||||
|
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/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
|
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
|
||||||
|
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||||
|
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||||
|
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||||
|
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||||
|
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||||
|
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||||
|
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
|
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
|
||||||
|
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||||
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||||
|
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||||
|
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
|
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||||
|
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||||
|
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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
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.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
|
||||||
|
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-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
|
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
|
||||||
|
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.1/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.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/judwhite/go-svc v1.2.1 h1:a7fsJzYUa33sfDJRF2N/WXhA+LonCEEY8BJb1tuS5tA=
|
||||||
|
github.com/judwhite/go-svc v1.2.1/go.mod h1:mo/P2JNX8C07ywpP9YtO2gnBgnUiFTHqtsZekJrUuTk=
|
||||||
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||||
|
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||||
|
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/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
|
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/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
|
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/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
|
||||||
|
github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
|
||||||
|
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
|
||||||
|
github.com/panjf2000/gnet/v2 v2.9.7 h1:6zW7Jl3oAfXwSuh1PxHLndoL2MQRWx0AJR6aaQjxUgA=
|
||||||
|
github.com/panjf2000/gnet/v2 v2.9.7/go.mod h1:WQTxDWYuQ/hz3eccH0FN32IVuvZ19HewEWx0l62fx7E=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||||
|
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/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||||
|
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||||
|
github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg=
|
||||||
|
github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
|
||||||
|
github.com/redis/go-redis/v9 v9.10.0 h1:FxwK3eV8p/CQa0Ch276C7u2d0eNC9kCmAYQ7mCXCzVs=
|
||||||
|
github.com/redis/go-redis/v9 v9.10.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
||||||
|
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||||
|
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||||
|
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||||
|
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||||
|
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||||
|
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||||
|
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||||
|
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||||
|
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||||
|
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||||
|
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||||
|
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||||
|
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||||
|
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/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.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.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
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/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||||
|
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
|
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
|
||||||
|
github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||||
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
go.etcd.io/etcd/api/v3 v3.6.1 h1:yJ9WlDih9HT457QPuHt/TH/XtsdN2tubyxyQHSHPsEo=
|
||||||
|
go.etcd.io/etcd/api/v3 v3.6.1/go.mod h1:lnfuqoGsXMlZdTJlact3IB56o3bWp1DIlXPIGKRArto=
|
||||||
|
go.etcd.io/etcd/client/pkg/v3 v3.6.1 h1:CxDVv8ggphmamrXM4Of8aCC8QHzDM4tGcVr9p2BSoGk=
|
||||||
|
go.etcd.io/etcd/client/pkg/v3 v3.6.1/go.mod h1:aTkCp+6ixcVTZmrJGa7/Mc5nMNs59PEgBbq+HCmWyMc=
|
||||||
|
go.etcd.io/etcd/client/v3 v3.6.1 h1:KelkcizJGsskUXlsxjVrSmINvMMga0VWwFF0tSPGEP0=
|
||||||
|
go.etcd.io/etcd/client/v3 v3.6.1/go.mod h1:fCbPUdjWNLfx1A6ATo9syUmFVxqHH9bCnPLBZmnLmMY=
|
||||||
|
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||||
|
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||||
|
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||||
|
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||||
|
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||||
|
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
|
||||||
|
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||||
|
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||||
|
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/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||||
|
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||||
|
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.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||||
|
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
|
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||||
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
|
golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=
|
||||||
|
golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||||
|
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||||
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
|
||||||
|
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||||
|
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||||
|
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||||
|
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||||
|
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
||||||
|
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
|
||||||
|
google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI=
|
||||||
|
google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||||
|
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||||
|
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||||
|
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/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||||
|
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=
|
||||||
|
gorm.io/datatypes v1.2.4 h1:uZmGAcK/QZ0uyfCuVg0VQY1ZmV9h1fuG0tMwKByO1z4=
|
||||||
|
gorm.io/datatypes v1.2.4/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI=
|
||||||
|
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.5.0 h1:u2FXTy14l45qc3UeCJ7QaAXZmZfDDv0YrthvmRq1l0U=
|
||||||
|
gorm.io/driver/postgres v1.5.0/go.mod h1:FUZXzO+5Uqg5zzwzv4KK49R8lvGIyscBOqYrtI1Ce9A=
|
||||||
|
gorm.io/driver/sqlite v1.1.6/go.mod h1:W8LmC/6UvVbHKah0+QOC7Ja66EaZXHwUTjgXY8YNWX8=
|
||||||
|
gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
|
||||||
|
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
|
||||||
|
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
|
||||||
|
gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
|
||||||
|
gorm.io/gen v0.3.27 h1:ziocAFLpE7e0g4Rum69pGfB9S6DweTxK8gAun7cU8as=
|
||||||
|
gorm.io/gen v0.3.27/go.mod h1:9zquz2xD1f3Eb/eHq4oLn2z6vDVvQlCY5S3uMBLv4EA=
|
||||||
|
gorm.io/gorm v1.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||||
|
gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||||
|
gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
|
||||||
|
gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
|
||||||
|
gorm.io/hints v1.1.0 h1:Lp4z3rxREufSdxn4qmkK3TLDltrM10FLTHiuqwDPvXw=
|
||||||
|
gorm.io/hints v1.1.0/go.mod h1:lKQ0JjySsPBj3uslFzY3JhYDtqEwzm+G1hv8rWujB6Y=
|
||||||
|
gorm.io/plugin/dbresolver v1.6.2 h1:F4b85TenghUeITqe3+epPSUtHH7RIk3fXr5l83DF8Pc=
|
||||||
|
gorm.io/plugin/dbresolver v1.6.2/go.mod h1:tctw63jdrOezFR9HmrKnPkmig3m5Edem9fdxk9bQSzM=
|
||||||
55
internal/ai/ai_client.go
Normal file
55
internal/ai/ai_client.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package ai
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
enableSearch bool // 是否开启搜索
|
||||||
|
searchStrategy string // 搜索策略(开了搜索才生效)
|
||||||
|
temperature float32 // 采样温度
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAIClient(enableSearch bool, searchStrategy string, temperature float32) *Client {
|
||||||
|
return &Client{
|
||||||
|
enableSearch: enableSearch,
|
||||||
|
searchStrategy: searchStrategy,
|
||||||
|
temperature: temperature,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) RequestAI(prompt []string, cb func(content string, i int) error) error {
|
||||||
|
inToken, outToken := int32(0), int32(0)
|
||||||
|
messages := make([]Message, 0)
|
||||||
|
for i, step := range prompt {
|
||||||
|
messages = append(messages, Message{
|
||||||
|
Role: "user",
|
||||||
|
Content: step,
|
||||||
|
})
|
||||||
|
r, err := request("deepseek-v3.2", Parameters{
|
||||||
|
EnableSearch: c.enableSearch,
|
||||||
|
SearchOptions: SearchOptions{
|
||||||
|
SearchStrategy: c.searchStrategy,
|
||||||
|
},
|
||||||
|
ResultFormat: "message",
|
||||||
|
Temperature: c.temperature,
|
||||||
|
}, messages)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
inToken += r.Usage.InputTokens
|
||||||
|
outToken += r.Usage.OutputTokens
|
||||||
|
if len(r.Output.Choices) == 0 {
|
||||||
|
log.Infof("AI response err, r: %#+v", r)
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
messages = append(messages, r.Output.Choices[0].Message)
|
||||||
|
}
|
||||||
|
log.Infof("AI 回答 %v: %v", i, r.Output.Choices[0].Message.Content)
|
||||||
|
if err = cb(r.Output.Choices[0].Message.Content, i); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Infof("AI finished, use token: in-%v out-%v", inToken, outToken)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
82
internal/ai/ai_request.go
Normal file
82
internal/ai/ai_request.go
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package ai
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
Role string `json:"role"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Input struct {
|
||||||
|
Messages []Message `json:"messages"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Parameters struct {
|
||||||
|
EnableSearch bool `json:"enable_search,omitempty"`
|
||||||
|
SearchOptions SearchOptions `json:"search_options,omitempty"`
|
||||||
|
ResultFormat string `json:"result_format,omitempty"`
|
||||||
|
Temperature float32 `json:"temperature,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SearchOptions struct {
|
||||||
|
SearchStrategy string `json:"search_strategy"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RequestBody struct {
|
||||||
|
Model string `json:"model"`
|
||||||
|
Input Input `json:"input"`
|
||||||
|
Parameters Parameters `json:"parameters"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResponseBody struct {
|
||||||
|
Output struct {
|
||||||
|
Choices []struct {
|
||||||
|
Message Message `json:"message"`
|
||||||
|
FinishReason string `json:"finish_reason"`
|
||||||
|
} `json:"choices"`
|
||||||
|
} `json:"output"`
|
||||||
|
Usage struct {
|
||||||
|
InputTokens int32 `json:"input_tokens"`
|
||||||
|
OutputTokens int32 `json:"output_tokens"`
|
||||||
|
TotalTokens int32 `json:"total_tokens"`
|
||||||
|
} `json:"usage"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func request(model string, parameters Parameters, messages []Message) (*ResponseBody, error) {
|
||||||
|
requestBody := RequestBody{
|
||||||
|
Model: model,
|
||||||
|
Input: Input{
|
||||||
|
Messages: messages,
|
||||||
|
},
|
||||||
|
Parameters: parameters,
|
||||||
|
}
|
||||||
|
jsonData, _ := json.Marshal(requestBody)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation", bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Set("Authorization", "Bearer "+"sk-4daf94ad2fa94288b198d2a1d8924cef")
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := (&http.Client{}).Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var res ResponseBody
|
||||||
|
if err = json.Unmarshal(body, &res); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &res, nil
|
||||||
|
}
|
||||||
42
internal/dao/model/questions.gen.go
Normal file
42
internal/dao/model/questions.gen.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/utils"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
const TableNameQuestion = "questions"
|
||||||
|
|
||||||
|
// Question mapped from table <questions>
|
||||||
|
type Question struct {
|
||||||
|
ID uint64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"`
|
||||||
|
Sn string `gorm:"column:sn;not null;comment:业务唯一编号" json:"sn"` // 业务唯一编号
|
||||||
|
Question string `gorm:"column:question;not null;comment:题干" json:"question"` // 题干
|
||||||
|
Options string `gorm:"column:options;not null;comment:选项" json:"options"` // 选项
|
||||||
|
Answer string `gorm:"column:answer;not null;comment:答案" json:"answer"` // 答案
|
||||||
|
Explanation string `gorm:"column:explanation;not null;comment:解析" json:"explanation"` // 解析
|
||||||
|
Difficulty int32 `gorm:"column:difficulty;not null;comment:难度分 0 - 100" json:"difficulty"` // 难度分 0 - 100
|
||||||
|
Category string `gorm:"column:category;not null;comment:分类" json:"category"` // 分类
|
||||||
|
CreatedAt time.Time `gorm:"column:created_at;not null" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:updated_at;not null" json:"updated_at"`
|
||||||
|
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName Question's table name
|
||||||
|
func (*Question) TableName() string {
|
||||||
|
return TableNameQuestion
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto sn
|
||||||
|
func (m *Question) BeforeCreate(_ *gorm.DB) error {
|
||||||
|
if m.Sn == "" {
|
||||||
|
m.Sn = utils.SnowflakeInstance().Generate().String()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
93
internal/dao/query/gen.go
Normal file
93
internal/dao/query/gen.go
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
"gorm.io/gen"
|
||||||
|
|
||||||
|
"gorm.io/plugin/dbresolver"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
||||||
|
return &Query{
|
||||||
|
db: db,
|
||||||
|
Question: newQuestion(db, opts...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Query struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
Question question
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Query) Available() bool { return q.db != nil }
|
||||||
|
|
||||||
|
func (q *Query) clone(db *gorm.DB) *Query {
|
||||||
|
return &Query{
|
||||||
|
db: db,
|
||||||
|
Question: q.Question.clone(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Query) ReadDB() *Query {
|
||||||
|
return q.ReplaceDB(q.db.Clauses(dbresolver.Read))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Query) WriteDB() *Query {
|
||||||
|
return q.ReplaceDB(q.db.Clauses(dbresolver.Write))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Query) ReplaceDB(db *gorm.DB) *Query {
|
||||||
|
return &Query{
|
||||||
|
db: db,
|
||||||
|
Question: q.Question.replaceDB(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type queryCtx struct {
|
||||||
|
Question *questionDo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
||||||
|
return &queryCtx{
|
||||||
|
Question: q.Question.WithContext(ctx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error {
|
||||||
|
return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx {
|
||||||
|
tx := q.db.Begin(opts...)
|
||||||
|
return &QueryTx{Query: q.clone(tx), Error: tx.Error}
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryTx struct {
|
||||||
|
*Query
|
||||||
|
Error error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *QueryTx) Commit() error {
|
||||||
|
return q.db.Commit().Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *QueryTx) Rollback() error {
|
||||||
|
return q.db.Rollback().Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *QueryTx) SavePoint(name string) error {
|
||||||
|
return q.db.SavePoint(name).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *QueryTx) RollbackTo(name string) error {
|
||||||
|
return q.db.RollbackTo(name).Error
|
||||||
|
}
|
||||||
367
internal/dao/query/questions.gen.go
Normal file
367
internal/dao/query/questions.gen.go
Normal file
@@ -0,0 +1,367 @@
|
|||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/clause"
|
||||||
|
"gorm.io/gorm/schema"
|
||||||
|
|
||||||
|
"gorm.io/gen"
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
|
||||||
|
"gorm.io/plugin/dbresolver"
|
||||||
|
|
||||||
|
"git.hlsq.asia/mmorpg/service-qgdzs/internal/dao/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newQuestion(db *gorm.DB, opts ...gen.DOOption) question {
|
||||||
|
_question := question{}
|
||||||
|
|
||||||
|
_question.questionDo.UseDB(db, opts...)
|
||||||
|
_question.questionDo.UseModel(&model.Question{})
|
||||||
|
|
||||||
|
tableName := _question.questionDo.TableName()
|
||||||
|
_question.ALL = field.NewAsterisk(tableName)
|
||||||
|
_question.ID = field.NewUint64(tableName, "id")
|
||||||
|
_question.Sn = field.NewString(tableName, "sn")
|
||||||
|
_question.Question = field.NewString(tableName, "question")
|
||||||
|
_question.Options = field.NewString(tableName, "options")
|
||||||
|
_question.Answer = field.NewString(tableName, "answer")
|
||||||
|
_question.Explanation = field.NewString(tableName, "explanation")
|
||||||
|
_question.Difficulty = field.NewInt32(tableName, "difficulty")
|
||||||
|
_question.Category = field.NewString(tableName, "category")
|
||||||
|
_question.CreatedAt = field.NewTime(tableName, "created_at")
|
||||||
|
_question.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||||
|
_question.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||||
|
|
||||||
|
_question.fillFieldMap()
|
||||||
|
|
||||||
|
return _question
|
||||||
|
}
|
||||||
|
|
||||||
|
type question struct {
|
||||||
|
questionDo questionDo
|
||||||
|
|
||||||
|
ALL field.Asterisk
|
||||||
|
ID field.Uint64
|
||||||
|
Sn field.String // 业务唯一编号
|
||||||
|
Question field.String // 题干
|
||||||
|
Options field.String // 选项
|
||||||
|
Answer field.String // 答案
|
||||||
|
Explanation field.String // 解析
|
||||||
|
Difficulty field.Int32 // 难度分 0 - 100
|
||||||
|
Category field.String // 分类
|
||||||
|
CreatedAt field.Time
|
||||||
|
UpdatedAt field.Time
|
||||||
|
DeletedAt field.Field
|
||||||
|
|
||||||
|
fieldMap map[string]field.Expr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q question) Table(newTableName string) *question {
|
||||||
|
q.questionDo.UseTable(newTableName)
|
||||||
|
return q.updateTableName(newTableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q question) As(alias string) *question {
|
||||||
|
q.questionDo.DO = *(q.questionDo.As(alias).(*gen.DO))
|
||||||
|
return q.updateTableName(alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *question) updateTableName(table string) *question {
|
||||||
|
q.ALL = field.NewAsterisk(table)
|
||||||
|
q.ID = field.NewUint64(table, "id")
|
||||||
|
q.Sn = field.NewString(table, "sn")
|
||||||
|
q.Question = field.NewString(table, "question")
|
||||||
|
q.Options = field.NewString(table, "options")
|
||||||
|
q.Answer = field.NewString(table, "answer")
|
||||||
|
q.Explanation = field.NewString(table, "explanation")
|
||||||
|
q.Difficulty = field.NewInt32(table, "difficulty")
|
||||||
|
q.Category = field.NewString(table, "category")
|
||||||
|
q.CreatedAt = field.NewTime(table, "created_at")
|
||||||
|
q.UpdatedAt = field.NewTime(table, "updated_at")
|
||||||
|
q.DeletedAt = field.NewField(table, "deleted_at")
|
||||||
|
|
||||||
|
q.fillFieldMap()
|
||||||
|
|
||||||
|
return q
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *question) WithContext(ctx context.Context) *questionDo { return q.questionDo.WithContext(ctx) }
|
||||||
|
|
||||||
|
func (q question) TableName() string { return q.questionDo.TableName() }
|
||||||
|
|
||||||
|
func (q question) Alias() string { return q.questionDo.Alias() }
|
||||||
|
|
||||||
|
func (q question) Columns(cols ...field.Expr) gen.Columns { return q.questionDo.Columns(cols...) }
|
||||||
|
|
||||||
|
func (q *question) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||||
|
_f, ok := q.fieldMap[fieldName]
|
||||||
|
if !ok || _f == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
_oe, ok := _f.(field.OrderExpr)
|
||||||
|
return _oe, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *question) fillFieldMap() {
|
||||||
|
q.fieldMap = make(map[string]field.Expr, 11)
|
||||||
|
q.fieldMap["id"] = q.ID
|
||||||
|
q.fieldMap["sn"] = q.Sn
|
||||||
|
q.fieldMap["question"] = q.Question
|
||||||
|
q.fieldMap["options"] = q.Options
|
||||||
|
q.fieldMap["answer"] = q.Answer
|
||||||
|
q.fieldMap["explanation"] = q.Explanation
|
||||||
|
q.fieldMap["difficulty"] = q.Difficulty
|
||||||
|
q.fieldMap["category"] = q.Category
|
||||||
|
q.fieldMap["created_at"] = q.CreatedAt
|
||||||
|
q.fieldMap["updated_at"] = q.UpdatedAt
|
||||||
|
q.fieldMap["deleted_at"] = q.DeletedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q question) clone(db *gorm.DB) question {
|
||||||
|
q.questionDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
return q
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q question) replaceDB(db *gorm.DB) question {
|
||||||
|
q.questionDo.ReplaceDB(db)
|
||||||
|
return q
|
||||||
|
}
|
||||||
|
|
||||||
|
type questionDo struct{ gen.DO }
|
||||||
|
|
||||||
|
func (q questionDo) Debug() *questionDo {
|
||||||
|
return q.withDO(q.DO.Debug())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) WithContext(ctx context.Context) *questionDo {
|
||||||
|
return q.withDO(q.DO.WithContext(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) ReadDB() *questionDo {
|
||||||
|
return q.Clauses(dbresolver.Read)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) WriteDB() *questionDo {
|
||||||
|
return q.Clauses(dbresolver.Write)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Session(config *gorm.Session) *questionDo {
|
||||||
|
return q.withDO(q.DO.Session(config))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Clauses(conds ...clause.Expression) *questionDo {
|
||||||
|
return q.withDO(q.DO.Clauses(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Returning(value interface{}, columns ...string) *questionDo {
|
||||||
|
return q.withDO(q.DO.Returning(value, columns...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Not(conds ...gen.Condition) *questionDo {
|
||||||
|
return q.withDO(q.DO.Not(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Or(conds ...gen.Condition) *questionDo {
|
||||||
|
return q.withDO(q.DO.Or(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Select(conds ...field.Expr) *questionDo {
|
||||||
|
return q.withDO(q.DO.Select(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Where(conds ...gen.Condition) *questionDo {
|
||||||
|
return q.withDO(q.DO.Where(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Order(conds ...field.Expr) *questionDo {
|
||||||
|
return q.withDO(q.DO.Order(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Distinct(cols ...field.Expr) *questionDo {
|
||||||
|
return q.withDO(q.DO.Distinct(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Omit(cols ...field.Expr) *questionDo {
|
||||||
|
return q.withDO(q.DO.Omit(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Join(table schema.Tabler, on ...field.Expr) *questionDo {
|
||||||
|
return q.withDO(q.DO.Join(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) LeftJoin(table schema.Tabler, on ...field.Expr) *questionDo {
|
||||||
|
return q.withDO(q.DO.LeftJoin(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) RightJoin(table schema.Tabler, on ...field.Expr) *questionDo {
|
||||||
|
return q.withDO(q.DO.RightJoin(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Group(cols ...field.Expr) *questionDo {
|
||||||
|
return q.withDO(q.DO.Group(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Having(conds ...gen.Condition) *questionDo {
|
||||||
|
return q.withDO(q.DO.Having(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Limit(limit int) *questionDo {
|
||||||
|
return q.withDO(q.DO.Limit(limit))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Offset(offset int) *questionDo {
|
||||||
|
return q.withDO(q.DO.Offset(offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *questionDo {
|
||||||
|
return q.withDO(q.DO.Scopes(funcs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Unscoped() *questionDo {
|
||||||
|
return q.withDO(q.DO.Unscoped())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Create(values ...*model.Question) error {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return q.DO.Create(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) CreateInBatches(values []*model.Question, batchSize int) error {
|
||||||
|
return q.DO.CreateInBatches(values, batchSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save : !!! underlying implementation is different with GORM
|
||||||
|
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||||
|
func (q questionDo) Save(values ...*model.Question) error {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return q.DO.Save(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) First() (*model.Question, error) {
|
||||||
|
if result, err := q.DO.First(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*model.Question), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Take() (*model.Question, error) {
|
||||||
|
if result, err := q.DO.Take(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*model.Question), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Last() (*model.Question, error) {
|
||||||
|
if result, err := q.DO.Last(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*model.Question), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Find() ([]*model.Question, error) {
|
||||||
|
result, err := q.DO.Find()
|
||||||
|
return result.([]*model.Question), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Question, err error) {
|
||||||
|
buf := make([]*model.Question, 0, batchSize)
|
||||||
|
err = q.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||||
|
defer func() { results = append(results, buf...) }()
|
||||||
|
return fc(tx, batch)
|
||||||
|
})
|
||||||
|
return results, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) FindInBatches(result *[]*model.Question, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||||
|
return q.DO.FindInBatches(result, batchSize, fc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Attrs(attrs ...field.AssignExpr) *questionDo {
|
||||||
|
return q.withDO(q.DO.Attrs(attrs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Assign(attrs ...field.AssignExpr) *questionDo {
|
||||||
|
return q.withDO(q.DO.Assign(attrs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Joins(fields ...field.RelationField) *questionDo {
|
||||||
|
for _, _f := range fields {
|
||||||
|
q = *q.withDO(q.DO.Joins(_f))
|
||||||
|
}
|
||||||
|
return &q
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Preload(fields ...field.RelationField) *questionDo {
|
||||||
|
for _, _f := range fields {
|
||||||
|
q = *q.withDO(q.DO.Preload(_f))
|
||||||
|
}
|
||||||
|
return &q
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) FirstOrInit() (*model.Question, error) {
|
||||||
|
if result, err := q.DO.FirstOrInit(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*model.Question), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) FirstOrCreate() (*model.Question, error) {
|
||||||
|
if result, err := q.DO.FirstOrCreate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*model.Question), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) FindByPage(offset int, limit int) (result []*model.Question, count int64, err error) {
|
||||||
|
result, err = q.Offset(offset).Limit(limit).Find()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||||
|
count = int64(size + offset)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err = q.Offset(-1).Limit(-1).Count()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||||
|
count, err = q.Count()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = q.Offset(offset).Limit(limit).Scan(result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Scan(result interface{}) (err error) {
|
||||||
|
return q.DO.Scan(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q questionDo) Delete(models ...*model.Question) (result gen.ResultInfo, err error) {
|
||||||
|
return q.DO.Delete(models)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *questionDo) withDO(do gen.Dao) *questionDo {
|
||||||
|
q.DO = *do.(*gen.DO)
|
||||||
|
return q
|
||||||
|
}
|
||||||
16
internal/dao/repository/define.go
Normal file
16
internal/dao/repository/define.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/db/mysql"
|
||||||
|
)
|
||||||
|
|
||||||
|
var dbName mysql.DBName = "qgdzs_db"
|
||||||
|
|
||||||
|
var (
|
||||||
|
cacheBySn = "c:%v:s:%v"
|
||||||
|
)
|
||||||
|
|
||||||
|
func keyCacheBySn(sn string, tableName string) string {
|
||||||
|
return fmt.Sprintf(cacheBySn, tableName, sn)
|
||||||
|
}
|
||||||
83
internal/dao/repository/questions.go
Normal file
83
internal/dao/repository/questions.go
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/db/mysql"
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/db/redis"
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/utils"
|
||||||
|
"git.hlsq.asia/mmorpg/service-qgdzs/internal/dao/model"
|
||||||
|
"git.hlsq.asia/mmorpg/service-qgdzs/internal/dao/query"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type QuestionDao struct {
|
||||||
|
ctx context.Context
|
||||||
|
query *query.Query
|
||||||
|
cache *redis.CacheClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQuestionDao(ctx context.Context, cache ...*redis.CacheClient) *QuestionDao {
|
||||||
|
dao := &QuestionDao{
|
||||||
|
ctx: ctx,
|
||||||
|
query: query.Use(mysql.GetDB(dbName)),
|
||||||
|
}
|
||||||
|
if len(cache) > 0 {
|
||||||
|
dao.cache = cache[0]
|
||||||
|
}
|
||||||
|
return dao
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *QuestionDao) Create(question *model.Question) error {
|
||||||
|
err := d.query.Question.WithContext(d.ctx).
|
||||||
|
Create(question)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *QuestionDao) FindByRandom() (*model.Question, error) {
|
||||||
|
count, err := d.query.Question.WithContext(d.ctx).Count()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return nil, gorm.ErrRecordNotFound
|
||||||
|
}
|
||||||
|
first, err := d.query.Question.WithContext(d.ctx).
|
||||||
|
Offset(utils.RandInt(0, int(count-1))).
|
||||||
|
First()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return first, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *QuestionDao) FindBySn(sn string) (*model.Question, error) {
|
||||||
|
if d.cache != nil {
|
||||||
|
var question model.Question
|
||||||
|
if ok := d.cache.Get(d.ctx, keyCacheBySn(sn, question.TableName()), &question); ok {
|
||||||
|
return &question, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
first, err := d.query.Question.WithContext(d.ctx).
|
||||||
|
Where(d.query.Question.Sn.Eq(sn)).
|
||||||
|
First()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if d.cache != nil {
|
||||||
|
d.cache.Set(d.ctx, keyCacheBySn(sn, first.TableName()), first, 5*time.Minute)
|
||||||
|
}
|
||||||
|
return first, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *QuestionDao) FindCategory() ([]string, error) {
|
||||||
|
var categories []string
|
||||||
|
err := d.query.Question.WithContext(d.ctx).
|
||||||
|
Select(d.query.Question.Category).
|
||||||
|
Distinct().
|
||||||
|
Scan(&categories)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return categories, nil
|
||||||
|
}
|
||||||
32
internal/grpc_server/server/server_init.go
Normal file
32
internal/grpc_server/server/server_init.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/discover/common"
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/net/grpc/service"
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
grpc_pb.UnimplementedQgdzsServer
|
||||||
|
service.Base
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServer(ttl int64) *Server {
|
||||||
|
s := &Server{
|
||||||
|
Base: service.Base{
|
||||||
|
Target: common.KeyDiscoverQgdzs,
|
||||||
|
EtcdTTL: ttl,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
s.Base.OnInit = s.OnInit
|
||||||
|
s.Base.OnClose = s.OnClose
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) OnInit(serve *grpc.Server) {
|
||||||
|
grpc_pb.RegisterQgdzsServer(serve, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) OnClose() {
|
||||||
|
}
|
||||||
156
internal/grpc_server/server/server_question.go
Normal file
156
internal/grpc_server/server/server_question.go
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/db/redis"
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/log"
|
||||||
|
"git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb"
|
||||||
|
"git.hlsq.asia/mmorpg/service-qgdzs/internal/ai"
|
||||||
|
"git.hlsq.asia/mmorpg/service-qgdzs/internal/dao/model"
|
||||||
|
"git.hlsq.asia/mmorpg/service-qgdzs/internal/dao/repository"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
//var prompt = []string{`
|
||||||
|
//你是一个微信小游戏的内容策划,请生成 %v 道“每日趣味题”,要求:
|
||||||
|
//- 避免敏感、争议或超纲内容
|
||||||
|
//- 每次从 [动物冷知识, 科学趣理, 语言陷阱, 历史轶事, 地理奇观, 数学谜题, 艺术人文, 综合杂学] 中**随机选一个类型**
|
||||||
|
//- 确保选项有迷惑性,解析有趣
|
||||||
|
//- 绝对要避免重复,现在的时间是:%v
|
||||||
|
//- 输出格式为 JSON 数组,不要任何解释、不要Markdown、不要任何其他字符:
|
||||||
|
// [{
|
||||||
|
// "question": "题目文本", // 简洁,30字以内
|
||||||
|
// "options": ["A. 选项1", "B. 选项2", "C. 选项3", "D. 选项4"], // 提供4个选项(A/B/C/D),其中仅1个正确
|
||||||
|
// "answer": "C", // 答案
|
||||||
|
// "explanation": "解析文本", // 200字以内,尽量幽默有趣
|
||||||
|
// "category": "分类", // 只能从上面列出的类型中选择
|
||||||
|
// "difficulty": 100, // 难度分 0 - 100
|
||||||
|
// }]
|
||||||
|
//`}
|
||||||
|
|
||||||
|
var prompt = []string{`
|
||||||
|
你是一个微信小游戏的内容策划,我需要生成“每日趣味题”,要求:
|
||||||
|
- 避免敏感、争议或超纲内容
|
||||||
|
- 确保选项有迷惑性,解析有趣
|
||||||
|
- 绝对要避免重复,现在的时间是:%v
|
||||||
|
- 这些是我目前的分类:%v
|
||||||
|
- 输出格式为 JSON 数组,不要任何解释、不要Markdown、不要任何其他字符:
|
||||||
|
[{
|
||||||
|
"question": "题目文本", // 简洁,30字以内
|
||||||
|
"options": ["A. 选项1", "B. 选项2", "C. 选项3", "D. 选项4"], // 提供4个选项(A/B/C/D),其中仅1个正确
|
||||||
|
"answer": "C", // 答案
|
||||||
|
"explanation": "解析文本", // 200字以内,尽量幽默有趣
|
||||||
|
"category": "分类", // 尽量从上述分类中选择,你也可以增加,但是命名风格要类似
|
||||||
|
"difficulty": 100, // 难度分 0 - 100
|
||||||
|
}]
|
||||||
|
如果你准备好了,请回答”好的“,不要有其他任何字符
|
||||||
|
`, `
|
||||||
|
请帮我生成 %v 道,只允许回答 JSON 数组:
|
||||||
|
`, `
|
||||||
|
请继续生成 %v 道,只允许回答 JSON 数组:
|
||||||
|
`, `
|
||||||
|
请继续生成 %v 道,只允许回答 JSON 数组:
|
||||||
|
`, `
|
||||||
|
请继续生成 %v 道,只允许回答 JSON 数组:
|
||||||
|
`, `
|
||||||
|
请继续生成 %v 道,只允许回答 JSON 数组:
|
||||||
|
`}
|
||||||
|
|
||||||
|
type Question struct {
|
||||||
|
Question string `json:"question"` // 题干
|
||||||
|
Options []string `json:"options"` // 选项
|
||||||
|
Answer string `json:"answer"` // 答案
|
||||||
|
Explanation string `json:"explanation"` // 解析
|
||||||
|
Category string `json:"category"` // 分类
|
||||||
|
Difficulty int32 `json:"difficulty"` // 难度分
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) GenerateQuestion(ctx context.Context, req *grpc_pb.GenerateQuestionReq) (*grpc_pb.GenerateQuestionResp, error) {
|
||||||
|
category, err := repository.NewQuestionDao(ctx).FindCategory()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("GenerateQuestion FindCategory error: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
question := make([]*Question, 0)
|
||||||
|
err = ai.NewAIClient(false, "", 0.9).
|
||||||
|
RequestAI(
|
||||||
|
[]string{
|
||||||
|
fmt.Sprintf(prompt[0], time.Now().Format("2006-01-02 15:04:05"), category),
|
||||||
|
fmt.Sprintf(prompt[1], req.Num, req.Category),
|
||||||
|
fmt.Sprintf(prompt[2], req.Num),
|
||||||
|
fmt.Sprintf(prompt[3], req.Num),
|
||||||
|
fmt.Sprintf(prompt[4], req.Num),
|
||||||
|
fmt.Sprintf(prompt[5], req.Num),
|
||||||
|
},
|
||||||
|
func(content string, i int) error {
|
||||||
|
if i == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
step := make([]*Question, 0)
|
||||||
|
if err := json.Unmarshal([]byte(content), &step); err != nil {
|
||||||
|
log.Errorf("RequestAI json.Unmarshal error: %v, data: %v", err, content)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
question = append(question, step...)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("RequestAI error: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
questionDao := repository.NewQuestionDao(ctx, redis.GetCacheClient())
|
||||||
|
for _, q := range question {
|
||||||
|
marshal, _ := json.Marshal(q.Options)
|
||||||
|
if err = questionDao.Create(&model.Question{
|
||||||
|
Question: q.Question,
|
||||||
|
Options: string(marshal),
|
||||||
|
Answer: q.Answer,
|
||||||
|
Explanation: q.Explanation,
|
||||||
|
Category: q.Category,
|
||||||
|
Difficulty: q.Difficulty,
|
||||||
|
}); err != nil {
|
||||||
|
log.Errorf("GenerateQuestion Create error: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) GetQuestion(ctx context.Context, req *grpc_pb.GetQuestionReq) (*grpc_pb.GetQuestionResp, error) {
|
||||||
|
question, err := repository.NewQuestionDao(ctx).FindByRandom()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("GetQuestion error: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
options := make([]string, 0)
|
||||||
|
if err = json.Unmarshal([]byte(question.Options), &options); err != nil {
|
||||||
|
log.Errorf("GetQuestion json.Unmarshal error: %v, data: %v", err, question.Options)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &grpc_pb.GetQuestionResp{
|
||||||
|
Sn: question.Sn,
|
||||||
|
Question: question.Question,
|
||||||
|
Options: options,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) AnswerQuestion(ctx context.Context, req *grpc_pb.AnswerQuestionReq) (*grpc_pb.AnswerQuestionResp, error) {
|
||||||
|
question, err := repository.NewQuestionDao(ctx).FindBySn(req.Sn)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("AnswerQuestion error: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
options := make([]string, 0)
|
||||||
|
if err = json.Unmarshal([]byte(question.Options), &options); err != nil {
|
||||||
|
log.Errorf("AnswerQuestion json.Unmarshal error: %v, data: %v", err, question.Options)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &grpc_pb.AnswerQuestionResp{
|
||||||
|
Answer: question.Answer,
|
||||||
|
Explanation: question.Explanation,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
161
internal/grpc_server/server/server_question_temp.go
Normal file
161
internal/grpc_server/server/server_question_temp.go
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
//
|
||||||
|
//import (
|
||||||
|
// "bytes"
|
||||||
|
// "context"
|
||||||
|
// "encoding/json"
|
||||||
|
// "git.hlsq.asia/mmorpg/service-common/log"
|
||||||
|
// "git.hlsq.asia/mmorpg/service-common/proto/rs/grpc_pb"
|
||||||
|
// "io"
|
||||||
|
// "net/http"
|
||||||
|
//)
|
||||||
|
//
|
||||||
|
//var question = []string{
|
||||||
|
// "本次对话 数据来源必须:东方财富,巨潮资讯,官网,数据截止:自上市至2025年第3季度\n帮我查询一下京东方科技集团股份有限公司公司的所有财报数量",
|
||||||
|
// "帮我从东方财富 / 巨潮资讯 / 官网这三个来源整理一下重大事项公告的数量,按照三个维度划分( 并购重组公告披露,关联交易公告,对外投资公告)",
|
||||||
|
// "帮我从东方财富 / 巨潮资讯 / 官网这三个来源整理一下投资者关系活动,按照三个维度划分( 年度业绩说明次数, 投资者调研次数,接待机构数量)",
|
||||||
|
// "帮我查询一下ESG与治理的信息各个维度评分评级",
|
||||||
|
// "帮我查询一下这个公司监管合规信息,综合评估一下本年度监管合规(信披评分,公司治理,内控合规,ESG表现,财务合规,业务运营合规,股东与投资者权益保护合规,合规风险管理)百分制",
|
||||||
|
// "将本次对话的所有内容总结和完整的装入这个结构体生成json对象数据返回,注意:必须以json(markdown代码)的形式返回,并且只输出json即可不用输出其它说明,下面内容就是结构体: \n// CompanyComplianceScore 公司合规评分\ntype CompanyComplianceScore struct {\n\tInformationDisclosureRating string `json:\"informationDisclosureRating\" bson:\"information_disclosure_rating\" comment:\"信息披露评级\"`//获取交易所的信披评级,如A/B/C等\n\tRegularReportFrequencyCount *RegularReportFrequency `json:\"regularReportFrequency\" bson:\"regular_report_frequency\" comment:\"定期报告披露频次\"`\n\tMajorAnnouncementCount *MajorAnnouncementCount `json:\"majorAnnouncementCount\" bson:\"major_announcement_count\" comment:\"重大事项公告\"`\n\tInvestorRelationsActivity *InvestorRelationsActivity `json:\"InvestorRelationsActivity\" bson:\"investor_relations_activity\" comment:\"投资者关系活动\"`\n\tEsgReport *EsgReport `json:\"esgReport\" bson:\"esg_report\" comment:\"ESG与治理\"`\n\tDisclosureScore float64 `json:\"disclosureScore\" bson:\"disclosure_score\" comment:\"信息披露专项评分\"`\n\tCorporateGovernanceScore float64 `json:\"corporateGovernanceScore\" bson:\"corporate_governance_score\" comment:\"公司治理评分\"`\n\tInternalControlCompliance float64 `json:\"internalControlCompliance\" bson:\"internal_control_compliance\" comment:\"内控合规评分\"`\n\tEsgPerformanceScore float64 `json:\"esgPerformanceScore\" bson:\"esg_performance_score\" comment:\"ESG表现评分\"`\n\tFinancialComplianceScore float64 `json:\"financialComplianceScore\" bson:\"financial_compliance_score\" comment:\"财务合规评分\"`\n\tBusinessOperationCompliance float64 `json:\"businessOperationCompliance\" bson:\"business_operation_compliance\" comment:\"业务运营合规评分\"`\n\tShareholderRightsCompliance float64 `json:\"shareholderRightsCompliance\" bson:\"shareholder_rights_compliance\" comment:\"股东权益保护合规评分\"`\n\tComplianceRiskManagement float64 `json:\"complianceRiskManagement\" bson:\"compliance_risk_management\" comment:\"合规风险管理评分\"`\n\tOverallComprehensiveScore float64 `json:\"overallComprehensiveScore\" bson:\"overall_comprehensive_score\" comment:\"综合评分\"`\n}\n\n// RegularReportFrequency 定期报告披露频次\ntype RegularReportFrequency struct {\n\tAnnualReportCount int `json:\"annualReportCount\" bson:\"annual_report_count\" comment:\"年报数量\"`\n\tSemiAnnualReportCount int `json:\"semiAnnualReportCount\" bson:\"semi_annual_report_count\" comment:\"半年报数量\"`\n\tQuarterlyReportCount int `json:\"quarterlyReportCount\" bson:\"quarterly_report_count\" comment:\"季度报告数量\"`\n\tTotalReportCount int `json:\"totalReportCount\" bson:\"total_report_count\" comment:\"报告总数\"`\n}\n\n// MajorAnnouncementCount 重大事项公告\ntype MajorAnnouncementCount struct {\n\tMnaAnnouncementCount int `json:\"mnaAnnouncementCount\" bson:\"mna_announcement_count\" comment:\"并购重组公告数量\"`\n\tRelatedTransactionCount int `json:\"relatedTransactionCount\" bson:\"related_transaction_count\" comment:\"关联交易公告数量\"`\n\tForeignInvestmentCount int `json:\"foreignInvestmentCount\" bson:\"foreign_investment_count\" comment:\"对外投资公告数量\"`\n}\n\n// InvestorRelationsActivity 投资者关系活动\ntype InvestorRelationsActivity struct {\n\tAnnualPerformanceBriefings int `json:\"annualPerformanceBriefings\" bson:\"annual_performance_briefings\" comment:\"年度业绩说明次数\"`\n\tInvestorResearchCount int `json:\"investorResearchCount\" bson:\"investor_research_count\" comment:\"投资者调研次数\"`\n\tInstitutionsReceivedCount int `json:\"institutionsReceivedCount\" bson:\"institutions_received_count\" comment:\"接待机构数量\"`\n}\n\n// EsgReport ESG与治理\ntype EsgReport struct {\n\tEsgOverallScore float64 `json:\"esgOverallScore\" bson:\"esg_overall_score\" comment:\"ESG综合评分\"`//通过【上海华证指数信息服务有限公司】披露的公司ESG评级,例如BBB,不允许返回分数\n\tEnvironmentalScore float64 `json:\"environmentalScore\" bson:\"environmental_score\" comment:\"环境评分\"`\n\tSocialScore float64 `json:\"socialScore\" bson:\"social_score\" comment:\"社会评分\"`\n\tGovernanceScore float64 `json:\"governanceScore\" bson:\"governance_score\" comment:\"治理评分\"`\n}",
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//type Message struct {
|
||||||
|
// Role string `json:"role"`
|
||||||
|
// Content string `json:"content"`
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//type Input struct {
|
||||||
|
// Messages []Message `json:"messages"`
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//type Parameters struct {
|
||||||
|
// EnableSearch bool `json:"enable_search"`
|
||||||
|
// ResultFormat string `json:"result_format"`
|
||||||
|
// SearchOptions SearchOptions `json:"search_options"`
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//type SearchOptions struct {
|
||||||
|
// SearchStrategy string `json:"search_strategy"`
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//type RequestBody struct {
|
||||||
|
// Model string `json:"model"`
|
||||||
|
// Input Input `json:"input"`
|
||||||
|
// Parameters Parameters `json:"parameters"`
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//type ResponseBody struct {
|
||||||
|
// Output struct {
|
||||||
|
// Choices []struct {
|
||||||
|
// Message Message `json:"message"`
|
||||||
|
// FinishReason string `json:"finish_reason"`
|
||||||
|
// } `json:"choices"`
|
||||||
|
// } `json:"output"`
|
||||||
|
// Usage struct {
|
||||||
|
// InputTokens int32 `json:"input_tokens"`
|
||||||
|
// OutputTokens int32 `json:"output_tokens"`
|
||||||
|
// TotalTokens int32 `json:"total_tokens"`
|
||||||
|
// } `json:"usage"`
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func (s *Server) GenerateQuestion(ctx context.Context, req *grpc_pb.GenerateQuestionReq) (*grpc_pb.GenerateQuestionResp, error) {
|
||||||
|
// inToken, outToken := int32(0), int32(0)
|
||||||
|
//
|
||||||
|
// messages := make([]Message, 0)
|
||||||
|
// for i, step := range question {
|
||||||
|
// messages = append(messages, newUserMessage(step))
|
||||||
|
//
|
||||||
|
// //chatCompletion, err := client.Chat.Completions.New(
|
||||||
|
// // context.Background(), openai.ChatCompletionNewParams{
|
||||||
|
// // Messages: messages,
|
||||||
|
// // Model: "qwen3-max",
|
||||||
|
// // },
|
||||||
|
// //)
|
||||||
|
// //if err != nil {
|
||||||
|
// // return nil, err
|
||||||
|
// //}
|
||||||
|
// r, err := request(messages)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// inToken += r.Usage.InputTokens
|
||||||
|
// outToken += r.Usage.OutputTokens
|
||||||
|
// log.Infof("回答 %v:%v", i, r)
|
||||||
|
// //break
|
||||||
|
// messages = append(messages, r.Output.Choices[0].Message)
|
||||||
|
//
|
||||||
|
// //log.Infof("回答 %v:%v", i, chatCompletion.Choices[0].Message.Content)
|
||||||
|
// //messages = append(messages, openai.AssistantMessage(chatCompletion.Choices[0].Message.Content))
|
||||||
|
// }
|
||||||
|
// log.Infof("返回:%v", messages[len(messages)-1].Content)
|
||||||
|
// //log.Infof("消耗token:%v %v, 费用:%v", inToken, outToken, float64(inToken)/1000*0.0032+float64(outToken)/1000*0.0128)
|
||||||
|
// log.Infof("消耗token:%v %v, 费用:%v", inToken, outToken, float64(inToken)/1000*0.002+float64(outToken)/1000*0.003)
|
||||||
|
//
|
||||||
|
// //chatCompletion, err := client.Chat.Completions.New(
|
||||||
|
// // context.Background(), openai.ChatCompletionNewParams{
|
||||||
|
// // Messages: []openai.ChatCompletionMessageParamUnion{
|
||||||
|
// // openai.UserMessage("你能做什么"),
|
||||||
|
// // },
|
||||||
|
// // Model: "qwen3-max",
|
||||||
|
// // },
|
||||||
|
// //)
|
||||||
|
// //if err != nil {
|
||||||
|
// // return nil, err
|
||||||
|
// //}
|
||||||
|
// //for i, choice := range chatCompletion.Choices {
|
||||||
|
// // log.Infof("chatCompletion %v: %#+v \n", i, choice)
|
||||||
|
// //}
|
||||||
|
// //log.Infof("返回:%v", chatCompletion.Choices[0].Message.Content)
|
||||||
|
// return nil, nil
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func newUserMessage(content string) Message {
|
||||||
|
// return Message{
|
||||||
|
// Role: "user",
|
||||||
|
// Content: content,
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func request(messages []Message) (*ResponseBody, error) {
|
||||||
|
// client := &http.Client{}
|
||||||
|
// requestBody := RequestBody{
|
||||||
|
// //Model: "qwen3-max",
|
||||||
|
// Model: "deepseek-v3.2",
|
||||||
|
// Input: Input{
|
||||||
|
// Messages: messages,
|
||||||
|
// },
|
||||||
|
// Parameters: Parameters{
|
||||||
|
// EnableSearch: true,
|
||||||
|
// SearchOptions: SearchOptions{
|
||||||
|
// SearchStrategy: "max",
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// ResultFormat: "message",
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// jsonData, _ := json.Marshal(requestBody)
|
||||||
|
//
|
||||||
|
// req, err := http.NewRequest("POST", "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation", bytes.NewBuffer(jsonData))
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// req.Header.Set("Authorization", "Bearer "+"sk-4daf94ad2fa94288b198d2a1d8924cef")
|
||||||
|
// req.Header.Set("Content-Type", "application/json")
|
||||||
|
//
|
||||||
|
// resp, err := client.Do(req)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// defer resp.Body.Close()
|
||||||
|
//
|
||||||
|
// body, err := io.ReadAll(resp.Body)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// var res ResponseBody
|
||||||
|
// if err = json.Unmarshal(body, &res); err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// return &res, nil
|
||||||
|
//}
|
||||||
Reference in New Issue
Block a user