Skip to content

Commit

Permalink
Merge pull request TencentBlueKing#1025 from lannoy0523/issue_1020
Browse files Browse the repository at this point in the history
feat:admin后台新增仓库大小统计 TencentBlueKing#1020
  • Loading branch information
owenlxu authored Aug 7, 2023
2 parents de48968 + d0efd6c commit 863874a
Show file tree
Hide file tree
Showing 7 changed files with 340 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
*
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
*
* BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.
*
* A copy of the MIT License is included in this file.
*
*
* Terms of the MIT License:
* ---------------------------------------------------
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of
* the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package com.tencent.bkrepo.opdata.pojo

import com.tencent.bkrepo.common.api.constant.DEFAULT_PAGE_NUMBER
import com.tencent.bkrepo.common.api.constant.DEFAULT_PAGE_SIZE

data class ProjectMetricsOption(
var projectId: String? = null,
val pageNumber: Int = DEFAULT_PAGE_NUMBER,
val pageSize: Int = DEFAULT_PAGE_SIZE
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
*
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
*
* BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.
*
* A copy of the MIT License is included in this file.
*
*
* Terms of the MIT License:
* ---------------------------------------------------
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of
* the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package com.tencent.bkrepo.opdata.controller

import com.tencent.bkrepo.common.api.pojo.Page
import com.tencent.bkrepo.common.api.pojo.Response
import com.tencent.bkrepo.common.security.permission.Principal
import com.tencent.bkrepo.common.security.permission.PrincipalType
import com.tencent.bkrepo.common.service.util.ResponseBuilder
import com.tencent.bkrepo.opdata.model.TProjectMetrics
import com.tencent.bkrepo.opdata.pojo.ProjectMetricsOption
import com.tencent.bkrepo.opdata.service.ProjectMetricsService
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/project/metrics")
@Principal(PrincipalType.ADMIN)
class ProjectController(
private val projectMetricsService: ProjectMetricsService
) {

/**
* 获取项目的统计数据
*/
@GetMapping("/list")
fun getProjectMetrics(
option: ProjectMetricsOption
): Response<Page<TProjectMetrics>> {
return ResponseBuilder.success(projectMetricsService.page(option))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@
package com.tencent.bkrepo.opdata.repository

import com.tencent.bkrepo.opdata.model.TProjectMetrics
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.mongodb.repository.MongoRepository
import org.springframework.stereotype.Repository

@Repository
interface ProjectMetricsRepository : MongoRepository<TProjectMetrics, String>
interface ProjectMetricsRepository : MongoRepository<TProjectMetrics, String>{
fun findByProjectIdOrderByCreatedDateDesc(projectId:String, pageable: Pageable): Page<TProjectMetrics>
fun findAllByOrderByCreatedDateDesc(pageable: Pageable): Page<TProjectMetrics>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
*
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
*
* BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.
*
* A copy of the MIT License is included in this file.
*
*
* Terms of the MIT License:
* ---------------------------------------------------
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of
* the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package com.tencent.bkrepo.opdata.service

import com.tencent.bkrepo.common.api.pojo.Page
import com.tencent.bkrepo.common.mongo.dao.util.Pages
import com.tencent.bkrepo.opdata.model.TProjectMetrics
import com.tencent.bkrepo.opdata.pojo.ProjectMetricsOption
import com.tencent.bkrepo.opdata.repository.ProjectMetricsRepository
import org.springframework.stereotype.Service

@Service
class ProjectMetricsService (
private val projectMetricsRepository: ProjectMetricsRepository
){

fun page(option: ProjectMetricsOption): Page<TProjectMetrics> {
with(option) {
val pageRequest = Pages.ofRequest(pageNumber, pageSize)
val queryResult = if (!projectId.isNullOrEmpty()) {
projectMetricsRepository.findByProjectIdOrderByCreatedDateDesc(projectId!!, pageRequest)
} else {
projectMetricsRepository.findAllByOrderByCreatedDateDesc(pageRequest)
}
return Pages.ofResponse(pageRequest, queryResult.totalElements, queryResult.content)
}
}
}
16 changes: 16 additions & 0 deletions src/frontend/devops-op/src/api/projectMetrics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import request from '@/utils/request'

export const DEFAULT_PAGE_SIZE = 10
const PREFIX = '/opdata/api/project/metrics'

export function queryProjectMetrics(projectId, pageNumber) {
return request({
url: `${PREFIX}/list`,
method: 'get',
params: {
pageNumber: pageNumber,
pageSize: DEFAULT_PAGE_SIZE,
projectId: projectId
}
})
}
7 changes: 7 additions & 0 deletions src/frontend/devops-op/src/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const ROUTER_NAME_PROJECT_SCAN_CONFIGURATIONS = 'ProjectScanConfiguration
export const ROUTER_NAME_FILTER_RULE = 'FilterRule'
export const ROUTER_NAME_JOB = 'Job'
export const ROUTER_NAME_SHED_LOCK = 'Shedlock'
export const ROUTER_NAME_PROJECT_METRICS = 'ProjectMetrics'

Vue.use(Router)

Expand Down Expand Up @@ -143,6 +144,12 @@ export const asyncRoutes = [
name: ROUTER_NAME_FIRST_LEVEL_FOLDER,
meta: { title: '一级目录统计', icon: 'file' },
component: () => import('@/views/node/FirstLevelFolder')
},
{
path: 'projectMetrics',
name: ROUTER_NAME_PROJECT_METRICS,
meta: { title: '仓库大小统计', icon: 'file' },
component: () => import('@/views/node/ProjectMetrics')
}
]
},
Expand Down
163 changes: 163 additions & 0 deletions src/frontend/devops-op/src/views/node/ProjectMetrics.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<template>
<div class="app-container">
<el-form ref="form" :inline="true">
<el-form-item ref="project-form-item" label="项目ID">
<el-autocomplete
v-model="projectId"
class="inline-input"
:fetch-suggestions="queryProjects"
placeholder="请输入项目ID"
size="mini"
@select="selectProject"
>
<template slot-scope="{ item }">
<div>{{ item.name }}</div>
</template>
</el-autocomplete>
</el-form-item>
<el-form-item>
<el-button size="mini" type="primary" @click="queryPage(1)">查询</el-button>
</el-form-item>
</el-form>
<el-table
:data="projectData"
style="width: 100%"
>
<el-table-column type="expand">
<template slot-scope="props">
<el-table
:data="props.row.repoMetrics"
>
<el-table-column
label="仓库名称"
prop="repoName"
/>
<el-table-column
label="数量"
prop="num"
/>
<el-table-column
label="大小"
prop="size"
/>
<el-table-column
label="存储凭据"
prop="credentialsKey"
/>
</el-table>
</template>
</el-table-column>
<el-table-column
prop="projectId"
label="项目ID"
/>
<el-table-column
label="创建时间"
prop="createdDate"
>
<template slot-scope="scope">
<span>{{ formatNormalDate(scope.row.createdDate) }}</span>
</template>
</el-table-column>
<el-table-column
label="节点数"
prop="nodeNum"
/>
<el-table-column
label="容量大小"
prop="capSize"
/>
</el-table>
<div v-if="total>0" style="margin-top:20px">
<el-pagination
:current-page="query.pageNumber"
:page-size="query.pageSize"
layout="total, prev, pager, next, jumper"
:total="total"
@current-change="handleCurrentChange"
/>
</div>
</div>
</template>
<script>
import { queryProjectMetrics } from '@/api/projectMetrics'
import { formatNormalDate } from '@/utils/date'
import { searchProjects } from '@/api/project'
export default {
name: 'ProjectMetrics',
data() {
return {
loading: true,
projectData: [],
projectId: this.$route.query.projectId ? this.$route.query.projectId : '',
total: 0,
query: {
pageNumber: 1,
pageSize: 10
}
}
},
mounted() {
this.onRouteUpdate(this.$route)
},
beforeRouteUpdate(to, from, next) {
this.onRouteUpdate(to)
next()
},
methods: {
queryProjects(queryStr, cb) {
searchProjects(queryStr).then(res => {
this.projects = res.data.records
cb(this.projects)
})
},
selectProject(project) {
this.projectId = project.name
},
handleCurrentChange(val) {
this.currentPage = val
this.queryPage(val)
},
queryPage(pageNum) {
const query = {
pageNumber: String(pageNum)
}
query.projectId = this.projectId
this.$router.push({ path: '/nodes/ProjectMetrics', query: query })
},
onRouteUpdate(route) {
const query = route.query
const projectMetricsQuery = {
pageNumber: String(query.pageNumber ? Number(query.pageNumber) : 1),
projectId: query.projectId ? query.projectId : ''
}
this.$nextTick(() => {
this.queryMetrics(projectMetricsQuery)
})
},
queryMetrics(projectMetricsQuery) {
this.loading = true
let promise = null
promise = queryProjectMetrics(projectMetricsQuery.projectId, projectMetricsQuery.pageNumber)
promise.then(res => {
this.projectData = res.data.records
this.total = res.data.totalRecords
}).catch(_ => {
this.projectData = []
this.total = 0
}).finally(() => {
this.loading = false
})
},
formatNormalDate(data) {
return formatNormalDate(data)
}
}
}
</script>

<style scoped>
</style>

0 comments on commit 863874a

Please sign in to comment.