Browse Source

Merge branches 'develop' and 'gin-vue-admin_v2_dev' of https://github.com/flipped-aurora/gin-vue-admin into gin-vue-admin_v2_dev

QM303176530 4 years ago
parent
commit
00665d8831

+ 12 - 2
server/api/v1/exa_file_upload_download.go

@@ -2,6 +2,7 @@ package v1
 
 import (
 	"fmt"
+	"gin-vue-admin/global"
 	"gin-vue-admin/global/response"
 	"gin-vue-admin/model"
 	"gin-vue-admin/model/request"
@@ -27,8 +28,17 @@ func UploadFile(c *gin.Context) {
 		response.FailWithMessage(fmt.Sprintf("上传文件失败,%v", err), c)
 	} else {
 		// 文件上传后拿到文件路径
-		err, filePath, key := utils.Upload(header)
-		if err != nil {
+		var uploadErr error
+		var filePath string
+		var key string
+		if global.GVA_CONFIG.LocalUpload.Local {
+			// 本地上传
+			uploadErr, filePath, key = utils.UploadFileLocal(header)
+		} else {
+			// 七牛云上传
+			uploadErr, filePath, key = utils.UploadRemote(header)
+		}
+		if uploadErr != nil {
 			response.FailWithMessage(fmt.Sprintf("接收返回值失败,%v", err), c)
 		} else {
 			// 修改数据库后得到修改后的user并且返回供前端使用

+ 10 - 2
server/api/v1/sys_user.go

@@ -195,8 +195,16 @@ func UploadHeaderImg(c *gin.Context) {
 		response.FailWithMessage(fmt.Sprintf("上传文件失败,%v", err), c)
 	} else {
 		// 文件上传后拿到文件路径
-		err, filePath, _ := utils.Upload(header)
-		if err != nil {
+		var uploadErr error
+		var filePath string
+		if global.GVA_CONFIG.LocalUpload.Local {
+			// 本地上传
+			uploadErr, filePath, _ = utils.UploadAvatarLocal(header)
+		} else {
+			// 七牛云上传
+			uploadErr, filePath, _ = utils.UploadRemote(header)
+		}
+		if uploadErr != nil {
 			response.FailWithMessage(fmt.Sprintf("接收返回值失败,%v", err), c)
 		} else {
 			// 修改数据库后得到修改后的user并且返回供前端使用

+ 37 - 31
server/config.yaml

@@ -2,60 +2,66 @@
 
 # casbin configuration
 casbin:
-    model-path: './resource/rbac_model.conf'
+  model-path: './resource/rbac_model.conf'
 
 # jwt configuration
 jwt:
-    signing-key: 'qmPlus'
+  signing-key: 'qmPlus'
 
 # mysql connect configuration
 mysql:
-    username: root
-    password: 'Aa@6447985'
-    path: '127.0.0.1:3306'
-    db-name: 'qmPlus'
-    config: 'charset=utf8mb4&parseTime=True&loc=Local'
-    max-idle-conns: 10
-    max-open-conns: 10
-    log-mode: false
+  username: root
+  password: 'Aa@6447985'
+  path: '127.0.0.1:3306'
+  db-name: 'qmPlus'
+  config: 'charset=utf8mb4&parseTime=True&loc=Local'
+  max-idle-conns: 10
+  max-open-conns: 10
+  log-mode: false
 
 #sqlite 配置
 sqlite:
-    path: db.db
-    log-mode: true
-    config: 'loc=Asia/Shanghai'
+  path: db.db
+  log-mode: true
+  config: 'loc=Asia/Shanghai'
 
 # oss configuration
 
+# 切换本地与七牛云上传,分配头像和文件路径
+localupload:
+  local: true
+  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'
+  access-key: '25j8dYBZ2wuiy0yhwShytjZDTX662b8xiFguwxzZ'
+  secret-key: 'pgdbqEsf7ooZh7W3xokP833h3dZ_VecFXPDeG5JY'
+  bucket: 'qm-plus-img'
+  img-path: 'http://qmplusimg.henrongyi.top'
 
 # redis configuration
 redis:
-    addr: '127.0.0.1:6379'
-    password: ''
-    db: 0
+  addr: '127.0.0.1:6379'
+  password: ''
+  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/sqlite
+  use-multipoint: false
+  env: 'public'  # Change to "develop" to skip authentication for development mode
+  addr: 8888
+  db-type: "mysql"  # support mysql/sqlite
 
 # captcha configuration
 captcha:
-    key-long: 6
-    img-width: 240
-    img-height: 80
+  key-long: 6
+  img-width: 240
+  img-height: 80
 
 # logger configuration
 log:
-    prefix: '[GIN-VUE-ADMIN]'
-    log-file: true
-    stdout: 'DEBUG'
-    file: 'DEBUG'
+  prefix: '[GIN-VUE-ADMIN]'
+  log-file: true
+  stdout: 'DEBUG'
+  file: 'DEBUG'

+ 8 - 0
server/config/config.go

@@ -10,6 +10,7 @@ type Server struct {
 	JWT       JWT       `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
 	Captcha   Captcha   `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
 	Log       Log       `mapstructure:"log" json:"log" yaml:"log"`
+	LocalUpload LocalUpload `mapstructure:"localUpload" json:"localUpload" yaml:"localUpload"`
 }
 
 type System struct {
@@ -43,6 +44,13 @@ type Redis struct {
 	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"`
+	AvatarPath string `mapstructure:"avatar-path" json:"avatarPath" yaml:"avatar-path"`
+	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"`

+ 4 - 0
server/initialize/router.go

@@ -8,12 +8,16 @@ import (
 	"github.com/gin-gonic/gin"
 	"github.com/swaggo/gin-swagger"
 	"github.com/swaggo/gin-swagger/swaggerFiles"
+	"net/http"
 )
 
 // 初始化总路由
 
 func Routers() *gin.Engine {
 	var Router = gin.Default()
+	// 为用户头像和文件提供静态地址
+	Router.StaticFS(global.GVA_CONFIG.LocalUpload.AvatarPath, http.Dir(global.GVA_CONFIG.LocalUpload.AvatarPath))
+	Router.StaticFS(global.GVA_CONFIG.LocalUpload.FilePath, http.Dir(global.GVA_CONFIG.LocalUpload.FilePath))
 	// Router.Use(middleware.LoadTls())  // 打开就能玩https了
 	global.GVA_LOG.Debug("use middleware logger")
 	// 跨域

+ 53 - 0
server/utils/upload_avatar_local.go

@@ -0,0 +1,53 @@
+package utils
+
+import (
+	"gin-vue-admin/global"
+	"io"
+	"mime/multipart"
+	"os"
+	"path"
+	"strings"
+	"time"
+)
+
+func UploadAvatarLocal(file *multipart.FileHeader) (err error, localPath string, key string) {
+	// 读取文件后缀
+	ext := path.Ext(file.Filename)
+	// 读取文件名并加密
+	fileName := strings.TrimSuffix(file.Filename, ext)
+	fileName = MD5V([]byte(fileName))
+	// 拼接新文件名
+	lastName := fileName + "_" + time.Now().Format("20060102150405") + ext
+	// 读取全局变量的定义路径
+	savePath := global.GVA_CONFIG.LocalUpload.AvatarPath
+	// 尝试创建此路径
+	err = os.MkdirAll(savePath, os.ModePerm)
+	if err != nil{
+		global.GVA_LOG.Error("upload local file fail:", err)
+		return err, "", ""
+	}
+	// 拼接路径和文件名
+	dst := savePath + "/" + lastName
+	// 下面为上传逻辑
+	// 打开文件 defer 关闭
+	src, err := file.Open()
+	if err != nil {
+		global.GVA_LOG.Error("upload local file fail:", err)
+		return err, "", ""
+	}
+	defer src.Close()
+	// 创建文件 defer 关闭
+	out, err := os.Create(dst)
+	if err != nil {
+		global.GVA_LOG.Error("upload local file fail:", err)
+		return err, "", ""
+	}
+	defer out.Close()
+	// 传输(拷贝)文件
+	_, err = io.Copy(out, src)
+	if err != nil {
+		global.GVA_LOG.Error("upload local file fail:", err)
+		return err, "", ""
+	}
+	return nil, dst, lastName
+}

+ 53 - 0
server/utils/upload_file_local.go

@@ -0,0 +1,53 @@
+package utils
+
+import (
+	"gin-vue-admin/global"
+	"io"
+	"mime/multipart"
+	"os"
+	"path"
+	"strings"
+	"time"
+)
+
+func UploadFileLocal(file *multipart.FileHeader) (err error, localPath string, key string) {
+	// 读取文件后缀
+	ext := path.Ext(file.Filename)
+	// 读取文件名并加密
+	fileName := strings.TrimSuffix(file.Filename, ext)
+	fileName = MD5V([]byte(fileName))
+	// 拼接新文件名
+	lastName := fileName + "_" + time.Now().Format("20060102150405") + ext
+	// 读取全局变量的定义路径
+	savePath := global.GVA_CONFIG.LocalUpload.FilePath
+	// 尝试创建此路径
+	err = os.MkdirAll(savePath, os.ModePerm)
+	if err != nil{
+		global.GVA_LOG.Error("upload local file fail:", err)
+		return err, "", ""
+	}
+	// 拼接路径和文件名
+	dst := savePath + "/" + lastName
+	// 下面为上传逻辑
+	// 打开文件 defer 关闭
+	src, err := file.Open()
+	if err != nil {
+		global.GVA_LOG.Error("upload local file fail:", err)
+		return err, "", ""
+	}
+	defer src.Close()
+	// 创建文件 defer 关闭
+	out, err := os.Create(dst)
+	if err != nil {
+		global.GVA_LOG.Error("upload local file fail:", err)
+		return err, "", ""
+	}
+	defer out.Close()
+	// 传输(拷贝)文件
+	_, err = io.Copy(out, src)
+	if err != nil {
+		global.GVA_LOG.Error("upload local file fail:", err)
+		return err, "", ""
+	}
+	return nil, dst, lastName
+}

+ 1 - 1
server/utils/upload.go → server/utils/upload_remote.go

@@ -11,7 +11,7 @@ import (
 )
 
 // 接收两个参数 一个文件流 一个 bucket 你的七牛云标准空间的名字
-func Upload(file *multipart.FileHeader) (err error, path string, key string) {
+func UploadRemote(file *multipart.FileHeader) (err error, path string, key string) {
 	putPolicy := storage.PutPolicy{
 		Scope: global.GVA_CONFIG.Qiniu.Bucket,
 	}

File diff suppressed because it is too large
+ 168 - 211
web/package-lock.json


+ 1 - 1
web/package.json

@@ -14,7 +14,7 @@
     "echarts": "^4.7.0",
     "element-ui": "^2.12.0",
     "mavon-editor": "^2.7.7",
-    "node-sass": "^4.12.0",
+    "node-sass": "^4.14.1",
     "path": "^0.12.7",
     "qs": "^6.8.0",
     "quill": "^1.3.7",

BIN
web/src/assets/noBody.png


+ 75 - 0
web/src/components/customPic/index.vue

@@ -0,0 +1,75 @@
+<template>
+    <span class="headerAvatar">
+        <template v-if="picType === 'avatar'">
+            <el-avatar :size="30" :src="avatar" v-if="userInfo.headerImg"></el-avatar>
+            <el-avatar :size="30" :src="require('@/assets/noBody.png')" v-else></el-avatar>
+        </template>
+        <template v-if="picType === 'img'">
+            <img :src="avatar" class="avatar" v-if="userInfo.headerImg" />
+            <img :src="require('@/assets/noBody.png')" class="avatar" v-else/>
+        </template>
+        <template v-if="picType === 'file'">
+            <img :src="file" class="file"/>
+        </template>
+    </span>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+const path = process.env.VUE_APP_BASE_API
+export default {
+    name: "customPic",
+    props: {
+        picType: {
+            type: String,
+            required: false,
+            default: "avatar"
+        },
+        picSrc: {
+            type: String,
+            required: false,
+            default: ""
+        }
+    },
+    data(){
+        return{
+            path: path,
+        }
+    },
+    computed:{
+        ...mapGetters('user', ['userInfo']),
+        avatar(){
+            if(this.picSrc === ''){
+                if(this.userInfo.headerImg !== '' && this.userInfo.headerImg.slice(0, 4) === "http"){
+                    return this.userInfo.headerImg
+                }
+                return this.path + this.userInfo.headerImg
+            }else{
+                if(this.picSrc !== '' && this.picSrc.slice(0, 4) === "http"){
+                    return this.picSrc
+                }
+                return this.path + this.picSrc
+            }
+        },
+        file(){
+            if(this.picSrc && this.picSrc.slice(0, 4) !== "http"){
+                return this.path + this.picSrc
+            }
+            return this.picSrc
+        }
+    }
+}
+</script>
+
+<style scoped>
+.headerAvatar{
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+.file{
+    width: 80px;
+    height: 80px;
+    position: relative;
+}
+</style>

+ 5 - 6
web/src/view/example/upload/upload.vue

@@ -17,12 +17,7 @@
       <el-table :data="tableData" border stripe>
         <el-table-column label="预览" width="100">
           <template slot-scope="scope">
-            <img
-              :alt="scope.row.alt"
-              :src="scope.row.url"
-              height="80"
-              width="80"
-            />
+            <CustomPic picType="file" :picSrc="scope.row.url"/>
           </template>
         </el-table-column>
         <el-table-column label="日期" prop="UpdatedAt" width="180">
@@ -77,9 +72,13 @@ import infoList from "@/components/mixins/infoList";
 import { getFileList, deleteFile } from "@/api/fileUploadAndDownload";
 import { downloadImage } from "@/utils/downloadImg";
 import { formatTimeToStr } from "@/utils/data";
+import CustomPic from '@/components/customPic'
 export default {
   name: "Upload",
   mixins: [infoList],
+  components: {
+		CustomPic
+	},
   data() {
     return {
       fullscreenLoading: false,

+ 11 - 4
web/src/view/layout/index.vue

@@ -31,9 +31,9 @@
                 <Search />
                 <Screenfull class="screenfull"></Screenfull>
                 <el-dropdown>
-                  <span class="el-dropdown-link">
-                    <img :src="userInfo.headerImg" height="30" width="30" />
-                    {{userInfo.title}}
+                  <span class="header-avatar">
+                    欢迎您,<CustomPic/>
+                    <span style="margin-left: 5px">{{userInfo.nickName}}</span>
                     <i class="el-icon-arrow-down"></i>
                   </span>
                   <el-dropdown-menu class="dropdown-group" slot="dropdown">
@@ -95,6 +95,7 @@ import Search from '@/view/layout/search/search'
 import BottomInfo from '@/view/layout/bottomInfo/bottomInfo'
 import { mapGetters, mapActions } from 'vuex'
 import { changePassword } from '@/api/user'
+import CustomPic from '@/components/customPic'
 export default {
   name: 'Layout',
   data() {
@@ -138,7 +139,8 @@ export default {
     HistoryComponent,
     Screenfull,
     Search,
-    BottomInfo
+    BottomInfo,
+    CustomPic
   },
   methods: {
     ...mapActions('user', ['LoginOut']),
@@ -374,4 +376,9 @@ $mainHight: 100vh;
 .screenfull {
   display: inline-block;
 }
+.header-avatar{
+	display: flex;
+	justify-content: center;
+	align-items: center;
+}
 </style>

+ 5 - 2
web/src/view/person/person.vue

@@ -9,8 +9,7 @@
         class="avatar-uploader"
         name="headerImg"
       >
-        <img :src="userInfo.headerImg" class="avatar" v-if="userInfo.headerImg" />
-        <i class="el-icon-plus avatar-uploader-icon" v-else></i>
+        <CustomPic picType="img"/>
       </el-upload>
 
       <!-- <el-avatar :size="120" :src="userInfo.headerImg" shape="square"></el-avatar> -->
@@ -23,6 +22,7 @@
   </div>
 </template>
 <script>
+import CustomPic from '@/components/customPic'
 import { mapGetters, mapMutations } from 'vuex'
 const path = process.env.VUE_APP_BASE_API
 export default {
@@ -32,6 +32,9 @@ export default {
       path:path
     }
   },
+  components: {
+		CustomPic
+	},
   computed: {
     ...mapGetters('user', ['userInfo', 'token'])
   },

+ 5 - 1
web/src/view/superAdmin/user/user.vue

@@ -7,7 +7,7 @@
       <el-table-column label="头像" min-width="50">
         <template slot-scope="scope">
           <div :style="{'textAlign':'center'}">
-            <img :src="scope.row.headerImg" height="35" width="35" />
+            <CustomPic :picSrc="scope.row.headerImg"/>
           </div>
         </template>
       </el-table-column>
@@ -106,9 +106,13 @@ import {
 import { getAuthorityList } from "@/api/authority";
 import infoList from "@/components/mixins/infoList";
 import { mapGetters } from "vuex";
+import CustomPic from '@/components/customPic'
 export default {
   name: "Api",
   mixins: [infoList],
+  components: {
+		CustomPic
+	},
   data() {
     return {
       listApi: getUserList,

+ 114 - 103
web/src/view/systemTools/system/system.vue

@@ -1,106 +1,116 @@
 <template>
-  <div class="system">
-    <el-form :model="config" label-width="100px" ref="form" class="system">
-      <h2>系统配置</h2>
-      <el-form-item label="多点登录拦截">
-        <el-checkbox v-model="config.system.useMultipoint">开启</el-checkbox>
-      </el-form-item>
-      <el-form-item label="环境值">
-        <el-input v-model="config.system.env"></el-input>
-      </el-form-item>
-      <el-form-item label="端口值">
-        <el-input v-model.number="config.system.addr"></el-input>
-      </el-form-item>
-      <el-form-item label="数据库类型">
-        <el-select v-model="config.system.dbType">
-          <el-option value="sqlite"></el-option>
-          <el-option value="mysql"></el-option>
-        </el-select>
-      </el-form-item>
-      <h2>jwt签名</h2>
-      <el-form-item label="jwt签名">
-        <el-input v-model="config.jwt.signingKey"></el-input>
-      </el-form-item>
-      <h2>casbin配置</h2>
-      <el-form-item label="模型地址">
-        <el-input v-model="config.casbin.modelPath"></el-input>
-      </el-form-item>
-      <template v-show="config.system.dbType == 'mysql'">
-        <h2>mysql 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="path">
-          <el-input v-model="config.mysql.path"></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="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="logMode">
-          <el-checkbox v-model="config.mysql.logMode"></el-checkbox>
-        </el-form-item>
-      </template>
-      <template v-show="config.system.dbType == 'sqlite'">
-        <h2>sqlite admin数据库配置</h2>
-        <el-form-item label="path">
-          <el-input v-model="config.sqlite.path"></el-input>
-        </el-form-item>
-        <el-form-item label="config">
-          <el-input v-model="config.sqlite.config"></el-input>
-        </el-form-item>
-        <el-form-item label="logMode">
-          <el-checkbox v-model="config.sqlite.logMode"></el-checkbox>
-        </el-form-item>
-      </template>
-      <h2>Redis admin数据库配置</h2>
-      <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>
-      <el-form-item label="db">
-        <el-input v-model="config.redis.db"></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="prefix">
-        <el-input v-model.number="config.log.prefix"></el-input>
-      </el-form-item>
-      <el-form-item label="logFile">
-        <el-checkbox v-model="config.log.logFile"></el-checkbox>
-      </el-form-item>
-      <el-form-item>
-        <el-button @click="update" type="primary">立即更新</el-button>
-        <el-button @click="reload" type="primary">重启服务(开发中)</el-button>
-      </el-form-item>
-    </el-form>
-  </div>
+	<div class="system">
+		<el-form :model="config" label-width="100px" ref="form" class="system">
+			<h2>系统配置</h2>
+			<el-form-item label="多点登录拦截">
+				<el-checkbox v-model="config.system.useMultipoint">开启</el-checkbox>
+			</el-form-item>
+			<el-form-item label="环境值">
+				<el-input v-model="config.system.env"></el-input>
+			</el-form-item>
+			<el-form-item label="端口值">
+				<el-input v-model.number="config.system.addr"></el-input>
+			</el-form-item>
+			<el-form-item label="数据库类型">
+				<el-select v-model="config.system.dbType">
+					<el-option value="sqlite"></el-option>
+					<el-option value="mysql"></el-option>
+				</el-select>
+			</el-form-item>
+			<h2>jwt签名</h2>
+			<el-form-item label="jwt签名">
+				<el-input v-model="config.jwt.signingKey"></el-input>
+			</el-form-item>
+			<h2>casbin配置</h2>
+			<el-form-item label="模型地址">
+				<el-input v-model="config.casbin.modelPath"></el-input>
+			</el-form-item>
+			<template v-show="config.system.dbType == 'mysql'">
+				<h2>mysql 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="path">
+					<el-input v-model="config.mysql.path"></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="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="logMode">
+					<el-checkbox v-model="config.mysql.logMode"></el-checkbox>
+				</el-form-item>
+			</template>
+			<template v-show="config.system.dbType == 'sqlite'">
+				<h2>sqlite admin数据库配置</h2>
+				<el-form-item label="path">
+					<el-input v-model="config.sqlite.path"></el-input>
+				</el-form-item>
+				<el-form-item label="config">
+					<el-input v-model="config.sqlite.config"></el-input>
+				</el-form-item>
+				<el-form-item label="logMode">
+					<el-checkbox v-model="config.sqlite.logMode"></el-checkbox>
+				</el-form-item>
+			</template>
+			<h2>Redis admin数据库配置</h2>
+			<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>
+			<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.avatarPath"></el-input>
+				</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="prefix">
+				<el-input v-model.number="config.log.prefix"></el-input>
+			</el-form-item>
+			<el-form-item label="logFile">
+				<el-checkbox v-model="config.log.logFile"></el-checkbox>
+			</el-form-item>
+			<el-form-item>
+				<el-button @click="update" type="primary">立即更新</el-button>
+				<el-button @click="reload" type="primary">重启服务(开发中)</el-button>
+			</el-form-item>
+		</el-form>
+	</div>
 </template>
 
 <script>
@@ -118,7 +128,8 @@ export default {
         redis: {},
         qiniu: {},
         captcha: {},
-        log: {}
+		log: {},
+		localUpload: {}
       }
     };
   },

Some files were not shown because too many files changed in this diff