Parcourir la source

添加 views/admin/oss 作为 oss-console 的前端模块

reghao il y a 5 mois
Parent
commit
9871864e5e

+ 44 - 0
src/api/oss.js

@@ -0,0 +1,44 @@
+import { get, post } from '@/utils/request'
+
+const ossApi = {
+  getStoreList: '/api/oss/store/list',
+  getStoreDisks: '/api/oss/store/disk',
+  getStoreNodeKeyValue: '/api/oss/store/kv',
+  getUserNodeList: '/api/oss/my/list',
+  getUserNodeKeyValue: '/api/oss/my/kv',
+  getUserKeyList: '/api/oss/key/list',
+  resetUserKey: '/api/oss/key/regenerate',
+  getChannelList: '/api/oss/channel/list'
+}
+
+export function getStoreList() {
+  return get(ossApi.getStoreList)
+}
+
+export function getStoreDisks(storeNodeId) {
+  return get(ossApi.getStoreDisks + '?storeNodeId=' + storeNodeId)
+}
+
+export function getStoreNodeKeyValue() {
+  return get(ossApi.getStoreNodeKeyValue)
+}
+
+export function getUserNodeList() {
+  return get(ossApi.getUserNodeList)
+}
+
+export function getUserNodeKeyValue() {
+  return get(ossApi.getUserNodeKeyValue)
+}
+
+export function getUserKeyList() {
+  return get(ossApi.getUserKeyList)
+}
+
+export function resetUserKey() {
+  return post(ossApi.resetUserKey)
+}
+
+export function getChannelList(userNodeId) {
+  return get(ossApi.getChannelList + '?userNodeId=' + userNodeId)
+}

+ 39 - 0
src/router/background_oss.js

@@ -0,0 +1,39 @@
+const Background = () => import('views/admin/Background')
+const AdminStoreNode = () => import('views/admin/oss/AdminStoreNode')
+const AdminUserNode = () => import('views/admin/oss/AdminUserNode')
+const AdminUploadChannel = () => import('views/admin/oss/AdminUploadChannel')
+const AdminStoreObject = () => import('views/admin/oss/AdminStoreObject')
+
+export default {
+  path: '/background/oss',
+  redirect: '/background/account',
+  name: 'OSS',
+  component: Background,
+  meta: { needAuth: true, roles: ['admin'] },
+  children: [
+    {
+      path: '/background/oss/store_node',
+      name: 'AdminStoreConfig',
+      component: AdminStoreNode,
+      meta: { needAuth: true }
+    },
+    {
+      path: '/background/oss/user_node',
+      name: 'AdminUserNode',
+      component: AdminUserNode,
+      meta: { needAuth: true }
+    },
+    {
+      path: '/background/oss/upload_channel',
+      name: 'AdminUploadChannel',
+      component: AdminUploadChannel,
+      meta: { needAuth: true }
+    },
+    {
+      path: '/background/oss/object',
+      name: 'AdminStoreObject',
+      component: AdminStoreObject,
+      meta: { needAuth: true }
+    }
+  ]
+}

+ 2 - 0
src/router/index.js

@@ -10,6 +10,7 @@ import BackgroundPostRouter from './background_post'
 import BackgroundSiteRouter from './background_site'
 import BackgroundAdminRouter from './background_admin'
 import BackgroundBackendRouter from './background_backend'
+import BackgroundOssRouter from './background_oss'
 
 // 懒加载引入页面组件,es6语法
 // ********************************************************************************************************************
@@ -46,6 +47,7 @@ export const constantRoutes = [
   BackgroundSiteRouter,
   BackgroundAdminRouter,
   BackgroundBackendRouter,
+  BackgroundOssRouter,
   {
     path: '/',
     name: 'Index',

+ 30 - 3
src/views/admin/LeftAside.vue

@@ -15,19 +15,19 @@
         <img class="logoimg" src="@/assets/img/icon/logo.png" alt="">
       </a>
     </div>
-    <el-submenu v-for="(item, index) in menuList" :index="item.url" :key="index">
+    <el-submenu v-for="(item, index) in menuList" :key="index" :index="item.url">
       <template slot="title">
         <i :class="item.icon" />
         <span>{{ item.title }}</span>
       </template>
       <el-menu-item-group>
-        <el-menu-item v-for="(child, index0) in item.children" :index="child.url" :key="index0">
+        <el-menu-item v-for="(child, index0) in item.children" :key="index0" :index="child.url">
           <i :class="child.icon" />
           <span slot="title">{{ child.title }}</span>
         </el-menu-item>
       </el-menu-item-group>
     </el-submenu>
-<!--    <el-submenu index="/background/account">
+    <!--    <el-submenu index="/background/account">
       <template slot="title">
         <i class="el-icon-user" />
         <span>我的帐号</span>
@@ -164,6 +164,33 @@ export default {
             }
           ]
         },
+        {
+          url: '/background/oss',
+          title: '存储系统',
+          icon: 'el-icon-files',
+          children: [
+            {
+              url: '/background/oss/store_node',
+              title: '存储节点',
+              icon: 'el-icon-files'
+            },
+            {
+              url: '/background/oss/user_node',
+              title: '我的节点',
+              icon: 'el-icon-files'
+            },
+            {
+              url: '/background/oss/upload_channel',
+              title: '上传通道',
+              icon: 'el-icon-files'
+            },
+            {
+              url: '/background/oss/object',
+              title: '对象列表',
+              icon: 'el-icon-files'
+            }
+          ]
+        },
         {
           url: '/background/site',
           title: '站点配置',

+ 202 - 0
src/views/admin/oss/AdminStoreNode.vue

@@ -0,0 +1,202 @@
+<template>
+  <el-container>
+    <el-header height="220">
+      <h3>存储节点</h3>
+    </el-header>
+    <el-main>
+      <el-table
+        :data="dataList"
+        border
+        height="480"
+        style="width: 100%"
+      >
+        <el-table-column
+          fixed="left"
+          label="No"
+          type="index"
+        />
+        <el-table-column
+          prop="nodeAddr"
+          label="地址"
+        />
+        <el-table-column
+          prop="httpPort"
+          label="HTTP 端口"
+        />
+        <el-table-column
+          prop="rpcPort"
+          label="RPC 端口"
+        />
+        <el-table-column
+          prop="total"
+          label="存储空间"
+        >
+          <template slot-scope="scope">
+            <el-progress :percentage="scope.row.percent"></el-progress>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="status"
+          label="状态"
+        />
+        <el-table-column
+          fixed="right"
+          label="操作"
+          width="280"
+        >
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              @click="handleEdit(scope.$index, scope.row)"
+            >磁盘详情</el-button>
+            <el-button
+              size="mini"
+              @click="handleEdit(scope.$index, scope.row)"
+            >禁用</el-button>
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleDelete(scope.$index, scope.row)"
+            >删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-main>
+
+    <!-- 修改视频可见范围对话框 -->
+    <el-dialog
+      append-to-body
+      :visible.sync="showEditScopeDialog"
+      center
+    >
+      <div>
+        <h3>存储节点磁盘详情</h3>
+        <el-table
+          :data="tableList"
+          border
+          height="480"
+          style="width: 100%"
+        >
+          <el-table-column
+            fixed="left"
+            label="No"
+            type="index"
+          />
+          <el-table-column
+            prop="fsType"
+            label="文件系统"
+          />
+          <el-table-column
+            prop="volume"
+            label="磁盘分区"
+          />
+          <el-table-column
+            prop="storeDir"
+            label="存储目录"
+          />
+          <el-table-column
+            prop="total"
+            label="分区容量"
+          >
+            <template slot-scope="scope">
+              <el-progress :percentage="scope.row.percent"></el-progress>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="totalInode"
+            label="inode 容量"
+          >
+            <template slot-scope="scope">
+              <el-progress :percentage="scope.row.percentInode"></el-progress>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </el-dialog>
+  </el-container>
+</template>
+
+<script>
+import { getStoreDisks, getStoreList } from '@/api/oss'
+
+export default {
+  name: 'AdminStoreNode',
+  data() {
+    return {
+      queryInfo: {
+        path: null
+      },
+      // 屏幕宽度, 为了控制分页条的大小
+      screenWidth: document.body.clientWidth,
+      currentPage: 1,
+      pageSize: 12,
+      totalSize: 0,
+      dataList: [],
+      tableList: [],
+      nextId: 0,
+      // **********************************************************************
+      showEditScopeDialog: false,
+      form: {
+        videoId: null,
+        scope: 1
+      }
+    }
+  },
+  created() {
+    document.title = '存储节点'
+    this.getData()
+  },
+  methods: {
+    getData() {
+      this.dataList = []
+      getStoreList().then(resp => {
+        if (resp.code === 0) {
+          this.dataList = resp.data
+        }
+      })
+    },
+    onRefresh() {
+      this.getData()
+    },
+    handleCurrentChange(pageNumber) {
+      this.currentPage = pageNumber
+      this.getData()
+      // 回到顶部
+      scrollTo(0, 0)
+    },
+    handleEdit(index, row) {
+      this.showEditScopeDialog = true
+      getStoreDisks((row.id)).then(resp => {
+        if (resp.code === 0) {
+          this.tableList = resp.data
+        }
+      })
+    },
+    handleDelete(index, row) {
+      this.$confirm('确定要删除 ' + row.title + '?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.$message.info('handleDelete')
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消'
+        })
+      })
+    },
+    onUpdateScope() {
+      this.showEditScopeDialog = false
+    },
+    onSelectChange() {
+      this.dataList = []
+    },
+    handleClose() {
+    }
+  }
+}
+</script>
+
+<style>
+</style>

+ 202 - 0
src/views/admin/oss/AdminStoreObject.vue

@@ -0,0 +1,202 @@
+<template>
+  <el-container>
+    <el-header height="220">
+      <h3>对象列表</h3>
+    </el-header>
+    <el-main>
+      <el-table
+        :data="dataList"
+        border
+        height="480"
+        style="width: 100%"
+      >
+        <el-table-column
+          fixed="left"
+          label="No"
+          type="index"
+        />
+        <el-table-column
+          prop="nodeAddr"
+          label="地址"
+        />
+        <el-table-column
+          prop="httpPort"
+          label="HTTP 端口"
+        />
+        <el-table-column
+          prop="rpcPort"
+          label="RPC 端口"
+        />
+        <el-table-column
+          prop="total"
+          label="存储空间"
+        >
+          <template slot-scope="scope">
+            <el-progress :percentage="scope.row.percent"></el-progress>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="status"
+          label="状态"
+        />
+        <el-table-column
+          fixed="right"
+          label="操作"
+          width="280"
+        >
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              @click="handleEdit(scope.$index, scope.row)"
+            >磁盘详情</el-button>
+            <el-button
+              size="mini"
+              @click="handleEdit(scope.$index, scope.row)"
+            >禁用</el-button>
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleDelete(scope.$index, scope.row)"
+            >删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-main>
+
+    <!-- 修改视频可见范围对话框 -->
+    <el-dialog
+      append-to-body
+      :visible.sync="showEditScopeDialog"
+      center
+    >
+      <div>
+        <h3>存储节点磁盘详情</h3>
+        <el-table
+          :data="tableList"
+          border
+          height="480"
+          style="width: 100%"
+        >
+          <el-table-column
+            fixed="left"
+            label="No"
+            type="index"
+          />
+          <el-table-column
+            prop="fsType"
+            label="文件系统"
+          />
+          <el-table-column
+            prop="volume"
+            label="磁盘分区"
+          />
+          <el-table-column
+            prop="storeDir"
+            label="存储目录"
+          />
+          <el-table-column
+            prop="total"
+            label="分区容量"
+          >
+            <template slot-scope="scope">
+              <el-progress :percentage="scope.row.percent"></el-progress>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="totalInode"
+            label="inode 容量"
+          >
+            <template slot-scope="scope">
+              <el-progress :percentage="scope.row.percentInode"></el-progress>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </el-dialog>
+  </el-container>
+</template>
+
+<script>
+import { getStoreDisks, getStoreList } from '@/api/oss'
+
+export default {
+  name: 'AdminStoreObject',
+  data() {
+    return {
+      queryInfo: {
+        path: null
+      },
+      // 屏幕宽度, 为了控制分页条的大小
+      screenWidth: document.body.clientWidth,
+      currentPage: 1,
+      pageSize: 12,
+      totalSize: 0,
+      dataList: [],
+      tableList: [],
+      nextId: 0,
+      // **********************************************************************
+      showEditScopeDialog: false,
+      form: {
+        videoId: null,
+        scope: 1
+      }
+    }
+  },
+  created() {
+    document.title = '存储节点'
+    this.getData()
+  },
+  methods: {
+    getData() {
+      this.dataList = []
+      getStoreList().then(resp => {
+        if (resp.code === 0) {
+          this.dataList = resp.data
+        }
+      })
+    },
+    onRefresh() {
+      this.getData()
+    },
+    handleCurrentChange(pageNumber) {
+      this.currentPage = pageNumber
+      this.getData()
+      // 回到顶部
+      scrollTo(0, 0)
+    },
+    handleEdit(index, row) {
+      this.showEditScopeDialog = true
+      getStoreDisks((row.id)).then(resp => {
+        if (resp.code === 0) {
+          this.tableList = resp.data
+        }
+      })
+    },
+    handleDelete(index, row) {
+      this.$confirm('确定要删除 ' + row.title + '?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.$message.info('handleDelete')
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消'
+        })
+      })
+    },
+    onUpdateScope() {
+      this.showEditScopeDialog = false
+    },
+    onSelectChange() {
+      this.dataList = []
+    },
+    handleClose() {
+    }
+  }
+}
+</script>
+
+<style>
+</style>

+ 183 - 0
src/views/admin/oss/AdminUploadChannel.vue

@@ -0,0 +1,183 @@
+<template>
+  <el-container>
+    <el-header height="220">
+      <h3>上传通道</h3>
+      <el-row style="margin-top: 10px">
+        <el-button type="plain" icon="el-icon-plus" @click="onAddChannel">添加</el-button>
+        <el-select
+          v-model="selectedValue"
+          style="margin-left: 5px"
+          @change="onSelectChange"
+        >
+          <el-option v-for="(item, index) in tableList" :key="index" :label="item.label" :value="item.value" />
+        </el-select>
+      </el-row>
+    </el-header>
+    <el-main>
+      <el-table
+        :data="dataList"
+        border
+        height="480"
+        style="width: 100%"
+      >
+        <el-table-column
+          fixed="left"
+          label="No"
+          type="index"
+        />
+        <el-table-column
+          prop="channelCode"
+          label="通道代码"
+        />
+        <el-table-column
+          prop="prefix"
+          label="URL 前缀"
+        />
+        <el-table-column
+          prop="maxSize"
+          label="可上传最大文件"
+        />
+        <el-table-column
+          prop="fileType"
+          label="可上传文件类型"
+        />
+        <el-table-column
+          prop="scope"
+          label="可见范围"
+        />
+        <el-table-column
+          prop="enabled"
+          label="状态"
+        >
+          <template slot-scope="scope">
+            <el-tag v-if="scope.row.enabled" :type="'success'" disable-transitions>读写</el-tag>
+            <el-tag v-else :type="'warning'" disable-transitions>只读</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column
+          fixed="right"
+          label="操作"
+          width="280"
+        >
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              @click="handleEdit(scope.$index, scope.row)"
+            >禁用</el-button>
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleDelete(scope.$index, scope.row)"
+            >删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-main>
+
+    <!-- 修改视频可见范围对话框 -->
+    <el-dialog
+      append-to-body
+      :visible.sync="showEditScopeDialog"
+      width="30%"
+      center
+    />
+  </el-container>
+</template>
+
+<script>
+import { getChannelList, getUserNodeKeyValue } from '@/api/oss'
+
+export default {
+  name: 'AdminUploadChannel',
+  data() {
+    return {
+      selectedValue: null,
+      // 屏幕宽度, 为了控制分页条的大小
+      screenWidth: document.body.clientWidth,
+      currentPage: 1,
+      pageSize: 12,
+      totalSize: 0,
+      dataList: [],
+      nextId: 0,
+      tableList: [],
+      // **********************************************************************
+      showEditScopeDialog: false,
+      form: {
+        videoId: null,
+        scope: 1
+      }
+    }
+  },
+  created() {
+    document.title = '上传通道'
+    this.getData()
+  },
+  methods: {
+    getData() {
+      this.tableList = []
+      getUserNodeKeyValue().then(resp => {
+        if (resp.code === 0) {
+          this.tableList = resp.data
+
+          this.selectedValue = this.tableList[0].value
+          this.dataList = []
+          getChannelList(this.selectedValue).then(resp => {
+            if (resp.code === 0) {
+              this.dataList = resp.data
+            }
+          })
+        }
+      })
+    },
+    onRefresh() {
+      this.getData()
+    },
+    handleCurrentChange(pageNumber) {
+      this.currentPage = pageNumber
+      this.getData()
+      // 回到顶部
+      scrollTo(0, 0)
+    },
+    handleEdit(index, row) {
+      this.$message.info('handleEdit')
+    },
+    handleDelete(index, row) {
+      this.$confirm('确定要删除 ' + row.title + '?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.$message.info('handleDelete')
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消'
+        })
+      })
+    },
+    onUpdateScope() {
+      this.showEditScopeDialog = false
+    },
+    onSelectChange() {
+      if (this.selectedValue === null) {
+        return
+      }
+
+      this.dataList = []
+      getChannelList(this.selectedValue).then(resp => {
+        if (resp.code === 0) {
+          this.dataList = resp.data
+        }
+      })
+    },
+    handleClose() {
+    },
+    onAddChannel() {
+      this.$message.info('add channel')
+    }
+  }
+}
+</script>
+
+<style>
+</style>

+ 203 - 0
src/views/admin/oss/AdminUserNode.vue

@@ -0,0 +1,203 @@
+<template>
+  <el-container>
+    <el-header height="220">
+      <h3>我的节点</h3>
+      <el-button type="text">添加节点</el-button>
+      <el-button type="text" @click="onShowKeyDialog">凭证列表</el-button>
+    </el-header>
+    <el-main>
+      <el-table
+        :data="dataList"
+        border
+        height="480"
+        style="width: 100%"
+      >
+        <el-table-column
+          fixed="left"
+          label="No"
+          type="index"
+        />
+        <el-table-column
+          prop="storeNodeAddr"
+          label="节点地址"
+        />
+        <el-table-column
+          prop="userNodeDomain"
+          label="节点域名"
+        />
+        <el-table-column
+          prop="referer"
+          label="Referer"
+        />
+        <el-table-column
+          prop="secretKey"
+          label="SecretKey"
+        />
+        <el-table-column
+          fixed="right"
+          label="操作"
+          width="280"
+        >
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              @click="handleEdit(scope.$index, scope.row)"
+            >编辑</el-button>
+            <el-button
+              size="mini"
+              @click="handleEdit(scope.$index, scope.row)"
+            >详情</el-button>
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleDelete(scope.$index, scope.row)"
+            >删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-main>
+
+    <!-- 修改视频可见范围对话框 -->
+    <el-dialog
+      append-to-body
+      :visible.sync="showKeyDialog"
+      center
+    >
+      <el-table
+        :data="tableList"
+        border
+        height="480"
+        style="width: 100%"
+      >
+        <el-table-column
+          fixed="left"
+          label="No"
+          type="index"
+        />
+        <el-table-column
+          prop="accessKeyId"
+          label="AccessKeyId"
+        />
+        <el-table-column
+          prop="accessKeySecret"
+          label="AccessKeySecret"
+        />
+        <el-table-column
+          fixed="right"
+          label="操作"
+        >
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              @click="handleEdit(scope.$index, scope.row)"
+            >复制</el-button>
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleReset(scope.$index, scope.row)"
+            >重置</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+  </el-container>
+</template>
+
+<script>
+import { getUserKeyList, getUserNodeList, resetUserKey } from '@/api/oss'
+
+export default {
+  name: 'AdminUserNode',
+  data() {
+    return {
+      queryInfo: {
+        path: null
+      },
+      // 屏幕宽度, 为了控制分页条的大小
+      screenWidth: document.body.clientWidth,
+      currentPage: 1,
+      pageSize: 12,
+      totalSize: 0,
+      dataList: [],
+      nextId: 0,
+      tableList: [],
+      // **********************************************************************
+      showKeyDialog: false,
+      form: {
+        videoId: null,
+        scope: 1
+      }
+    }
+  },
+  created() {
+    document.title = '我的节点'
+    this.getData()
+  },
+  methods: {
+    getData() {
+      this.dataList = []
+      getUserNodeList().then(resp => {
+        if (resp.code === 0) {
+          this.dataList = resp.data
+        }
+      })
+    },
+    onRefresh() {
+      this.getData()
+    },
+    handleCurrentChange(pageNumber) {
+      this.currentPage = pageNumber
+      this.getData()
+      // 回到顶部
+      scrollTo(0, 0)
+    },
+    handleEdit(index, row) {
+      this.$message.info('handleEdit')
+    },
+    handleDelete(index, row) {
+      this.$confirm('确定要删除 ' + row.title + '?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.$message.info('handleDelete')
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消'
+        })
+      })
+    },
+    handleReset(index, row) {
+      this.$confirm('确定要重置 ' + row.accessKeyId + '?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        resetUserKey().then(resp => {
+          this.$message.info(resp.msg)
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消'
+        })
+      })
+    },
+    onShowKeyDialog() {
+      this.tableList = []
+      getUserKeyList().then(resp => {
+        if (resp.code === 0) {
+          this.tableList = resp.data
+          this.showKeyDialog = true
+        }
+      })
+    },
+    handleClose() {
+    }
+  }
+}
+</script>
+
+<style>
+</style>