Compare commits

..

4 Commits

Author SHA1 Message Date
wxlong
0d2f3411ff Merge branch 'main' of http://8.130.135.159:3000/dubingchen/Lydc_frontend 2025-12-05 11:23:20 +08:00
wxlong
c4c36028d3 20251205优化数据请求逻辑 2025-12-05 11:22:40 +08:00
wxlong
b10c88dbd7 20251205优化数据请求逻辑 2025-12-05 11:12:10 +08:00
wxlong
7140e63b3f 20251205任务数据分配分页 2025-12-05 10:46:19 +08:00
16 changed files with 571 additions and 344 deletions

View File

@@ -12,8 +12,8 @@ module.exports = {
assetsPublicPath: '/', assetsPublicPath: '/',
proxyTable: { proxyTable: {
'/': { '/': {
// target:'http://127.0.0.1:9006/', target:'http://127.0.0.1:9006/',
target:'http://8.130.135.159:9006/', // target:'http://8.130.135.159:9006/',
// target:'http://8.130.135.159:9001/', // target:'http://8.130.135.159:9001/',
// target:'http://127.0.0.1:9001/', // target:'http://127.0.0.1:9001/',
changeOrigin: true, changeOrigin: true,

View File

@@ -1,71 +1,12 @@
<template> <template>
<div id="app"> <div id="app">
<router-view/> <router-view/>
<!-- 全局数据初始化失败提示对话框 -->
<el-dialog
title="数据初始化失败"
:visible.sync="initErrorVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="false"
width="400px"
>
<div style="text-align: center; padding: 20px 0;">
<i class="el-icon-warning" style="font-size: 48px; color: #E6A23C; margin-bottom: 16px;"></i>
<p style="font-size: 16px; color: #606266; margin-bottom: 20px;">{{ initErrorMessage }}</p>
</div>
<div slot="footer" style="text-align: center;">
<el-button type="primary" @click="retryInit" :loading="retrying">重试</el-button>
<el-button @click="goToLogin">返回登录</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
name: 'App', name: 'App'
data() {
return {
retrying: false
}
},
computed: {
initErrorVisible: {
get() {
return !!this.$store.state.initError
},
set(value) {
if (!value) {
this.$store.commit('clearInitError')
}
}
},
initErrorMessage() {
return this.$store.state.initError || '数据初始化失败,请重试'
}
},
methods: {
async retryInit() {
this.retrying = true
this.$store.commit('clearInitError')
const result = await this.$store.dispatch('initTaskData')
this.retrying = false
if (result.success) {
// 初始化成功,刷新当前路由
this.$router.go(0)
} else {
// 初始化失败,显示错误
this.$store.commit('setInitError', result.error)
}
},
goToLogin() {
this.$store.commit('clearInitError')
this.$router.push({ path: '/login' })
}
}
} }
</script> </script>

View File

@@ -34,7 +34,7 @@
background-color="#E8F5E9" background-color="#E8F5E9"
text-color="#2E7D32" text-color="#2E7D32"
active-text-color="#1B5E20" active-text-color="#1B5E20"
router @select="handleMenuSelect"
> >
<template v-for="item in menu"> <template v-for="item in menu">
<el-submenu <el-submenu
@@ -80,6 +80,22 @@ export default {
myname: myname, myname: myname,
}; };
}, },
methods: {
// 处理菜单选择,避免重复导航
handleMenuSelect(index) {
// 如果点击的是当前路径,阻止导航
if (this.$route.path === index) {
return false;
}
// 否则正常导航
this.$router.push({ path: index }).catch(err => {
// 忽略 NavigationDuplicated 错误
if (err.name !== 'NavigationDuplicated') {
console.error('路由导航错误:', err);
}
});
}
},
mounted() { mounted() {
if (sessionStorage.getItem("access-user") == "Leader") { if (sessionStorage.getItem("access-user") == "Leader") {
this.menu = [ this.menu = [

View File

@@ -1759,7 +1759,9 @@ export default {
// if (name != "") { // if (name != "") {
// name = feature.get(name).toString(); // name = feature.get(name).toString();
// } // }
let name = feature.get("_upload_name").toString(); // 安全获取 _upload_name如果不存在则使用空字符串
let uploadName = feature.get("_upload_name");
let name = uploadName != null && uploadName !== undefined ? uploadName.toString() : "";
var styles = { var styles = {
Point: new Style({ Point: new Style({
image: new CircleStyle({ image: new CircleStyle({
@@ -2323,6 +2325,11 @@ export default {
}, },
// 获得历史轨迹 // 获得历史轨迹
chooseTask(id) { chooseTask(id) {
// 检查 taskId 是否有效,避免请求 taskId=NaN
if (!this.listQuery.taskId || isNaN(this.listQuery.taskId)) {
this.$message.info("请先选择任务");
return;
}
api api
.getTaskWorker(this.listQuery) .getTaskWorker(this.listQuery)
.then((res) => { .then((res) => {
@@ -4775,8 +4782,9 @@ export default {
// 从 store 获取数据 // 从 store 获取数据
const taskData = this.$store.state.taskData.selectAll || []; const taskData = this.$store.state.taskData.selectAll || [];
that.taskList = taskData; that.taskList = taskData;
if (that.taskList.length) that.listQuery.taskId = that.taskList[0].id; // 不再自动调用 chooseTask等待用户主动选择任务
that.chooseTask(that.listQuery.taskId); // if (that.taskList.length) that.listQuery.taskId = that.taskList[0].id;
// that.chooseTask(that.listQuery.taskId);
}, },
watch: { watch: {
activeItem: { activeItem: {

View File

@@ -8,8 +8,14 @@
prefix-icon="el-icon-search" prefix-icon="el-icon-search"
clearable clearable
size="small" size="small"
@input="handleSearch" @keyup.enter.native="handleSearch"
></el-input> ></el-input>
<el-button
class="forest-btn search-btn"
size="small"
icon="el-icon-search"
@click="handleSearch"
>搜索</el-button>
</div> </div>
<div class="toolbar-actions"> <div class="toolbar-actions">
<el-button class="forest-btn" size="medium" icon="el-icon-download" @click="openBatchDownloadDialog"> <el-button class="forest-btn" size="medium" icon="el-icon-download" @click="openBatchDownloadDialog">
@@ -98,6 +104,18 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 分页组件 -->
<div class="pagination-container">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
<el-card class="box-card" v-show="tpkCardV"> <el-card class="box-card" v-show="tpkCardV">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span style="float: left; padding: 3px 0; font-size: 16px" <span style="float: left; padding: 3px 0; font-size: 16px"
@@ -734,6 +752,11 @@ export default {
filteredData: [], // 过滤后的数据 filteredData: [], // 过滤后的数据
batchDownloadDialogVisible: false, // 批量下载对话框显示 batchDownloadDialogVisible: false, // 批量下载对话框显示
batchDownloadSelectedTasks: [], // 勾选的任务ID batchDownloadSelectedTasks: [], // 勾选的任务ID
// 分页相关属性
pageNum: 1,
pageSize: 10,
total: 0,
totalPages: 0
}; };
}, },
@@ -771,33 +794,71 @@ export default {
this.$message.success("批量下载请求已发起"); this.$message.success("批量下载请求已发起");
}, },
// 搜索处理方法 // 搜索处理方法 - 搜索时重置到第一页并重新加载数据
handleSearch() { handleSearch() {
if (!this.searchKeyword.trim()) { this.pageNum = 1;
this.filteredData = [...this.tasksData]; this.init();
} else { },
const keyword = this.searchKeyword.toLowerCase(); // 分页大小改变处理
this.filteredData = this.tasksData.filter(item => { handleSizeChange(val) {
return ( this.pageSize = val;
(item.taskName && item.taskName.toLowerCase().includes(keyword)) || this.pageNum = 1;
(item.databaseName && item.databaseName.toLowerCase().includes(keyword)) || this.init();
(item.introduction && item.introduction.toLowerCase().includes(keyword)) },
); // 当前页改变处理
}); handleCurrentChange(val) {
} this.pageNum = val;
this.init();
}, },
// formatter(row, column) { //读取数据库 初始化数据 - 使用分页接口获取数据
// return row.address;
// },
init() { init() {
let that = this; let that = this;
// 从 store 获取数据 // 构建请求参数
const taskData = that.$store.state.taskData.selectTaskHasCreated || []; const params = {
that.tasksData = taskData; pageNum: that.pageNum,
that.filteredData = [...that.tasksData]; // 初始化过滤数据 pageSize: that.pageSize,
that.srcTaskOptions = taskData; keyword: that.searchKeyword && that.searchKeyword.trim() ? that.searchKeyword.trim() : ''
that.destTaskOptions = taskData; };
request({
url: "/task/selectTaskHasCreatedPaginated",
method: "get",
params: params
}).then(function (response) {
if (response.data.success === true) {
const result = response.data.data;
// 从返回的数据结构中提取数据数组和分页信息
that.tasksData = result.data || [];
// 分页信息在 pageInfo 对象中
if (result.pageInfo) {
that.total = result.pageInfo.total || 0;
that.totalPages = result.pageInfo.totalPages || 0;
that.pageNum = result.pageInfo.pageNum || 1;
that.pageSize = result.pageInfo.pageSize || 10;
} else {
// 兼容旧格式(如果 pageInfo 不存在)
that.total = result.total || 0;
that.totalPages = result.totalPages || 0;
that.pageNum = result.pageNum || 1;
that.pageSize = result.pageSize || 10;
}
that.filteredData = [...that.tasksData];
that.srcTaskOptions = that.tasksData;
that.destTaskOptions = that.tasksData;
} else if (response.data.status === "401") {
that.$alert(response.data.message);
that.$router.push({ path: "/login" });
} else {
that.$message.error(response.data.message || "获取数据失败");
}
}).catch(function (error) {
console.error("获取数据失败:", error);
that.$message.error("获取数据失败,请稍后重试");
});
}, },
beforeTpkUpload(file) { beforeTpkUpload(file) {
if (file.type != "tpk") { if (file.type != "tpk") {
@@ -1563,11 +1624,20 @@ export default {
.search-box { .search-box {
flex: 0 0 auto; flex: 0 0 auto;
display: flex;
align-items: center;
gap: 12px;
width: 450px; width: 450px;
} }
:deep(.search-box .el-input) { :deep(.search-box .el-input) {
width: 100%; flex: 1;
}
.search-btn {
flex-shrink: 0;
padding: 0 20px;
min-width: 80px;
} }
.toolbar-actions { .toolbar-actions {
@@ -1600,6 +1670,13 @@ export default {
filter: brightness(1.05); filter: brightness(1.05);
} }
.pagination-container {
display: flex;
justify-content: flex-end;
margin-top: 20px;
padding: 16px 0;
}
#tableStyle { #tableStyle {
margin-bottom: 30px; margin-bottom: 30px;
background: rgba(255, 255, 255, 0.92); background: rgba(255, 255, 255, 0.92);

View File

@@ -11,7 +11,7 @@
text-color="#2E7D32" text-color="#2E7D32"
active-text-color="#1B5E20" active-text-color="#1B5E20"
:default-active="this.$route.path" :default-active="this.$route.path"
router @select="handleMenuSelect"
> >
<el-submenu index="1"> <el-submenu index="1">
<template slot="title"> <template slot="title">
@@ -44,7 +44,22 @@ export default {
data() { data() {
return {}; return {};
}, },
method: {}, methods: {
// 处理菜单选择,避免重复导航
handleMenuSelect(index) {
// 如果点击的是当前路径,阻止导航
if (this.$route.path === index) {
return false;
}
// 否则正常导航
this.$router.push({ path: index }).catch(err => {
// 忽略 NavigationDuplicated 错误
if (err.name !== 'NavigationDuplicated') {
console.error('路由导航错误:', err);
}
});
}
},
}; };
</script> </script>
<style scoped> <style scoped>

View File

@@ -8,8 +8,14 @@
prefix-icon="el-icon-search" prefix-icon="el-icon-search"
clearable clearable
size="small" size="small"
@input="handleSearch" @keyup.enter.native="handleSearch"
></el-input> ></el-input>
<el-button
class="forest-btn-small search-btn"
size="small"
icon="el-icon-search"
@click="handleSearch"
>搜索</el-button>
</div> </div>
<el-table <el-table
@@ -42,11 +48,12 @@
</el-dropdown> </el-dropdown>
</template> </template>
<template slot-scope="scope"> <template slot-scope="scope">
<el-checkbox <el-switch
label="需要分配"
v-model="scope.row.isAllocationOptional" v-model="scope.row.isAllocationOptional"
@change="changeisAllocationOptional(scope.row.id)" active-color="#4CAF50"
></el-checkbox> inactive-color="#E0E0E0"
@change="changeisAllocationOptional(scope.row.id, scope.row)"
></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column min-width="95" filterable label="是否已分配" sortable> <el-table-column min-width="95" filterable label="是否已分配" sortable>
@@ -144,6 +151,18 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 分页组件 -->
<div class="pagination-container">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
<el-dialog <el-dialog
v-dialogDrag v-dialogDrag
@@ -294,52 +313,53 @@ export default {
}, },
], ],
searchKeyword: "", // 搜索关键词 searchKeyword: "", // 搜索关键词
// 分页相关属性
pageNum: 1,
pageSize: 10,
total: 0,
totalPages: 0
}; };
}, },
methods: { methods: {
// 搜索处理方法 // 搜索处理方法 - 搜索时重置到第一页并重新加载数据
handleSearch() { handleSearch() {
this.applyFilter(); this.pageNum = 1;
this.init();
},
// 分页大小改变处理
handleSizeChange(val) {
this.pageSize = val;
this.pageNum = 1;
this.init();
},
// 当前页改变处理
handleCurrentChange(val) {
this.pageNum = val;
this.init();
}, },
// 应用筛选和搜索 // 筛选处理方法 - 筛选时重置到第一页并重新加载数据
applyFilter() {
let filtered = [...this.tasksData];
// 先应用分配状态筛选
if (this.currentFilter === 'need') {
filtered = filtered.filter(item => item.isAllocationOptional === true);
} else if (this.currentFilter === 'notNeed') {
filtered = filtered.filter(item => item.isAllocationOptional === false);
}
// 再应用搜索关键词筛选
if (this.searchKeyword.trim()) {
const keyword = this.searchKeyword.toLowerCase();
filtered = filtered.filter(item => {
return item.taskName && item.taskName.toLowerCase().includes(keyword);
});
}
this.filteredData = filtered;
},
// 筛选处理方法
handleFilter(command) { handleFilter(command) {
this.currentFilter = command; this.currentFilter = command;
this.applyFilter(); this.pageNum = 1;
// 筛选是在前端进行的,因为后端接口不支持分配状态筛选
// 所以需要重新获取数据后应用筛选
this.init();
}, },
// 修改方法参数从index改为taskId // 修改方法参数从index改为taskId
changeisAllocationOptional(taskId) { changeisAllocationOptional(taskId, row) {
let row = this.tasksData.find(item => item.id === taskId);
if (!row) return; if (!row) return;
// 保存原始状态,用于请求失败时恢复
const originalValue = !row.isAllocationOptional;
const newValue = row.isAllocationOptional;
let that = this; let that = this;
let str = row.isAllocationOptional === true let str = newValue === true
? "确认任务需要分配吗" ? "确认任务需要分配吗"
: "确认任务无需分配吗"; : "确认任务无需分配吗";
let res = row.isAllocationOptional === true ? 0 : 1; let res = newValue === true ? 0 : 1;
this.$confirm(str, "提示", {}) this.$confirm(str, "提示", {})
.then(() => { .then(() => {
@@ -353,26 +373,63 @@ export default {
}).then(function (response) { }).then(function (response) {
if (response.data.success == true) { if (response.data.success == true) {
that.$message.success("设置成功"); that.$message.success("设置成功");
// 请求成功,状态已经改变,不需要额外操作
// 重新获取数据以确保状态同步
that.init();
} else if (response.data.status == "401") { } else if (response.data.status == "401") {
// 请求失败,恢复原始状态
row.isAllocationOptional = originalValue;
that.$alert(response.data.message); that.$alert(response.data.message);
that.$router.push({ path: "/login" }); that.$router.push({ path: "/login" });
} else { } else {
// 请求失败,恢复原始状态
row.isAllocationOptional = originalValue;
that.$message.error("设置失败"); that.$message.error("设置失败");
} }
}).catch(function (error) {
// 请求异常,恢复原始状态
row.isAllocationOptional = originalValue;
console.error("设置失败:", error);
that.$message.error("设置失败请稍后重试");
}); });
}) })
.catch(() => { .catch(() => {
// 取消操作,不需要回滚状态 // 用户取消操作,恢复原始状态
row.isAllocationOptional = originalValue;
}); });
}, },
init() { init() {
let that = this; let that = this;
// 从 store 获取数据 // 构建请求参数
const taskData = that.$store.state.taskData.selectTaskHasCreated || []; const params = {
that.tasksData = taskData; pageNum: that.pageNum,
pageSize: that.pageSize,
keyword: that.searchKeyword && that.searchKeyword.trim() ? that.searchKeyword.trim() : ''
};
request({
url: "/task/selectTaskHasCreatedPaginated",
method: "get",
params: params
}).then(function (response) {
if (response.data.success === true) {
const result = response.data.data;
// 从返回的数据结构中提取数据数组和分页信息
that.tasksData = result.data || [];
// 分页信息在 pageInfo 对象中
if (result.pageInfo) {
that.total = result.pageInfo.total || 0;
that.totalPages = result.pageInfo.totalPages || 0;
that.pageNum = result.pageInfo.pageNum || 1;
that.pageSize = result.pageInfo.pageSize || 10;
} else {
// 兼容旧格式(如果 pageInfo 不存在)
that.total = result.total || 0;
that.totalPages = result.totalPages || 0;
that.pageNum = result.pageNum || 1;
that.pageSize = result.pageSize || 10;
}
//0表示需要分配 //0表示需要分配
for (var i = 0; i < that.tasksData.length; i++) { for (var i = 0; i < that.tasksData.length; i++) {
if (that.tasksData[i].isAllocationOptional == 0) { if (that.tasksData[i].isAllocationOptional == 0) {
@@ -386,8 +443,27 @@ export default {
that.tasksData[i].allocated = false; that.tasksData[i].allocated = false;
} }
} }
// 应用当前筛选和搜索
that.applyFilter(); // 应用当前筛选(只应用分配状态筛选,搜索已由后端处理)
let filtered = [...that.tasksData];
if (that.currentFilter === 'need') {
filtered = filtered.filter(item => item.isAllocationOptional === true);
} else if (that.currentFilter === 'notNeed') {
filtered = filtered.filter(item => item.isAllocationOptional === false);
}
that.filteredData = filtered;
} else if (response.data.status === "401") {
that.$alert(response.data.message);
that.$router.push({ path: "/login" });
} else {
that.$message.error(response.data.message || "获取数据失败");
}
}).catch(function (error) {
console.error("获取数据失败:", error);
that.$message.error("获取数据失败请稍后重试");
});
// 获取工作人员列表
request({ request({
url: "/user/all_worker", url: "/user/all_worker",
method: "get", method: "get",
@@ -611,12 +687,21 @@ export default {
.search-box { .search-box {
flex: 0 0 auto; flex: 0 0 auto;
display: flex;
align-items: center;
gap: 12px;
width: 450px; width: 450px;
margin-bottom: 20px; margin-bottom: 20px;
} }
:deep(.search-box .el-input) { :deep(.search-box .el-input) {
width: 100%; flex: 1;
}
.search-btn {
flex-shrink: 0;
padding: 0 20px;
min-width: 80px;
} }
.forest-btn-small { .forest-btn-small {
@@ -657,6 +742,13 @@ export default {
box-shadow: 0 14px 28px rgba(76, 175, 80, 0.12); box-shadow: 0 14px 28px rgba(76, 175, 80, 0.12);
} }
.pagination-container {
display: flex;
justify-content: flex-end;
margin-top: 20px;
padding: 16px 0;
}
:deep(#tableStyle .el-table__header-wrapper th) { :deep(#tableStyle .el-table__header-wrapper th) {
background: linear-gradient(90deg, #e0f0e2, #f2fbf3) !important; background: linear-gradient(90deg, #e0f0e2, #f2fbf3) !important;
color: #1b5e20 !important; color: #1b5e20 !important;
@@ -708,18 +800,34 @@ export default {
transform: translateY(-1px); transform: translateY(-1px);
} }
:deep(#tableStyle .el-checkbox__input.is-checked .el-checkbox__inner) { /* Switch 组件样式 */
:deep(#tableStyle .el-switch.is-checked .el-switch__core) {
background-color: #4caf50 !important; background-color: #4caf50 !important;
border-color: #4caf50 !important; border-color: #4caf50 !important;
} }
:deep(#tableStyle .el-checkbox__inner) { :deep(#tableStyle .el-switch__core) {
border-color: rgba(129, 199, 132, 0.5) !important; border-color: rgba(129, 199, 132, 0.5) !important;
background-color: #e0e0e0 !important;
transition: all 0.3s ease !important;
} }
:deep(#tableStyle .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner) { :deep(#tableStyle .el-switch.is-checked .el-switch__core::after) {
background-color: rgba(76, 175, 80, 0.5) !important; background-color: #ffffff !important;
border-color: rgba(76, 175, 80, 0.5) !important; }
:deep(#tableStyle .el-switch__core::after) {
background-color: #ffffff !important;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15) !important;
}
:deep(#tableStyle .el-switch:hover .el-switch__core) {
border-color: rgba(76, 175, 80, 0.8) !important;
}
:deep(#tableStyle .el-switch.is-checked:hover .el-switch__core) {
background-color: #66bb6a !important;
border-color: #66bb6a !important;
} }
.el-dropdown-link { .el-dropdown-link {

View File

@@ -522,7 +522,7 @@ export default {
border-radius: 20px; border-radius: 20px;
box-shadow: 0 14px 32px rgba(76, 175, 80, 0.12); box-shadow: 0 14px 32px rgba(76, 175, 80, 0.12);
border: 1px solid rgba(129, 199, 132, 0.25); border: 1px solid rgba(129, 199, 132, 0.25);
} }
.toolbar-container { .toolbar-container {
display: flex; display: flex;

View File

@@ -2,7 +2,7 @@
<div id="TPcontainer"> <div id="TPcontainer">
<el-container> <el-container>
<el-aside width="160px" style="text-align: left"> <el-aside width="160px" style="text-align: left">
<el-menu router :default-active="this.$route.path"> <el-menu :default-active="this.$route.path" @select="handleMenuSelect">
<el-submenu index="1"> <el-submenu index="1">
<template slot="title"> <template slot="title">
<i class="el-icon-menu"></i>基础配置</template <i class="el-icon-menu"></i>基础配置</template
@@ -90,6 +90,20 @@ export default {
}; };
}, },
methods: { methods: {
// 处理菜单选择,避免重复导航
handleMenuSelect(index) {
// 如果点击的是当前路径,阻止导航
if (this.$route.path === index) {
return false;
}
// 否则正常导航
this.$router.push({ path: index }).catch(err => {
// 忽略 NavigationDuplicated 错误
if (err.name !== 'NavigationDuplicated') {
console.error('路由导航错误:', err);
}
});
},
initConfig() { initConfig() {
let config1 = sessionStorage["Data"]; let config1 = sessionStorage["Data"];
if (config1) { if (config1) {
@@ -128,7 +142,15 @@ export default {
tables: [], tables: [],
}; };
this.$store.dispatch("updateData", { config: config1 }); this.$store.dispatch("updateData", { config: config1 });
this.$router.push({ path: "/main" }); // 检查当前路径,避免重复导航
if (this.$route.path !== "/main") {
this.$router.push({ path: "/main" }).catch(err => {
// 忽略 NavigationDuplicated 错误
if (err.name !== 'NavigationDuplicated') {
console.error('路由导航错误:', err)
}
})
}
}, },
addTable() { addTable() {
this.$router.push({ this.$router.push({
@@ -252,7 +274,15 @@ export default {
tables: [], tables: [],
}; };
that.$store.dispatch("updateData", { config: config1 }); that.$store.dispatch("updateData", { config: config1 });
that.$router.push({ path: "/main" }); // 检查当前路径,避免重复导航
if (that.$route.path !== "/main") {
that.$router.push({ path: "/main" }).catch(err => {
// 忽略 NavigationDuplicated 错误
if (err.name !== 'NavigationDuplicated') {
console.error('路由导航错误:', err)
}
})
}
that.$notify.success({ that.$notify.success({
title: "提示", title: "提示",
message: "提交成功", message: "提交成功",
@@ -309,7 +339,15 @@ export default {
id: that.id, id: that.id,
}, },
}).then(function (response) { }).then(function (response) {
that.$router.push({ path: "/main" }); // 检查当前路径,避免重复导航
if (that.$route.path !== "/main") {
that.$router.push({ path: "/main" }).catch(err => {
// 忽略 NavigationDuplicated 错误
if (err.name !== 'NavigationDuplicated') {
console.error('路由导航错误:', err)
}
})
}
if (response.data.success) { if (response.data.success) {
that.$alert(response.data.message, "提示", { that.$alert(response.data.message, "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",

View File

@@ -8,8 +8,14 @@
prefix-icon="el-icon-search" prefix-icon="el-icon-search"
clearable clearable
size="small" size="small"
@input="handleSearch" @keyup.enter.native="handleSearch"
></el-input> ></el-input>
<el-button
class="forest-btn search-btn"
size="small"
icon="el-icon-search"
@click="handleSearch"
>搜索</el-button>
</div> </div>
<div class="toolbar-actions"> <div class="toolbar-actions">
<el-button class="forest-btn" size="medium" icon="el-icon-plus" @click="addRow()" <el-button class="forest-btn" size="medium" icon="el-icon-plus" @click="addRow()"
@@ -124,6 +130,18 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 分页组件 -->
<div class="pagination-container">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
<el-dialog <el-dialog
v-dialogDrag v-dialogDrag
class="taskDialog" class="taskDialog"
@@ -276,32 +294,79 @@ export default {
fileList: [], fileList: [],
searchKeyword: "", // 搜索关键词 searchKeyword: "", // 搜索关键词
filteredData: [], // 过滤后的数据 filteredData: [], // 过滤后的数据
// 分页相关属性
pageNum: 1,
pageSize: 10,
total: 0,
totalPages: 0
}; };
}, },
methods: { methods: {
// 搜索处理方法 // 搜索处理方法 - 搜索时重置到第一页并重新加载数据
handleSearch() { handleSearch() {
if (!this.searchKeyword.trim()) { this.pageNum = 1;
this.filteredData = [...this.xmlData]; this.init();
} else { },
const keyword = this.searchKeyword.toLowerCase(); // 分页大小改变处理
this.filteredData = this.xmlData.filter(item => { handleSizeChange(val) {
return ( this.pageSize = val;
(item.taskName && item.taskName.toLowerCase().includes(keyword)) || this.pageNum = 1;
(item.databaseName && item.databaseName.toLowerCase().includes(keyword)) || this.init();
(item.introduction && item.introduction.toLowerCase().includes(keyword)) },
); // 当前页改变处理
}); handleCurrentChange(val) {
} this.pageNum = val;
this.init();
}, },
//读取数据库 初始化xml - 从 store 获取数据 //读取数据库 初始化xml - 使用分页接口获取数据
init() { init() {
let that = this; let that = this;
// 从 store 获取数据 // 构建请求参数
const taskData = that.$store.state.taskData.selectAll || []; const params = {
that.xmlData = taskData; pageNum: that.pageNum,
that.filteredData = [...that.xmlData]; // 初始化过滤数据 pageSize: that.pageSize,
keyword: that.searchKeyword && that.searchKeyword.trim() ? that.searchKeyword.trim() : ''
};
request({
url: "/task/selectAllWithKeywordPaginated",
method: "get",
params: params
}).then(function (response) {
if (response.data.success === true) {
// 解析 data 字段(可能是 JSON 字符串)
let result;
if (typeof response.data.data === 'string') {
try {
result = JSON.parse(response.data.data);
} catch (e) {
console.error("解析数据失败:", e);
that.$message.error("数据格式错误,请稍后重试");
return;
}
} else {
result = response.data.data;
}
// 从返回的数据结构中提取数据数组和分页信息
that.xmlData = result.data || [];
// 分页信息在 pageInfo 对象中
if (result.pageInfo) {
that.total = result.pageInfo.total || 0;
that.totalPages = result.pageInfo.totalPages || 0;
that.pageNum = result.pageInfo.pageNum || 1;
that.pageSize = result.pageInfo.pageSize || 10;
} else {
// 兼容旧格式(如果 pageInfo 不存在)
that.total = result.total || 0;
that.totalPages = result.totalPages || 0;
that.pageNum = result.pageNum || 1;
that.pageSize = result.pageSize || 10;
}
// 处理数据格式转换
for (var i = 0; i < that.xmlData.length; i++) { for (var i = 0; i < that.xmlData.length; i++) {
if (that.xmlData[i].hasCreateTables == 1) { if (that.xmlData[i].hasCreateTables == 1) {
that.xmlData[i].hasCreateTables = true; that.xmlData[i].hasCreateTables = true;
@@ -317,6 +382,18 @@ export default {
that.xmlData[i].isReviewerRestricted = false; that.xmlData[i].isReviewerRestricted = false;
} }
} }
that.filteredData = [...that.xmlData];
} else if (response.data.status === "401") {
that.$alert(response.data.message);
that.$router.push({ path: "/login" });
} else {
that.$message.error(response.data.message || "获取数据失败");
}
}).catch(function (error) {
console.error("获取数据失败:", error);
that.$message.error("获取数据失败,请稍后重试");
});
}, },
// 修改方法参数从index改为id // 修改方法参数从index改为id
changeRestricted(id, val) { changeRestricted(id, val) {
@@ -487,6 +564,7 @@ export default {
title: "提示", title: "提示",
message: "创建成功", message: "创建成功",
}); });
// 重新加载当前页数据
that.init(); that.init();
} else if (response.data.message == "hasCreated") { } else if (response.data.message == "hasCreated") {
that.$confirm("该任务已经创库,是否重新创库?", "提示", { that.$confirm("该任务已经创库,是否重新创库?", "提示", {
@@ -593,7 +671,7 @@ export default {
return; return;
} }
if (!this.xmlform.xmlkey) { if (!this.xmlform.xmlkey) {
that.$alert("请输入数据库名称!", "提示", { this.$alert("请输入数据库名称!", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
}); });
return; return;
@@ -722,11 +800,20 @@ export default {
.search-box { .search-box {
flex: 0 0 auto; flex: 0 0 auto;
display: flex;
align-items: center;
gap: 12px;
width: 450px; width: 450px;
} }
:deep(.search-box .el-input) { :deep(.search-box .el-input) {
width: 100%; flex: 1;
}
.search-btn {
flex-shrink: 0;
padding: 0 20px;
min-width: 80px;
} }
.toolbar-actions { .toolbar-actions {
@@ -961,6 +1048,13 @@ export default {
text-align: right; text-align: right;
margin-top: 12px; margin-top: 12px;
} }
.pagination-container {
display: flex;
justify-content: flex-end;
margin-top: 20px;
padding: 16px 0;
}
</style> </style>
<style> <style>

View File

@@ -74,24 +74,6 @@
<span style="position: fixed; bottom: 10px; left: 10px; color: lightgray" <span style="position: fixed; bottom: 10px; left: 10px; color: lightgray"
>v20251006</span >v20251006</span
> >
<!-- 数据初始化失败提示对话框 -->
<el-dialog
title="数据初始化失败"
:visible.sync="initErrorVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="false"
width="400px"
>
<div style="text-align: center; padding: 20px 0;">
<i class="el-icon-warning" style="font-size: 48px; color: #E6A23C; margin-bottom: 16px;"></i>
<p style="font-size: 16px; color: #606266; margin-bottom: 20px;">{{ initErrorMessage }}</p>
</div>
<div slot="footer" style="text-align: center;">
<el-button type="primary" @click="retryInit" :loading="loading">重试</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
@@ -126,8 +108,6 @@ export default {
}, },
loading: false, loading: false,
pwdType: "password", pwdType: "password",
initErrorVisible: false,
initErrorMessage: "",
}; };
}, },
methods: { methods: {
@@ -159,8 +139,38 @@ export default {
sessionStorage.setItem("access-user", response.data.data.role); sessionStorage.setItem("access-user", response.data.data.role);
sessionStorage.setItem("access-id", response.data.data.id); sessionStorage.setItem("access-id", response.data.data.id);
// 初始化任务数据 // 根据用户角色跳转
that.initTaskData(); that.loading = false;
if (
sessionStorage.getItem("access-user") == "Admin" ||
sessionStorage.getItem("access-user") == "SuperAdmin" ||
sessionStorage.getItem("access-user") == "Leader"
) {
// 检查当前路径,避免重复导航
if (that.$route.path !== "/view") {
that.$router.push({ path: "/view" }).catch(err => {
// 忽略 NavigationDuplicated 错误
if (err.name !== 'NavigationDuplicated') {
console.error('路由导航错误:', err)
}
})
}
} else if (sessionStorage.getItem("access-user") == "Operator") {
// 检查当前路径,避免重复导航
if (that.$route.path !== "/main") {
that.$router.push({ path: "/main" }).catch(err => {
// 忽略 NavigationDuplicated 错误
if (err.name !== 'NavigationDuplicated') {
console.error('路由导航错误:', err)
}
})
}
} else {
that.$notify.error({
title: "提示",
message: "用户不可登录该系统!",
});
}
} else if (response.data.status == "204") { } else if (response.data.status == "204") {
that that
.$confirm("用户信息不完善,是否去完善信息?", "提示", { .$confirm("用户信息不完善,是否去完善信息?", "提示", {
@@ -196,41 +206,6 @@ export default {
toRegister() { toRegister() {
this.$router.push({ path: "/register" }); this.$router.push({ path: "/register" });
}, },
// 初始化任务数据
async initTaskData() {
let that = this;
const result = await store.dispatch('initTaskData');
if (result.success) {
// 初始化成功,根据用户角色跳转
that.loading = false;
if (
sessionStorage.getItem("access-user") == "Admin" ||
sessionStorage.getItem("access-user") == "SuperAdmin" ||
sessionStorage.getItem("access-user") == "Leader"
) {
that.$router.push({ path: "/view" });
} else if (sessionStorage.getItem("access-user") == "Operator") {
that.$router.push({ path: "/main" });
} else {
that.$notify.error({
title: "提示",
message: "用户不可登录该系统!",
});
}
} else {
// 初始化失败,显示错误提示
that.loading = false;
that.initErrorMessage = result.error || "数据初始化失败,请重试";
that.initErrorVisible = true;
}
},
// 重试初始化
retryInit() {
this.initErrorVisible = false;
this.loading = true;
this.initTaskData();
},
}, },
}; };
</script> </script>

View File

@@ -150,72 +150,27 @@ const router = new VueRouter({
routes routes
}) })
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
// 如果目标路径与当前路径相同,直接放行,避免 NavigationDuplicated 错误
if (to.path === from.path) {
next()
return
}
if (to.path.startsWith('/login')) { if (to.path.startsWith('/login')) {
window.sessionStorage.removeItem('access-user') window.sessionStorage.removeItem('access-user')
window.sessionStorage.removeItem('access-id') window.sessionStorage.removeItem('access-id')
// 清除初始化状态
store.commit('setTaskDataInitialized', false)
store.commit('clearInitError')
next() next()
} else if (to.path.startsWith('/register') || to.path.startsWith('/modifypassword') || to.path.startsWith('/forgetpassword') || to.path.startsWith('/addinfo')) { } else if (to.path.startsWith('/register') || to.path.startsWith('/modifypassword') || to.path.startsWith('/forgetpassword') || to.path.startsWith('/addinfo')) {
window.sessionStorage.removeItem('access-user') window.sessionStorage.removeItem('access-user')
window.sessionStorage.removeItem('access-id') window.sessionStorage.removeItem('access-id')
// 清除初始化状态
store.commit('setTaskDataInitialized', false)
store.commit('clearInitError')
next() next()
} else { } else {
let user = window.sessionStorage.getItem('access-user') === '' ? false : window.sessionStorage.getItem('access-user') let user = window.sessionStorage.getItem('access-user') === '' ? false : window.sessionStorage.getItem('access-user')
if (!user) { if (!user) {
next({ path: '/login' }) next({ path: '/login' })
} else { } else {
// 检查数据是否已初始化 // 用户已登录,直接放行
const isInitialized = store.state.taskDataInitialized
const isInitializing = store.state.taskDataInitializing
// 如果数据未初始化且不在初始化中,则进行初始化
if (!isInitialized && !isInitializing) {
try {
const result = await store.dispatch('initTaskData')
if (result.success) {
// 初始化成功,继续路由
next() next()
} else {
// 初始化失败,显示错误提示并阻止路由
store.commit('setInitError', result.error)
// 阻止路由跳转,显示错误对话框
next(false)
}
} catch (error) {
// 初始化异常
store.commit('setInitError', error.message || '初始化失败,请重试')
next(false)
}
} else if (isInitializing) {
// 正在初始化中等待完成最多等待5秒
let waited = 0
const maxWait = 5000
const checkInterval = setInterval(() => {
waited += 100
if (!store.state.taskDataInitializing || waited >= maxWait) {
clearInterval(checkInterval)
if (store.state.taskDataInitialized) {
next()
} else {
if (waited >= maxWait) {
store.commit('setTaskDataInitializing', false)
store.commit('setInitError', '初始化超时,请重试')
} else {
store.commit('setInitError', '初始化失败,请重试')
}
next(false)
}
}
}, 100)
} else {
// 已初始化,继续路由
next()
}
} }
} }
}) })