调整上传数据页轻改版前端实现

This commit is contained in:
wkc
2026-03-25 14:11:54 +08:00
parent 85f4e7bc61
commit ed54b01d26
4 changed files with 87 additions and 492 deletions

View File

@@ -9,6 +9,14 @@
<el-button
size="small"
type="primary"
icon="el-icon-upload2"
:disabled="isProjectTagging || isProjectArchived"
@click="handleOpenBatchUploadDialog"
>
上传流水
</el-button>
<el-button
size="small"
icon="el-icon-view"
:disabled="isReportDisabled"
@click="handleViewReport"
@@ -38,34 +46,6 @@
{{ isProjectArchived ? "项目已归档暂不可上传或拉取数据" : "项目正在进行银行流水打标暂不可上传或拉取数据" }}
</div>
<!-- 上传模块 -->
<div class="upload-section">
<div class="upload-cards">
<div
v-for="card in uploadCards"
:key="card.key"
class="upload-card"
:class="{ 'is-disabled': card.disabled }"
>
<div class="card-icon">
<i :class="card.icon"></i>
</div>
<div class="card-title">{{ card.title }}</div>
<div class="card-desc">{{ card.desc }}</div>
<el-button
size="small"
:type="card.uploaded ? 'primary' : ''"
:icon="card.uploaded ? 'el-icon-view' : 'el-icon-upload2'"
:plain="!card.uploaded"
:disabled="card.disabled"
@click="handleUploadClick(card.key)"
>
{{ card.btnText }}
</el-button>
</div>
</div>
</div>
<!-- 文件上传记录列表 -->
<div class="file-list-section">
<div class="list-toolbar">
@@ -124,47 +104,6 @@
style="margin-top: 16px; text-align: right"
></el-pagination>
</div>
<!-- 数据质量检查
<div class="quality-check-section">
<div class="section-header">
<i class="el-icon-warning-outline warning-icon"></i>
<span>检查结果</span>
</div>
<div class="metrics">
<div v-for="metric in metrics" :key="metric.key" class="metric-card">
<div class="metric-title">{{ metric.title }}</div>
<div class="metric-value" :class="`value-${metric.level}`">
{{ metric.value }}
</div>
<div class="progress-ring-container">
<svg class="progress-ring" viewBox="0 0 32 32">
<circle
class="progress-ring-bg"
cx="16"
cy="16"
r="14"
fill="none"
stroke="#f0f0f0"
stroke-width="4"
/>
<circle
class="progress-ring-progress"
:stroke="getProgressColor(metric.level)"
cx="16"
cy="16"
r="14"
fill="none"
stroke-width="4"
:stroke-dasharray="circumference"
:stroke-dashoffset="getProgressOffset(metric.value)"
stroke-linecap="round"
/>
</svg>
</div>
</div>
</div>
</div> -->
</div>
<el-dialog
@@ -319,7 +258,6 @@
<script>
import {
getUploadStatus,
pullBankInfo,
parseIdCardFile,
batchUploadFiles,
@@ -358,8 +296,6 @@ export default {
activeMenu: "upload",
// 当前菜单标题
currentMenuTitle: "上传数据",
// 圆环周长
circumference: 2 * Math.PI * 14,
pullBankInfoDialogVisible: false,
pullBankInfoLoading: false,
parsingIdCardFile: false,
@@ -368,8 +304,6 @@ export default {
idCardText: "",
dateRange: [],
},
// 上传状态列表
uploadStatusList: [],
// 侧边栏菜单项
menuItems: [
{ key: "upload", label: "上传数据", route: "upload" },
@@ -378,39 +312,6 @@ export default {
{ key: "special", label: "专项排查", route: "special" },
{ key: "detail", label: "流水明细查询", route: "detail" },
],
// 上传卡片
uploadCards: [
{
key: "transaction",
title: "流水导入",
desc: "支持 PDF、CSV、Excel 格式文件上传",
icon: "el-icon-document",
btnText: "上传流水",
uploaded: false,
disabled: false,
},
],
// 质量指标
metrics: [
{
key: "completeness",
title: "数据完整性",
value: "98.5%",
level: "success",
},
{
key: "consistency",
title: "格式一致性",
value: "95.2%",
level: "info",
},
{
key: "continuity",
title: "余额连续性",
value: "92.8%",
level: "info",
},
],
// === 批量上传相关 ===
batchUploadDialogVisible: false,
selectedFiles: [],
@@ -457,22 +358,10 @@ export default {
return ["0", "3"].includes(String(this.projectInfo.projectStatus));
},
},
watch: {
"projectInfo.projectStatus"() {
this.syncUploadCardDisabledState();
},
},
created() {
// 加载初始数据
// this.loadInitialData();
// 监听路由变化更新选中菜单
this.updateActiveMenu();
this.syncUploadCardDisabledState();
},
mounted() {
// 组件挂载后监听项目ID变化
this.$watch("projectId", this.loadInitialData);
// 加载统计数据和文件列表
this.loadStatistics();
this.loadFileList();
@@ -488,76 +377,6 @@ export default {
this.stopPolling();
},
methods: {
/** 加载初始数据 */
async loadInitialData() {
if (!this.projectId) return;
try {
this.loading = true;
const uploadStatusRes = await getUploadStatus(this.projectId);
this.uploadStatusList = uploadStatusRes.data || [];
// 更新上传卡片状态
this.updateUploadCards();
// 模拟更新质量指标实际应从API获取
this.updateQualityMetrics();
} catch (error) {
console.error("加载初始数据失败:", error);
this.$message.error("加载数据失败");
} finally {
this.loading = false;
}
},
/** 更新上传卡片状态 */
updateUploadCards() {
const statusMap = {};
this.uploadStatusList.forEach((item) => {
statusMap[item.uploadType] = item;
});
this.uploadCards.forEach((card) => {
const status = statusMap[card.key.toUpperCase()];
if (status) {
card.uploaded = status.uploaded;
card.btnText = status.uploaded
? "已上传" + card.title.replace("导入", "").replace("上传", "")
: card.btnText;
}
});
this.syncUploadCardDisabledState();
},
syncUploadCardDisabledState() {
this.uploadCards = this.uploadCards.map((card) => {
if (card.key === "transaction") {
return {
...card,
disabled: this.isProjectTagging || this.isProjectArchived,
};
}
return card;
});
},
/** 更新质量指标 */
updateQualityMetrics() {
// 模拟更新质量指标
this.metrics.forEach((metric) => {
if (metric.key === "completeness") {
metric.value = "98.5%";
metric.level = "success";
} else if (metric.key === "consistency") {
metric.value = "95.2%";
metric.level = "info";
} else if (metric.key === "continuity") {
metric.value = "92.8%";
metric.level = "info";
}
});
},
/** 菜单点击 */
handleMenuClick(key, route) {
const menuItem = this.menuItems.find((m) => m.key === key);
@@ -588,24 +407,12 @@ export default {
}
this.$router.push("/maintain/creditInfo");
},
/** 上传卡片点击 */
handleUploadClick(key) {
const card = this.uploadCards.find((c) => c.key === key);
if (!card || card.disabled) return;
if (key === "transaction") {
this.batchUploadDialogVisible = true;
this.selectedFiles = [];
}
},
async loadUploadStatus() {
try {
const res = await getUploadStatus(this.projectId);
this.uploadStatusList = res.data || [];
this.updateUploadCards();
} catch (error) {
console.error("加载上传状态失败:", error);
handleOpenBatchUploadDialog() {
if (this.isProjectTagging || this.isProjectArchived) {
return;
}
this.batchUploadDialogVisible = true;
this.selectedFiles = [];
},
openPullBankInfoDialog() {
this.pullBankInfoDialogVisible = true;
@@ -797,21 +604,6 @@ export default {
this.resetPullBankInfoForm();
this.openPullBankInfoDialog();
},
/** 获取进度条偏移 */
getProgressOffset(value) {
const percentage = parseFloat(value);
return this.circumference * (1 - percentage / 100);
},
/** 获取进度条颜色 */
getProgressColor(level) {
const colorMap = {
success: "#52c41a",
info: "#1890ff",
warning: "#fa8c16",
danger: "#f5222d",
};
return colorMap[level] || "#1890ff";
},
/** 格式化更新时间 */
formatUpdateTime(time) {
if (!time) return "-";
@@ -1233,209 +1025,73 @@ export default {
.content-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
align-items: flex-start;
gap: 16px;
margin-bottom: 16px;
padding: 20px 24px;
border: 1px solid #ebeef5;
border-radius: 12px;
background: linear-gradient(135deg, #fffaf5 0%, #ffffff 58%, #fff4ec 100%);
box-shadow: 0 10px 24px rgba(140, 76, 38, 0.08);
.content-title {
margin: 0;
font-size: 18px;
font-size: 20px;
font-weight: 600;
color: #303133;
line-height: 32px;
}
.header-actions {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 12px;
.el-button {
min-width: 104px;
}
}
}
.tagging-lock-tip {
margin-bottom: 16px;
padding: 12px 16px;
padding: 10px 14px;
color: #ad6800;
background: #fff7e6;
border: 1px solid #ffd591;
border-radius: 6px;
}
// 上传模块
.upload-section {
background: #ffffff;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
padding: 20px;
margin-bottom: 16px;
.upload-cards {
display: flex;
justify-content: center;
.upload-card {
width: 420px;
max-width: 100%;
border: 1px solid #ebeef5;
border-radius: 4px;
padding: 20px 16px;
text-align: center;
transition: all 0.3s;
background-color: #fff;
&:hover {
border-color: #1890ff;
box-shadow: 0 4px 12px rgba(24, 144, 255, 0.15);
}
&.is-disabled {
background-color: #fafafa;
border-color: #ebeef5;
opacity: 0.7;
&:hover {
border-color: #ebeef5;
box-shadow: none;
}
.card-icon,
.card-title,
.card-desc {
color: #c0c4cc;
}
}
.card-icon {
font-size: 32px;
color: #1890ff;
margin-bottom: 12px;
i {
font-size: 32px;
}
}
.card-title {
font-size: 16px;
font-weight: 500;
color: #303133;
margin-bottom: 8px;
}
.card-desc {
font-size: 13px;
color: #909399;
margin-bottom: 16px;
min-height: 36px;
line-height: 1.4;
}
.el-upload {
width: 100%;
}
}
}
}
// 数据质量检查
.quality-check-section {
background: #ffffff;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
padding: 20px;
.section-header {
display: flex;
align-items: center;
margin-bottom: 20px;
.warning-icon {
font-size: 18px;
color: #fa8c16;
margin-right: 8px;
}
span {
font-size: 15px;
font-weight: 500;
color: #303133;
}
}
.metrics {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 32px;
.metric-card {
display: flex;
flex-direction: column;
align-items: center;
padding: 16px;
border: 1px solid #ebeef5;
border-radius: 4px;
background: #fafafa;
.metric-title {
font-size: 14px;
color: #606266;
margin-bottom: 12px;
}
.metric-value {
font-size: 24px;
font-weight: 600;
margin-bottom: 12px;
&.value-success {
color: #52c41a;
}
&.value-info {
color: #1890ff;
}
&.value-warning {
color: #fa8c16;
}
&.value-danger {
color: #f5222d;
}
}
.progress-ring-container {
width: 48px;
height: 48px;
.progress-ring {
width: 48px;
height: 48px;
transform: rotate(-90deg);
.progress-ring-bg {
stroke: #ebeef5;
}
.progress-ring-progress {
transition: stroke-dashoffset 0.5s ease;
}
}
}
}
}
background: #fff8ec;
border: 1px solid #ffe0b2;
border-radius: 10px;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.65);
}
}
// 文件列表区域
.file-list-section {
background: #fff;
border-radius: 4px;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
border: 1px solid #ebeef5;
border-radius: 12px;
padding: 20px 24px 24px;
box-shadow: 0 12px 30px rgba(17, 24, 39, 0.06);
.list-toolbar {
display: flex;
justify-content: flex-end;
align-items: center;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 1px solid #f0f2f5;
}
::v-deep .el-table {
border: 1px solid #f0f2f5;
border-radius: 10px;
overflow: hidden;
}
::v-deep .el-table th {
background: #faf6f2;
color: #5f4b3a;
font-weight: 600;
}
}
@@ -1619,15 +1275,9 @@ export default {
// 响应式
@media (max-width: 1200px) {
.upload-section .upload-cards {
grid-template-columns: repeat(2, 1fr);
.main-content .content-header {
padding: 18px 20px;
}
.quality-check-section .metrics {
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
}
@media (max-width: 768px) {
@@ -1643,14 +1293,11 @@ export default {
flex-direction: column;
align-items: flex-start;
gap: 12px;
}
.upload-section .upload-cards {
grid-template-columns: 1fr;
}
.quality-check-section .metrics {
grid-template-columns: 1fr;
.header-actions {
width: 100%;
justify-content: flex-start;
}
}
.file-list-section .list-toolbar {