!160 style(supervision): 习讲话与巡视整改详情弹窗样式对齐党委会

* style(supervision): 习讲话与巡视整改详情弹窗样式对齐党委会
This commit is contained in:
wsm
2026-08-19 06:11:55 +00:00
parent 03d4dfebf0
commit 44e12e2240
2 changed files with 699 additions and 92 deletions
@@ -7,20 +7,55 @@
:footer="null"
:maskClosable="true"
:bodyStyle="{ maxHeight: '70vh', overflowY: 'auto', padding: '16px 24px 20px' }"
wrapClassName="xispeak-detail-modal"
destroyOnClose
>
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="item" tab="事项信息">
<div class="detail-grid">
<div
v-for="field in detailFields"
:key="field.label"
class="detail-row"
:class="{ 'detail-row-full': field.fullWidth, 'detail-row-bold': field.bold }"
>
<span class="detail-label">{{ field.label }}</span>
<span class="detail-value">{{ field.value }}</span>
</div>
<div class="matter-detail">
<section class="matter-summary">
<div class="summary-heading">
<span class="summary-heading-icon">
<Icon :icon="summaryIcon" />
</span>
<div class="summary-heading-content">
<span class="summary-kicker">{{ summaryKicker }}</span>
<h3 class="summary-title">{{ detailSummary.title }}</h3>
</div>
</div>
<div class="summary-meta">
<div class="summary-meta-item">
<Icon icon="ant-design:calendar-outlined" />
<span class="summary-meta-label">时间</span>
<span class="summary-meta-value">{{ detailSummary.time }}</span>
</div>
<div class="summary-meta-item">
<Icon icon="ant-design:lock-outlined" />
<span class="summary-meta-label">密级</span>
<span class="summary-meta-value">{{ detailSummary.secretLevel }}</span>
</div>
<div class="summary-tag-group">
<a-tag class="summary-tag">截止日期{{ detailSummary.deadline }}</a-tag>
<a-tag class="summary-tag">督办次数{{ detailSummary.supervisionCount }}</a-tag>
</div>
</div>
</section>
<section v-for="group in detailGroups" :key="group.title" class="detail-section">
<div class="detail-section-header">
<span class="detail-section-icon">
<Icon :icon="group.icon" />
</span>
<h3>{{ group.title }}</h3>
</div>
<div class="detail-grid">
<div v-for="field in group.fields" :key="field.label" class="detail-item" :class="{ 'detail-item-full': field.fullWidth }">
<span class="detail-label">{{ field.label }}</span>
<span class="detail-value" :class="{ 'detail-value-strong': field.bold }">{{ field.value }}</span>
</div>
</div>
</section>
</div>
</a-tab-pane>
@@ -103,25 +138,59 @@
return fmt(record[`${key}_dictText`] || record[key]);
}
const detailFields = computed(() => {
const summaryKicker = '习讲话事项';
const summaryIcon = 'ant-design:sound-outlined';
// 摘要区只承载最常用于快速判断事项状态的信息,详细字段放入下方分组,避免重复平铺。
const detailSummary = computed(() => {
const r = record.value || {};
return {
title: fmt(r.speakStatus),
time: fmtDate(r.time),
secretLevel: dictText(r, 'secretLevel'),
deadline: fmtDate(r.deadline),
supervisionCount: fmt(r.supervisionCount),
};
});
const detailGroups = computed(() => {
const r = record.value || {};
return [
{ label: '重要讲话指示批示', value: fmt(r.speakStatus), fullWidth: true, bold: true },
{ label: '时间', value: fmtDate(r.time), bold: true },
{ label: '企业负责同志批示情况', value: fmt(r.elmComment) },
{ label: '学习传达研究部署', value: fmt(r.status) },
{ label: '密级', value: dictText(r, 'secretLevel') },
{ label: '所党委责任领导', value: dictText(r, 'responsiblePerson'), bold: true },
{ label: '牵头部门', value: dictText(r, 'implDept'), bold: true },
{ label: '贯彻落实措施', value: fmt(r.implMeasures) },
{ label: '会议决策数', value: fmt(r.numberOfResolutions) },
{ label: '是否需要所党委领导督办', value: ynText(r.needSdwApproval) },
{ label: '所党委领导列表', value: dictText(r, 'sdwLeaderList') },
{ label: '指定落实措施条数', value: fmt(r.implCount) },
{ label: '措施已闭环数量', value: fmt(r.closedCount) },
{ label: '报告反馈情况', value: fmt(r.reportFeedbackStatus) },
{ label: '截止日期', value: fmtDate(r.deadline) },
{ label: '督办次数', value: fmt(r.supervisionCount) },
{
title: '批示与传达',
icon: 'ant-design:notification-outlined',
fields: [
{ label: '企业负责同志批示情况', value: fmt(r.elmComment) },
{ label: '学习传达研究部署', value: fmt(r.status) },
],
},
{
title: '责任与落实',
icon: 'ant-design:team-outlined',
fields: [
{ label: '所党委责任领导', value: dictText(r, 'responsiblePerson'), bold: true },
{ label: '牵头部门', value: dictText(r, 'implDept'), bold: true },
{ label: '贯彻落实措施', value: fmt(r.implMeasures), fullWidth: true },
],
},
{
title: '决策与进展',
icon: 'ant-design:fund-outlined',
fields: [
{ label: '会议决策数', value: fmt(r.numberOfResolutions) },
{ label: '指定落实措施条数', value: fmt(r.implCount) },
{ label: '措施已闭环数量', value: fmt(r.closedCount) },
{ label: '报告反馈情况', value: fmt(r.reportFeedbackStatus) },
],
},
{
title: '审批设置',
icon: 'ant-design:safety-outlined',
fields: [
{ label: '是否需要所党委领导督办', value: ynText(r.needSdwApproval) },
{ label: '所党委领导列表', value: dictText(r, 'sdwLeaderList'), fullWidth: true },
],
},
];
});
@@ -176,40 +245,265 @@
</script>
<style lang="less" scoped>
.detail-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 12px 32px;
padding: 4px 0;
// 弹窗内容会 Teleport 到 body,通过专属类限定公共组件的字号,避免影响其他页面。
:global(.xispeak-detail-modal .ant-modal-title) {
font-size: 18px;
line-height: 26px;
}
.detail-row {
:global(.xispeak-detail-modal .ant-tabs-tab-btn) {
font-size: 15px;
line-height: 24px;
}
:global(.xispeak-detail-modal .ant-table) {
font-size: 15px;
}
:global(.xispeak-detail-modal .ant-table-thead > tr > th),
:global(.xispeak-detail-modal .ant-table-tbody > tr > td) {
font-size: 15px;
line-height: 24px;
}
.matter-detail {
padding: 4px 2px 10px;
}
.matter-summary {
position: relative;
overflow: hidden;
margin-bottom: 16px;
padding: 20px 22px;
background: linear-gradient(135deg, #f2f8ff 0%, #f8fbff 48%, #ffffff 100%);
border: 1px solid #d6e8ff;
border-radius: 10px;
box-shadow: 0 4px 14px rgb(22 119 255 / 8%);
&::after {
position: absolute;
top: -46px;
right: -24px;
width: 132px;
height: 132px;
background: rgb(22 119 255 / 5%);
border-radius: 50%;
content: '';
pointer-events: none;
}
}
.summary-heading {
position: relative;
z-index: 1;
display: flex;
align-items: flex-start;
gap: 12px;
}
.summary-heading-icon {
display: inline-flex;
flex: 0 0 40px;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
color: #1677ff;
font-size: 20px;
background: #e6f4ff;
border-radius: 10px;
}
.summary-heading-content {
min-width: 0;
}
.detail-row-full {
.summary-kicker {
display: block;
margin-bottom: 2px;
color: #64748b;
font-size: 14px;
line-height: 20px;
}
.summary-title {
margin: 0;
color: #172033;
font-size: 21px;
font-weight: 600;
line-height: 30px;
overflow-wrap: anywhere;
}
.summary-meta {
position: relative;
z-index: 1;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 10px 18px;
margin-top: 16px;
padding-top: 14px;
border-top: 1px solid #deebfa;
}
.summary-meta-item {
display: inline-flex;
align-items: center;
gap: 6px;
min-height: 24px;
color: #64748b;
> :first-child {
color: #1677ff;
font-size: 15px;
}
}
.summary-meta-label {
font-size: 14px;
}
.summary-meta-value {
color: #1f2937;
font-size: 15px;
font-weight: 600;
}
.summary-tag-group {
display: inline-flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
min-width: 0;
}
.summary-tag {
margin-inline-end: 0;
padding: 2px 10px;
font-size: 14px;
line-height: 22px;
white-space: normal;
}
.detail-section {
overflow: hidden;
margin-top: 14px;
background: #ffffff;
border: 1px solid #e7edf4;
border-radius: 8px;
}
.detail-section-header {
display: flex;
align-items: center;
gap: 8px;
min-height: 44px;
padding: 10px 16px;
background: #f8fbff;
border-bottom: 1px solid #e7edf4;
h3 {
margin: 0;
color: #27364b;
font-size: 16px;
font-weight: 600;
line-height: 24px;
}
}
.detail-section-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
color: #1677ff;
background: #e6f4ff;
border-radius: 6px;
}
.detail-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1px;
background: #edf1f5;
}
.detail-item {
display: grid;
grid-template-columns: 142px minmax(0, 1fr);
align-items: start;
gap: 12px;
min-width: 0;
min-height: 54px;
padding: 14px 16px;
background: #ffffff;
}
.detail-item-full {
grid-column: 1 / -1;
}
.detail-label {
flex: 0 0 150px;
color: #8c8c8c;
line-height: 22px;
color: #7b8798;
font-size: 14px;
line-height: 26px;
}
.detail-value {
flex: 1;
color: #1f2937;
line-height: 22px;
word-break: break-all;
min-width: 0;
color: #27364b;
font-size: 15px;
line-height: 26px;
white-space: pre-wrap;
overflow-wrap: anywhere;
}
.detail-row-bold .detail-value {
font-weight: 700;
font-size: 15px;
.detail-value-strong {
color: #172033;
font-weight: 600;
}
@media (max-width: 768px) {
.matter-summary {
padding: 16px;
}
.summary-meta {
align-items: flex-start;
}
.summary-tag-group {
flex-basis: 100%;
}
.detail-grid {
grid-template-columns: minmax(0, 1fr);
}
.detail-item-full {
grid-column: auto;
}
}
@media (max-width: 576px) {
.summary-title {
font-size: 19px;
line-height: 27px;
}
.summary-meta {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: 8px;
}
.detail-item {
grid-template-columns: minmax(0, 1fr);
gap: 2px;
padding: 11px 14px;
}
}
.feedback-summary-header {
@@ -7,20 +7,60 @@
:footer="null"
:maskClosable="true"
:bodyStyle="{ maxHeight: '70vh', overflowY: 'auto', padding: '16px 24px 20px' }"
wrapClassName="inspecttask-detail-modal"
destroyOnClose
>
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="item" tab="事项信息">
<div class="detail-grid">
<div
v-for="field in detailFields"
:key="field.label"
class="detail-row"
:class="{ 'detail-row-full': field.fullWidth, 'detail-row-bold': field.bold }"
>
<span class="detail-label">{{ field.label }}</span>
<span class="detail-value">{{ field.value }}</span>
</div>
<div class="matter-detail">
<section class="matter-summary">
<div class="summary-heading">
<span class="summary-heading-icon">
<Icon :icon="summaryIcon" />
</span>
<div class="summary-heading-content">
<span class="summary-kicker">{{ summaryKicker }}</span>
<h3 class="summary-title">{{ detailSummary.title }}</h3>
</div>
</div>
<div class="summary-meta">
<div class="summary-meta-item">
<Icon icon="ant-design:appstore-outlined" />
<span class="summary-meta-label">问题分类</span>
<span class="summary-meta-value">{{ detailSummary.categoryName }}</span>
</div>
<div class="summary-meta-item">
<Icon icon="ant-design:lock-outlined" />
<span class="summary-meta-label">密级</span>
<span class="summary-meta-value">{{ detailSummary.secretLevel }}</span>
</div>
<div class="summary-meta-item">
<Icon icon="ant-design:clock-circle-outlined" />
<span class="summary-meta-label">完成时限</span>
<span class="summary-meta-value">{{ detailSummary.deadline }}</span>
</div>
<div class="summary-tag-group">
<a-tag class="summary-tag" :color="taskStatusTagColor">整改状态{{ detailSummary.taskStatus }}</a-tag>
<a-tag class="summary-tag">督办状态{{ detailSummary.bpmStatus }}</a-tag>
</div>
</div>
</section>
<section v-for="group in detailGroups" :key="group.title" class="detail-section">
<div class="detail-section-header">
<span class="detail-section-icon">
<Icon :icon="group.icon" />
</span>
<h3>{{ group.title }}</h3>
</div>
<div class="detail-grid">
<div v-for="field in group.fields" :key="field.label" class="detail-item" :class="{ 'detail-item-full': field.fullWidth }">
<span class="detail-label">{{ field.label }}</span>
<span class="detail-value" :class="{ 'detail-value-strong': field.bold }">{{ field.value }}</span>
</div>
</div>
</section>
</div>
</a-tab-pane>
@@ -97,29 +137,77 @@
return fmt(record[`${key}_dictText`] || record[key]);
}
const detailFields = computed(() => {
const summaryKicker = '整改任务';
const summaryIcon = 'ant-design:flag-outlined';
// 摘要区只承载最常用于快速判断事项状态的信息,详细字段放入下方分组,避免重复平铺。
const detailSummary = computed(() => {
const r = record.value || {};
return {
title: fmt(r.specificName),
categoryName: fmt(r.categoryName),
secretLevel: dictText(r, 'secretLevel'),
deadline: fmtDate(r.deadline),
taskStatus: fmt(r.taskStatus),
bpmStatus: dictText(r, 'bpmStatus'),
};
});
const taskStatusTagColor = computed(() => {
const text = detailSummary.value.taskStatus;
if (text.includes('已完成')) return 'success';
if (text.includes('整改中') || text.includes('进行中')) return 'processing';
if (text.includes('未开始')) return 'warning';
return undefined;
});
const detailGroups = computed(() => {
const r = record.value || {};
return [
{ label: '问题分类', value: fmt(r.categoryName) },
{ label: '面上问题', value: fmt(r.surfaceName) },
{ label: '具体问题', value: fmt(r.specificName) },
{ label: '整改措施', value: fmt(r.improveMeasure), fullWidth: true, bold: true },
{ label: '密级', value: dictText(r, 'secretLevel') },
{ label: '完成时限', value: fmtDate(r.deadline) },
{ label: '目标节点', value: fmt(r.targetNode) },
{ label: '巡视建议', value: fmt(r.inspectAdvice) },
{ label: '检查情况', value: fmt(r.inspectionStatus) },
{ label: '监督意见', value: fmt(r.supervisoryOpinion) },
{ label: '整改状态', value: fmt(r.taskStatus) },
{ label: '措施责任部门', value: dictText(r, 'measureResDept'), bold: true },
{ label: '措施责任负责人', value: dictText(r, 'measureResLeader'), bold: true },
{ label: '分管所领导', value: dictText(r, 'chargeLeaderId'), bold: true },
{ label: '整改交付成果', value: fmt(r.rectificationEvidence) },
{ label: '成效评价标准', value: fmt(r.evaluationCriterion) },
{ label: '需党群负责人审批', value: ynText(r.isNeedAppro) },
{ label: '党群负责人', value: dictText(r, 'supDeptleaderid') },
{ label: '督办状态', value: dictText(r, 'bpmStatus') },
{ label: '督办次数', value: fmt(r.superviseCount) },
{
title: '问题定位',
icon: 'ant-design:flag-outlined',
fields: [
{ label: '面上问题', value: fmt(r.surfaceName) },
{ label: '目标节点', value: fmt(r.targetNode) },
],
},
{
title: '整改要求',
icon: 'ant-design:edit-outlined',
fields: [
{ label: '整改措施', value: fmt(r.improveMeasure), fullWidth: true, bold: true },
{ label: '巡视建议', value: fmt(r.inspectAdvice) },
],
},
{
title: '责任分工',
icon: 'ant-design:team-outlined',
fields: [
{ label: '措施责任部门', value: dictText(r, 'measureResDept'), bold: true },
{ label: '措施责任负责人', value: dictText(r, 'measureResLeader'), bold: true },
{ label: '分管所领导', value: dictText(r, 'chargeLeaderId'), bold: true },
],
},
{
title: '成效与监督',
icon: 'ant-design:audit-outlined',
fields: [
{ label: '整改交付成果', value: fmt(r.rectificationEvidence) },
{ label: '成效评价标准', value: fmt(r.evaluationCriterion) },
{ label: '检查情况', value: fmt(r.inspectionStatus) },
{ label: '监督意见', value: fmt(r.supervisoryOpinion) },
],
},
{
title: '审批与进展',
icon: 'ant-design:safety-outlined',
fields: [
{ label: '需党群负责人审批', value: ynText(r.isNeedAppro) },
{ label: '党群负责人', value: dictText(r, 'supDeptleaderid') },
{ label: '督办次数', value: fmt(r.superviseCount) },
],
},
];
});
@@ -160,40 +248,265 @@
</script>
<style lang="less" scoped>
.detail-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 12px 32px;
padding: 4px 0;
// 弹窗内容会 Teleport 到 body,通过专属类限定公共组件的字号,避免影响其他页面。
:global(.inspecttask-detail-modal .ant-modal-title) {
font-size: 18px;
line-height: 26px;
}
.detail-row {
:global(.inspecttask-detail-modal .ant-tabs-tab-btn) {
font-size: 15px;
line-height: 24px;
}
:global(.inspecttask-detail-modal .ant-table) {
font-size: 15px;
}
:global(.inspecttask-detail-modal .ant-table-thead > tr > th),
:global(.inspecttask-detail-modal .ant-table-tbody > tr > td) {
font-size: 15px;
line-height: 24px;
}
.matter-detail {
padding: 4px 2px 10px;
}
.matter-summary {
position: relative;
overflow: hidden;
margin-bottom: 16px;
padding: 20px 22px;
background: linear-gradient(135deg, #f2f8ff 0%, #f8fbff 48%, #ffffff 100%);
border: 1px solid #d6e8ff;
border-radius: 10px;
box-shadow: 0 4px 14px rgb(22 119 255 / 8%);
&::after {
position: absolute;
top: -46px;
right: -24px;
width: 132px;
height: 132px;
background: rgb(22 119 255 / 5%);
border-radius: 50%;
content: '';
pointer-events: none;
}
}
.summary-heading {
position: relative;
z-index: 1;
display: flex;
align-items: flex-start;
gap: 12px;
}
.summary-heading-icon {
display: inline-flex;
flex: 0 0 40px;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
color: #1677ff;
font-size: 20px;
background: #e6f4ff;
border-radius: 10px;
}
.summary-heading-content {
min-width: 0;
}
.detail-row-full {
.summary-kicker {
display: block;
margin-bottom: 2px;
color: #64748b;
font-size: 14px;
line-height: 20px;
}
.summary-title {
margin: 0;
color: #172033;
font-size: 21px;
font-weight: 600;
line-height: 30px;
overflow-wrap: anywhere;
}
.summary-meta {
position: relative;
z-index: 1;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 10px 18px;
margin-top: 16px;
padding-top: 14px;
border-top: 1px solid #deebfa;
}
.summary-meta-item {
display: inline-flex;
align-items: center;
gap: 6px;
min-height: 24px;
color: #64748b;
> :first-child {
color: #1677ff;
font-size: 15px;
}
}
.summary-meta-label {
font-size: 14px;
}
.summary-meta-value {
color: #1f2937;
font-size: 15px;
font-weight: 600;
}
.summary-tag-group {
display: inline-flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
min-width: 0;
}
.summary-tag {
margin-inline-end: 0;
padding: 2px 10px;
font-size: 14px;
line-height: 22px;
white-space: normal;
}
.detail-section {
overflow: hidden;
margin-top: 14px;
background: #ffffff;
border: 1px solid #e7edf4;
border-radius: 8px;
}
.detail-section-header {
display: flex;
align-items: center;
gap: 8px;
min-height: 44px;
padding: 10px 16px;
background: #f8fbff;
border-bottom: 1px solid #e7edf4;
h3 {
margin: 0;
color: #27364b;
font-size: 16px;
font-weight: 600;
line-height: 24px;
}
}
.detail-section-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
color: #1677ff;
background: #e6f4ff;
border-radius: 6px;
}
.detail-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1px;
background: #edf1f5;
}
.detail-item {
display: grid;
grid-template-columns: 142px minmax(0, 1fr);
align-items: start;
gap: 12px;
min-width: 0;
min-height: 54px;
padding: 14px 16px;
background: #ffffff;
}
.detail-item-full {
grid-column: 1 / -1;
}
.detail-label {
flex: 0 0 150px;
color: #8c8c8c;
line-height: 22px;
color: #7b8798;
font-size: 14px;
line-height: 26px;
}
.detail-value {
flex: 1;
color: #1f2937;
line-height: 22px;
word-break: break-all;
min-width: 0;
color: #27364b;
font-size: 15px;
line-height: 26px;
white-space: pre-wrap;
overflow-wrap: anywhere;
}
.detail-row-bold .detail-value {
font-weight: 700;
font-size: 15px;
.detail-value-strong {
color: #172033;
font-weight: 600;
}
@media (max-width: 768px) {
.matter-summary {
padding: 16px;
}
.summary-meta {
align-items: flex-start;
}
.summary-tag-group {
flex-basis: 100%;
}
.detail-grid {
grid-template-columns: minmax(0, 1fr);
}
.detail-item-full {
grid-column: auto;
}
}
@media (max-width: 576px) {
.summary-title {
font-size: 19px;
line-height: 27px;
}
.summary-meta {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: 8px;
}
.detail-item {
grid-template-columns: minmax(0, 1fr);
gap: 2px;
padding: 11px 14px;
}
}
.feedback-summary-header {