fix: 调整前端组件样式和修复后端调度器问题

修复操作列按钮宽度计算问题,调整日志详情页标签宽度
优化任务状态选项标签,从"暂停"改为"停用"
移除后端调度器无用导入,添加job_id到日志记录
添加job_id查询参数到任务日志接口
优化前端应用列表页搜索表单和分页样式
修复Pydantic错误消息处理,去除冗余前缀
添加应用模型的前置处理和验证逻辑
This commit is contained in:
zhangtao
2025-10-28 01:35:06 +08:00
parent 780e02b9de
commit 96335b385f
9 changed files with 85 additions and 86 deletions
@@ -82,7 +82,7 @@ const getOperationMaxWidth = () => {
const buttons = item.querySelectorAll(".el-button");
// 获取每行按钮的总宽度
totalWidth = Array.from(buttons).reduce((acc, button: any) => {
return acc + button.scrollWidth + 22; // 每个按钮的宽度加上预留宽度
return acc + button.scrollWidth + 14; // 每个按钮的宽度加上预留宽度
}, 0);
// 获取最大的宽度
@@ -127,7 +127,7 @@
<el-dialog v-model="dialogVisible.visible" :title="dialogVisible.title" @close="handleCloseDialog">
<!-- 详情 -->
<template v-if="dialogVisible.type === 'detail'">
<el-descriptions :column="2" border>
<el-descriptions :column="2" border label-width="120px">
<el-descriptions-item label="日志ID" :span="2">{{ detailFormData.id }}</el-descriptions-item>
<el-descriptions-item label="任务名称" :span="2">{{ detailFormData.job_name }}</el-descriptions-item>
<el-descriptions-item label="任务组名" :span="2">{{ detailFormData.job_group }}</el-descriptions-item>
+2 -2
View File
@@ -24,7 +24,7 @@
style="width: 167.5px"
>
<el-option value="true" label="启用" />
<el-option value="false" label="停" />
<el-option value="false" label="停" />
</el-select>
</el-form-item>
<!-- 时间范围收起状态下隐藏 -->
@@ -521,7 +521,7 @@
max-height="500px"
@change="handlechangeCron"
@close="openCron = false"
></vue3CronPlus>
/>
</el-popover>
</el-form-item>
<!-- 开始日期和结束日期 -->
+45 -77
View File
@@ -2,29 +2,47 @@
<template>
<div class="app-container">
<!-- 顶部搜索和操作区域 -->
<div class="search-container mb-4">
<div class="search-container">
<el-form ref="queryFormRef" :model="queryFormData" :inline="true" label-suffix=":">
<el-form-item prop="name" label="应用名称">
<el-input v-model="queryFormData.name" placeholder="请输入应用名称" clearable style="width: 200px" />
<el-input v-model="queryFormData.name" placeholder="请输入应用名称" clearable/>
</el-form-item>
<el-form-item prop="status" label="状态">
<el-select v-model="queryFormData.status" placeholder="请选择状态" clearable style="width: 120px">
<el-select v-model="queryFormData.status" placeholder="请选择状态" clearable style="width: 170px;">
<el-option label="启用" :value="true" />
<el-option label="停用" :value="false" />
</el-select>
</el-form-item>
<el-form-item prop="creator" label="创建人">
<el-input v-model="queryFormData.creator" placeholder="请输入创建人" clearable style="width: 150px" />
<el-form-item v-if="isExpand" prop="creator" label="创建人">
<UserTableSelect
v-model="queryFormData.creator"
@confirm-click="handleConfirm"
@clear-click="handleQuery"
/>
</el-form-item>
<el-form-item class="search-buttons">
<el-button v-hasPerm="['application:myapp:query']" type="primary" icon="search" @click="handleQuery">查询</el-button>
<el-button v-hasPerm="['application:myapp:query']" icon="refresh" @click="handleResetQuery">重置</el-button>
<!-- 展开/收起 -->
<template v-if="isExpandable">
<el-link class="ml-3" type="primary" underline="never" @click="isExpand = !isExpand">
{{ isExpand ? "收起" : "展开" }}
<el-icon>
<template v-if="isExpand">
<ArrowUp />
</template>
<template v-else>
<ArrowDown />
</template>
</el-icon>
</el-link>
</template>
</el-form-item>
</el-form>
</div>
<!-- 应用卡片展示区域 -->
<el-card shadow="hover" class="app-grid-card">
<el-card shadow="hover" class="app-grid-card" >
<template #header>
<div class="card-header">
<span>应用市场</span>
@@ -35,7 +53,7 @@
</template>
<!-- 应用网格 -->
<div v-loading="loading" class="app-grid">
<div v-loading="loading" class="app-grid" >
<el-card
v-for="app in applicationList"
:key="app.id"
@@ -136,17 +154,14 @@
<!-- 分页区域 -->
<template #footer>
<div class="pagination-container">
<el-pagination
v-model:current-page="queryFormData.page_no"
v-model:page-size="queryFormData.page_size"
:total="total"
:page-sizes="[12, 24, 48]"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
<!-- 使用卡片 footer 样式右对齐无需额外容器 -->
<pagination
v-model:total="total"
v-model:page="queryFormData.page_no"
v-model:limit="queryFormData.page_size"
:page-sizes="[12, 24, 48]"
@pagination="loadApplicationList"
/>
</template>
</el-card>
@@ -232,6 +247,8 @@ const total = ref(0);
const dialogVisible = ref(false);
const dialogType = ref<'create' | 'edit'>('create');
const currentApp = ref<ApplicationInfo | null>(null);
const isExpand = ref(false);
const isExpandable = ref(true);
// 分页查询参数
const queryFormData = reactive<ApplicationPageQuery>({
@@ -256,7 +273,9 @@ const formData = reactive<ApplicationForm>({
// 表单验证规则
const formRules = reactive({
name: [{ required: true, message: "请输入应用名称", trigger: "blur" }],
name: [
{ required: true, message: "请输入应用名称", trigger: "blur" },
{ min: 2, max: 30, message: "长度在 2 到 30 个字符", trigger: "blur" }],
access_url: [
{ required: true, message: "请输入访问地址", trigger: "blur" },
{ type: 'url' as const, message: "请输入正确的URL格式", trigger: "blur" }
@@ -298,6 +317,11 @@ async function handleQuery() {
await loadApplicationList();
}
// 选择创建人后触发查询
function handleConfirm() {
handleQuery();
}
// 重置查询
async function handleResetQuery() {
queryFormRef.value?.resetFields();
@@ -305,19 +329,6 @@ async function handleResetQuery() {
await loadApplicationList();
}
// 分页大小改变
async function handleSizeChange(size: number) {
queryFormData.page_size = size;
queryFormData.page_no = 1;
await loadApplicationList();
}
// 当前页改变
async function handleCurrentChange(page: number) {
queryFormData.page_no = page;
await loadApplicationList();
}
// 创建应用
function handleCreateApp() {
console.log('handleCreateApp');
@@ -465,19 +476,6 @@ onMounted(() => {
</script>
<style lang="scss" scoped>
.app-container {
padding: 20px;
background-color: var(--el-bg-color-page);
min-height: calc(100vh - 84px);
}
.search-container {
background: var(--el-bg-color);
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.app-grid-card {
height: calc(100vh - 200px);
position: relative;
@@ -486,6 +484,8 @@ onMounted(() => {
:deep(.el-card__footer) {
margin-top: auto;
display: flex;
justify-content: flex-end;
}
}
@@ -493,14 +493,11 @@ onMounted(() => {
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 600;
}
.app-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 16px;
padding: 20px 0;
flex: 1;
}
@@ -508,13 +505,6 @@ onMounted(() => {
border: 1px solid var(--el-border-color-lighter);
border-radius: 6px;
transition: all 0.3s ease;
min-height: 180px;
width: 100%;
&:hover {
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
}
.app-card-header-el {
@@ -531,14 +521,6 @@ onMounted(() => {
min-width: 0;
}
.app-avatar-el {
flex-shrink: 0;
}
.app-title-section {
flex: 1;
min-width: 0;
}
.app-name-el {
font-size: 16px;
@@ -551,18 +533,7 @@ onMounted(() => {
text-overflow: ellipsis;
}
.app-status-tag {
margin-top: 2px;
}
.app-menu-btn {
padding: 4px;
color: var(--el-text-color-secondary);
&:hover {
color: var(--el-color-primary);
}
}
.app-card-content {
margin: 12px 0;
@@ -571,8 +542,6 @@ onMounted(() => {
.app-description {
font-size: 14px;
color: var(--el-text-color-regular);
line-height: 1.5;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
@@ -625,7 +594,6 @@ onMounted(() => {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 100%;
}
.app-card-actions {
+1 -1
View File
@@ -154,7 +154,7 @@
<el-dialog v-model="dialogVisible.visible" :title="dialogVisible.title" @close="handleCloseDialog">
<!-- 详情 -->
<template v-if="dialogVisible.type === 'detail'">
<el-descriptions :column="8" border label-width="140px">
<el-descriptions :column="8" border label-width="200px">
<el-descriptions-item label="日志类型" :span="2">
<el-tag :type="formData.type === 1 ? 'success' : 'primary'">
{{ formData.type === 1 ? '登录日志' : '操作日志' }}