|
@@ -109,7 +109,7 @@
|
|
|
type="daterange"
|
|
|
range-separator="至"
|
|
|
start-placeholder="开始日期"
|
|
|
- end-placeholder="结束日期"
|
|
|
+ end-placeholder="结束日��"
|
|
|
value-format="yyyy-MM-dd"
|
|
|
/>
|
|
|
</el-form-item> -->
|
|
@@ -235,66 +235,27 @@
|
|
|
/>
|
|
|
<el-table-column prop="status" label="处理状态" width="100">
|
|
|
<template #default="{ row }">
|
|
|
- <!-- <el-tooltip
|
|
|
- effect="dark"
|
|
|
- placement="top"
|
|
|
- :disabled="
|
|
|
- Number(row.processing_status) !== 1 &&
|
|
|
- Number(row.processing_status) !== 5 &&
|
|
|
- Number(row.processing_status) !== 4
|
|
|
- "
|
|
|
- >
|
|
|
- <template #content>
|
|
|
- <div style="padding: 5px">
|
|
|
- <div style="margin-top: 5px; font-size: 12px">
|
|
|
- {{ row.progress_msg || "正在处理中..." }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <div class="status-wrapper">
|
|
|
- <template v-if="Number(row.processing_status) === 1 || Number(row.processing_status) === 5">
|
|
|
- <div class="progress-wrapper">
|
|
|
- <el-progress
|
|
|
- type="circle"
|
|
|
- :percentage="Math.floor(row.progress) || 0"
|
|
|
- :width="35"
|
|
|
- :stroke-width="4"
|
|
|
- :format="percentFormat"
|
|
|
-
|
|
|
- ></el-progress>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
- <el-tag :type="getStatusType(row.processing_status)">
|
|
|
- {{ getStatusText(row.processing_status) }}
|
|
|
- </el-tag>
|
|
|
- </template>
|
|
|
- </div>
|
|
|
- </el-tooltip> -->
|
|
|
<el-tooltip
|
|
|
effect="dark"
|
|
|
placement="top"
|
|
|
- :disabled="
|
|
|
- Number(row.processing_status) !== 1 &&
|
|
|
- Number(row.processing_status) !== 5 &&
|
|
|
- Number(row.processing_status) !== 4
|
|
|
- "
|
|
|
+ :disabled="![1, 3, 5].includes(Number(row.processing_status))"
|
|
|
>
|
|
|
<template #content>
|
|
|
<div style="padding: 5px">
|
|
|
<div style="margin-top: 5px; font-size: 12px">
|
|
|
- {{ row.progress_msg || "正在处理中..." }}
|
|
|
+ {{
|
|
|
+ row.progress_msg ||
|
|
|
+ (row.processing_status === 3
|
|
|
+ ? "处理失败"
|
|
|
+ : "正在处理中...")
|
|
|
+ }}
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
<div class="status-wrapper">
|
|
|
<template
|
|
|
- v-if="
|
|
|
- Number(row.processing_status) === 1 ||
|
|
|
- Number(row.processing_status) === 5
|
|
|
- "
|
|
|
+ v-if="[1, 5].includes(Number(row.processing_status))"
|
|
|
>
|
|
|
- <!-- 移除进度条,改为显示文本 -->
|
|
|
<el-tag type="warning">处理中</el-tag>
|
|
|
</template>
|
|
|
<template v-else>
|
|
@@ -368,26 +329,70 @@
|
|
|
</el-tab-pane>
|
|
|
|
|
|
<!-- 添加 SOTA详情 tab -->
|
|
|
- <el-tab-pane label="SOTA详情" name="second">
|
|
|
+ <el-tab-pane label="Outcomes详情" name="second">
|
|
|
+ <!-- 添加搜索表单 -->
|
|
|
+ <div class="search-form">
|
|
|
+ <el-form
|
|
|
+ :inline="true"
|
|
|
+ :model="Sota_searchForm"
|
|
|
+ class="demo-form-inline"
|
|
|
+ label-width="80px"
|
|
|
+ ><el-form-item label="内容:">
|
|
|
+ <el-input
|
|
|
+ style="width: 260px"
|
|
|
+ v-model="Sota_searchForm.keyword"
|
|
|
+ clearable
|
|
|
+ placeholder="请输入文献名称\ID"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button type="primary" @click="handleSotaSearch"
|
|
|
+ >搜索</el-button
|
|
|
+ >
|
|
|
+ <el-button @click="resetSotaSearch" type="danger">重置</el-button>
|
|
|
+ <el-button @click="outExport" type="primary">导出</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
<el-table :data="sotaDetailsList" style="width: 100%">
|
|
|
- <el-table-column label="Identifier" prop="identifier" />
|
|
|
- <el-table-column label="Device" prop="device" />
|
|
|
- <el-table-column label="Outcomes" prop="outcomes" />
|
|
|
- <el-table-column label="Unit for analysis" prop="unit" />
|
|
|
- <el-table-column label="Mean" prop="mean" />
|
|
|
+ <el-table-column label="文献ID" prop="literature_id" />
|
|
|
+ <el-table-column label="文献名称" prop="literature_name" />
|
|
|
+ <!-- <el-table-column label="Identifier" prop="identifier" /> -->
|
|
|
+ <el-table-column label="Outcomes Name" prop="outcome_name" />
|
|
|
+ <el-table-column
|
|
|
+ label="Outcome Definition"
|
|
|
+ prop="outcome_definition"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column label="Group" prop="group"></el-table-column>
|
|
|
+ <el-table-column label="Patient" prop="patient" />
|
|
|
+ <el-table-column label="Outcomes Value" prop="value" />
|
|
|
+ <!-- <el-table-column label="Unit for analysis" prop="unit" /> -->
|
|
|
+ <el-table-column label="创建时间" prop="create_time" />
|
|
|
<!-- 操作列与原有类似 -->
|
|
|
</el-table>
|
|
|
+
|
|
|
+ <!-- 分页器 -->
|
|
|
+ <el-pagination
|
|
|
+ class="pagination"
|
|
|
+ @size-change="handleStoaSizeChange"
|
|
|
+ @current-change="handleStoaCurrentChange"
|
|
|
+ :current-page="Sota_searchForm.page"
|
|
|
+ :page-sizes="[10, 20, 50, 100]"
|
|
|
+ :page-size="Sota_searchForm.page_size"
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
+ :total="Stoa_total"
|
|
|
+ />
|
|
|
</el-tab-pane>
|
|
|
|
|
|
<!-- 添加 SOTA汇总表 tab -->
|
|
|
- <el-tab-pane label="SOTA汇总表" name="third">
|
|
|
+ <!-- <el-tab-pane label="SOTA汇总表" name="third">
|
|
|
<el-table :data="sotaSummaryList" style="width: 100%">
|
|
|
<el-table-column label="Summary" prop="summary" />
|
|
|
<el-table-column label="EqMD" prop="eqmd" />
|
|
|
<el-table-column label="Pain:VAS" prop="painVas" />
|
|
|
- <!-- 操作列与原有类似 -->
|
|
|
+
|
|
|
</el-table>
|
|
|
- </el-tab-pane>
|
|
|
+ </el-tab-pane> -->
|
|
|
</el-tabs>
|
|
|
|
|
|
<!-- 添加标签对话框 -->
|
|
@@ -460,6 +465,8 @@ import {
|
|
|
process_model_regeneration,
|
|
|
categories,
|
|
|
literResult,
|
|
|
+ getSotaDetails,
|
|
|
+ exportOutcoms
|
|
|
} from "@/api/knowledge";
|
|
|
import axios from "axios";
|
|
|
// 状态映射表
|
|
@@ -517,18 +524,26 @@ export default {
|
|
|
1: { text: "处理中", type: "warning" },
|
|
|
2: { text: "处理完成", type: "success" },
|
|
|
3: { text: "处理失败", type: "danger" },
|
|
|
- 4: { text: "处理失败", type: "danger" },
|
|
|
5: { text: "待处理", type: "warning" },
|
|
|
},
|
|
|
multipleSelection: [], // 存储跨页选中的数据
|
|
|
selectedRows: [], // 当前页选中的行
|
|
|
allSelectedRows: new Map(), // 存储所有选中的行
|
|
|
isAllDataSelected: false, // 是否选中所有数据
|
|
|
+
|
|
|
+ /* SOTA搜索 */
|
|
|
+ Sota_searchForm: {
|
|
|
+ page: 1,
|
|
|
+ page_size: 10,
|
|
|
+ keyword: "",
|
|
|
+ },
|
|
|
+ /* SOTA详情 总数 */
|
|
|
+ Stoa_total: 0,
|
|
|
};
|
|
|
},
|
|
|
|
|
|
created() {
|
|
|
- // 使用防抖处理数据加载
|
|
|
+ // 使用抖处理数据加载
|
|
|
this.debouncedFetchGpuList = debounce(this.fetchGpuList, 300);
|
|
|
},
|
|
|
|
|
@@ -546,6 +561,61 @@ export default {
|
|
|
},
|
|
|
},
|
|
|
methods: {
|
|
|
+ /* outcoms导出 */
|
|
|
+ async outExport() {
|
|
|
+ try {
|
|
|
+ // 添加确认对话框
|
|
|
+ await this.$confirm("确认要导出Outcomes数据吗?", "提示", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning",
|
|
|
+ });
|
|
|
+
|
|
|
+ // 准备导出参数
|
|
|
+ const params = {
|
|
|
+ keyword: this.Sota_searchForm.keyword || undefined
|
|
|
+ };
|
|
|
+
|
|
|
+ // 调用导出接口
|
|
|
+ const response = await exportOutcoms(params);
|
|
|
+
|
|
|
+ if (response.status === 200) {
|
|
|
+ const downloadUrl = response.data.data.download_url;
|
|
|
+
|
|
|
+ // 显示下载链接对话框
|
|
|
+ await this.$alert(
|
|
|
+ `<div>
|
|
|
+ <p>导出成功!请点击下方链接下载文件:</p>
|
|
|
+ <p style="word-break: break-all;">
|
|
|
+ <a href="${downloadUrl}" target="_blank">${downloadUrl}</a>
|
|
|
+ </p>
|
|
|
+ <p>您也可以复制链接后在新窗口打开</p>
|
|
|
+ </div>`,
|
|
|
+ "下载链接",
|
|
|
+ {
|
|
|
+ dangerouslyUseHTMLString: true,
|
|
|
+ confirmButtonText: "复制链接",
|
|
|
+ callback: (action) => {
|
|
|
+ if (action === "confirm") {
|
|
|
+ // 复制链接到剪贴板
|
|
|
+ const textarea = document.createElement("textarea");
|
|
|
+ textarea.value = downloadUrl;
|
|
|
+ document.body.appendChild(textarea);
|
|
|
+ textarea.select();
|
|
|
+ document.execCommand("copy");
|
|
|
+ document.body.removeChild(textarea);
|
|
|
+ this.$message.success("链接已复制到剪贴板");
|
|
|
+ }
|
|
|
+ },
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ if (error === "cancel") return;
|
|
|
+ this.$message.error(error.message || "导出失败");
|
|
|
+ console.error("导出错误:", error);
|
|
|
+ }
|
|
|
+ },
|
|
|
// 添加获取分类列表方法
|
|
|
async fetchCategories() {
|
|
|
try {
|
|
@@ -558,7 +628,7 @@ export default {
|
|
|
this.$message.error("获取分类列表失败");
|
|
|
}
|
|
|
},
|
|
|
- // 添加导出处理方法
|
|
|
+ // 修改导出处理方法
|
|
|
async handleExport() {
|
|
|
try {
|
|
|
const ids = this.selectedRows.map((row) => row.id);
|
|
@@ -570,36 +640,43 @@ export default {
|
|
|
type: "warning",
|
|
|
});
|
|
|
|
|
|
- // 调用导出接口
|
|
|
- const response = await axios({
|
|
|
- url: `${process.env.VUE_APP_BASE_API}/literature-data/export/`,
|
|
|
- method: "POST",
|
|
|
- data: { ids },
|
|
|
- responseType: "blob", // 指定响应类型为 blob
|
|
|
- });
|
|
|
+ // 调用导出接口获取下载链接
|
|
|
+ const response = await axios.post(
|
|
|
+ `${process.env.VUE_APP_BASE_API}/literature-data/export/`,
|
|
|
+ { ids }
|
|
|
+ );
|
|
|
|
|
|
- // 创建下载链接
|
|
|
- const blob = new Blob([response.data], {
|
|
|
- type: response.headers["content-type"],
|
|
|
- });
|
|
|
- const url = window.URL.createObjectURL(blob);
|
|
|
- const link = document.createElement("a");
|
|
|
- link.href = url;
|
|
|
-
|
|
|
- // 从响应头获取文件名,如果没有则使用默认名称
|
|
|
- const filename = response.headers["content-disposition"]
|
|
|
- ? decodeURIComponent(
|
|
|
- response.headers["content-disposition"].split("filename=")[1]
|
|
|
- )
|
|
|
- : "文献导出.xlsx";
|
|
|
-
|
|
|
- link.setAttribute("download", filename);
|
|
|
- document.body.appendChild(link);
|
|
|
- link.click();
|
|
|
- document.body.removeChild(link);
|
|
|
- window.URL.revokeObjectURL(url);
|
|
|
-
|
|
|
- this.$message.success("导出成功");
|
|
|
+ if (response.status === 200) {
|
|
|
+ const downloadUrl = response.data.data.data.download_url;
|
|
|
+
|
|
|
+ // 显示下载链接对话框
|
|
|
+ await this.$alert(
|
|
|
+ `<div>
|
|
|
+ <p>导出成功!请点击下方链接下载文件:</p>
|
|
|
+ <p style="word-break: break-all;">
|
|
|
+ <a href="${downloadUrl}" target="_blank">${downloadUrl}</a>
|
|
|
+ </p>
|
|
|
+ <p>您也可以复制链接后在新窗口打开</p>
|
|
|
+ </div>`,
|
|
|
+ "下载链接",
|
|
|
+ {
|
|
|
+ dangerouslyUseHTMLString: true,
|
|
|
+ confirmButtonText: "复制链接",
|
|
|
+ callback: (action) => {
|
|
|
+ if (action === "confirm") {
|
|
|
+ // 复制链接到剪贴板
|
|
|
+ const textarea = document.createElement("textarea");
|
|
|
+ textarea.value = downloadUrl;
|
|
|
+ document.body.appendChild(textarea);
|
|
|
+ textarea.select();
|
|
|
+ document.execCommand("copy");
|
|
|
+ document.body.removeChild(textarea);
|
|
|
+ this.$message.success("链接已复制到剪贴板");
|
|
|
+ }
|
|
|
+ },
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
} catch (error) {
|
|
|
if (error === "cancel") return;
|
|
|
this.$message.error(error.message || "导出失败");
|
|
@@ -1089,7 +1166,7 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
- // 修改 fetchGpuList 方法中的分页处理部分
|
|
|
+ // 修改 fetchGpuList 方法
|
|
|
async fetchGpuList() {
|
|
|
this.isLoading = true;
|
|
|
try {
|
|
@@ -1100,52 +1177,42 @@ export default {
|
|
|
tag_names: this.searchForm.id,
|
|
|
create_time_start: this.searchForm.createTimeRange?.[0] || "",
|
|
|
create_time_end: this.searchForm.createTimeRange?.[1] || "",
|
|
|
- update_time_start: this.searchForm.updateTimeRange?.[0] || "", // 新增
|
|
|
- update_time_end: this.searchForm.updateTimeRange?.[1] || "", // 新增
|
|
|
+ update_time_start: this.searchForm.updateTimeRange?.[0] || "",
|
|
|
+ update_time_end: this.searchForm.updateTimeRange?.[1] || "",
|
|
|
processing_status: this.searchForm.processing_status || null,
|
|
|
};
|
|
|
|
|
|
const response = await axios.post(
|
|
|
`${process.env.VUE_APP_BASE_API}/literature-data/search/`,
|
|
|
- params,
|
|
|
- {
|
|
|
- headers: {
|
|
|
- "Content-Type": "application/json",
|
|
|
- },
|
|
|
- }
|
|
|
+ params
|
|
|
);
|
|
|
|
|
|
if (response.status !== 200) return;
|
|
|
|
|
|
// 更新数据和分页信息
|
|
|
const { list, total, current_page, page_size } = response.data.data;
|
|
|
+
|
|
|
+ // 处理列表数据
|
|
|
this.gpuList = list.map((item) => {
|
|
|
const nameParts = item.name.split(".");
|
|
|
- const processedItem = {
|
|
|
+ return {
|
|
|
...item,
|
|
|
name: nameParts[0],
|
|
|
type: nameParts.length > 1 ? nameParts.pop() : "未知",
|
|
|
+ processing_status: Number(item.processing_status),
|
|
|
};
|
|
|
+ });
|
|
|
|
|
|
- // 检查处理状态,如果是处理中且没有设置轮询,则开始轮询
|
|
|
- if (
|
|
|
- processedItem.processing_status === 1 &&
|
|
|
- !this.pollingTimers[processedItem.id]
|
|
|
- ) {
|
|
|
- this.startPolling(processedItem.id);
|
|
|
- }
|
|
|
- // 如果状态不是处理中,但存在轮询,则停止轮询
|
|
|
- else if (
|
|
|
- processedItem.processing_status !== 1 &&
|
|
|
- this.pollingTimers[processedItem.id]
|
|
|
- ) {
|
|
|
- this.stopPolling(processedItem.id);
|
|
|
- }
|
|
|
+ // 获取需要查询详细状态的文献ID(处理中和处理失败的)
|
|
|
+ const needStatusCheckIds = this.gpuList
|
|
|
+ .filter((item) => [1, 3, 5].includes(Number(item.processing_status)))
|
|
|
+ .map((item) => item.id);
|
|
|
|
|
|
- return processedItem;
|
|
|
- });
|
|
|
+ if (needStatusCheckIds.length > 0) {
|
|
|
+ await this.fetchBatchStatus(needStatusCheckIds);
|
|
|
+ }
|
|
|
|
|
|
- // 确保这些值都是数字类型
|
|
|
+ // 更新分页信息
|
|
|
this.total = parseInt(total);
|
|
|
this.currentPage = parseInt(current_page);
|
|
|
this.pageSize = parseInt(page_size);
|
|
@@ -1156,6 +1223,46 @@ export default {
|
|
|
this.isLoading = false;
|
|
|
}
|
|
|
},
|
|
|
+
|
|
|
+ // 修改批量获取状态的方法
|
|
|
+ async fetchBatchStatus(ids) {
|
|
|
+ try {
|
|
|
+ const statusPromises = ids.map((id) => literResult(id));
|
|
|
+ const responses = await Promise.allSettled(statusPromises);
|
|
|
+
|
|
|
+ responses.forEach((response, index) => {
|
|
|
+ if (
|
|
|
+ response.status === "fulfilled" &&
|
|
|
+ response.value.status === 200
|
|
|
+ ) {
|
|
|
+ const id = ids[index];
|
|
|
+ const item = this.gpuList.find((item) => item.id === id);
|
|
|
+ if (item) {
|
|
|
+ const literatureInfo = response.value.data.data.literature_info;
|
|
|
+ const status = Number(literatureInfo.processing_status);
|
|
|
+
|
|
|
+ // 只更新处理中和处理失败的状态信息
|
|
|
+ if ([1, 3, 5].includes(status)) {
|
|
|
+ this.$set(item, "processing_status", status);
|
|
|
+ this.$set(
|
|
|
+ item,
|
|
|
+ "progress_msg",
|
|
|
+ literatureInfo.status_description
|
|
|
+ );
|
|
|
+
|
|
|
+ // 如果状态是处理中,启动轮询
|
|
|
+ if (status === 1 || status === 5) {
|
|
|
+ this.startPolling(id);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ console.error("批量获取状态失败:", error);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
// 新增:开始轮询
|
|
|
startPolling(id) {
|
|
|
if (this.pollingTimers[id]) return;
|
|
@@ -1166,20 +1273,13 @@ export default {
|
|
|
if (response.status === 200) {
|
|
|
const item = this.gpuList.find((item) => item.id === id);
|
|
|
if (item) {
|
|
|
- // 使用接口返回的状态数据
|
|
|
- const newStatus = Number(
|
|
|
- response.data.data.literature_info.processing_status
|
|
|
- );
|
|
|
-
|
|
|
- /*进度 const newProgress = Number(
|
|
|
- response.data.data.progress_info.calculated_progress.percentage
|
|
|
- ); */
|
|
|
- const newProgressMsg =
|
|
|
- response.data.data.literature_info.status_description;
|
|
|
+ // 获取状态信息
|
|
|
+ const literatureInfo = response.data.data.literature_info;
|
|
|
+ const newStatus = Number(literatureInfo.processing_status);
|
|
|
+ const newProgressMsg = literatureInfo.status_description;
|
|
|
|
|
|
// 更新状态相关数据
|
|
|
this.$set(item, "processing_status", newStatus);
|
|
|
- /* this.$set(item, "progress", newProgress); */
|
|
|
this.$set(item, "progress_msg", newProgressMsg);
|
|
|
|
|
|
// 根据状态处理结果
|
|
@@ -1188,9 +1288,12 @@ export default {
|
|
|
this.$message.success("处理成功");
|
|
|
this.stopPolling(id);
|
|
|
await this.fetchGpuList();
|
|
|
- } else if (newStatus === 4) {
|
|
|
- // 处理失败
|
|
|
- this.$message.error(newProgressMsg || "处理失败");
|
|
|
+ } else if (newStatus === 3) {
|
|
|
+ // 处理失败 - 保存失败原因
|
|
|
+ const failureReason =
|
|
|
+ literatureInfo.status_description || "处理失败";
|
|
|
+ this.$set(item, "progress_msg", failureReason);
|
|
|
+ this.$message.error(failureReason);
|
|
|
this.stopPolling(id);
|
|
|
} else if (newStatus === 1 || newStatus === 5) {
|
|
|
// 继续轮询
|
|
@@ -1252,6 +1355,7 @@ export default {
|
|
|
name: row.name,
|
|
|
tag: JSON.stringify(row.tags),
|
|
|
identifier: row.identifier,
|
|
|
+ type: row.type,
|
|
|
},
|
|
|
});
|
|
|
// 这里可以添加详情处理逻辑
|
|
@@ -1276,14 +1380,41 @@ export default {
|
|
|
async loadSotaDetails() {
|
|
|
try {
|
|
|
// 这里调用API获取SOTA详情数据
|
|
|
- const response = await getSotaDetails();
|
|
|
- this.sotaDetailsList = response.data;
|
|
|
+ const response = await getSotaDetails(this.Sota_searchForm);
|
|
|
+ this.sotaDetailsList = response.data.list;
|
|
|
+ this.Sota_searchForm.page_size = response.data.page_size;
|
|
|
+ this.Sota_searchForm.page = response.data.current_page;
|
|
|
+ this.Stoa_total = response.data.total;
|
|
|
} catch (error) {
|
|
|
/* this.$message.error("获取SOTA详情失败");
|
|
|
console.error(error); */
|
|
|
}
|
|
|
},
|
|
|
|
|
|
+ /* 详情翻页 */
|
|
|
+ async handleStoaSizeChange(val) {
|
|
|
+ this.Sota_searchForm.page_size = val;
|
|
|
+ this.Sota_searchForm.page = 1;
|
|
|
+ await this.loadSotaDetails();
|
|
|
+ },
|
|
|
+
|
|
|
+ /* 详情 */
|
|
|
+ async handleStoaCurrentChange(val) {
|
|
|
+ this.Sota_searchForm.page = val;
|
|
|
+ await this.loadSotaDetails();
|
|
|
+ },
|
|
|
+ /* 详情搜索 */
|
|
|
+ handleSotaSearch() {
|
|
|
+ this.loadSotaDetails();
|
|
|
+ },
|
|
|
+ /* 详情重置 */
|
|
|
+ resetSotaSearch() {
|
|
|
+ this.Sota_searchForm = {
|
|
|
+ keyword: "",
|
|
|
+ };
|
|
|
+ this.loadSotaDetails();
|
|
|
+ },
|
|
|
+
|
|
|
// 加载SOTA汇总表数据
|
|
|
async loadSotaSummary() {
|
|
|
try {
|