提交 910c857e 编写于 作者: Mr.奇淼('s avatar Mr.奇淼(

Merge remote-tracking branch 'origin/gva_gormv2_dev' into gva_gormv2_dev

server { server {
listen 8000; listen 8080;
server_name localhost; server_name localhost;
#charset koi8-r; #charset koi8-r;
......
...@@ -7,58 +7,51 @@ filename="./config.yaml" ...@@ -7,58 +7,51 @@ filename="./config.yaml"
cat>"${filename}"<<EOF cat>"${filename}"<<EOF
# Gin-Vue-Admin Global Configuration # Gin-Vue-Admin Global Configuration
# casbin configuration
casbin:
model-path: './resource/rbac_model.conf'
# jwt configuration # jwt configuration
jwt: jwt:
signing-key: 'qmPlus' signing-key: 'qmPlus'
# mysql connect configuration # zap logger configuration
mysql: zap:
username: root level: 'info'
password: 'Aa@6447985' format: 'console'
path: mysql prefix: '[GIN-VUE-ADMIN]'
db-name: 'qmPlus' director: 'log'
config: 'charset=utf8mb4&parseTime=True&loc=Local' link-name: 'latest_log'
max-idle-conns: 10 show-line: true
max-open-conns: 10 encode-level: 'LowercaseColorLevelEncoder'
log-mode: true stacktrace-key: 'stacktrace'
log-in-console: true
#sqlite 配置
sqlite:
path: db.db
log-mode: true
config: 'loc=Asia/Shanghai'
# oss configuration
# 切换本地与七牛云上传,分配头像和文件路径
localupload:
local: false
avatar-path: uploads/avatar
file-path: uploads/file
# 请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址
qiniu:
access-key: '25j8dYBZ2wuiy0yhwShytjZDTX662b8xiFguwxzZ'
secret-key: 'pgdbqEsf7ooZh7W3xokP833h3dZ_VecFXPDeG5JY'
bucket: 'qm-plus-img'
img-path: 'http://qmplusimg.henrongyi.top'
# redis configuration # redis configuration
redis: redis:
addr: redis:6379
password: ''
db: 0 db: 0
addr: '177.7.0.14:6379'
password: ''
# email configuration
email:
to: 'xxx@qq.com'
port: 465
from: 'xxx@163.com'
host: 'smtp.163.com'
is-ssl: true
secret: 'xxx'
nickname: 'test'
# casbin configuration
casbin:
model-path: './resource/rbac_model.conf'
# system configuration # system configuration
system: system:
use-multipoint: true
env: 'public' # Change to "develop" to skip authentication for development mode env: 'public' # Change to "develop" to skip authentication for development mode
addr: 8888 addr: 8888
db-type: "mysql" # support mysql/sqlite db-type: 'mysql'
oss-type: 'local'
config-env: 'GVA_CONFIG'
need-init-data: true
use-multipoint: false
# captcha configuration # captcha configuration
captcha: captcha:
...@@ -66,28 +59,59 @@ captcha: ...@@ -66,28 +59,59 @@ captcha:
img-width: 240 img-width: 240
img-height: 80 img-height: 80
# zap logger configuration # mysql connect configuration
zap: mysql:
# 可使用 "debug", "info", "warn", "error", "dpanic", "panic", "fatal", path: '177.7.0.13:3306'
level: 'info' config: 'charset=utf8mb4&parseTime=True&loc=Local'
# console: 控制台, json: json格式输出 db-name: 'qmPlus'
format: 'console' username: 'root'
prefix: '[GIN-VUE-ADMIN]' password: 'Aa@6447985'
director: 'log' max-idle-conns: 10
link-name: 'latest_log' max-open-conns: 10
show-line: true log-mode: false
# LowercaseLevelEncoder:小写, LowercaseColorLevelEncoder:小写带颜色,CapitalLevelEncoder: 大写, CapitalColorLevelEncoder: 大写带颜色,
encode-level: 'LowercaseColorLevelEncoder'
stacktrace-key: 'stacktrace'
log-in-console: true
email: # sqlite connect configuration (sqlite需要gcc支持 windows用户需要自行安装gcc)
email-from: 'xxx@163.com' sqlite:
email-nickname: 'test' path: 'db.db'
email-secret: 'xxx' max-idle-conns: 10
email-to: 'xxx@qq.com' max-open-conns: 10
email-host: 'smtp.163.com' logger: true
email-port: 465
email-isSSL: true # Sqlserver connect configuration
sqlserver:
path: 'localhost:9930'
db-name: 'gorm'
username: 'gorm'
password: 'LoremIpsum86'
max-idle-conns: 10
max-open-conns: 10
logger: true
# Postgresql connect configuration
postgresql:
host: '127.0.0.1'
port: '9920'
config: 'sslmode=disable TimeZone=Asia/Shanghai'
db-name: 'gorm'
username: 'gorm'
password: 'gorm'
max-idle-conns: 10
max-open-conns: 10
prefer-simple-protocol: true
logger: false
# local configuration
local:
path: 'uploads/file'
# qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址)
qiniu:
zone: 'ZoneHuadong'
bucket: 'qm-plus-img'
img-path: 'http://qmplusimg.henrongyi.top'
use-https: false
access-key: '25j8dYBZ2wuiy0yhwShytjZDTX662b8xiFguwxzZ'
secret-key: 'pgdbqEsf7ooZh7W3xokP833h3dZ_VecFXPDeG5JY'
use-cdn-domains: false
EOF EOF
...@@ -3,16 +3,16 @@ name: gin-vue-admin build test ...@@ -3,16 +3,16 @@ name: gin-vue-admin build test
on: on:
push: push:
branches: branches:
- '*' - "*"
paths-ignore: paths-ignore:
- './db/**' - "./db/**"
- '**.md' - "**.md"
pull_request: pull_request:
branches: branches:
- '*' - "*"
paths-ignore: paths-ignore:
- './db/**' - "./db/**"
- '**.md' - "**.md"
jobs: jobs:
frontend: frontend:
...@@ -22,7 +22,6 @@ jobs: ...@@ -22,7 +22,6 @@ jobs:
matrix: matrix:
node-version: [12.x] node-version: [12.x]
steps: steps:
- name: Check out branch - name: Check out branch
uses: actions/checkout@v2 uses: actions/checkout@v2
...@@ -41,11 +40,10 @@ jobs: ...@@ -41,11 +40,10 @@ jobs:
name: Backend build name: Backend build
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Set up Go 1.14
- name: Set up Go 1.13
uses: actions/setup-go@v1 uses: actions/setup-go@v1
with: with:
go-version: 1.13 go-version: 1.14
id: go id: go
- name: Check out branch - name: Check out branch
......
...@@ -15,7 +15,7 @@ services: ...@@ -15,7 +15,7 @@ services:
container_name: gva-web container_name: gva-web
restart: always restart: always
ports: ports:
- '8000:8000' - '8080:8080'
depends_on: depends_on:
- server - server
command: [ 'nginx-debug', '-g', 'daemon off;' ] command: [ 'nginx-debug', '-g', 'daemon off;' ]
...@@ -34,6 +34,9 @@ services: ...@@ -34,6 +34,9 @@ services:
depends_on: depends_on:
- mysql - mysql
- redis - redis
links:
- mysql
- redis
networks: networks:
network: network:
ipv4_address: 177.7.0.12 ipv4_address: 177.7.0.12
...@@ -48,8 +51,6 @@ services: ...@@ -48,8 +51,6 @@ services:
environment: environment:
MYSQL_DATABASE: 'qmPlus' # 初始化启动时要创建的数据库的名称 MYSQL_DATABASE: 'qmPlus' # 初始化启动时要创建的数据库的名称
MYSQL_ROOT_PASSWORD: 'Aa@6447985' # root管理员用户密码 MYSQL_ROOT_PASSWORD: 'Aa@6447985' # root管理员用户密码
volumes:
- '.docker-compose/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d'
networks: networks:
network: network:
ipv4_address: 177.7.0.13 ipv4_address: 177.7.0.13
...@@ -59,7 +60,7 @@ services: ...@@ -59,7 +60,7 @@ services:
container_name: gva-redis # 容器名 container_name: gva-redis # 容器名
restart: always restart: always
ports: ports:
- '6379:6379' - '16379:6379'
networks: networks:
network: network:
ipv4_address: 177.7.0.14 ipv4_address: 177.7.0.14
\ No newline at end of file
...@@ -24,6 +24,8 @@ COPY --from=0 /go/src/gin-vue-admin/server ./ ...@@ -24,6 +24,8 @@ COPY --from=0 /go/src/gin-vue-admin/server ./
COPY --from=0 /go/src/gin-vue-admin/config.yaml ./ COPY --from=0 /go/src/gin-vue-admin/config.yaml ./
COPY --from=0 /go/src/gin-vue-admin/resource ./resource COPY --from=0 /go/src/gin-vue-admin/resource ./resource
EXPOSE 8888
ENTRYPOINT ./server ENTRYPOINT ./server
# 根据Dockerfile生成Docker镜像 # 根据Dockerfile生成Docker镜像
......
...@@ -60,3 +60,19 @@ func ReloadSystem(c *gin.Context) { ...@@ -60,3 +60,19 @@ func ReloadSystem(c *gin.Context) {
response.OkWithMessage("设置成功", c) response.OkWithMessage("设置成功", c)
} }
} }
// @Tags system
// @Summary 获取服务器信息
// @Security ApiKeyAuth
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /system/getServerInfo [post]
func GetServerInfo(c *gin.Context) {
server, err := service.GetServerInfo()
if err != nil {
response.FailWithMessage(fmt.Sprintf("获取失败,%v", err), c)
return
}
response.OkDetailed(gin.H{"server":server}, "获取成功",c)
}
\ No newline at end of file
# Gin-Vue-Admin Global Configuration # Gin-Vue-Admin Global Configuration
# jwt configuration
jwt:
signing-key: 'qmPlus'
# zap logger configuration
zap:
level: 'info'
format: 'console'
prefix: '[GIN-VUE-ADMIN]'
director: 'log'
link-name: 'latest_log'
show-line: true
encode-level: 'LowercaseColorLevelEncoder'
stacktrace-key: 'stacktrace'
log-in-console: true
# redis configuration
redis:
db: 0
addr: '127.0.0.1:6379'
password: ''
# email configuration
email:
to: 'xxx@qq.com'
port: 465
from: 'xxx@163.com'
host: 'smtp.163.com'
is-ssl: true
secret: 'xxx'
nickname: 'test'
# casbin configuration # casbin configuration
casbin: casbin:
model-path: './resource/rbac_model.conf' model-path: './resource/rbac_model.conf'
# jwt configuration # system configuration
jwt: system:
signing-key: 'qmPlus' env: 'public' # Change to "develop" to skip authentication for development mode
addr: 8888
db-type: 'mysql'
oss-type: 'local'
config-env: 'GVA_CONFIG'
need-init-data: false
use-multipoint: false
# captcha configuration
captcha:
key-long: 6
img-width: 240
img-height: 80
# mysql connect configuration # mysql connect configuration
mysql: mysql:
username: root
password: 'Aa@6447985'
path: '127.0.0.1:3306' path: '127.0.0.1:3306'
db-name: 'qmPlus'
config: 'charset=utf8mb4&parseTime=True&loc=Local' config: 'charset=utf8mb4&parseTime=True&loc=Local'
db-name: 'qmPlus'
username: 'root'
password: 'Aa@6447985'
max-idle-conns: 10 max-idle-conns: 10
max-open-conns: 10 max-open-conns: 10
log-mode: false log-mode: false
# Postgresql connect configuration # sqlite connect configuration (sqlite需要gcc支持 windows用户需要自行安装gcc)
postgresql:
username: 'gorm'
password: 'gorm'
db-name: 'gorm'
port: '9920'
config: 'sslmode=disable TimeZone=Asia/Shanghai'
max-idle-conns: 10
max-open-conns: 10
logger: false
prefer-simple-protocol: true
# sqlite connect configuration
# sqlite需要gcc支持 windows用户需要自行安装gcc
sqlite: sqlite:
# path: 'file::memory:?cache=shared' # 内存模式
path: 'db.db' path: 'db.db'
max-idle-conns: 10 max-idle-conns: 10
max-open-conns: 10 max-open-conns: 10
...@@ -42,70 +72,37 @@ sqlite: ...@@ -42,70 +72,37 @@ sqlite:
# Sqlserver connect configuration # Sqlserver connect configuration
sqlserver: sqlserver:
path: 'localhost:9930'
db-name: 'gorm'
username: 'gorm' username: 'gorm'
password: 'LoremIpsum86' password: 'LoremIpsum86'
db-name: 'gorm'
path: 'localhost:9930'
max-idle-conns: 10 max-idle-conns: 10
max-open-conns: 10 max-open-conns: 10
logger: true logger: true
# oss configuration # Postgresql connect configuration
postgresql:
host: '127.0.0.1'
port: '9920'
config: 'sslmode=disable TimeZone=Asia/Shanghai'
db-name: 'gorm'
username: 'gorm'
password: 'gorm'
max-idle-conns: 10
max-open-conns: 10
prefer-simple-protocol: true
logger: false
# 切换本地与七牛云上传,分配头像和文件路径 # local configuration
localupload: local:
local: false path: 'uploads/file'
file-path: uploads/file
# 请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址 # qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址)
qiniu: qiniu:
access-key: '25j8dYBZ2wuiy0yhwShytjZDTX662b8xiFguwxzZ' zone: 'ZoneHuadong'
secret-key: 'pgdbqEsf7ooZh7W3xokP833h3dZ_VecFXPDeG5JY'
bucket: 'qm-plus-img' bucket: 'qm-plus-img'
img-path: 'http://qmplusimg.henrongyi.top' img-path: 'http://qmplusimg.henrongyi.top'
use-https: false
# redis configuration access-key: '25j8dYBZ2wuiy0yhwShytjZDTX662b8xiFguwxzZ'
redis: secret-key: 'pgdbqEsf7ooZh7W3xokP833h3dZ_VecFXPDeG5JY'
addr: '127.0.0.1:6379' use-cdn-domains: false
password: '' \ No newline at end of file
db: 0
# system configuration
system:
use-multipoint: false
env: 'public' # Change to "develop" to skip authentication for development mode
addr: 8888
db-type: "mysql" # support mysql/postgresql/sqlite/sqlserver
need-init-data: false
error-to-email: false
config-env: "GVA_CONFIG"
# captcha configuration
captcha:
key-long: 6
img-width: 240
img-height: 80
# zap logger configuration
zap:
# 可使用 "debug", "info", "warn", "error", "dpanic", "panic", "fatal",
level: 'info'
# console: 控制台, json: json格式输出
format: 'console'
prefix: '[GIN-VUE-ADMIN]'
director: 'log'
link-name: 'latest_log'
show-line: true
# LowercaseLevelEncoder:小写, LowercaseColorLevelEncoder:小写带颜色,CapitalLevelEncoder: 大写, CapitalColorLevelEncoder: 大写带颜色,
encode-level: 'LowercaseColorLevelEncoder'
stacktrace-key: 'stacktrace'
log-in-console: true
email:
email-from: 'xxx@163.com'
email-nickname: 'test'
email-secret: 'xxx'
email-to: 'xxx@qq.com'
email-host: 'smtp.163.com'
email-port: 465
email-is-ssl: true
\ No newline at end of file
package config
type Captcha struct {
KeyLong int `mapstructure:"key-long" json:"keyLong" yaml:"key-long"`
ImgWidth int `mapstructure:"img-width" json:"imgWidth" yaml:"img-width"`
ImgHeight int `mapstructure:"img-height" json:"imgHeight" yaml:"img-height"`
}
package config
type Casbin struct {
ModelPath string `mapstructure:"model-path" json:"modelPath" yaml:"model-path"`
}
package config package config
type Server struct { type Server struct {
JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"`
Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"`
Email Email `mapstructure:"email" json:"email" yaml:"email"`
Casbin Casbin `mapstructure:"casbin" json:"casbin" yaml:"casbin"`
System System `mapstructure:"system" json:"system" yaml:"system"`
Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
// gorm
Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"` Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
Postgresql Postgresql `mapstructure:"postgresql" json:"postgresql" yaml:"postgresql"`
Sqlite Sqlite `mapstructure:"sqlite" json:"sqlite" yaml:"sqlite"` Sqlite Sqlite `mapstructure:"sqlite" json:"sqlite" yaml:"sqlite"`
Sqlserver Sqlserver `mapstructure:"sqlserver" json:"sqlserver" yaml:"sqlserver"` Sqlserver Sqlserver `mapstructure:"sqlserver" json:"sqlserver" yaml:"sqlserver"`
Postgresql Postgresql `mapstructure:"postgresql" json:"postgresql" yaml:"postgresql"`
// oss
Local Local `mapstructure:"local" json:"local" yaml:"local"`
Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"` Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"`
Casbin Casbin `mapstructure:"casbin" json:"casbin" yaml:"casbin"`
Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"`
System System `mapstructure:"system" json:"system" yaml:"system"`
JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"`
LocalUpload LocalUpload `mapstructure:"localUpload" json:"localUpload" yaml:"localUpload"`
Email Email `mapstructure:"email" json:"email" yaml:"email"`
}
type System struct {
UseMultipoint bool `mapstructure:"use-multipoint" json:"useMultipoint" yaml:"use-multipoint"`
Env string `mapstructure:"env" json:"env" yaml:"env"`
Addr int `mapstructure:"addr" json:"addr" yaml:"addr"`
DbType string `mapstructure:"db-type" json:"dbType" yaml:"db-type"`
NeedInitData bool `mapstructure:"need-init-data" json:"needInitData" yaml:"need-init-data"`
ErrorToEmail bool `mapstructure:"error-to-email" json:"errorToEmail" yaml:"error-to-email"`
ConfigEnv string `mapstructure:"config-env" json:"configEnv" yaml:"config-env"`
}
type JWT struct {
SigningKey string `mapstructure:"signing-key" json:"signingKey" yaml:"signing-key"`
}
type Casbin struct {
ModelPath string `mapstructure:"model-path" json:"modelPath" yaml:"model-path"`
}
type Mysql struct {
Username string `mapstructure:"username" json:"username" yaml:"username"`
Password string `mapstructure:"password" json:"password" yaml:"password"`
Path string `mapstructure:"path" json:"path" yaml:"path"`
Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"`
Config string `mapstructure:"config" json:"config" yaml:"config"`
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"`
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"`
LogMode bool `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"`
}
type Postgresql struct {
Host string `mapstructure:"host" json:"host" yaml:"host"`
Username string `mapstructure:"username" json:"username" yaml:"username"`
Password string `mapstructure:"password" json:"password" yaml:"password"`
Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"`
Port string `mapstructure:"port" json:"port" yaml:"port"`
Config string `mapstructure:"config" json:"config" yaml:"config"`
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"`
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"`
Logger bool `mapstructure:"logger" json:"logger" yaml:"logger"`
PreferSimpleProtocol bool `mapstructure:"prefer-simple-protocol" json:"preferSimpleProtocol" yaml:"prefer-simple-protocol"`
}
type Sqlite struct {
Path string `mapstructure:"path" json:"path" yaml:"path"`
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"`
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"`
Logger bool `mapstructure:"logger" json:"logger" yaml:"logger"`
}
type Sqlserver struct {
Username string `mapstructure:"username" json:"username" yaml:"username"`
Password string `mapstructure:"password" json:"password" yaml:"password"`
Path string `mapstructure:"path" json:"path" yaml:"path"`
Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"`
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"`
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"`
Logger bool `mapstructure:"logger" json:"logger" yaml:"logger"`
}
type Redis struct {
Addr string `mapstructure:"addr" json:"addr" yaml:"addr"`
Password string `mapstructure:"password" json:"password" yaml:"password"`
DB int `mapstructure:"db" json:"db" yaml:"db"`
}
type LocalUpload struct {
Local bool `mapstructure:"local" json:"local" yaml:"local"`
FilePath string `mapstructure:"file-path" json:"filePath" yaml:"file-path"`
}
type Qiniu struct {
AccessKey string `mapstructure:"access-key" json:"accessKey" yaml:"access-key"`
SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"`
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
ImgPath string `mapstructure:"img-path" json:"imgPath" yaml:"img-path"`
}
type Captcha struct {
KeyLong int `mapstructure:"key-long" json:"keyLong" yaml:"key-long"`
ImgWidth int `mapstructure:"img-width" json:"imgWidth" yaml:"img-width"`
ImgHeight int `mapstructure:"img-height" json:"imgHeight" yaml:"img-height"`
}
type Zap struct {
Level string `mapstructure:"level" json:"level" yaml:"level"`
Format string `mapstructure:"format" json:"format" yaml:"format"`
Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"`
Director string `mapstructure:"director" json:"director" yaml:"director"`
LinkName string `mapstructure:"link-name" json:"linkName" yaml:"link-name"`
ShowLine bool `mapstructure:"show-line" json:"showLine" yaml:"showLine"`
EncodeLevel string `mapstructure:"encode-level" json:"encodeLevel" yaml:"encode-level"`
StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktraceKey" yaml:"stacktrace-key"`
LogInConsole bool `mapstructure:"log-in-console" json:"logInConsole" yaml:"log-in-console"`
}
type Email struct {
EmailFrom string `mapstructure:"email-from" json:"emailFrom" yaml:"email-from"`
EmailNickname string `mapstructure:"email-nickname" json:"emailNickname" yaml:"email-nickname"`
EmailSecret string `mapstructure:"email-secret" json:"emailSecret" yaml:"email-secret"`
EmailTo string `mapstructure:"email-to" json:"emailTo" yaml:"email-to"`
EmailHost string `mapstructure:"email-host" json:"emailHost" yaml:"email-host"`
EmailPort int `mapstructure:"email-port" json:"emailPort" yaml:"email-port"`
EmailIsSSL bool `mapstructure:"email-is-ssl" json:"emailIsSSL" yaml:"email-is-ssl"`
} }
package config
type Email struct {
To string `mapstructure:"to" json:"to" yaml:"to"`
Port int `mapstructure:"port" json:"port" yaml:"port"`
From string `mapstructure:"from" json:"from" yaml:"from"`
Host string `mapstructure:"host" json:"host" yaml:"host"`
IsSSL bool `mapstructure:"is-ssl" json:"isSSL" yaml:"is-ssl"`
Secret string `mapstructure:"secret" json:"secret" yaml:"secret"`
Nickname string `mapstructure:"nickname" json:"nickname" yaml:"nickname"`
}
package config
type Mysql struct {
Path string `mapstructure:"path" json:"path" yaml:"path"`
Config string `mapstructure:"config" json:"config" yaml:"config"`
Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"`
Username string `mapstructure:"username" json:"username" yaml:"username"`
Password string `mapstructure:"password" json:"password" yaml:"password"`
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"`
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"`
LogMode bool `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"`
}
type Sqlite struct {
Path string `mapstructure:"path" json:"path" yaml:"path"`
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"`
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"`
Logger bool `mapstructure:"logger" json:"logger" yaml:"logger"`
}
type Sqlserver struct {
Path string `mapstructure:"path" json:"path" yaml:"path"`
Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"`
Username string `mapstructure:"username" json:"username" yaml:"username"`
Password string `mapstructure:"password" json:"password" yaml:"password"`
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"`
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"`
Logger bool `mapstructure:"logger" json:"logger" yaml:"logger"`
}
type Postgresql struct {
Host string `mapstructure:"host" json:"host" yaml:"host"`
Port string `mapstructure:"port" json:"port" yaml:"port"`
Config string `mapstructure:"config" json:"config" yaml:"config"`
Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"`
Username string `mapstructure:"username" json:"username" yaml:"username"`
Password string `mapstructure:"password" json:"password" yaml:"password"`
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"`
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"`
PreferSimpleProtocol bool `mapstructure:"prefer-simple-protocol" json:"preferSimpleProtocol" yaml:"prefer-simple-protocol"`
Logger bool `mapstructure:"logger" json:"logger" yaml:"logger"`
}
package config
type JWT struct {
SigningKey string `mapstructure:"signing-key" json:"signingKey" yaml:"signing-key"`
}
package config
type Local struct {
Path string `mapstructure:"path" json:"path" yaml:"path" `
}
type Qiniu struct {
Zone string `mapstructure:"zone" json:"zone" yaml:"zone"`
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
ImgPath string `mapstructure:"img-path" json:"imgPath" yaml:"img-path"`
UseHTTPS bool `mapstructure:"use-https" json:"useHttps" yaml:"use-https"`
AccessKey string `mapstructure:"access-key" json:"accessKey" yaml:"access-key"`
SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"`
UseCdnDomains bool `mapstructure:"use-cdn-domains" json:"useCdnDomains" yaml:"use-cdn-domains"`
}
package config
type Redis struct {
DB int `mapstructure:"db" json:"db" yaml:"db"`
Addr string `mapstructure:"addr" json:"addr" yaml:"addr"`
Password string `mapstructure:"password" json:"password" yaml:"password"`
}
\ No newline at end of file
package config
type System struct {
Env string `mapstructure:"env" json:"env" yaml:"env"`
Addr int `mapstructure:"addr" json:"addr" yaml:"addr"`
DbType string `mapstructure:"db-type" json:"dbType" yaml:"db-type"`
OssType string `mapstructure:"oss-type" json:"ossType" yaml:"oss-type"`
ConfigEnv string `mapstructure:"config-env" json:"configEnv" yaml:"config-env"`
NeedInitData bool `mapstructure:"need-init-data" json:"needInitData" yaml:"need-init-data"`
UseMultipoint bool `mapstructure:"use-multipoint" json:"useMultipoint" yaml:"use-multipoint"`
}
package config
type Zap struct {
Level string `mapstructure:"level" json:"level" yaml:"level"`
Format string `mapstructure:"format" json:"format" yaml:"format"`
Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"`
Director string `mapstructure:"director" json:"director" yaml:"director"`
LinkName string `mapstructure:"link-name" json:"linkName" yaml:"link-name"`
ShowLine bool `mapstructure:"show-line" json:"showLine" yaml:"showLine"`
EncodeLevel string `mapstructure:"encode-level" json:"encodeLevel" yaml:"encode-level"`
StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktraceKey" yaml:"stacktrace-key"`
LogInConsole bool `mapstructure:"log-in-console" json:"logInConsole" yaml:"log-in-console"`
}
...@@ -87,6 +87,8 @@ func InitSysApi() (err error) { ...@@ -87,6 +87,8 @@ func InitSysApi() (err error) {
{gorm.Model{ID: 63, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/simpleUploader/checkFileMd5", "文件完整度验证", "simpleUploader", "GET"}, {gorm.Model{ID: 63, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/simpleUploader/checkFileMd5", "文件完整度验证", "simpleUploader", "GET"},
{gorm.Model{ID: 64, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/simpleUploader/mergeFileMd5", "上传完成合并文件", "simpleUploader", "GET"}, {gorm.Model{ID: 64, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/simpleUploader/mergeFileMd5", "上传完成合并文件", "simpleUploader", "GET"},
{gorm.Model{ID: 65, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/setUserInfo", "设置用户信息", "user", "PUT"}, {gorm.Model{ID: 65, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/setUserInfo", "设置用户信息", "user", "PUT"},
{gorm.Model{ID: 66, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/system/getServerInfo", "获取服务器信息", "system", "POST"},
{gorm.Model{ID: 67, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/email/emailTest", "发送测试邮件", "email", "POST"},
} }
if tx.Create(&insert).Error != nil { // 遇到错误时回滚事务 if tx.Create(&insert).Error != nil { // 遇到错误时回滚事务
tx.Rollback() tx.Rollback()
...@@ -161,6 +163,7 @@ func InitCasbinModel() (err error) { ...@@ -161,6 +163,7 @@ func InitCasbinModel() (err error) {
{"p", "888", "/jwt/jsonInBlacklist", "POST"}, {"p", "888", "/jwt/jsonInBlacklist", "POST"},
{"p", "888", "/system/getSystemConfig", "POST"}, {"p", "888", "/system/getSystemConfig", "POST"},
{"p", "888", "/system/setSystemConfig", "POST"}, {"p", "888", "/system/setSystemConfig", "POST"},
{"p", "888", "/system/getServerInfo", "POST"},
{"p", "888", "/customer/customer", "POST"}, {"p", "888", "/customer/customer", "POST"},
{"p", "888", "/customer/customer", "PUT"}, {"p", "888", "/customer/customer", "PUT"},
{"p", "888", "/customer/customer", "DELETE"}, {"p", "888", "/customer/customer", "DELETE"},
...@@ -187,6 +190,7 @@ func InitCasbinModel() (err error) { ...@@ -187,6 +190,7 @@ func InitCasbinModel() (err error) {
{"p", "888", "/sysOperationRecord/getSysOperationRecordList", "GET"}, {"p", "888", "/sysOperationRecord/getSysOperationRecordList", "GET"},
{"p", "888", "/sysOperationRecord/deleteSysOperationRecordByIds", "DELETE"}, {"p", "888", "/sysOperationRecord/deleteSysOperationRecordByIds", "DELETE"},
{"p", "888", "/user/setUserInfo", "PUT"}, {"p", "888", "/user/setUserInfo", "PUT"},
{"p", "888", "/email/emailTest", "POST"},
{"p", "8881", "/base/login", "POST"}, {"p", "8881", "/base/login", "POST"},
{"p", "8881", "/base/register", "POST"}, {"p", "8881", "/base/register", "POST"},
{"p", "8881", "/api/createApi", "POST"}, {"p", "8881", "/api/createApi", "POST"},
...@@ -311,6 +315,7 @@ func InitSysBaseMenus() (err error) { ...@@ -311,6 +315,7 @@ func InitSysBaseMenus() (err error) {
{Model: gorm.Model{ID: 24, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "3", Path: "operation", Name: "operation", Component: "view/superAdmin/operation/sysOperationRecord.vue", Sort: 6, Meta: model.Meta{Title: "操作历史", Icon: "time"}}, {Model: gorm.Model{ID: 24, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "3", Path: "operation", Name: "operation", Component: "view/superAdmin/operation/sysOperationRecord.vue", Sort: 6, Meta: model.Meta{Title: "操作历史", Icon: "time"}},
{Model: gorm.Model{ID: 25, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "simpleUploader", Name: "simpleUploader", Component: "view/example/simpleUploader/simpleUploader", Sort: 6, Meta: model.Meta{Title: "断点续传(插件版)", Icon: "upload"}}, {Model: gorm.Model{ID: 25, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "9", Path: "simpleUploader", Name: "simpleUploader", Component: "view/example/simpleUploader/simpleUploader", Sort: 6, Meta: model.Meta{Title: "断点续传(插件版)", Icon: "upload"}},
{Model: gorm.Model{ID: 26, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "0", Path: "https://www.gin-vue-admin.com", Name: "https://www.gin-vue-admin.com", Hidden: false, Component: "/", Sort: 0, Meta: model.Meta{Title: "官方网站", Icon: "s-home"}}, {Model: gorm.Model{ID: 26, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "0", Path: "https://www.gin-vue-admin.com", Name: "https://www.gin-vue-admin.com", Hidden: false, Component: "/", Sort: 0, Meta: model.Meta{Title: "官方网站", Icon: "s-home"}},
{Model: gorm.Model{ID: 27, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "0", Path: "state", Name: "state", Hidden: false, Component: "view/system/state.vue", Sort: 6, Meta: model.Meta{Title: "服务器状态", Icon: "cloudy"}},
} }
if tx.Create(&insert).Error != nil { // 遇到错误时回滚事务 if tx.Create(&insert).Error != nil { // 遇到错误时回滚事务
tx.Rollback() tx.Rollback()
...@@ -369,6 +374,7 @@ func InitSysAuthorityMenus() (err error) { ...@@ -369,6 +374,7 @@ func InitSysAuthorityMenus() (err error) {
{"888", 24}, {"888", 24},
{"888", 25}, {"888", 25},
{"888", 26}, {"888", 26},
{"888", 27},
{"8881", 1}, {"8881", 1},
{"8881", 2}, {"8881", 2},
{"8881", 8}, {"8881", 8},
......
...@@ -25,6 +25,8 @@ func Gorm() { ...@@ -25,6 +25,8 @@ func Gorm() {
// GormSqlite() // GormSqlite()
case "sqlserver": case "sqlserver":
GormSqlServer() GormSqlServer()
default:
GormMysql()
} }
} }
......
...@@ -15,8 +15,7 @@ import ( ...@@ -15,8 +15,7 @@ import (
func Routers() *gin.Engine { func Routers() *gin.Engine {
var Router = gin.Default() var Router = gin.Default()
// 为用户头像和文件提供静态地址 Router.StaticFS(global.GVA_CONFIG.Local.Path, http.Dir(global.GVA_CONFIG.Local.Path)) // 为用户头像和文件提供静态地址
Router.StaticFS(global.GVA_CONFIG.LocalUpload.FilePath, http.Dir(global.GVA_CONFIG.LocalUpload.FilePath))
// Router.Use(middleware.LoadTls()) // 打开就能玩https了 // Router.Use(middleware.LoadTls()) // 打开就能玩https了
global.GVA_LOG.Info("use middleware logger") global.GVA_LOG.Info("use middleware logger")
// 跨域 // 跨域
......
...@@ -19,10 +19,10 @@ func ErrorToEmail() gin.HandlerFunc { ...@@ -19,10 +19,10 @@ func ErrorToEmail() gin.HandlerFunc {
if claims, ok := c.Get("claims"); ok { if claims, ok := c.Get("claims"); ok {
waitUse := claims.(*request.CustomClaims) waitUse := claims.(*request.CustomClaims)
username = waitUse.Username username = waitUse.Username
}else { } else {
id, _ := strconv.Atoi(c.Request.Header.Get("x-user-id")) id, _ := strconv.Atoi(c.Request.Header.Get("x-user-id"))
err, user := service.FindUserById(id) err, user := service.FindUserById(id)
if err != nil{ if err != nil {
username = "Unknown" username = "Unknown"
} }
username = user.Username username = user.Username
...@@ -43,13 +43,11 @@ func ErrorToEmail() gin.HandlerFunc { ...@@ -43,13 +43,11 @@ func ErrorToEmail() gin.HandlerFunc {
status := c.Writer.Status() status := c.Writer.Status()
record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String() record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String()
str := "接收到的请求为" + record.Body + "\n" + "请求方式为" + record.Method + "\n" + "报错信息如下" + record.ErrorMessage + "\n" + "耗时" + latency.String() + "\n" str := "接收到的请求为" + record.Body + "\n" + "请求方式为" + record.Method + "\n" + "报错信息如下" + record.ErrorMessage + "\n" + "耗时" + latency.String() + "\n"
if global.GVA_CONFIG.System.ErrorToEmail {
if status != 200 { if status != 200 {
subject := username + "" +record.Ip + "调用了" + record.Path + "报错了" subject := username + "" + record.Ip + "调用了" + record.Path + "报错了"
if err := utils.ErrorToEmail(subject, str); err != nil { if err := utils.ErrorToEmail(subject, str); err != nil {
global.GVA_LOG.Error("ErrorToEmail Failed, err:", zap.Any("err", err)) global.GVA_LOG.Error("ErrorToEmail Failed, err:", zap.Any("err", err))
} }
} }
} }
}
} }
...@@ -49,6 +49,12 @@ func JWTAuth() gin.HandlerFunc { ...@@ -49,6 +49,12 @@ func JWTAuth() gin.HandlerFunc {
c.Abort() c.Abort()
return return
} }
if err, _ = service.FindUserByUuid(claims.UUID.String()); err != nil{
response.Result(response.ERROR, gin.H{
"reload": true,
}, err.Error(), c)
c.Abort()
}
if claims.ExpiresAt - time.Now().Unix()<claims.BufferTime { if claims.ExpiresAt - time.Now().Unix()<claims.BufferTime {
claims.ExpiresAt = time.Now().Unix() + 60*60*24*7 claims.ExpiresAt = time.Now().Unix() + 60*60*24*7
newToken,_ := j.CreateToken(*claims) newToken,_ := j.CreateToken(*claims)
......
...@@ -47,7 +47,7 @@ func OperationRecord() gin.HandlerFunc { ...@@ -47,7 +47,7 @@ func OperationRecord() gin.HandlerFunc {
UserID: userId, UserID: userId,
} }
values := c.Request.Header.Values("content-type") values := c.Request.Header.Values("content-type")
if strings.Contains(values[0], "boundary"){ if len(values) >0 && strings.Contains(values[0], "boundary") {
record.Body = "file" record.Body = "file"
} }
writer := responseBodyWriter{ writer := responseBodyWriter{
......
...@@ -2,14 +2,14 @@ package router ...@@ -2,14 +2,14 @@ package router
import ( import (
"gin-vue-admin/api/v1" "gin-vue-admin/api/v1"
"gin-vue-admin/middleware"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
func InitSystemRouter(Router *gin.RouterGroup) { func InitSystemRouter(Router *gin.RouterGroup) {
UserRouter := Router.Group("system").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()) SystemRouter := Router.Group("system")
{ {
UserRouter.POST("getSystemConfig", v1.GetSystemConfig) // 获取配置文件内容 SystemRouter.POST("getSystemConfig", v1.GetSystemConfig) // 获取配置文件内容
UserRouter.POST("setSystemConfig", v1.SetSystemConfig) // 设置配置文件内容 SystemRouter.POST("setSystemConfig", v1.SetSystemConfig) // 设置配置文件内容
SystemRouter.POST("getServerInfo", v1.GetServerInfo) // 获取服务器信息
} }
} }
...@@ -5,9 +5,8 @@ import ( ...@@ -5,9 +5,8 @@ import (
"gin-vue-admin/global" "gin-vue-admin/global"
"gin-vue-admin/model" "gin-vue-admin/model"
"gin-vue-admin/model/request" "gin-vue-admin/model/request"
"gin-vue-admin/utils" "gin-vue-admin/utils/upload"
"mime/multipart" "mime/multipart"
"os"
"strings" "strings"
) )
...@@ -43,19 +42,9 @@ func FindFile(id uint) (error, model.ExaFileUploadAndDownload) { ...@@ -43,19 +42,9 @@ func FindFile(id uint) (error, model.ExaFileUploadAndDownload) {
func DeleteFile(file model.ExaFileUploadAndDownload) (err error) { func DeleteFile(file model.ExaFileUploadAndDownload) (err error) {
var fileFromDb model.ExaFileUploadAndDownload var fileFromDb model.ExaFileUploadAndDownload
err, fileFromDb = FindFile(file.ID) err, fileFromDb = FindFile(file.ID)
if err != nil { oss := upload.NewOss()
return errors.New("文件不存在") if err = oss.DeleteFile(fileFromDb.Key); err != nil{
} return errors.New("文件删除失败")
if global.GVA_CONFIG.LocalUpload.Local { // 删除本地文件
if strings.Contains(fileFromDb.Url, global.GVA_CONFIG.LocalUpload.FilePath) {
if err = os.Remove(fileFromDb.Url); err != nil {
err = errors.New("本地文件删除失败, err:" + err.Error())
}
}
} else {
if err = utils.DeleteFile(file.Key); err != nil { // 删除七牛云文件
err = errors.New("七牛云文件删除失败, err:" + err.Error())
}
} }
err = global.GVA_DB.Where("id = ?", file.ID).Unscoped().Delete(file).Error err = global.GVA_DB.Where("id = ?", file.ID).Unscoped().Delete(file).Error
return err return err
...@@ -88,19 +77,19 @@ func GetFileRecordInfoList(info request.PageInfo) (err error, list interface{}, ...@@ -88,19 +77,19 @@ func GetFileRecordInfoList(info request.PageInfo) (err error, list interface{},
// @return file file model.ExaFileUploadAndDownload // @return file file model.ExaFileUploadAndDownload
func UploadFile(header *multipart.FileHeader, noSave string) (err error, file model.ExaFileUploadAndDownload) { func UploadFile(header *multipart.FileHeader, noSave string) (err error, file model.ExaFileUploadAndDownload) {
var filePath, key string oss := upload.NewOss()
var f model.ExaFileUploadAndDownload filePath, key, uploadErr := oss.UploadFile(header)
if global.GVA_CONFIG.LocalUpload.Local { // 本地上传 if uploadErr != nil {
err, filePath, key = utils.UploadFileLocal(header) panic(err)
} else { // 七牛云上传
err, filePath, key = utils.UploadRemote(header)
} }
if noSave == "0" { if noSave == "0" {
f.Url = filePath s := strings.Split(header.Filename, ".")
f.Name = header.Filename f := model.ExaFileUploadAndDownload{
s := strings.Split(f.Name, ".") Url: filePath,
f.Tag = s[len(s)-1] Name: header.Filename,
f.Key = key Tag: s[len(s)-1],
Key: key,
}
return Upload(f), f return Upload(f), f
} }
return return
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"gin-vue-admin/global" "gin-vue-admin/global"
"gin-vue-admin/model" "gin-vue-admin/model"
"gin-vue-admin/utils" "gin-vue-admin/utils"
"go.uber.org/zap"
) )
// @title GetSystemConfig // @title GetSystemConfig
...@@ -31,3 +32,30 @@ func SetSystemConfig(system model.System) (err error) { ...@@ -31,3 +32,30 @@ func SetSystemConfig(system model.System) (err error) {
err = global.GVA_VP.WriteConfig() err = global.GVA_VP.WriteConfig()
return err return err
} }
// @title GetServerInfo
// @description get server info , 获取服务器信息
// @auth (2020/04/05 20:22)
// @return server *utils.Server
// @return err error
func GetServerInfo() (server *utils.Server, err error) {
var s utils.Server
s.Os = utils.InitOS()
if s.Cpu, err = utils.InitCPU(); err != nil{
global.GVA_LOG.Error("func utils.InitCPU() Failed!", zap.String("err", err.Error()))
return &s, err
}
if s.Rrm, err = utils.InitRAM(); err != nil{
global.GVA_LOG.Error("func utils.InitRAM() Failed!", zap.String("err", err.Error()))
return &s, err
}
if s.Disk, err = utils.InitDisk(); err != nil{
global.GVA_LOG.Error("func utils.InitDisk() Failed!", zap.String("err", err.Error()))
return &s, err
}
return &s, nil
}
...@@ -125,3 +125,18 @@ func FindUserById(id int) (err error, user *model.SysUser) { ...@@ -125,3 +125,18 @@ func FindUserById(id int) (err error, user *model.SysUser) {
err = global.GVA_DB.Where("`id` = ?", id).First(&u).Error err = global.GVA_DB.Where("`id` = ?", id).First(&u).Error
return err, &u return err, &u
} }
// @title FindUserByUuid
// @description Get user information by uuid, 通过uuid获取用户信息
// @auth (2020/04/05 20:22)
// @param uuid string
// @return err error
// @return user *model.SysUser
func FindUserByUuid(uuid string) (err error, user *model.SysUser) {
var u model.SysUser
if err = global.GVA_DB.Where("`uuid` = ?", uuid).First(&u).Error; err != nil{
return errors.New("用户不存在"), &u
}
return nil, &u
}
\ No newline at end of file
...@@ -12,13 +12,13 @@ import ( ...@@ -12,13 +12,13 @@ import (
) )
func Email(subject string, body string) error { func Email(subject string, body string) error {
to := strings.Split(global.GVA_CONFIG.Email.EmailTo, ",") to := strings.Split(global.GVA_CONFIG.Email.To, ",")
return send(to, subject, body) return send(to, subject, body)
} }
// ErrorToEmail Error 发送邮件 // ErrorToEmail Error 发送邮件
func ErrorToEmail(subject string, body string) error { func ErrorToEmail(subject string, body string) error {
to := strings.Split(global.GVA_CONFIG.Email.EmailTo, ",") to := strings.Split(global.GVA_CONFIG.Email.To, ",")
if to[len(to)-1] == "" { // 判断切片的最后一个元素是否为空,为空则移除 if to[len(to)-1] == "" { // 判断切片的最后一个元素是否为空,为空则移除
to = to[:len(to)-1] to = to[:len(to)-1]
} }
...@@ -26,17 +26,17 @@ func ErrorToEmail(subject string, body string) error { ...@@ -26,17 +26,17 @@ func ErrorToEmail(subject string, body string) error {
} }
func EmailTest(subject string, body string) error { func EmailTest(subject string, body string) error {
to := []string{global.GVA_CONFIG.Email.EmailFrom} to := []string{global.GVA_CONFIG.Email.From}
return send(to, subject, body) return send(to, subject, body)
} }
func send(to []string, subject string, body string) error { func send(to []string, subject string, body string) error {
from := global.GVA_CONFIG.Email.EmailFrom from := global.GVA_CONFIG.Email.From
nickname := global.GVA_CONFIG.Email.EmailNickname nickname := global.GVA_CONFIG.Email.Nickname
secret := global.GVA_CONFIG.Email.EmailSecret secret := global.GVA_CONFIG.Email.Secret
host := global.GVA_CONFIG.Email.EmailHost host := global.GVA_CONFIG.Email.Host
port := global.GVA_CONFIG.Email.EmailPort port := global.GVA_CONFIG.Email.Port
isSSL := global.GVA_CONFIG.Email.EmailIsSSL isSSL := global.GVA_CONFIG.Email.IsSSL
auth := smtp.PlainAuth("", from, secret, host) auth := smtp.PlainAuth("", from, secret, host)
e := email.NewEmail() e := email.NewEmail()
......
package utils package utils
import ( import (
"fmt"
"github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/disk" "github.com/shirou/gopsutil/disk"
"github.com/shirou/gopsutil/load"
"github.com/shirou/gopsutil/mem" "github.com/shirou/gopsutil/mem"
"runtime" "runtime"
"time" "time"
) )
const ( const (
B = 1 B = 1
KB = 1024 * B KB = 1024 * B
...@@ -16,47 +15,88 @@ const ( ...@@ -16,47 +15,88 @@ const (
GB = 1024 * MB GB = 1024 * MB
) )
//服务器硬盘使用量 type Server struct {
func DiskCheck() { Os Os `json:"os"`
u, _ := disk.Usage("/") Cpu Cpu `json:"cpu"`
usedMB := int(u.Used) / MB Rrm Rrm `json:"ram"`
usedGB := int(u.Used) / GB Disk Disk `json:"disk"`
totalMB := int(u.Total) / MB }
totalGB := int(u.Total) / GB
usedPercent := int(u.UsedPercent) type Os struct {
fmt.Printf("Free space: %dMB (%dGB) / %dMB (%dGB) | Used: %d%%\n", usedMB, usedGB, totalMB, totalGB, usedPercent) GOOS string `json:"goos"`
NumCPU int `json:"numCpu"`
Compiler string `json:"compiler"`
GoVersion string `json:"goVersion"`
NumGoroutine int `json:"numGoroutine"`
}
type Cpu struct {
Cpus []float64 `json:"cpus"`
Cores int `json:"cores"`
} }
//OS
func OSCheck() { type Rrm struct {
fmt.Printf("goOs:%s,compiler:%s,numCpu:%d,version:%s,numGoroutine:%d\n", runtime.GOOS, runtime.Compiler, runtime.NumCPU(), runtime.Version(), runtime.NumGoroutine()) UsedMB int `json:"usedMb"`
TotalMB int `json:"totalMb"`
UsedPercent int `json:"usedPercent"`
} }
//CPU 使用量 type Disk struct {
func CPUCheck() { UsedMB int `json:"usedMb"`
cores, _ := cpu.Counts(false) UsedGB int `json:"usedGb"`
TotalMB int `json:"totalMb"`
TotalGB int `json:"totalGb"`
UsedPercent int `json:"usedPercent"`
}
cpus, err := cpu.Percent(time.Duration(200)*time.Millisecond, true) // InitOS OS信息
if err == nil { func InitOS() (o Os) {
for i, c := range cpus { o.GOOS = runtime.GOOS
fmt.Printf("cpu%d : %f%%\n", i, c) o.NumCPU = runtime.NumCPU()
o.Compiler = runtime.Compiler
o.GoVersion = runtime.Version()
o.NumGoroutine = runtime.NumGoroutine()
return o
}
// InitCPU CPU信息
func InitCPU() (c Cpu, err error) {
if cores, err := cpu.Counts(false); err != nil {
return c, err
} else {
c.Cores = cores
}
if cpus, err := cpu.Percent(time.Duration(200)*time.Millisecond, true); err != nil {
return c, err
} else {
c.Cpus = cpus
} }
return c, nil
}
// InitRAM ARM信息
func InitRAM() (r Rrm, err error) {
if u, err := mem.VirtualMemory(); err != nil{
return r, err
}else {
r.UsedMB = int(u.Used) / MB
r.TotalMB = int(u.Total) / MB
r.UsedPercent = int(u.UsedPercent)
}
return r, nil
}
// InitDisk 硬盘信息
func InitDisk() (d Disk, err error) {
if u, err := disk.Usage("/"); err != nil{
return d, err
} else {
d.UsedMB = int(u.Used) / MB
d.UsedGB = int(u.Used) / GB
d.TotalMB = int(u.Total) / MB
d.TotalGB = int(u.Total) / GB
d.UsedPercent = int(u.UsedPercent)
} }
a, _ := load.Avg() return d, nil
l1 := a.Load1
l5 := a.Load5
l15 := a.Load15
fmt.Println(l1)
fmt.Println(l5)
fmt.Println(l15)
fmt.Println(cores)
}
//内存使用量
func RAMCheck() {
u, _ := mem.VirtualMemory()
usedMB := int(u.Used) / MB
totalMB := int(u.Total) / MB
usedPercent := int(u.UsedPercent)
fmt.Printf("usedMB:%d,totalMB:%d,usedPercent:%d", usedMB, totalMB, usedPercent)
} }
\ No newline at end of file
package upload
import (
"errors"
"gin-vue-admin/global"
"gin-vue-admin/utils"
"go.uber.org/zap"
"io"
"mime/multipart"
"os"
"path"
"strings"
"time"
)
type Local struct{}
// UploadFile 上传文件
func (l Local) UploadFile(file *multipart.FileHeader) (string, string, error) {
// 读取文件后缀
ext := path.Ext(file.Filename)
// 读取文件名并加密
name := strings.TrimSuffix(file.Filename, ext)
name = utils.MD5V([]byte(name))
// 拼接新文件名
filename := name + "_" + time.Now().Format("20060102150405") + ext
// 尝试创建此路径
mkdirErr := os.MkdirAll(global.GVA_CONFIG.Local.Path, os.ModePerm)
if mkdirErr != nil {
global.GVA_LOG.Error("function os.MkdirAll() Filed", zap.Any("err", mkdirErr.Error()))
return "", "", errors.New("function os.MkdirAll() Filed, err:" + mkdirErr.Error())
}
// 拼接路径和文件名
p := global.GVA_CONFIG.Local.Path + "/" + filename
f, openError := file.Open() // 读取文件
if openError != nil {
global.GVA_LOG.Error("function file.Open() Filed", zap.Any("err", openError.Error()))
return "", "", errors.New("function file.Open() Filed, err:" + openError.Error())
}
defer f.Close() // 创建文件 defer 关闭
out, createErr := os.Create(p)
if createErr != nil {
global.GVA_LOG.Error("function os.Create() Filed", zap.Any("err", createErr.Error()))
return "", "", errors.New("function os.Create() Filed, err:" + createErr.Error())
}
defer out.Close() // 创建文件 defer 关闭
_, copyErr := io.Copy(out, f) // 传输(拷贝)文件
if copyErr != nil {
global.GVA_LOG.Error("function io.Copy() Filed", zap.Any("err", copyErr.Error()))
return "", "", errors.New("function io.Copy() Filed, err:" + copyErr.Error())
}
return p, filename, nil
}
// DeleteFile 删除文件
func (l Local) DeleteFile(key string) error {
p := global.GVA_CONFIG.Local.Path + "/" + key
if strings.Contains(p, global.GVA_CONFIG.Local.Path) {
if err := os.Remove(p); err != nil {
return errors.New("本地文件删除失败, err:" + err.Error())
}
}
return nil
}
package upload
import (
"context"
"errors"
"fmt"
"gin-vue-admin/global"
"github.com/qiniu/api.v7/v7/auth/qbox"
"github.com/qiniu/api.v7/v7/storage"
"go.uber.org/zap"
"mime/multipart"
"time"
)
type Qiniu struct{}
// Upload 上传文件
func (*Qiniu) UploadFile(file *multipart.FileHeader) (string, string, error) {
putPolicy := storage.PutPolicy{Scope: global.GVA_CONFIG.Qiniu.Bucket}
mac := qbox.NewMac(global.GVA_CONFIG.Qiniu.AccessKey, global.GVA_CONFIG.Qiniu.SecretKey)
upToken := putPolicy.UploadToken(mac)
cfg := qiniuConfig()
formUploader := storage.NewFormUploader(cfg)
ret := storage.PutRet{}
putExtra := storage.PutExtra{Params: map[string]string{"x:name": "github logo"}}
f, openError := file.Open()
if openError != nil {
global.GVA_LOG.Error("function file.Open() Filed", zap.Any("err", openError.Error()))
return "", "", errors.New("function file.Open() Filed, err:" + openError.Error())
}
fileKey := fmt.Sprintf("%d%s", time.Now().Unix(), file.Filename) // 文件名格式 自己可以改 建议保证唯一性
putErr := formUploader.Put(context.Background(), &ret, upToken, fileKey, f, file.Size, &putExtra)
if putErr != nil {
global.GVA_LOG.Error("function formUploader.Put() Filed", zap.Any("err", putErr.Error()))
return "", "", errors.New("function formUploader.Put() Filed, err:" + putErr.Error())
}
return global.GVA_CONFIG.Qiniu.ImgPath + "/" + ret.Key, ret.Key, nil
}
// DeleteFile 删除文件
func (*Qiniu) DeleteFile(key string) error {
mac := qbox.NewMac(global.GVA_CONFIG.Qiniu.AccessKey, global.GVA_CONFIG.Qiniu.SecretKey)
cfg := qiniuConfig()
bucketManager := storage.NewBucketManager(mac, cfg)
if err := bucketManager.Delete(global.GVA_CONFIG.Qiniu.Bucket, key); err != nil{
global.GVA_LOG.Error("function bucketManager.Delete() Filed", zap.Any("err", err.Error()))
return errors.New("function bucketManager.Delete() Filed, err:" + err.Error())
}
return nil
}
// config 根据配置文件进行返回七牛云的配置
func qiniuConfig() *storage.Config {
cfg := storage.Config{
UseHTTPS: global.GVA_CONFIG.Qiniu.UseHTTPS,
UseCdnDomains: global.GVA_CONFIG.Qiniu.UseCdnDomains,
}
switch global.GVA_CONFIG.Qiniu.Zone { // 根据配置文件进行初始化空间对应的机房
case "ZoneHuadong":
cfg.Zone = &storage.ZoneHuadong
case "ZoneHuabei":
cfg.Zone = &storage.ZoneHuabei
case "ZoneHuanan":
cfg.Zone = &storage.ZoneHuanan
case "ZoneBeimei":
cfg.Zone = &storage.ZoneBeimei
case "ZoneXinjiapo":
cfg.Zone = &storage.ZoneXinjiapo
}
return &cfg
}
\ No newline at end of file
package upload
import (
"gin-vue-admin/global"
"mime/multipart"
)
var Oss OSS
type OSS interface {
UploadFile(file *multipart.FileHeader) (string, string, error)
DeleteFile(key string) error
}
func NewOss() OSS {
switch global.GVA_CONFIG.System.OssType {
case "local":
return &Local{}
case "qiniu":
return &Qiniu{}
default:
return &Local{}
}
}
\ No newline at end of file
...@@ -20,7 +20,7 @@ func UploadFileLocal(file *multipart.FileHeader) (err error, localPath string, k ...@@ -20,7 +20,7 @@ func UploadFileLocal(file *multipart.FileHeader) (err error, localPath string, k
// 拼接新文件名 // 拼接新文件名
lastName := fileName + "_" + time.Now().Format("20060102150405") + ext lastName := fileName + "_" + time.Now().Format("20060102150405") + ext
// 读取全局变量的定义路径 // 读取全局变量的定义路径
savePath := global.GVA_CONFIG.LocalUpload.FilePath savePath := global.GVA_CONFIG.Local.Path
// 尝试创建此路径 // 尝试创建此路径
err = os.MkdirAll(savePath, os.ModePerm) err = os.MkdirAll(savePath, os.ModePerm)
if err != nil { if err != nil {
......
import service from '@/utils/request' import service from "@/utils/request";
// @Tags systrm // @Tags systrm
// @Summary 获取配置文件内容 // @Summary 获取配置文件内容
...@@ -9,9 +9,9 @@ import service from '@/utils/request' ...@@ -9,9 +9,9 @@ import service from '@/utils/request'
export const getSystemConfig = () => { export const getSystemConfig = () => {
return service({ return service({
url: "/system/getSystemConfig", url: "/system/getSystemConfig",
method: 'post', method: "post",
}) });
} };
// @Tags system // @Tags system
// @Summary 设置配置文件内容 // @Summary 设置配置文件内容
...@@ -23,7 +23,20 @@ export const getSystemConfig = () => { ...@@ -23,7 +23,20 @@ export const getSystemConfig = () => {
export const setSystemConfig = (data) => { export const setSystemConfig = (data) => {
return service({ return service({
url: "/system/setSystemConfig", url: "/system/setSystemConfig",
method: 'post', method: "post",
data data,
}) });
} };
\ No newline at end of file
// @Tags system
// @Summary 获取服务器运行状态
// @Security ApiKeyAuth
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}"
// @Router /system/getServerInfo [post]
export const getSystemState = () => {
return service({
url: "/system/getServerInfo",
method: "post",
});
};
<template>
<div>
<el-row :gutter="15" class="system_state">
<el-col :span="12">
<el-card v-if="state.os" class="card_item">
<div slot="header">Runtime</div>
<div>
<el-row :gutter="10">
<el-col :span="12">os:</el-col>
<el-col :span="12" v-text="state.os.goos"></el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="12">cpu nums:</el-col>
<el-col :span="12" v-text="state.os.numCpu"></el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="12">compiler:</el-col>
<el-col :span="12" v-text="state.os.compiler"></el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="12">go version:</el-col>
<el-col :span="12" v-text="state.os.goVersion"></el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="12">goroutine nums:</el-col>
<el-col :span="12" v-text="state.os.numGoroutine"></el-col>
</el-row>
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card v-if="state.disk" class="card_item">
<div slot="header">Disk</div>
<div>
<el-row :gutter="10">
<el-col :span="12">
<el-row :gutter="10">
<el-col :span="12">total (MB)</el-col>
<el-col :span="12" v-text="state.disk.totalMb"></el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="12">used (MB)</el-col>
<el-col :span="12" v-text="state.disk.usedMb"></el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="12">total (GB)</el-col>
<el-col :span="12" v-text="state.disk.totalGb"></el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="12">used (GB)</el-col>
<el-col :span="12" v-text="state.disk.usedGb"></el-col>
</el-row>
</el-col>
<el-col :span="12">
<el-progress
type="dashboard"
:percentage="state.disk.usedPercent"
:color="colors"
></el-progress>
</el-col>
</el-row>
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="15" class="system_state">
<el-col :span="12">
<el-card
class="card_item"
v-if="state.cpu"
:body-style="{ height: '180px', 'overflow-y': 'scroll' }"
>
<div slot="header">CPU</div>
<div>
<el-row :gutter="10">
<el-col :span="12">physical number of cores:</el-col>
<el-col :span="12" v-text="state.cpu.cores"> </el-col>
</el-row>
<template v-for="(item, index) in state.cpu.cpus">
<el-row :key="index" :gutter="10">
<el-col :span="12">core {{ index }}:</el-col>
<el-col :span="12"
><el-progress
type="line"
:percentage="+item.toFixed(0)"
:color="colors"
></el-progress
></el-col>
</el-row>
</template>
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card class="card_item" v-if="state.ram">
<div slot="header">Ram</div>
<div>
<el-row :gutter="10">
<el-col :span="12">
<el-row :gutter="10">
<el-col :span="12">total (MB)</el-col>
<el-col :span="12" v-text="state.ram.totalMb"></el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="12">used (MB)</el-col>
<el-col :span="12" v-text="state.ram.usedMb"></el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="12">total (GB)</el-col>
<el-col :span="12" v-text="state.ram.totalMb / 1024"></el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="12">used (GB)</el-col>
<el-col
:span="12"
v-text="(state.ram.usedMb / 1024).toFixed(2)"
></el-col>
</el-row>
</el-col>
<el-col :span="12">
<el-progress
type="dashboard"
:percentage="state.ram.usedPercent"
:color="colors"
></el-progress>
</el-col>
</el-row>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import { getSystemState } from "@/api/system.js";
export default {
name: "State",
data() {
return {
state: {},
colors: [
{ color: "#5cb87a", percentage: 20 },
{ color: "#e6a23c", percentage: 40 },
{ color: "#f56c6c", percentage: 80 },
],
};
},
created() {
this.reload();
},
methods: {
async reload() {
const { data } = await getSystemState();
this.state = data.server;
},
},
};
</script>
<style>
.system_state {
padding: 10px;
}
.card_item {
height: 280px;
}
</style>
<template> <template>
<div class="system"> <div class="system">
<el-form :model="config" label-width="100px" ref="form" class="system"> <el-form :model="config" label-width="100px" ref="form" class="system">
<!-- System start -->
<h2>系统配置</h2> <h2>系统配置</h2>
<el-form-item label="多点登录拦截">
<el-checkbox v-model="config.system.useMultipoint">开启</el-checkbox>
</el-form-item>
<el-form-item label="环境值"> <el-form-item label="环境值">
<el-input v-model="config.system.env"></el-input> <el-input v-model="config.system.env"></el-input>
</el-form-item> </el-form-item>
...@@ -13,20 +11,126 @@ ...@@ -13,20 +11,126 @@
</el-form-item> </el-form-item>
<el-form-item label="数据库类型"> <el-form-item label="数据库类型">
<el-select v-model="config.system.dbType"> <el-select v-model="config.system.dbType">
<el-option value="sqlite"></el-option>
<el-option value="mysql"></el-option> <el-option value="mysql"></el-option>
<el-option value="postgresql"></el-option> <el-option value="sqlite"></el-option>
<el-option value="sqlserver"></el-option> <el-option value="sqlserver"></el-option>
<el-option value="postgresql"></el-option>
</el-select>
</el-form-item>
<el-form-item label="Oss类型">
<el-select v-model="config.system.ossType">
<el-option value="local"></el-option>
<el-option value="qiniu"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="配置文件环境变量名">
<el-input v-model.number="config.system.configEnv"></el-input>
</el-form-item>
<el-form-item label="数据初始化">
<el-checkbox v-model="config.system.needInitData">开启</el-checkbox>
</el-form-item>
<el-form-item label="多点登录拦截">
<el-checkbox v-model="config.system.useMultipoint">开启</el-checkbox>
</el-form-item>
<!-- System end -->
<!-- JWT start -->
<h2>jwt签名</h2> <h2>jwt签名</h2>
<el-form-item label="jwt签名"> <el-form-item label="jwt签名">
<el-input v-model="config.jwt.signingKey"></el-input> <el-input v-model="config.jwt.signingKey"></el-input>
</el-form-item> </el-form-item>
<!-- JWT end -->
<!-- Zap start -->
<h2>Zap日志配置</h2>
<el-form-item label="级别">
<el-input v-model.number="config.zap.level"></el-input>
</el-form-item>
<el-form-item label="输出">
<el-input v-model="config.zap.format"></el-input>
</el-form-item>
<el-form-item label="日志前缀">
<el-input v-model="config.zap.prefix"></el-input>
</el-form-item>
<el-form-item label="日志文件夹">
<el-input v-model="config.zap.director"></el-input>
</el-form-item>
<el-form-item label="软链接名称">
<el-input v-model="config.zap.linkName"></el-input>
</el-form-item>
<el-form-item label="编码级">
<el-input v-model="config.zap.encodeLevel"></el-input>
</el-form-item>
<el-form-item label="栈名">
<el-input v-model="config.zap.stacktraceKey"></el-input>
</el-form-item>
<el-form-item label="显示行">
<el-checkbox v-model="config.zap.showLine"></el-checkbox>
</el-form-item>
<el-form-item label="输出控制台">
<el-checkbox v-model="config.zap.logInConsole"></el-checkbox>
</el-form-item>
<!-- Zap end -->
<!-- Redis start -->
<h2>Redis admin数据库配置</h2>
<el-form-item label="db">
<el-input v-model="config.redis.db"></el-input>
</el-form-item>
<el-form-item label="addr">
<el-input v-model="config.redis.addr"></el-input>
</el-form-item>
<el-form-item label="password">
<el-input v-model="config.redis.password"></el-input>
</el-form-item>
<!-- Redis end -->
<!-- Email start -->
<h2>邮箱配置</h2>
<el-form-item label="接收者邮箱">
<el-input v-model="config.email.to" placeholder="可多个,以逗号分隔"></el-input>
</el-form-item>
<el-form-item label="端口">
<el-input v-model.number="config.email.port"></el-input>
</el-form-item>
<el-form-item label="发送者邮箱">
<el-input v-model="config.email.from"></el-input>
</el-form-item>
<el-form-item label="host">
<el-input v-model="config.email.host"></el-input>
</el-form-item>
<el-form-item label="是否为ssl">
<el-checkbox v-model="config.email.isSSL"></el-checkbox>
</el-form-item>
<el-form-item label="secret">
<el-input v-model="config.email.secret"></el-input>
</el-form-item>
<el-form-item label="测试邮件">
<el-button @click="email">测试邮件</el-button>
</el-form-item>
<!-- Email end -->
<!-- Casbin start -->
<h2>casbin配置</h2> <h2>casbin配置</h2>
<el-form-item label="模型地址"> <el-form-item label="模型地址">
<el-input v-model="config.casbin.modelPath"></el-input> <el-input v-model="config.casbin.modelPath"></el-input>
</el-form-item> </el-form-item>
<!-- Casbin end -->
<!-- Captcha start -->
<h2>验证码配置</h2>
<el-form-item label="keyLong">
<el-input v-model.number="config.captcha.keyLong"></el-input>
</el-form-item>
<el-form-item label="imgWidth">
<el-input v-model.number="config.captcha.imgWidth"></el-input>
</el-form-item>
<el-form-item label="imgHeight">
<el-input v-model.number="config.captcha.imgHeight"></el-input>
</el-form-item>
<!-- Captcha end -->
<!-- dbType start -->
<template v-if="config.system.dbType == 'mysql'"> <template v-if="config.system.dbType == 'mysql'">
<h2>mysql admin数据库配置</h2> <h2>mysql admin数据库配置</h2>
<el-form-item label="username"> <el-form-item label="username">
...@@ -51,36 +155,6 @@ ...@@ -51,36 +155,6 @@
<el-checkbox v-model="config.mysql.logMode"></el-checkbox> <el-checkbox v-model="config.mysql.logMode"></el-checkbox>
</el-form-item> </el-form-item>
</template> </template>
<template v-if="config.system.dbType == 'postgresql'">
<h2>postgresql admin数据库配置</h2>
<el-form-item label="username">
<el-input v-model="config.mysql.username"></el-input>
</el-form-item>
<el-form-item label="password">
<el-input v-model="config.mysql.password"></el-input>
</el-form-item>
<el-form-item label="dbName">
<el-input v-model="config.mysql.dbName"></el-input>
</el-form-item>
<el-form-item label="port">
<el-input v-model="config.mysql.port"></el-input>
</el-form-item>
<el-form-item label="config">
<el-input v-model="config.mysql.config"></el-input>
</el-form-item>
<el-form-item label="maxIdleConns">
<el-input v-model.number="config.mysql.maxIdleConns"></el-input>
</el-form-item>
<el-form-item label="maxOpenConns">
<el-input v-model.number="config.mysql.maxOpenConns"></el-input>
</el-form-item>
<el-form-item label="logger">
<el-checkbox v-model="config.mysql.logger"></el-checkbox>
</el-form-item>
<el-form-item label="prefer-simple-protocol">
<el-checkbox v-model="config.mysql.preferSimpleProtocol"></el-checkbox>
</el-form-item>
</template>
<template v-if="config.system.dbType == 'sqlite'"> <template v-if="config.system.dbType == 'sqlite'">
<h2>sqlite admin数据库配置</h2> <h2>sqlite admin数据库配置</h2>
<el-form-item label="path"> <el-form-item label="path">
...@@ -120,93 +194,71 @@ ...@@ -120,93 +194,71 @@
<el-checkbox v-model="config.sqlserver.logger"></el-checkbox> <el-checkbox v-model="config.sqlserver.logger"></el-checkbox>
</el-form-item> </el-form-item>
</template> </template>
<h2>Redis admin数据库配置</h2> <template v-if="config.system.dbType == 'postgresql'">
<el-form-item label="addr"> <h2>postgresql admin数据库配置</h2>
<el-input v-model="config.redis.addr"></el-input> <el-form-item label="username">
<el-input v-model="config.mysql.username"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="password"> <el-form-item label="password">
<el-input v-model="config.redis.password"></el-input> <el-input v-model="config.mysql.password"></el-input>
</el-form-item>
<el-form-item label="db">
<el-input v-model="config.redis.db"></el-input>
</el-form-item>
<h2>上传配置</h2>
<el-form-item label="本地或七牛云">
<el-checkbox v-model="config.localUpload.local">本地</el-checkbox>
</el-form-item>
<el-form-item label="本地文件路径">
<el-input v-model="config.localUpload.filePath"></el-input>
</el-form-item>
<h2>七牛密钥配置</h2>
<el-form-item label="accessKey">
<el-input v-model="config.qiniu.accessKey"></el-input>
</el-form-item>
<el-form-item label="secretKey">
<el-input v-model="config.qiniu.secretKey"></el-input>
</el-form-item>
<h2>验证码配置</h2>
<el-form-item label="keyLong">
<el-input v-model.number="config.captcha.keyLong"></el-input>
</el-form-item>
<el-form-item label="imgWidth">
<el-input v-model.number="config.captcha.imgWidth"></el-input>
</el-form-item>
<el-form-item label="imgHeight">
<el-input v-model.number="config.captcha.imgHeight"></el-input>
</el-form-item>
<h2>日志配置</h2>
<el-form-item label="level">
<el-input v-model.number="config.zap.level"></el-input>
</el-form-item>
<el-form-item label="format">
<el-input v-model="config.zap.format"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="prefix"> <el-form-item label="dbName">
<el-input v-model="config.zap.prefix"></el-input> <el-input v-model="config.mysql.dbName"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="director"> <el-form-item label="port">
<el-input v-model="config.zap.director"></el-input> <el-input v-model="config.mysql.port"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="link-name"> <el-form-item label="config">
<el-input v-model="config.zap.linkName"></el-input> <el-input v-model="config.mysql.config"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="encode-level"> <el-form-item label="maxIdleConns">
<el-input v-model="config.zap.encodeLevel"></el-input> <el-input v-model.number="config.mysql.maxIdleConns"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="stacktrace-key"> <el-form-item label="maxOpenConns">
<el-input v-model="config.zap.stacktraceKey"></el-input> <el-input v-model.number="config.mysql.maxOpenConns"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="show-line"> <el-form-item label="logger">
<el-checkbox v-model="config.zap.showLine"></el-checkbox> <el-checkbox v-model="config.mysql.logger"></el-checkbox>
</el-form-item> </el-form-item>
<el-form-item label="log-in-console"> <el-form-item label="prefer-simple-protocol">
<el-checkbox v-model="config.zap.logInConsole"></el-checkbox> <el-checkbox v-model="config.mysql.preferSimpleProtocol"></el-checkbox>
</el-form-item> </el-form-item>
<h2>邮箱配置</h2> </template>
<el-form-item label="emailFrom"> <!-- dbType end -->
<el-input v-model="config.email.emailFrom"></el-input>
<!-- ossType start -->
<template v-if="config.system.ossType == 'local'">
<h2>本地上传配置</h2>
<el-form-item label="本地文件路径">
<el-input v-model="config.local.path"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="emailNickName"> </template>
<el-input v-model="config.email.emailNickName"></el-input> <template v-if="config.system.ossType == 'qiniu'">
<h2>qiniu上传配置</h2>
<el-form-item label="存储区域">
<el-input v-model="config.qiniu.zone"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="emailSecret"> <el-form-item label="空间名称">
<el-input v-model="config.email.emailSecret"></el-input> <el-input v-model="config.qiniu.bucket"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="emailTo"> <el-form-item label="CDN加速域名">
<el-input v-model="config.email.emailTo" placeholder="可多个,以逗号分隔"></el-input> <el-input v-model="config.qiniu.imgPath"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="emailHost"> <el-form-item label="是否使用https">
<el-input v-model="config.email.emailHost"></el-input> <el-checkbox v-model="config.qiniu.imgPath">开启</el-checkbox>
</el-form-item> </el-form-item>
<el-form-item label="emailPort"> <el-form-item label="accessKey">
<el-input v-model.number="config.email.emailPort"></el-input> <el-input v-model="config.qiniu.accessKey"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="emailIsSSL"> <el-form-item label="secretKey">
<el-checkbox v-model="config.email.emailIsSSL"></el-checkbox> <el-input v-model="config.qiniu.secretKey"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="测试邮件"> <el-form-item label="上传是否使用CDN上传加速">
<el-button @click="email">测试邮件</el-button> <el-checkbox v-model="config.qiniu.useCdnDomains">开启</el-checkbox>
</el-form-item> </el-form-item>
</template>
<!-- ossType end -->
<el-form-item> <el-form-item>
<el-button @click="update" type="primary">立即更新</el-button> <el-button @click="update" type="primary">立即更新</el-button>
<el-button @click="reload" type="primary">重启服务(开发中)</el-button> <el-button @click="reload" type="primary">重启服务(开发中)</el-button>
...@@ -231,8 +283,8 @@ export default { ...@@ -231,8 +283,8 @@ export default {
redis: {}, redis: {},
qiniu: {}, qiniu: {},
captcha: {}, captcha: {},
log: {}, zap: {},
localUpload: {}, local: {},
email: {} email: {}
} }
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册