|
@@ -75,17 +75,19 @@
|
|
|
</div>
|
|
</div>
|
|
|
<div class="lighter-container">
|
|
<div class="lighter-container">
|
|
|
<!-- <div style="padding-bottom: 10px">检索出{{ taskNum }}条任务</div> -->
|
|
<!-- <div style="padding-bottom: 10px">检索出{{ taskNum }}条任务</div> -->
|
|
|
- <el-table
|
|
|
|
|
- table-layout="fixed"
|
|
|
|
|
- row-key="main_id"
|
|
|
|
|
- :data="taskData"
|
|
|
|
|
- class="table"
|
|
|
|
|
- :header-cell-style="headerCellStyle"
|
|
|
|
|
- :row-style="rowStyle"
|
|
|
|
|
- :cell-style="cellStyle"
|
|
|
|
|
- stripe
|
|
|
|
|
- border
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <div class="task-table-wrap" ref="taskTableWrap">
|
|
|
|
|
+ <el-table
|
|
|
|
|
+ table-layout="fixed"
|
|
|
|
|
+ row-key="main_id"
|
|
|
|
|
+ :data="taskData"
|
|
|
|
|
+ class="table"
|
|
|
|
|
+ :height="tableHeight"
|
|
|
|
|
+ :header-cell-style="headerCellStyle"
|
|
|
|
|
+ :row-style="rowStyle"
|
|
|
|
|
+ :cell-style="cellStyle"
|
|
|
|
|
+ stripe
|
|
|
|
|
+ border
|
|
|
|
|
+ >
|
|
|
<el-table-column prop="main_c_name" label="名称" />
|
|
<el-table-column prop="main_c_name" label="名称" />
|
|
|
<el-table-column prop="main_c_user_name" label="用户" />
|
|
<el-table-column prop="main_c_user_name" label="用户" />
|
|
|
<el-table-column prop="main_c_state" label="类型">
|
|
<el-table-column prop="main_c_state" label="类型">
|
|
@@ -132,15 +134,7 @@
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column label="操作" width="420">
|
|
<el-table-column label="操作" width="420">
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
- <el-button
|
|
|
|
|
- type="primary"
|
|
|
|
|
- @click="
|
|
|
|
|
- () => {
|
|
|
|
|
- dialog = true;
|
|
|
|
|
- focusTask = scope.row;
|
|
|
|
|
- }
|
|
|
|
|
- "
|
|
|
|
|
- >
|
|
|
|
|
|
|
+ <el-button type="primary" @click="openTaskDetail(scope.row)">
|
|
|
查看详情
|
|
查看详情
|
|
|
</el-button>
|
|
</el-button>
|
|
|
<el-button
|
|
<el-button
|
|
@@ -180,6 +174,7 @@
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
</el-table>
|
|
</el-table>
|
|
|
|
|
+ </div>
|
|
|
<!-- <div class="between-row pagination-container">
|
|
<!-- <div class="between-row pagination-container">
|
|
|
<div></div>
|
|
<div></div>
|
|
|
<el-pagination
|
|
<el-pagination
|
|
@@ -281,6 +276,12 @@
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
</el-descriptions-item>
|
|
</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item
|
|
|
|
|
+ v-if="focusTask.main_c_state == 3 && taskErrorText(focusTask)"
|
|
|
|
|
+ label="失败详情"
|
|
|
|
|
+ >
|
|
|
|
|
+ <pre class="task-error-detail">{{ taskErrorText(focusTask) }}</pre>
|
|
|
|
|
+ </el-descriptions-item>
|
|
|
</el-descriptions>
|
|
</el-descriptions>
|
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
</div>
|
|
</div>
|
|
@@ -288,7 +289,7 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
-import { getTasks, getCName, executeTask } from "@/api/rwgl";
|
|
|
|
|
|
|
+import { getTasks, getCName, executeTask, getTaskDetail } from "@/api/rwgl";
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
|
data() {
|
|
data() {
|
|
@@ -318,7 +319,7 @@ export default {
|
|
|
dialog: false,
|
|
dialog: false,
|
|
|
page: 1,
|
|
page: 1,
|
|
|
pageSize: 10,
|
|
pageSize: 10,
|
|
|
- tableHeight: 0,
|
|
|
|
|
|
|
+ tableHeight: 420,
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
computed: {
|
|
computed: {
|
|
@@ -386,6 +387,7 @@ export default {
|
|
|
// if(this.taskStatus.length==this.focusTaskStatus.length){
|
|
// if(this.taskStatus.length==this.focusTaskStatus.length){
|
|
|
// this.focusTaskStatus = ["all"]
|
|
// this.focusTaskStatus = ["all"]
|
|
|
// }
|
|
// }
|
|
|
|
|
+ this.$nextTick(() => this.calculateTableHeight());
|
|
|
},
|
|
},
|
|
|
getCheckedStatus() {
|
|
getCheckedStatus() {
|
|
|
if (this.focusTaskStatus.includes("all")) {
|
|
if (this.focusTaskStatus.includes("all")) {
|
|
@@ -436,6 +438,7 @@ export default {
|
|
|
}
|
|
}
|
|
|
this.focusTaskType = Array.from(set);
|
|
this.focusTaskType = Array.from(set);
|
|
|
}
|
|
}
|
|
|
|
|
+ this.$nextTick(() => this.calculateTableHeight());
|
|
|
},
|
|
},
|
|
|
getCheckedType() {
|
|
getCheckedType() {
|
|
|
if (this.focusTaskType.includes("all")) {
|
|
if (this.focusTaskType.includes("all")) {
|
|
@@ -463,6 +466,7 @@ export default {
|
|
|
);
|
|
);
|
|
|
this.taskNum = res.count;
|
|
this.taskNum = res.count;
|
|
|
this.taskData = res.data;
|
|
this.taskData = res.data;
|
|
|
|
|
+ this.calculateTableHeight();
|
|
|
},
|
|
},
|
|
|
timeFormatter(time) {
|
|
timeFormatter(time) {
|
|
|
if (time == null) return "";
|
|
if (time == null) return "";
|
|
@@ -495,16 +499,13 @@ export default {
|
|
|
async runTask(taskId) {
|
|
async runTask(taskId) {
|
|
|
try {
|
|
try {
|
|
|
const res = await executeTask(taskId);
|
|
const res = await executeTask(taskId);
|
|
|
- if (res.code === 200) {
|
|
|
|
|
|
|
+ if (res && (res.code === 200 || res.code === "200")) {
|
|
|
this.$message({
|
|
this.$message({
|
|
|
type: "success",
|
|
type: "success",
|
|
|
message: res.content || "任务已提交,正在后台执行",
|
|
message: res.content || "任务已提交,正在后台执行",
|
|
|
});
|
|
});
|
|
|
- // 先禁用按钮,防止重复点击
|
|
|
|
|
- this.$refs.runTaskBtn.disabled = true;
|
|
|
|
|
- // 刷新任务列表
|
|
|
|
|
|
|
+ // 列表每行各有「运行/重试」按钮,不能使用单一 ref;刷新列表即可反映最新状态
|
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
|
- // 执行成功后,刷新任务列表
|
|
|
|
|
this.pullTaskData(this.page);
|
|
this.pullTaskData(this.page);
|
|
|
}, 300);
|
|
}, 300);
|
|
|
} else {
|
|
} else {
|
|
@@ -527,26 +528,65 @@ export default {
|
|
|
}
|
|
}
|
|
|
return text.substring(0, maxLength) + "…";
|
|
return text.substring(0, maxLength) + "…";
|
|
|
},
|
|
},
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 失败说明:优先 main_c_error_message;否则从 main_c_source_data JSON 的 _qpyzt_task_error 读取。
|
|
|
|
|
+ */
|
|
|
|
|
+ taskErrorText(row) {
|
|
|
|
|
+ if (!row) return "";
|
|
|
|
|
+ const direct =
|
|
|
|
|
+ row.main_c_error_message ??
|
|
|
|
|
+ row.c_error_message ??
|
|
|
|
|
+ row.main_C_error_message ??
|
|
|
|
|
+ "";
|
|
|
|
|
+ if (direct != null && String(direct).trim()) return String(direct).trim();
|
|
|
|
|
+ const raw = row.main_c_source_data;
|
|
|
|
|
+ if (!raw || typeof raw !== "string") return "";
|
|
|
|
|
+ try {
|
|
|
|
|
+ const o = JSON.parse(raw);
|
|
|
|
|
+ const e = o && o._qpyzt_task_error;
|
|
|
|
|
+ if (e != null && String(e).trim()) return String(e).trim();
|
|
|
|
|
+ } catch (_) {
|
|
|
|
|
+ /* ignore */
|
|
|
|
|
+ }
|
|
|
|
|
+ return "";
|
|
|
|
|
+ },
|
|
|
|
|
+ openTaskDetail(row) {
|
|
|
|
|
+ this.dialog = true;
|
|
|
|
|
+ this.focusTask = { ...row };
|
|
|
|
|
+ this.refreshTaskDetailFromServer(row.main_id);
|
|
|
|
|
+ },
|
|
|
|
|
+ async refreshTaskDetailFromServer(taskId) {
|
|
|
|
|
+ if (!taskId) return;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await getTaskDetail(taskId);
|
|
|
|
|
+ if (res && res.code === 200 && res.content) {
|
|
|
|
|
+ const c = res.content;
|
|
|
|
|
+ this.focusTask = {
|
|
|
|
|
+ ...this.focusTask,
|
|
|
|
|
+ main_c_error_message: c.c_error_message ?? this.focusTask.main_c_error_message,
|
|
|
|
|
+ main_c_source_data: c.c_source_data ?? this.focusTask.main_c_source_data,
|
|
|
|
|
+ main_c_comment: c.c_comment ?? this.focusTask.main_c_comment,
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.warn("加载任务详情失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
calculateTableHeight() {
|
|
calculateTableHeight() {
|
|
|
- // 计算表格高度:窗口高度 - header高度 - footer高度 - 页面padding - 其他元素高度
|
|
|
|
|
- const windowHeight = window.innerHeight;
|
|
|
|
|
- const headerHeight = 70; // Header组件高度
|
|
|
|
|
- const footerHeight = 50; // Footer组件高度
|
|
|
|
|
- const pagePadding = 40 * 2; // 页面上下padding
|
|
|
|
|
- const filterAreaHeight = 120; // 筛选条件区域高度
|
|
|
|
|
- const taskCountHeight = 30; // 任务数量文字高度
|
|
|
|
|
- const paginationHeight = 50; // 分页区域高度
|
|
|
|
|
- const containerMargin = 15 * 2; // 容器上下margin
|
|
|
|
|
-
|
|
|
|
|
- this.tableHeight =
|
|
|
|
|
- windowHeight -
|
|
|
|
|
- headerHeight -
|
|
|
|
|
- footerHeight -
|
|
|
|
|
- pagePadding -
|
|
|
|
|
- filterAreaHeight -
|
|
|
|
|
- taskCountHeight -
|
|
|
|
|
- paginationHeight -
|
|
|
|
|
- containerMargin;
|
|
|
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
|
+ const winH = window.innerHeight;
|
|
|
|
|
+ const wrap = this.$refs.taskTableWrap;
|
|
|
|
|
+ let top = 0;
|
|
|
|
|
+ if (wrap && typeof wrap.getBoundingClientRect === "function") {
|
|
|
|
|
+ top = wrap.getBoundingClientRect().top;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ top = 220;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 分页条 + lighter-container 下内边距 + 与视口底部的安全间距
|
|
|
|
|
+ const bottomReserve = 88;
|
|
|
|
|
+ let h = winH - top - bottomReserve;
|
|
|
|
|
+ this.tableHeight = Math.max(240, Math.floor(h));
|
|
|
|
|
+ });
|
|
|
},
|
|
},
|
|
|
},
|
|
},
|
|
|
};
|
|
};
|
|
@@ -594,6 +634,21 @@ export default {
|
|
|
:deep(.el-table__body) {
|
|
:deep(.el-table__body) {
|
|
|
background-color: rgba(0, 0, 0, 0.05);
|
|
background-color: rgba(0, 0, 0, 0.05);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+.task-error-detail {
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ max-height: 360px;
|
|
|
|
|
+ overflow: auto;
|
|
|
|
|
+ white-space: pre-wrap;
|
|
|
|
|
+ word-break: break-word;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ line-height: 1.45;
|
|
|
|
|
+ color: #ffb4b4;
|
|
|
|
|
+ background: rgba(0, 0, 0, 0.35);
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ border: 1px solid rgba(255, 77, 79, 0.35);
|
|
|
|
|
+}
|
|
|
:deep(.el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell) {
|
|
:deep(.el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell) {
|
|
|
background-color: rgba(255, 255, 255, 0.02);
|
|
background-color: rgba(255, 255, 255, 0.02);
|
|
|
}
|
|
}
|
|
@@ -653,8 +708,9 @@ link {
|
|
|
margin-left: 0;
|
|
margin-left: 0;
|
|
|
padding-left: 90px;
|
|
padding-left: 90px;
|
|
|
padding-right: 90px;
|
|
padding-right: 90px;
|
|
|
- // min-height: 80vh
|
|
|
|
|
- height: 100vh;
|
|
|
|
|
|
|
+ /* 用 min-height 避免整页被固定为 100vh 时把分页等内容裁切到视口外 */
|
|
|
|
|
+ min-height: 100vh;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.darkblue-background {
|
|
.darkblue-background {
|
|
@@ -688,6 +744,11 @@ body {
|
|
|
border-radius: 10px;
|
|
border-radius: 10px;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.task-table-wrap {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ min-height: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.task-count {
|
|
.task-count {
|
|
|
margin-bottom: 10px;
|
|
margin-bottom: 10px;
|
|
|
color: #fff;
|
|
color: #fff;
|