mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 04:22:33 +08:00
fix: lint
This commit is contained in:
@@ -21,8 +21,8 @@ type ProcessSignal struct {
|
||||
type ProcessList struct {
|
||||
Page uint `json:"page" form:"page" query:"page"`
|
||||
Limit uint `json:"limit" form:"limit" query:"limit"`
|
||||
Sort string `json:"sort" form:"sort" query:"sort"` // pid, name, cpu, rss, start_time
|
||||
Order string `json:"order" form:"order" query:"order"` // asc, desc
|
||||
Status string `json:"status" form:"status" query:"status"` // R, S, T, I, Z, W, L
|
||||
Sort string `json:"sort" form:"sort" query:"sort" validate:"in:pid,name,cpu,rss,start_time,ppid,num_threads"`
|
||||
Order string `json:"order" form:"order" query:"order" validate:"in:asc,desc"`
|
||||
Status string `json:"status" form:"status" query:"status" validate:"in:R,S,T,I,Z,W,L"`
|
||||
Keyword string `json:"keyword" form:"keyword" query:"keyword"`
|
||||
}
|
||||
|
||||
@@ -75,52 +75,11 @@ func (s *ProcessService) List(w http.ResponseWriter, r *http.Request) {
|
||||
s.sortProcesses(data, req.Sort, req.Order)
|
||||
}
|
||||
|
||||
// 分页 - 使用 int64 避免溢出
|
||||
total := uint(len(data))
|
||||
start := uint64(req.Page-1) * uint64(req.Limit)
|
||||
end := uint64(req.Page) * uint64(req.Limit)
|
||||
|
||||
if start > uint64(total) {
|
||||
data = []types.ProcessData{}
|
||||
} else {
|
||||
if end > uint64(total) {
|
||||
end = uint64(total)
|
||||
}
|
||||
data = data[start:end]
|
||||
}
|
||||
paged, total := Paginate(r, data)
|
||||
|
||||
Success(w, chix.M{
|
||||
"total": total,
|
||||
"items": data,
|
||||
})
|
||||
}
|
||||
|
||||
// sortProcesses 对进程列表进行排序
|
||||
func (s *ProcessService) sortProcesses(data []types.ProcessData, sortBy, order string) {
|
||||
sort.Slice(data, func(i, j int) bool {
|
||||
var less bool
|
||||
switch sortBy {
|
||||
case "pid":
|
||||
less = data[i].PID < data[j].PID
|
||||
case "name":
|
||||
less = strings.ToLower(data[i].Name) < strings.ToLower(data[j].Name)
|
||||
case "cpu":
|
||||
less = data[i].CPU < data[j].CPU
|
||||
case "rss":
|
||||
less = data[i].RSS < data[j].RSS
|
||||
case "start_time":
|
||||
less = data[i].StartTime < data[j].StartTime
|
||||
case "ppid":
|
||||
less = data[i].PPID < data[j].PPID
|
||||
case "num_threads":
|
||||
less = data[i].NumThreads < data[j].NumThreads
|
||||
default:
|
||||
less = data[i].PID < data[j].PID
|
||||
}
|
||||
if order == "desc" {
|
||||
return !less
|
||||
}
|
||||
return less
|
||||
"items": paged,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -186,7 +145,7 @@ func (s *ProcessService) Detail(w http.ResponseWriter, r *http.Request) {
|
||||
Success(w, data)
|
||||
}
|
||||
|
||||
// processProcessBasic 处理进程基本数据(用于列表,减少数据获取)
|
||||
// processProcessBasic 处理进程基本数据(用于列表)
|
||||
func (s *ProcessService) processProcessBasic(proc *process.Process) types.ProcessData {
|
||||
data := types.ProcessData{
|
||||
PID: proc.Pid,
|
||||
@@ -211,6 +170,12 @@ func (s *ProcessService) processProcessBasic(proc *process.Process) types.Proces
|
||||
data.CPU, _ = proc.CPUPercent()
|
||||
if mem, err := proc.MemoryInfo(); err == nil {
|
||||
data.RSS = mem.RSS
|
||||
data.Data = mem.Data
|
||||
data.VMS = mem.VMS
|
||||
data.HWM = mem.HWM
|
||||
data.Stack = mem.Stack
|
||||
data.Locked = mem.Locked
|
||||
data.Swap = mem.Swap
|
||||
}
|
||||
|
||||
return data
|
||||
@@ -220,17 +185,6 @@ func (s *ProcessService) processProcessBasic(proc *process.Process) types.Proces
|
||||
func (s *ProcessService) processProcessFull(proc *process.Process) types.ProcessData {
|
||||
data := s.processProcessBasic(proc)
|
||||
|
||||
// 获取更多内存信息
|
||||
if mem, err := proc.MemoryInfo(); err == nil {
|
||||
data.RSS = mem.RSS
|
||||
data.Data = mem.Data
|
||||
data.VMS = mem.VMS
|
||||
data.HWM = mem.HWM
|
||||
data.Stack = mem.Stack
|
||||
data.Locked = mem.Locked
|
||||
data.Swap = mem.Swap
|
||||
}
|
||||
|
||||
if ioStat, err := proc.IOCounters(); err == nil {
|
||||
data.DiskWrite = ioStat.WriteBytes
|
||||
data.DiskRead = ioStat.ReadBytes
|
||||
@@ -250,3 +204,32 @@ func (s *ProcessService) processProcessFull(proc *process.Process) types.Process
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// sortProcesses 对进程列表进行排序
|
||||
func (s *ProcessService) sortProcesses(data []types.ProcessData, sortBy, order string) {
|
||||
sort.Slice(data, func(i, j int) bool {
|
||||
var less bool
|
||||
switch sortBy {
|
||||
case "pid":
|
||||
less = data[i].PID < data[j].PID
|
||||
case "name":
|
||||
less = strings.ToLower(data[i].Name) < strings.ToLower(data[j].Name)
|
||||
case "cpu":
|
||||
less = data[i].CPU < data[j].CPU
|
||||
case "rss":
|
||||
less = data[i].RSS < data[j].RSS
|
||||
case "start_time":
|
||||
less = data[i].StartTime < data[j].StartTime
|
||||
case "ppid":
|
||||
less = data[i].PPID < data[j].PPID
|
||||
case "num_threads":
|
||||
less = data[i].NumThreads < data[j].NumThreads
|
||||
default:
|
||||
less = data[i].PID < data[j].PID
|
||||
}
|
||||
if order == "desc" {
|
||||
return !less
|
||||
}
|
||||
return less
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { http } from '@/utils'
|
||||
export interface ProcessListParams {
|
||||
page: number
|
||||
limit: number
|
||||
sort?: string // pid, name, cpu, rss, start_time
|
||||
sort?: string // pid, name, cpu, rss, start_time, ppid, num_threads
|
||||
order?: string // asc, desc
|
||||
status?: string // R, S, T, I, Z, W, L
|
||||
keyword?: string
|
||||
@@ -11,8 +11,7 @@ export interface ProcessListParams {
|
||||
|
||||
export default {
|
||||
// 获取进程列表
|
||||
list: (params: ProcessListParams) =>
|
||||
http.Get(`/process`, { params }),
|
||||
list: (params: ProcessListParams) => http.Get(`/process`, { params }),
|
||||
// 获取进程详情
|
||||
detail: (pid: number) => http.Get(`/process/detail`, { params: { pid } }),
|
||||
// 杀死进程 (SIGKILL)
|
||||
|
||||
@@ -39,12 +39,12 @@ const themeStore = useThemeStore()
|
||||
<header
|
||||
:style="`height: ${themeStore.header.height}px`"
|
||||
dark="bg-dark border-0"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
px-15 border-b bg-white flex items-center bc-eee
|
||||
px-15
|
||||
border-b
|
||||
bg-white
|
||||
flex
|
||||
items-center
|
||||
bc-eee
|
||||
>
|
||||
<app-header />
|
||||
</header>
|
||||
|
||||
@@ -638,7 +638,7 @@ if (import.meta.hot) {
|
||||
trigger="hover"
|
||||
>
|
||||
<template #trigger>
|
||||
<n-flex vertical p-20 pl-40 pr-40 flex items-center >
|
||||
<n-flex vertical p-20 pl-40 pr-40 flex items-center>
|
||||
<p>{{ item.path }}</p>
|
||||
<n-progress
|
||||
type="dashboard"
|
||||
@@ -855,7 +855,7 @@ if (import.meta.hot) {
|
||||
>
|
||||
<n-tag>{{ $gettext('Read/Write Latency') }} {{ current.diskRWTime }}ms</n-tag>
|
||||
</n-flex>
|
||||
<n-card :bordered="false" pt-10 h-530 >
|
||||
<n-card :bordered="false" pt-10 h-530>
|
||||
<v-chart class="chart" :option="chartOptions" autoresize />
|
||||
</n-card>
|
||||
</n-flex>
|
||||
|
||||
@@ -100,7 +100,7 @@ const handleTest = async () => {
|
||||
</n-alert>
|
||||
<n-progress v-if="inTest" :percentage="progress" processing />
|
||||
</n-flex>
|
||||
<n-flex vertical pt-40 items-center >
|
||||
<n-flex vertical pt-40 items-center>
|
||||
<div w-800>
|
||||
<n-grid :cols="3">
|
||||
<n-gi>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { NButton, NDataTable, NTag } from 'naive-ui'
|
||||
import type { DataTableSortState, DropdownOption } from 'naive-ui'
|
||||
import { NButton, NDataTable, NTag } from 'naive-ui'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
|
||||
import process, { type ProcessListParams } from '@/api/panel/process'
|
||||
@@ -31,8 +31,8 @@ const SIGNALS = {
|
||||
SIGINT: 2, // 中断 (Ctrl+C)
|
||||
SIGKILL: 9, // 强制终止
|
||||
SIGTERM: 15, // 终止
|
||||
SIGSTOP: 19, // 暂停
|
||||
SIGCONT: 18, // 继续
|
||||
SIGSTOP: 19, // 暂停
|
||||
SIGUSR1: 10, // 用户自定义信号1
|
||||
SIGUSR2: 12 // 用户自定义信号2
|
||||
}
|
||||
@@ -171,25 +171,6 @@ const columns: any = [
|
||||
render(row: any): string {
|
||||
return formatDateTime(row.start_time)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: $gettext('Actions'),
|
||||
key: 'actions',
|
||||
width: 100,
|
||||
hideInExcel: true,
|
||||
render(row: any) {
|
||||
return h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
type: 'error',
|
||||
onClick: () => handleKill(row.pid)
|
||||
},
|
||||
{
|
||||
default: () => $gettext('Kill')
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -277,22 +258,6 @@ const handleSignal = (pid: number, signal: number, signalName: string) => {
|
||||
})
|
||||
}
|
||||
|
||||
// 强制终止进程
|
||||
const handleKill = (pid: number) => {
|
||||
window.$dialog.warning({
|
||||
title: $gettext('Confirm'),
|
||||
content: $gettext('Are you sure you want to kill process %{ pid }?', { pid: pid.toString() }),
|
||||
positiveText: $gettext('Confirm'),
|
||||
negativeText: $gettext('Cancel'),
|
||||
onPositiveClick: () => {
|
||||
useRequest(process.kill(pid)).onSuccess(() => {
|
||||
refresh()
|
||||
window.$message.success($gettext('Process %{ pid } has been killed', { pid: pid.toString() }))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 显示进程详情
|
||||
const handleShowDetail = (pid: number) => {
|
||||
detailLoading.value = true
|
||||
@@ -318,21 +283,9 @@ const handleSorterChange = (sorter: DataTableSortState | DataTableSortState[] |
|
||||
refresh()
|
||||
}
|
||||
|
||||
// 搜索防抖
|
||||
const debouncedSearch = useDebounceFn(() => {
|
||||
page.value = 1
|
||||
refresh()
|
||||
}, 300)
|
||||
|
||||
// 处理搜索输入
|
||||
const handleSearch = () => {
|
||||
debouncedSearch()
|
||||
}
|
||||
|
||||
// 处理状态筛选变化
|
||||
const handleStatusChange = () => {
|
||||
page.value = 1
|
||||
refresh()
|
||||
}
|
||||
|
||||
// 分页获取进程列表
|
||||
@@ -367,11 +320,9 @@ const { loading, data, page, total, pageSize, pageCount, refresh } = usePaginati
|
||||
:placeholder="$gettext('Search by PID or name')"
|
||||
clearable
|
||||
style="width: 250px"
|
||||
@input="handleSearch"
|
||||
@clear="handleSearch"
|
||||
>
|
||||
<template #prefix>
|
||||
<n-icon :component="() => h('span', { class: 'i-mdi-magnify' })" />
|
||||
<the-icon :size="16" icon="mdi:magnify" />
|
||||
</template>
|
||||
</n-input>
|
||||
<n-select
|
||||
@@ -383,11 +334,6 @@ const { loading, data, page, total, pageSize, pageCount, refresh } = usePaginati
|
||||
<n-button @click="refresh" type="primary" ghost>{{ $gettext('Refresh') }}</n-button>
|
||||
</n-flex>
|
||||
|
||||
<!-- 提示信息 -->
|
||||
<n-alert type="info" :show-icon="false">
|
||||
{{ $gettext('Right-click on a process row to send signals (like Windows Task Manager)') }}
|
||||
</n-alert>
|
||||
|
||||
<!-- 进程列表 -->
|
||||
<n-data-table
|
||||
striped
|
||||
@@ -538,4 +484,3 @@ const { loading, data, page, total, pageSize, pageCount, refresh } = usePaginati
|
||||
</n-modal>
|
||||
</n-flex>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -339,7 +339,7 @@ onMounted(() => {
|
||||
</n-form-item>
|
||||
<n-form-item :label="$gettext('Raw Output')">
|
||||
<n-switch v-model:value="createModel.raw" />
|
||||
<span text-gray ml-10 >
|
||||
<span text-gray ml-10>
|
||||
{{ $gettext('Return script output as raw text instead of JSON') }}
|
||||
</span>
|
||||
</n-form-item>
|
||||
@@ -374,7 +374,7 @@ onMounted(() => {
|
||||
</n-form-item>
|
||||
<n-form-item :label="$gettext('Raw Output')">
|
||||
<n-switch v-model:value="editModel.raw" />
|
||||
<span text-gray ml-10 >
|
||||
<span text-gray ml-10>
|
||||
{{ $gettext('Return script output as raw text instead of JSON') }}
|
||||
</span>
|
||||
</n-form-item>
|
||||
|
||||
@@ -201,7 +201,7 @@ const hasArg = (args: string[], arg: string) => {
|
||||
:on-create="onCreateListen"
|
||||
>
|
||||
<template #default="{ value }">
|
||||
<div flex w-full items-center >
|
||||
<div flex w-full items-center>
|
||||
<n-input v-model:value="value.address" clearable />
|
||||
<n-checkbox
|
||||
:checked="hasArg(value.args, 'ssl')"
|
||||
|
||||
Reference in New Issue
Block a user