refactor(售后工单页面): 全面优化页面UI与功能体验

1.  api层优化:新增驳回接口,优化提交接口过滤无用参数
2.  页面重构:统一页面布局为左右分栏拖拽面板,替换原有弹窗模式
3.  样式升级:采用类Word文档风格重构所有页面样式,新增中英双语标题
4.  功能新增:添加流程总览组件,新增PDF导出功能,新增驳回操作
5.  交互优化:调整卡片布局与间距,优化空状态提示,统一标签样式
This commit is contained in:
2026-06-24 14:59:23 +08:00
parent 8d2d22de50
commit fc537a1aa6
13 changed files with 1397 additions and 522 deletions

View File

@@ -1,28 +1,31 @@
<template>
<div v-if="enabled" class="section-container">
<div class="section-title">
<span>执行反馈</span>
<span>执行反馈 <span class="en-sub">· Execution Feedback</span></span>
<el-button size="mini" type="text" icon="el-icon-refresh" @click="$emit('refresh')" title="刷新执行反馈"></el-button>
</div>
<div v-if="executeList.length > 0" class="card-grid">
<div v-for="item in executeList" :key="item.relId" class="invoice-card">
<div class="invoice-row">
<span class="invoice-dept">{{ getDeptName(item.deptId) }}</span>
<el-tag v-if="item.executeStatus === 0" type="warning" size="mini">待执行</el-tag>
<div v-for="item in executeList" :key="item.relId" class="opinion-card">
<div class="opinion-card-header">
<div class="opinion-dept">
<span class="opinion-dept-icon"></span>
<span>{{ getDeptName(item.deptId) }}</span>
</div>
<el-tag v-if="item.rejectMark === 1" type="danger" size="mini">已驳回</el-tag>
<el-tag v-else-if="item.rejectMark === 2" type="info" size="mini">已隐藏</el-tag>
<el-tag v-else-if="item.executeStatus === 0" type="warning" size="mini">待执行</el-tag>
<el-tag v-else-if="item.executeStatus === 1" type="success" size="mini">已反馈</el-tag>
</div>
<hr class="invoice-divider" />
<div class="invoice-body">
<div v-if="item.executeResult" class="invoice-content" v-html="item.executeResult"></div>
<div v-else class="invoice-empty">暂无反馈</div>
<div v-if="item.feedbackFile" class="invoice-file">
<div class="opinion-card-body">
<div v-if="item.executeResult" class="opinion-content" v-html="item.executeResult"></div>
<div v-else class="opinion-empty"> No feedback yet · 暂无反馈 </div>
<div v-if="item.feedbackFile" class="opinion-file">
<FileList :ossIds="item.feedbackFile" />
</div>
</div>
<hr class="invoice-divider" />
<div class="invoice-meta">
<span v-if="item.feedbackNo" class="invoice-meta-item"><i class="el-icon-document"></i> {{ item.feedbackNo }}</span>
<span v-if="item.feedbackTime" class="invoice-meta-item"><i class="el-icon-time"></i> {{ parseTime(item.feedbackTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
<div class="opinion-card-footer">
<span v-if="item.feedbackNo" class="opinion-footer-item">{{ item.feedbackNo }}</span>
<span v-if="item.feedbackTime" class="opinion-footer-item">{{ parseTime(item.feedbackTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</div>
</div>
</div>
@@ -75,93 +78,125 @@ export default {
<style scoped>
.section-title {
font-family: 'Georgia', 'Times New Roman', 'Noto Serif SC', 'SimSun', serif;
width: 100%;
font-size: 15px;
font-weight: 600;
color: #1d2129;
margin: 20px 0 12px 0;
font-weight: 700;
color: #1a1a1a;
margin: 32px 0 16px 0;
padding: 0 0 10px 0;
border-bottom: 2px solid transparent;
border-image: linear-gradient(to right, #c0c4cc, transparent) 1;
border-bottom: 1px solid #d4d0c8;
white-space: nowrap;
display: flex;
align-items: center;
gap: 8px;
gap: 10px;
letter-spacing: 0.3px;
}
.section-title:first-child {
margin-top: 0;
}
.section-title .en-sub {
font-size: 11px;
font-weight: 400;
color: #8c8c8c;
letter-spacing: 0.5px;
font-family: 'Georgia', 'Times New Roman', serif;
font-style: italic;
}
.section-title i {
font-size: 16px;
color: #1a3c6e;
}
/* ===== 反馈卡片(正式文档风格) ===== */
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 10px;
gap: 14px;
}
.invoice-card {
flex: 0 0 calc((100% - 20px) / 3);
background: #fff;
border: 1px solid #e8eaec;
border-left: 3px solid #409eff;
.opinion-card {
flex: 0 0 calc((100% - 14px) / 2);
background: #ffffff;
border: 1px solid #e8e4de;
border-radius: 2px;
padding: 10px 12px 8px;
padding: 14px 16px 12px;
display: flex;
flex-direction: column;
}
.invoice-row {
.opinion-card-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 6px;
margin-bottom: 10px;
padding-bottom: 8px;
border-bottom: 1px dashed #e0dcd6;
}
.invoice-dept {
font-size: 13px;
font-weight: 600;
color: #303133;
.opinion-dept {
display: flex;
align-items: center;
gap: 6px;
font-family: 'Georgia', 'Times New Roman', 'Noto Serif SC', 'SimSun', serif;
font-size: 14px;
font-weight: 700;
color: #1a3c6e;
letter-spacing: 0.3px;
}
.invoice-divider {
border: none;
border-top: 1px dashed #dcdfe6;
margin: 6px 0;
.opinion-dept-icon {
font-size: 10px;
color: #1a3c6e;
}
.invoice-body {
.opinion-card-body {
flex: 1;
}
.invoice-content {
font-size: 12px;
color: #606266;
line-height: 1.6;
.opinion-content {
font-size: 13px;
color: #3a3a3a;
line-height: 1.7;
word-break: break-all;
max-height: 80px;
max-height: 100px;
overflow-y: auto;
}
.invoice-content /deep/ p {
.opinion-content /deep/ p {
margin: 0;
}
.invoice-empty {
color: #c0c4cc;
.opinion-empty {
color: #bab5ae;
font-size: 12px;
font-style: italic;
font-family: 'Georgia', 'Times New Roman', serif;
}
.invoice-file {
margin-top: 6px;
.opinion-file {
margin-top: 8px;
}
.invoice-meta {
.opinion-card-footer {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 6px;
gap: 14px;
margin-top: 10px;
padding-top: 8px;
border-top: 1px dashed #e0dcd6;
}
.invoice-meta-item {
font-size: 11px;
color: #909399;
display: inline-flex;
align-items: center;
gap: 2px;
}
.invoice-meta-item i {
.opinion-footer-item {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: 11px;
color: #8c8c8c;
}
.empty-data {
color: #909399;
color: #8c8c8c;
font-size: 13px;
padding: 8px 0;
font-style: italic;
}
</style>