Compare commits
7 Commits
master
...
269771f982
| Author | SHA1 | Date | |
|---|---|---|---|
| 269771f982 | |||
| 4d8cabacc5 | |||
| 06b3f40905 | |||
| 508f139da2 | |||
| 7b8caaca53 | |||
| 12a743d8da | |||
| 19d62ab927 |
51
Dockerfile
Normal file
51
Dockerfile
Normal 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"]
|
||||
38
config.yml
38
config.yml
@@ -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:
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package consts
|
||||
|
||||
// MongoDB集合名称常量
|
||||
const (
|
||||
FileCollection = "file"
|
||||
TenantOssTotalCollection = "tenant_oss_total"
|
||||
)
|
||||
7
consts/table_name.go
Normal file
7
consts/table_name.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package consts
|
||||
|
||||
// 数据库表名
|
||||
const (
|
||||
TableNameFile = "file"
|
||||
TableNameTenantOssTotal = "tenant_oss_total"
|
||||
)
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
2
go.mod
@@ -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
4
go.sum
@@ -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=
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user