Files
ccdi/ruoyi-ui/src/views/ccdiProject/detail.vue

573 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="app-container dpc-detail-container">
<!-- 原页面头部 (已隐藏使用UploadData组件的头部) -->
<div class="detail-header">
<div class="header-left">
<el-button size="small" icon="el-icon-back" @click="handleBack"
>返回</el-button
>
<div class="title-section">
<div class="page-title">
<h2>
{{ projectInfo.projectName }}
</h2>
<el-tag
:type="getStatusType(projectInfo.projectStatus)"
size="small"
>
{{ getStatusLabel(projectInfo.projectStatus) }}
</el-tag>
</div>
<p class="update-time">
最后更新时间{{ formatUpdateTime(projectInfo.updateTime) }}
</p>
</div>
</div>
<div class="header-right">
<el-menu
:default-active="activeTab"
mode="horizontal"
@select="handleMenuSelect"
class="nav-menu"
>
<el-menu-item index="upload">上传数据</el-menu-item>
<el-menu-item index="config">参数配置</el-menu-item>
<el-menu-item index="overview">结果总览</el-menu-item>
<el-menu-item index="special">专项排查</el-menu-item>
<el-menu-item index="detail">流水明细查询</el-menu-item>
</el-menu>
</div>
</div>
<!-- 动态组件渲染区域 -->
<component
:is="currentComponent"
:project-id="projectId"
:project-info="projectInfo"
@menu-change="handleMenuChange"
@data-uploaded="handleDataUploaded"
@name-selected="handleNameSelected"
@generate-report="handleGenerateReport"
@fetch-bank-info="handleFetchBankInfo"
/>
</div>
</template>
<script>
import UploadData from "./components/detail/UploadData";
import ParamConfig from "./components/detail/ParamConfig";
import PreliminaryCheck from "./components/detail/PreliminaryCheck";
import SpecialCheck from "./components/detail/SpecialCheck";
import DetailQuery from "./components/detail/DetailQuery";
import {getProject} from "@/api/ccdiProject";
export default {
name: "ProjectDetail",
components: {
UploadData,
ParamConfig,
PreliminaryCheck,
SpecialCheck,
DetailQuery,
},
data() {
return {
// 当前激活的菜单项索引
activeTab: "upload",
// 当前显示的组件名称
currentComponent: "UploadData",
// 项目ID
projectId: this.$route.params.projectId,
// 项目信息
projectInfo: {
projectId: this.$route.params.projectId,
projectName: "",
projectDesc: "",
createTime: "",
updateTime: "",
startDate: "",
endDate: "",
targetCount: 0,
warningCount: 0,
warningThreshold: 60,
projectStatus: "0",
},
};
},
watch: {
"$route.params.projectId"(newId) {
if (newId) {
this.projectId = newId;
this.projectInfo.projectId = newId;
this.initActiveTabFromRoute();
this.initPageData();
}
},
"$route.query.tab"() {
this.initActiveTabFromRoute();
},
},
created() {
// 初始化页面数据
this.initActiveTabFromRoute();
this.initPageData();
},
methods: {
initActiveTabFromRoute() {
const tab = (this.$route.query && this.$route.query.tab) || "";
const validTabs = ["upload", "config", "overview", "special", "detail"];
const targetTab = validTabs.includes(tab) ? tab : "upload";
this.setActiveTab(targetTab);
},
setActiveTab(index) {
this.activeTab = index;
const componentMap = {
upload: "UploadData",
config: "ParamConfig",
overview: "PreliminaryCheck",
special: "SpecialCheck",
detail: "DetailQuery",
};
this.currentComponent = componentMap[index] || "UploadData";
},
/** 初始化页面数据 */
initPageData() {
// 这里应该从API获取项目详细信息
if (!this.projectId) {
return;
}
this.projectInfo.projectName = "";
this.updatePageTitle();
getProject(this.projectId)
.then((res) => {
const data = res.data || {};
this.projectInfo = {
...this.projectInfo,
...data,
projectId: data.projectId || this.projectId,
projectName: data.projectName || "",
projectDesc: data.projectDesc || data.description || "",
projectStatus: String(
data.projectStatus !== undefined && data.projectStatus !== null
? data.projectStatus
: data.status !== undefined && data.status !== null
? data.status
: this.projectInfo.projectStatus
),
};
this.updatePageTitle();
})
.catch(() => {
this.$message.error("Failed to load project details");
this.updatePageTitle();
});
},
updatePageTitle() {
const title = this.projectInfo.projectName || `ProjectDetail-${this.projectId}`;
this.$route.meta.title = title;
this.$store.dispatch("settings/setTitle", title);
this.$store.dispatch("tagsView/updateVisitedView", {
path: this.$route.path,
title,
});
},
/** 格式化更新时间 */
formatUpdateTime(time) {
if (!time) return "-";
const date = new Date(time);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
/** 模拟项目信息 */
mockProjectInfo() {
// 模拟数据实际应该调用API
this.projectInfo = {
projectId: this.projectId,
projectName: "2024年Q1初核项目",
projectDesc: "第一季度员工异常行为排查",
createTime: "2024-01-01 10:00:00",
updateTime: new Date().toISOString(),
startDate: "2024-01-01",
endDate: "2024-03-31",
targetCount: 500,
warningCount: 15,
warningThreshold: 60,
projectStatus: "0",
};
},
/** 获取状态类型 */
getStatusType(status) {
const statusMap = {
0: "primary", // 进行中
1: "success", // 已完成
2: "info", // 已归档
};
return statusMap[status] || "info";
},
/** 获取状态标签 */
getStatusLabel(status) {
const statusMap = {
0: "进行中",
1: "已完成",
2: "已归档",
};
return statusMap[status] || "未知";
},
/** 标签页切换 */
handleTabChange(tab) {
console.log("切换到标签页:", tab.name);
},
/** 返回列表页 */
handleBack() {
this.$router.push("/ccdiProject");
},
/** 菜单选择事件 */
handleMenuSelect(index) {
console.log("菜单选择:", index);
this.setActiveTab(index);
},
/** UploadData 组件:菜单切换 */
handleMenuChange({ key, route }) {
console.log("切换到菜单:", key, route);
// 直接触发菜单选择
this.handleMenuSelect(route);
},
/** UploadData 组件:数据上传完成 */
handleDataUploaded({ type }) {
console.log("数据上传完成:", type);
this.$message.success(`${type} 数据上传成功`);
},
/** UploadData 组件:名单选择完成 */
handleNameSelected(nameList) {
console.log("名单选择完成:", nameList);
this.$message.success("名单选择成功");
},
/** UploadData 组件:生成报告 */
handleGenerateReport() {
console.log("生成报告");
// this.$message.info("生成报告功能开发中");
},
/** UploadData 组件:拉取本行信息 */
handleFetchBankInfo() {
console.log("拉取本行信息");
this.$message.info("拉取本行信息功能开发中");
},
/** 数据上传完成 */
handleDataUploaded() {
console.log("数据上传完成");
this.$message.success("数据上传成功");
},
/** 刷新页面 */
handleRefresh() {
this.initPageData();
this.$message.success("刷新成功");
},
/** 导出报告 */
handleExport() {
console.log("导出报告");
this.$message.info("报告导出功能开发中");
},
/** 完成项目 */
handleComplete() {
this.$confirm("确定要完成当前项目吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.$message.success("项目已完成");
this.projectInfo.projectStatus = "1";
})
.catch(() => {
this.$message.info("已取消");
});
},
/** 归档项目 */
handleArchive() {
this.$confirm(
"确定要归档当前项目吗?归档后将不能进行修改操作。",
"警告",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
this.$message.success("项目已归档");
this.projectInfo.projectStatus = "2";
})
.catch(() => {
this.$message.info("已取消");
});
},
},
};
</script>
<style lang="scss" scoped>
.dpc-detail-container {
padding: 16px;
background: #f0f2f5;
min-height: calc(100vh - 84px);
}
.detail-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
padding: 16px 20px;
background: #ffffff;
border-radius: 4px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
.header-left {
display: flex;
align-items: flex-start;
gap: 12px;
.el-button {
padding: 8px 12px;
font-size: 13px;
margin-top: 4px;
}
.title-section {
.page-title {
display: flex;
align-items: center;
h2 {
margin: 0 0 4px 0;
font-size: 20px;
font-weight: 500;
color: #303133;
margin-right: 5px;
}
}
.update-time {
margin: 0;
font-size: 13px;
color: #909399;
}
}
}
.header-right {
display: flex;
align-items: center;
.nav-menu {
// 移除默认背景色和边框
background-color: transparent;
border-bottom: none;
// 菜单项基础样式
.el-menu-item,
.el-submenu__title {
font-size: 14px;
color: #606266;
padding: 0 16px;
height: 40px;
line-height: 40px;
border-bottom: 2px solid transparent;
&:hover {
background-color: #f5f7fa;
color: #303133;
}
}
// 子菜单容器高度统一
.el-submenu {
height: 40px;
line-height: 40px;
}
// 激活状态:底部下划线 + 蓝色文字
.el-menu-item.is-active {
color: #1890ff;
border-bottom: 2px solid #1890ff;
background-color: transparent;
}
// 下拉菜单激活状态
.el-submenu.is-active > .el-submenu__title {
color: #1890ff;
border-bottom: 2px solid #1890ff;
}
// 下拉菜单图标
.el-submenu__icon-arrow {
margin-left: 4px;
}
}
}
}
.info-card {
margin-bottom: 16px;
:deep(.el-card__body) {
padding: 20px;
}
}
.info-header {
margin-bottom: 16px;
h3 {
margin: 0;
font-size: 16px;
font-weight: 500;
color: #303133;
}
}
.info-content {
.info-row {
display: flex;
gap: 32px;
margin-bottom: 12px;
&:last-child {
margin-bottom: 0;
}
}
.info-item {
display: flex;
align-items: center;
font-size: 14px;
.label {
color: #606266;
min-width: 100px;
font-weight: 500;
}
.value {
color: #303133;
font-weight: 400;
&.warning-count {
color: #e6a23c;
font-weight: 600;
}
}
}
}
.content-card {
margin-bottom: 16px;
:deep(.el-card__body) {
padding: 0;
.el-tabs {
height: 100%;
.el-tabs__content {
padding: 20px;
}
}
}
}
.action-bar {
display: flex;
justify-content: center;
gap: 12px;
padding: 16px;
background: #ffffff;
border-radius: 4px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
.el-button {
padding: 10px 20px;
i {
margin-right: 4px;
}
}
}
// 响应式设计
@media (max-width: 768px) {
.dpc-detail-container {
padding: 8px;
}
.detail-header {
flex-direction: column;
align-items: flex-start;
gap: 12px;
.header-right {
width: 100%;
margin-top: 12px;
.nav-menu {
width: 100%;
display: flex;
justify-content: flex-start;
.el-menu-item,
.el-submenu {
flex: 1;
text-align: center;
padding: 0 8px;
font-size: 13px;
}
}
}
}
.info-content {
.info-row {
flex-direction: column;
gap: 8px;
.info-item {
.label {
min-width: auto;
}
}
}
}
.action-bar {
flex-wrap: wrap;
.el-button {
width: 100%;
}
}
}
// 下拉菜单弹窗样式
::v-deep .el-menu--popup {
min-width: 140px;
.el-menu-item {
font-size: 14px;
&:hover {
background-color: #f5f7fa;
}
&.is-active {
color: #1890ff;
background-color: #e6f7ff;
}
}
}
</style>