Compare commits

...

7 Commits

Author SHA1 Message Date
269771f982 Dockerfile 2026-04-01 13:16:32 +08:00
4d8cabacc5 Merge remote-tracking branch 'origin/dev' into dev 2026-04-01 13:05:42 +08:00
06b3f40905 Dockerfile 2026-04-01 13:04:59 +08:00
qhd
508f139da2 refactor: 优化数据库查询构建链式调用 2026-03-27 14:55:45 +08:00
qhd
7b8caaca53 refactor: 重命名集合常量并优化配置注释 2026-03-27 10:59:54 +08:00
qhd
12a743d8da refactor: 将分布式锁从 redis 迁移至 utils 包 2026-03-27 09:49:45 +08:00
qhd
19d62ab927 Generating commit message... 2026-03-24 16:23:04 +08:00
13 changed files with 111 additions and 49 deletions

51
Dockerfile Normal file
View File

@@ -0,0 +1,51 @@
# 阶段1: 构建
FROM golang:1.25-alpine AS builder
RUN apk add --no-cache git ca-certificates tzdata
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.cn,direct
ENV CGO_ENABLED=0
ENV GOTOOLCHAIN=auto
ENV GOPRIVATE=gitea.com/red-future/common
# 配置git使用私有Gitea仓库
RUN git config --global url."http://x-token-auth:9b31146aa8c10a7cb4f2e49dcee0934a223be1076289810e1ad98b968066c2bc@116.204.74.41:3000/red-future/common.git".insteadOf "https://gitea.com/red-future/common.git" && \
git config --global credential.helper store
WORKDIR /build
# 复制父目录的 common 模块(因为 go.mod 中使用了本地 replace)
COPY ../common /build/common
COPY . .
RUN go mod download && go mod tidy
RUN go build -ldflags="-s -w" -o main ./main.go
# 阶段2: 运行
FROM alpine:3.19
RUN apk add --no-cache ca-certificates tzdata
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
WORKDIR /app
COPY --from=builder /build/main .
COPY --from=builder /build/config.yml ./
RUN mkdir -p /app/resource/log/run \
/app/resource/log/server \
&& adduser -D -u 1000 appuser \
&& chown -R appuser:appuser /app
USER appuser
EXPOSE 3008
CMD ["./main"]

View File

@@ -13,15 +13,17 @@ database:
host: "116.204.74.41"
port: "15432"
user: "postgres"
pass: "123456"
pass: "Bjang09@686^*^"
name: "oss"
role: "master"
maxIdle: "5"
maxOpen: "20"
maxLifetime: "60s"
charset: "utf8mb4" #数据库编码
debug: true
dryRun: false #空跑
role: "master" # (可选)数据库主从角色(master/slave)默认为master。如果不使用应用主从机制请不配置或留空即可。
debug: false # (可选)开启调试模式
dryRun: false # (可选)ORM空跑(只读不写)
charset: "utf8" # (可选)数据库编码(如: utf8mb4/utf8/gbk/gb2312)一般设置为utf8mb4。默认为utf8。
timezone: "Asia/Shanghai" # (可选)时区配置,例如:Local
maxIdle: 5 # (可选)连接池最大闲置的连接数(默认10)
maxOpen: 20 # (可选)连接池最大打开的连接数(默认无限制)
maxLifetime: "30s" # (可选)连接对象可重复使用的时间长度(默认30秒)
maxIdleConnTime: "30s" # (可选v2.10新增)连接池中空闲连接的最大生存时间(默认30秒)。可以通过配置文件或SetConnMaxIdleTime方法设置避免长时间空闲连接占用资源。
createdAt: "created_at" # (可选)自动创建时间字段名称
updatedAt: "updated_at" # (可选)自动更新时间字段名称
deletedAt: "deleted_at" # (可选)软删除时间字段名称
@@ -30,15 +32,17 @@ database:
host: "116.204.74.41"
port: "15432"
user: "postgres"
pass: "123456"
pass: "Bjang09@686^*^"
name: "oss"
role: "slave"
maxIdle: "5"
maxOpen: "20"
maxLifetime: "60s"
charset: "utf8mb4" #数据库编码
debug: true
dryRun: false #空跑
role: "slave" # (可选)数据库主从角色(master/slave)默认为master。如果不使用应用主从机制请不配置或留空即可。
debug: false # (可选)开启调试模式
dryRun: false # (可选)ORM空跑(只读不写)
charset: "utf8" # (可选)数据库编码(如: utf8mb4/utf8/gbk/gb2312)一般设置为utf8mb4。默认为utf8。
timezone: "Asia/Shanghai" # (可选)时区配置,例如:Local
maxIdle: 5 # (可选)连接池最大闲置的连接数(默认10)
maxOpen: 20 # (可选)连接池最大打开的连接数(默认无限制)
maxLifetime: "30s" # (可选)连接对象可重复使用的时间长度(默认30秒)
maxIdleConnTime: "30s" # (可选v2.10新增)连接池中空闲连接的最大生存时间(默认30秒)。可以通过配置文件或SetConnMaxIdleTime方法设置避免长时间空闲连接占用资源。
createdAt: "created_at" # (可选)自动创建时间字段名称
updatedAt: "updated_at" # (可选)自动更新时间字段名称
deletedAt: "deleted_at" # (可选)软删除时间字段名称
@@ -71,7 +75,7 @@ minio:
region: "us-east-1" # 与 MinIO 服务端 REGION 一致(默认 us-east-1
# 文件上传服务地址与oss模块minio中的endpoint一致
filePrefix: "116.204.74.41:9000"
filePrefix: "http://116.204.74.41:9000"
# 文件存储初始化容量大小配置
oss:

View File

@@ -1,7 +0,0 @@
package consts
// MongoDB集合名称常量
const (
FileCollection = "file"
TenantOssTotalCollection = "tenant_oss_total"
)

7
consts/table_name.go Normal file
View File

@@ -0,0 +1,7 @@
package consts
// 数据库表名
const (
TableNameFile = "file"
TableNameTenantOssTotal = "tenant_oss_total"
)

View File

@@ -20,7 +20,7 @@ func (d *file) Insert(ctx context.Context, req *dto.UploadFile) (id int64, err e
if err = gconv.Struct(req, &res); err != nil {
return
}
r, err := gfdb.DB(ctx).Model(ctx, consts.FileCollection).Insert(&res)
r, err := gfdb.DB(ctx).Model(ctx, consts.TableNameFile).Insert(&res)
if err != nil {
return
}

View File

@@ -20,7 +20,7 @@ func (d *tenantOssTotal) SaveOrUpdate(ctx context.Context, updateData []*dto.Upd
if err = gconv.Structs(updateData, &res); err != nil {
return
}
r, err := gfdb.DB(ctx).Model(ctx, consts.TenantOssTotalCollection).Data(res).OnConflict(entity.TenantOssCol.TenantId).Save()
r, err := gfdb.DB(ctx).Model(ctx, consts.TableNameTenantOssTotal).Data(res).OnConflict(entity.TenantOssCol.TenantId).Save()
if err != nil {
return
}
@@ -28,7 +28,7 @@ func (d *tenantOssTotal) SaveOrUpdate(ctx context.Context, updateData []*dto.Upd
}
func (d *tenantOssTotal) GetOneByTenantId(ctx context.Context, req *dto.GetByTenantIdReq) (res *entity.TenantOssTotal, err error) {
model := gfdb.DB(ctx).Model(ctx, consts.TenantOssTotalCollection).Where(entity.TenantOssCol.TenantId, req.TenantId)
model := gfdb.DB(ctx).Model(ctx, consts.TableNameTenantOssTotal).Where(entity.TenantOssCol.TenantId, req.TenantId)
record, err := model.One()
if err != nil {
return

2
go.mod
View File

@@ -3,7 +3,7 @@ module oss
go 1.26.0
require (
gitea.com/red-future/common v0.0.4
gitea.com/red-future/common v0.0.6
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.10.0
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.5
github.com/gogf/gf/v2 v2.10.0

4
go.sum
View File

@@ -1,6 +1,6 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
gitea.com/red-future/common v0.0.4 h1:2QgKc+B2iNfPRncKpmIqIzVwaMGJ3y3dt5v+35YD8SU=
gitea.com/red-future/common v0.0.4/go.mod h1:UI9N5UUjilbMPF7+/lypZSnqDVHigt14300oSRrAyZg=
gitea.com/red-future/common v0.0.6 h1:2Otksfcy5V5JCBcqd2eRKh4WwZ/iAiIhJZMr6uM1x+Q=
gitea.com/red-future/common v0.0.6/go.mod h1:UI9N5UUjilbMPF7+/lypZSnqDVHigt14300oSRrAyZg=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=

View File

@@ -20,5 +20,8 @@ type UploadFile struct {
// UploadFileRes 上传文件响应
type UploadFileRes struct {
FileURL string `json:"fileURL" dc:"上传地址"`
FileSize int `json:"fileSize" dc:"文件大小"`
FileName string `json:"fileName" dc:"文件名称"`
FileFormat string `json:"fileFormat" dc:"文件格式"`
FileAddressPrefix string `json:"fileAddressPrefix"`
}

View File

@@ -8,21 +8,18 @@ import (
type File struct {
beans.SQLBaseDO `orm:",inherit"` // 嵌入基础字段Id, Bid, Creator, CreatedAt, Updater, UpdatedAt, Deleter, DeletedAt, IsDeleted
// 业务字段
TenantId uint64 `orm:"tenant_id" json:"tenantId"` // 租户ID
FileURL string `orm:"file_url" json:"fileURL"` // 文件URL
FileURL string `orm:"file_url" json:"fileURL"` // 文件URL
FileSize int `orm:"file_size" json:"fileSize"`
}
type fileCol struct {
beans.SQLBaseCol
TenantId string
FileURL string
FileSize string
}
var FileCol = fileCol{
SQLBaseCol: beans.DefSQLBaseCol,
TenantId: "tenant_id",
FileURL: "file_url",
FileSize: "file_size",
}

View File

@@ -8,21 +8,18 @@ import (
type TenantOssTotal struct {
beans.SQLBaseDO `orm:",inherit"` // 嵌入基础字段Id, Creator, CreatedAt, Updater, UpdatedAt, TenantId, IsDeleted
// 基础信息
TenantId uint64 `orm:"tenant_id" json:"tenantId"` // 租户ID
UsedOssSize int `orm:"used_oss_size" json:"usedOssSize"`
TotalOssSize int `orm:"total_oss_size" json:"totalOssSize"`
UsedOssSize int `orm:"used_oss_size" json:"usedOssSize"`
TotalOssSize int `orm:"total_oss_size" json:"totalOssSize"`
}
type tenantOssCol struct {
beans.SQLBaseCol
TenantId string
UsedOssSize string
TotalOssSize string
}
var TenantOssCol = tenantOssCol{
SQLBaseCol: beans.DefSQLBaseCol,
TenantId: "tenant_id",
UsedOssSize: "used_oss_size",
TotalOssSize: "total_oss_size",
}

View File

@@ -39,7 +39,7 @@ func (f *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto
// 获取redis-租户存储-锁key
fileLockKey := fmt.Sprintf(consts.FileLockKey, gconv.String(user.TenantId))
success, err := redis.Lock(ctx, fileLockKey, gconv.Int64(time.Minute*1), func(ctx context.Context) error {
success, err := utils.Lock(ctx, fileLockKey, gconv.Int64(time.Minute*1), func(ctx context.Context) error {
// 获取redis-租户存储容量总数
get, err := redis.RedisClient().Get(ctx, tenantOssTotalKey)
if err != nil {
@@ -100,7 +100,7 @@ func (f *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto
return nil, gerror.New("存储服务内存不足")
}
// 上传图片
fileURL, err := minio.UploadFile(ctx, req.File)
fileURL, fileName, fileFormat, err := minio.UploadFile(ctx, req.File)
if err != nil {
glog.Errorf(ctx, "上传图片失败: %v", err)
return nil, err
@@ -115,8 +115,16 @@ func (f *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto
return nil, err
}
// 返回图片url
return &dto.UploadFileRes{
FileURL: fileURL,
FileAddressPrefix: minio.GetFileAddressPrefix(ctx),
}, err
res = &dto.UploadFileRes{
FileURL: fileURL,
FileSize: fileSize,
FileName: fileName,
FileFormat: fileFormat,
}
url, err := utils.GetFileAddressPrefix(ctx)
if err != nil {
return
}
res.FileAddressPrefix = url
return
}

View File

@@ -40,10 +40,12 @@ func (s *tenantOssTotal) UpdateUsedOssSize(ctx context.Context) (err error) {
updateData = append(updateData, e)
}
// 更新数据库
_, err = dao.TenantOssTotal.SaveOrUpdate(ctx, updateData)
if err != nil {
return err
if len(updateData) != 0 {
// 更新数据库
_, err = dao.TenantOssTotal.SaveOrUpdate(ctx, updateData)
if err != nil {
return err
}
}
return err
}