diff --git a/server/config.yaml b/server/config.yaml index b336c7cc..1dbf4436 100644 --- a/server/config.yaml +++ b/server/config.yaml @@ -60,6 +60,7 @@ mysql: max-idle-conns: 10 max-open-conns: 100 log-mode: false + log-zap: false # local configuration local: diff --git a/server/config/gorm.go b/server/config/gorm.go index 9290ab10..1888d4c8 100644 --- a/server/config/gorm.go +++ b/server/config/gorm.go @@ -9,4 +9,5 @@ type Mysql struct { 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"` + LogZap bool `mapstructure:"log-zap" json:"logZap" yaml:"log-zap"` } diff --git a/server/initialize/gorm.go b/server/initialize/gorm.go index f722495b..441fdecb 100644 --- a/server/initialize/gorm.go +++ b/server/initialize/gorm.go @@ -73,6 +73,12 @@ func GormMysql() *gorm.DB { // gormConfig 根据配置决定是否开启日志 func gormConfig(mod bool) *gorm.Config { + if global.GVA_CONFIG.Mysql.LogZap { + return &gorm.Config{ + Logger: Default.LogMode(logger.Info), + DisableForeignKeyConstraintWhenMigrating: true, + } + } if mod { return &gorm.Config{ Logger: logger.Default.LogMode(logger.Info), diff --git a/server/initialize/logger.go b/server/initialize/logger.go new file mode 100644 index 00000000..a736a7d5 --- /dev/null +++ b/server/initialize/logger.go @@ -0,0 +1,150 @@ +package initialize + +import ( + "context" + "fmt" + "gin-vue-admin/global" + "go.uber.org/zap" + "gorm.io/gorm/logger" + "gorm.io/gorm/utils" + "io/ioutil" + "log" + "os" + "time" +) + +var ( + Discard = New(log.New(ioutil.Discard, "", log.LstdFlags), GormConfig{}) + Default = New(log.New(os.Stdout, "\r\n", log.LstdFlags), GormConfig{ + SlowThreshold: 200 * time.Millisecond, + LogLevel: logger.Warn, + Colorful: true, + }) + Recorder = traceRecorder{Interface: Default, BeginAt: time.Now()} +) + +type traceRecorder struct { + logger.Interface + BeginAt time.Time + SQL string + RowsAffected int64 + Err error +} + +func New(writer Writer, config GormConfig) logger.Interface { + var ( + infoStr = "%s\n[info] " + warnStr = "%s\n[warn] " + errStr = "%s\n[error] " + traceStr = "%s\n[%.3fms] [rows:%v] %s" + traceWarnStr = "%s %s\n[%.3fms] [rows:%v] %s" + traceErrStr = "%s %s\n[%.3fms] [rows:%v] %s" + ) + + if config.Colorful { + infoStr = logger.Green + "%s\n" + logger.Reset + logger.Green + "[info] " + logger.Reset + warnStr = logger.BlueBold + "%s\n" + logger.Reset + logger.Magenta + "[warn] " + logger.Reset + errStr = logger.Magenta + "%s\n" + logger.Reset + logger.Red + "[error] " + logger.Reset + traceStr = logger.Green + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s" + traceWarnStr = logger.Green + "%s " + logger.Yellow + "%s\n" + logger.Reset + logger.RedBold + "[%.3fms] " + logger.Yellow + "[rows:%v]" + logger.Magenta + " %s" + logger.Reset + traceErrStr = logger.RedBold + "%s " + logger.MagentaBold + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s" + } + + return &GormLogger{ + Writer: writer, + GormConfig: config, + infoStr: infoStr, + warnStr: warnStr, + errStr: errStr, + traceStr: traceStr, + traceWarnStr: traceWarnStr, + traceErrStr: traceErrStr, + } +} + +// Writer log writer interface +type Writer interface { + Printf(string, ...interface{}) +} + +type GormConfig struct { + SlowThreshold time.Duration + Colorful bool + LogLevel logger.LogLevel +} + +type GormLogger struct { + Writer + GormConfig + infoStr, warnStr, errStr string + traceStr, traceErrStr, traceWarnStr string +} + +func (g *GormLogger) LogMode(level logger.LogLevel) logger.Interface { + newLogger := *g + newLogger.LogLevel = level + return &newLogger +} + +func (g *GormLogger) Info(ctx context.Context, message string, data ...interface{}) { + if g.LogLevel >= logger.Info { + g.Printf(g.infoStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...) + } +} + +func (g *GormLogger) Warn(ctx context.Context, message string, data ...interface{}) { + if g.LogLevel >= logger.Warn { + g.Printf(g.warnStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...) + } +} + +func (g *GormLogger) Error(ctx context.Context, message string, data ...interface{}) { + if g.LogLevel >= logger.Error { + g.Printf(g.errStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...) + } +} + +func (g *GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { + if g.LogLevel > 0 { + elapsed := time.Since(begin) + switch { + case err != nil && g.LogLevel >= logger.Error: + sql, rows := fc() + if rows == -1 { + g.Printf(g.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql) + } else { + g.Printf(g.traceErrStr, utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql) + } + case elapsed > g.SlowThreshold && g.SlowThreshold != 0 && g.LogLevel >= logger.Warn: + sql, rows := fc() + slowLog := fmt.Sprintf("SLOW SQL >= %v", g.SlowThreshold) + if rows == -1 { + g.Printf(g.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql) + } else { + g.Printf(g.traceWarnStr, utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql) + } + case g.LogLevel >= logger.Info: + sql, rows := fc() + if rows == -1 { + g.Printf(g.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql) + } else { + g.Printf(g.traceStr, utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql) + } + } + } +} + +func (g *GormLogger) Printf(message string, data ...interface{}) { + switch len(data) { + case 0: + global.GVA_LOG.Info(message) + case 1: + global.GVA_LOG.Info("gorm", zap.Any("src", data[0])) + case 2: + global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1])) + case 3: + global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]), zap.Any("rows", data[2])) + case 4: + global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]), zap.Any("rows", data[2]), zap.Any("sql", data[3])) + } +} diff --git a/web/src/App.vue b/web/src/App.vue index b79771fe..4564d38a 100644 --- a/web/src/App.vue +++ b/web/src/App.vue @@ -15,6 +15,7 @@ export default { // 引入初始化样式 @import '@/style/main.scss'; @import '@/style/base.scss'; +@import '@/style/mobile.scss'; #app { background: #eee; height: 100vh; diff --git a/web/src/style/basics.scss b/web/src/style/basics.scss index 1280dfee..767a99e5 100644 --- a/web/src/style/basics.scss +++ b/web/src/style/basics.scss @@ -32,3 +32,6 @@ $color-table-tbody:#595959; $color-table-thead:#262626; // dashboard $height-car:68px; +// mobile +$padding-xs: 5px; +$margin-xs: 5px; diff --git a/web/src/style/main.scss b/web/src/style/main.scss index b849814e..432b1cb6 100644 --- a/web/src/style/main.scss +++ b/web/src/style/main.scss @@ -1204,6 +1204,14 @@ $mainHight: 100vh; top: 0; box-sizing: border-box; z-index: 999; + >.el-row{ + padding: 0; + .el-col-lg-14{ + height: 60px; + } + } + + } @@ -1387,14 +1395,14 @@ $mainHight: 100vh; .car-left { height: $height-car; - width: 70%; - float: left; + // width: 70%; + // float: left; } .car-right { height: $height-car; - width: 29%; - float: left; + // width: 29%; + // float: left; .flow, .user-number, diff --git a/web/src/style/mobile.scss b/web/src/style/mobile.scss new file mode 100644 index 00000000..4bc840b4 --- /dev/null +++ b/web/src/style/mobile.scss @@ -0,0 +1,89 @@ + +@import '@/style/basics.scss'; +@media screen and (min-width: 320px)and (max-width: 750px){ + .el-header{ + padding: 0 $padding-xs; + } + .layout-cont { + .main-cont{ + .breadcrumb{ + padding: 0 $padding-xs; + } + } + } + .layout-cont{ + .right-box{ + margin-right: $margin-xs; + } + } + .search-component{ + width: 30px; + } + .screenfull{ + width: 26px; + text-align: center; + } + .el-main{ + .admin-box{ + margin-left: 0; + margin-right: 0; + } + .big.admin-box{ + padding: 0 0 15px 0; + } + .big { + .bottom { + .chart-player{ + height: auto!important; + margin-bottom: 15px; + } + .todoapp{ + background-color: #fff; + padding-bottom: 10px; + } + } + } + } + + .card .car-left, + .card .car-right{ + width: 100%; + height: 100%; + } + .card{ + padding-left: $padding-xs; + padding-right: $padding-xs; + + } + .card { + .text{ + width: 100%; + h4{ + white-space: break-spaces; + } + } + } + .shadow{ + margin-left: 5px; + margin-right: 5px; + .grid-content{ + margin-bottom: 10px; + padding: 0; + } + } + .el-dialog{ + width: 90%; + } + .el-transfer{ + .el-transfer-panel{ + width: 40%; + display: inline-block; + } + .el-transfer__buttons{ + padding: 0 5px; + display: inline-block; + } + + } + +} \ No newline at end of file diff --git a/web/src/view/dashboard/index.vue b/web/src/view/dashboard/index.vue index 3f93b575..4b7b45b2 100644 --- a/web/src/view/dashboard/index.vue +++ b/web/src/view/dashboard/index.vue @@ -1,179 +1,204 @@ diff --git a/web/src/view/example/form/form.vue b/web/src/view/example/form/form.vue index 8c8c0f9e..c1f70f87 100644 --- a/web/src/view/example/form/form.vue +++ b/web/src/view/example/form/form.vue @@ -2,12 +2,12 @@
- - + + - - + + @@ -15,8 +15,8 @@ - - + + @@ -27,12 +27,12 @@ - - + + - - + + @@ -42,8 +42,8 @@ - - + + @@ -51,12 +51,12 @@ - - + + - - + + - + diff --git a/web/src/view/layout/index.vue b/web/src/view/layout/index.vue index ad5ad72e..6749b46e 100644 --- a/web/src/view/layout/index.vue +++ b/web/src/view/layout/index.vue @@ -16,18 +16,25 @@ :style="{width: `calc(100% - ${isMobile?'0px':isCollapse?'54px':'220px'})`}" class="topfix" > + + - - - {{item.meta.title}} - -
+ + + + + + {{item.meta.title}} + + + +
@@ -48,7 +55,10 @@
+
+ + @@ -172,8 +182,9 @@ export default { } } -