fix(xispeak): 调整讲话批示页面格式并修复反馈表单组件引用

参考 fixcontact 方案统一查询区列宽与弹窗 labelCol,精简长标签消除文字遮挡;
修复 BgXiSpeakFeedbackModal 中 mainId 未注入、unref 未导入的引用缺陷。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
wsm
2026-08-06 11:40:06 +08:00
co-authored by Claude Opus 4.7
parent 5eecdd16e9
commit 7698c6c084
7 changed files with 144 additions and 18 deletions
+6 -6
View File
@@ -4,10 +4,10 @@
<div class="jeecg-basic-table-form-container">
<a-form ref="formRef" @keyup.enter="searchQuery" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-row :gutter="24">
<a-col :xl="4" :lg="6" :md="8" :sm="12">
<a-col :xl="6" :lg="6" :md="8" :sm="12">
<a-form-item name="speakStatus">
<template #label>
<a-tooltip title="支持模糊查询,输入重要讲话指示批示情况关键词">重要讲话指示批示情况</a-tooltip>
<a-tooltip title="支持模糊查询,输入重要讲话指示批示情况关键词">讲话指示批示</a-tooltip>
</template>
<a-tooltip title="支持模糊查询,输入重要讲话指示批示情况关键词"><JInput v-model:value="queryParam.speakStatus" type="like" placeholder="请输入重要讲话指示批示情况" allow-clear trim @change="searchQuery" /></a-tooltip>
</a-form-item>
@@ -20,10 +20,10 @@
<a-tooltip title="按牵头部门筛选"><SzSelectDept v-model:value="selectedImplDept" :multiple="true" placeholder="选择牵头部门" allow-clear style="width: 100%" @change="handleImplDeptChange" /></a-tooltip>
</a-form-item>
</a-col>
<a-col :xl="4" :lg="6" :md="8" :sm="12">
<a-col :xl="6" :lg="6" :md="8" :sm="12">
<a-form-item name="responsiblePerson">
<template #label>
<a-tooltip title="按所党委责任领导筛选">所党委责任领导</a-tooltip>
<a-tooltip title="按所党委责任领导筛选">责任领导</a-tooltip>
</template>
<a-tooltip title="按所党委责任领导筛选"><DeptRoleUserSelectDropDown v-model:value="queryParam.responsiblePerson" :deptId="PARTY_COMMITTEE_DEPT_ID" :roleId="SDW_LEADER_ROLE_ID" placeholder="请选择所党委责任领导" allow-clear style="width: 100%" @change="searchQuery" /></a-tooltip>
</a-form-item>
@@ -33,7 +33,7 @@
<!-- <JDictSelectTag v-model:value="queryParam.completionStatus" dictCode="db_status" placeholder="请选择完成状态" allow-clear @change="searchQuery" />-->
<!-- </a-form-item>-->
<!-- </a-col>-->
<a-col :xl="4" :lg="6" :md="8" :sm="12">
<a-col :xl="6" :lg="6" :md="8" :sm="12">
<a-form-item name="bpmStatus">
<template #label>
<a-tooltip title="按督办状态筛选">督办状态</a-tooltip>
@@ -45,7 +45,7 @@
</a-select></a-tooltip>
</a-form-item>
</a-col>
<a-col :xl="4" :lg="6" :md="8" :sm="12">
<a-col :xl="6" :lg="6" :md="8" :sm="12">
<span class="table-page-search-submitButtons">
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
<a-button preIcon="ant-design:reload-outlined" style="margin-left: 8px" @click="searchReset">重置</a-button>
+125
View File
@@ -0,0 +1,125 @@
# 习总书记重要讲话指示批示(xispeak)页面格式调整与前端核查说明
> 核对日期:2026-08-06
> 核对范围:`src/views/bg/xispeak/` 全部 Vue 组件(12 个)
> 核对方式:静态代码审查(项目 package.json 未配置 lint / vue-tsc 脚本,故采用逐文件人工核查 + 引用存在性校验),参照 `src/views/bg/fixcontact/` 已完成的格式调整方案
---
## 一、格式调整记录(消除文字被输入框遮挡 / 对齐)
### 1. `BgXiSpeakList.vue`(列表页 / 查询区)
| 问题 | 调整 |
|------|------|
| 查询表单 4 个筛选列中 3 个为 `:xl="4"`(约占 1/6 屏宽),「重要讲话指示批示情况」10 字、「所党委责任领导」7 字标签在窄 label 列内超宽,输入框被压缩 | 全部 5 列(4 个筛选 + 按钮)统一放宽为 `:xl="6"`(每行 4 个),输入框由约 90px 拓宽到约 150px+ |
| 长标签即使放宽列后仍偏紧 | 标签文字精简,完整含义保留在 tooltip 中:`重要讲话指示批示情况→讲话指示批示``所党委责任领导→责任领导``牵头部门``督办状态` 已 ≤4 字无需调整 |
| labelCol 为 `xl:10 / xxl:14` | 保持不动(10+14=24),放宽列后标签与输入框均有余量 |
### 2. `BgXiSpeakForm.vue`(新增/编辑弹窗表单,弹窗宽 1400)
| 问题 | 调整 |
|------|------|
| 整行字段「重要讲话指示批示」的标签列写死为 `span 3`,与表单基准 `labelCol 6 / wrapperCol 18` 不一致,输入框起点左偏、与其他半行字段不对齐 | 该字段行内 `:labelCol``3/21` 改为 `6/18`,与基准标签列对齐 |
| 基准 `labelCol 6/18` 在半行字段下可容纳 ≤10 字标签(如「企业负责同志批示情况」「是否需要所党委领导督办」) | 保持不动(弹窗宽 1400,半行标签盒约 165px > 10 字 140px |
### 3. `BgXiSpeakBPMForm.vue`(流程表单)
| 问题 | 调整 |
|------|------|
| 流程办理字段(是否办结 / 部门经办人)使用 `wideLabelCol span 3`,在任务办理页半行字段下标签盒仅约 74px,标签贴边 | `wideLabelCol: span 3→7``wideWrapperCol: span 21→17`7+17=24),与基准标签列 `span 7` 对齐 |
| 基础信息区基准 `labelCol 7/17` 可容纳 ≤10 字标签(「企业负责同志批示情况」140px < 标签盒约 172px | 保持不动 |
### 4. `BgXiSpeakBPMFeedbackModal.vue`(流程反馈弹窗,宽 820
| 问题 | 调整 |
|------|------|
| 整行字段(具体措施/进展情况/监督意见(纪检)/证明材料)使用 `wideLabelCol span 3`,16 字标签「体现落实措施,取得成果的证明材料」约 238px >> 标签盒约 95px,严重溢出 | `wideLabelCol: span 3→8``wideWrapperCol: span 21→16`8+16=24),标签盒约 248px 可容纳 |
| 半行字段基准 `labelCol 7` 标签盒约 106px,「是否有报送上级报告」9 字约 126px 溢出 | 基准 `labelCol: span 7→8``wrapperCol: span 17→16`;标签精简为 `是否有报送上级报告→是否报送上级`(完整语义通过字段下方选项承载) |
### 5. `BgXiSpeakFeedbackForm.vue`(反馈表单,弹窗宽 800
| 问题 | 调整 |
|------|------|
| 基准 `labelCol 7/17` 标签盒约 104px,8 字「是否报送上级报告」约 112px 溢出换行 | `labelCol: span 7→8``wrapperCol: span 17→16`8+16=24),标签盒约 119px 单行放下 |
### 6. 无需调整的文件
- `BgXiSpeakModal.vue`(仅弹窗壳,宽 1400)、`BgXiSpeakFeedbackViewModal.vue`(仅只读表格)、`FeedbackRightNowModal.vue`(仅单选卡片,无表单布局)
- `BgXiSpeak.api.ts``BgXiSpeak.data.ts`(无布局)
- `BgXiSpeakFeedbackList.vue`(无查询表单,`labelCol/wrapperCol` 为未使用的残留定义)
---
## 二、前端错误核查
### 发现并修复 1 处(功能级)
| 级别 | 文件 | 问题 | 处理 |
|------|------|------|------|
| 功能 | `BgXiSpeakFeedbackModal.vue` | 模板 `registerForm.value.setMainId(unref(mainId))` 中的 `mainId` 未定义(未 `inject('mainId')`)、`unref` 未从 `vue` 导入,点击「新增」会抛 `ReferenceError` | 补上 `inject``unref` 导入并 `const mainId = inject('mainId')` |
### 引用存在性校验(全部通过)
| 引用 | 校验结果 |
|------|---------|
| `PARTY_COMMITTEE_DEPT_ID / SDW_LEADER_ROLE_ID` | `src/constant/supervision/index.ts` 存在 ✓ |
| `SzSelectDept.vue``DeptRoleUserSelectDropDown.vue``DeptRoleUserSelectRadioGroup.vue``JSelectUser.vue``SzDeptUserModal.vue``JTreeSelect.vue``JDictSelectTag.vue``JSelectDept.vue` | 均存在 ✓ |
| `SUploadFile.vue` | `src/components/semri/fileComponent/SUploadFile.vue` ✓ |
| `TaskHandleInnerContent.vue` | `src/views/super/bpm/process/personalOffice/myHandleTask/content/` ✓ |
| `useSubApproveUserResolver` | `src/composables/useSubApproveUserResolver.ts` ✓ |
| `FlowScheduleStartModal.vue` / `BusinessProcessListModal.vue` | `src/components/semri/process/` 下存在 ✓ |
| api.ts 导出的 list/statusStats/saveOrUpdateDict/bgXiSpeakFeedbackList/bgXiSpeakFeedbackSaveOrUpdate/saveBpmForm/saveSubApprove/getProcessVariable/withDrawXiSpeak/updateLaunchType/queryFeedbackCounts/deleteBgXiSpeak/batchDeleteBgXiSpeak/getChildList/getChildListBatch/loadTreeData/bgXiSpeakFeedbackDelete/bgXiSpeakFeedbackDeleteBatch | 均在 List/BPMForm/Feedback 中有引用且导出 ✓ |
| `showImportValidationErrors``dateUtil``startProcessSchedules``getValueType` | 引用存在 ✓ |
| `taskTaskColumns``/@/views/taskProcess/TaskTask.data` | 存在 ✓ |
### 已核对、无异常
- 各组件 `defineExpose` / 模板 ref 调用(如 `registerModal.value.disableSubmit`)沿用本仓库既有模式。
- 表单校验 `Form.useForm``validateInfos``resetFields``scrollToField` 用法正确。
- 树形表格展开(`handleExpand` / `getChildList` / `getChildListBatch`)、反馈统计刷新(`refreshFeedbackCounts` / `onFetchSuccess`)、行状态着色(`status-row-1/2/3`)、导出/导入/模板校验回调均正常。
- `BgXiSpeakBPMForm.vue` 中反馈表格列、附件上传、`showJiJianFields` 条件列均正常。
### 发现但未改(P2 建议,不影响运行)
| 文件 | 说明 |
|------|------|
| `BgXiSpeakList.vue` | `JDictSelectTag``prefixCls``onImportXls` 仅在被注释代码中使用(预留的完成状态筛选/导入按钮),为未使用引用 |
| `BgXiSpeakForm.vue` / `BgXiSpeakBPMForm.vue` | `JTreeSelect` 仅在被注释代码中使用,未使用引用;BPMForm 中 `compactLabelCol/compactWrapperCol` 定义但模板未使用 |
| `BgXiSpeakBPMForm.vue` | 存在多处 `console.log` 调试输出,建议后续清理 |
| `BgXiSpeakFeedbackForm.vue` | `edit()``value.format('YYYY-MM-DD HH:mm:ss')` 对 Date 对象调用 `.format`,Date 无该方法;但接口返回 JSON 字符串不会产生 Date,实际不会触发(防御性代码,风险极低) |
---
## 三、说明与假设
1. 查询表单标签做了**文字精简**(完整说明保留在 tooltip),这是在不改动列宽布局的前提下消除遮挡的最稳妥方式;如需完整标签,请按上文说明放宽列宽。
2. 各弹窗 labelCol 调整依据弹窗声明宽度核算(BgXiSpeakModal=1400、BgXiSpeakFeedbackModal=800、BgXiSpeakBPMFeedbackModal=820)。`BgXiSpeakBPMFeedbackModal` 的基准/整行标签列统一为 `8/16`,可容纳 8-9 字标签单行显示;若后续弹窗被嵌入更窄容器,需再加大标签占比。
3. `BgXiSpeakFeedbackList.vue``BgXiSpeakFeedbackModal.vue``BgXiSpeakFeedbackForm.vue` 构成反馈子表单链;其中 FeedbackModal 的 `mainId` 注入缺陷已修复,但其父级 `BgXiSpeakFeedbackList``mainId` 来自 `inject('mainId')`,仅在嵌入提供该值的父页面时生效,作为独立菜单页打开时 `mainId` 为空(既有行为,未改动)。
4. 项目未配置 lint/typecheck 脚本,本核对以静态审查为准;建议在开发环境实际打开各弹窗与查询区目视复核一遍最终效果。
---
## 四、Playwright 渲染验证记录(2026-08-06
### 验证方式
- 工具:Playwright + Chromium 无头浏览器(安装在项目外临时目录 `%TEMP%/pwverify`,未污染 package.json),Vite dev server 以 mock 模式启动(`VITE_USE_MOCK=true`,登录 admin/123456)。
- 路由:本模块页面为菜单驱动动态路由(BACK 模式下仅注册 `staticRouter.ts``staticRoutesList`),故临时在 `staticRouter.ts` 挂载 `/bg-verify-temp` 验证路由,验证完成后已删除,`staticRouter.ts` 恢复原样。
- 手段:真实登录后截图(过滤条 + 新增弹窗)+ DOM 度量(canvas 测量 label 文本自然宽度 vs label 盒宽判断溢出)。
### 度量结果(视口 1600×1000
| 页面 | 项数 | label 溢出 | 说明 |
|------|------|-----------|------|
| xispeak 查询区(4 列) | 4 | 0 | 列宽已生效 span 6(容器 1373px,每列 344px),标签盒约 187px,输入框约 133px,精简标签单行放下 |
| xispeak 新增弹窗(15 项) | 15 | 0(1 处折行) | 「是否需要所党委领导督办」文本 154px > 盒宽 151px**折为 2 行**,输入框在下方独占全宽,无遮挡 |
| fixcontact 查询区(5 列) | 5 | 0 | 参考方案基线良好 |
| fixcontact 新增弹窗(16 项) | 16 | 0 | 参考方案基线良好 |
### 结论
- 查询区与新增弹窗的长标签**均不再挤压输入框**,本次格式调整达到预期。
- 唯一注意点:`BgXiSpeakForm.vue` 中「是否需要所党委领导督办」在 1400px 弹窗半行字段下折为 2 行(超出盒宽 3px)。属优雅换行、非遮挡问题,P2 级;如需单行可再精简为「是否需党委领导督办」或加大标签列。
- `BgXiSpeakBPMForm.vue`(流程表单)、`BgXiSpeakBPMFeedbackModal.vue`/`BgXiSpeakFeedbackModal.vue`(反馈弹窗)因需流程实例/表格数据触发,未纳入本次无头渲染;其 labelCol 改动为静态核算 + 引用校验通过。
- 截图留存于 `%TEMP%/pwverify/shots/`xispeak/fixcontact 的 list、filterbar、modal、modal_bottom 共 8 张),可自行打开目视复核。
@@ -48,7 +48,7 @@
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="是否报送上级报告" name="isReportedToHigher">
<a-form-item label="是否报送上级" name="isReportedToHigher">
<JDictSelectTag v-model:value="formData.isReportedToHigher" dictCode="need_report_higher" placeholder="请选择" type="select" :stringToNumber="true" :disabled="nonJiJianFieldsReadonly" allow-clear />
</a-form-item>
</a-col>
@@ -126,10 +126,10 @@
const uploadFileRef = ref<InstanceType<typeof SUploadFile> | null>(null);
const uploadSecretLevel = ref(1);
const uploadKey = ref(0);
const labelCol = { xs: { span: 24 }, sm: { span: 7 } };
const wrapperCol = { xs: { span: 24 }, sm: { span: 17 } };
const wideLabelCol = { xs: { span: 24 }, sm: { span: 3 } };
const wideWrapperCol = { xs: { span: 24 }, sm: { span: 21 } };
const labelCol = { xs: { span: 24 }, sm: { span: 8 } };
const wrapperCol = { xs: { span: 24 }, sm: { span: 16 } };
const wideLabelCol = { xs: { span: 24 }, sm: { span: 8 } };
const wideWrapperCol = { xs: { span: 24 }, sm: { span: 16 } };
const formData = reactive<Record<string, any>>({
id: '',
@@ -317,8 +317,8 @@ import {
const labelCol = { xs: { span: 24 }, sm: { span: 7 } };
const wrapperCol = { xs: { span: 24 }, sm: { span: 17 } };
const wideLabelCol = { xs: { span: 24 }, sm: { span: 3 } };
const wideWrapperCol = { xs: { span: 24 }, sm: { span: 21 } };
const wideLabelCol = { xs: { span: 24 }, sm: { span: 7 } };
const wideWrapperCol = { xs: { span: 24 }, sm: { span: 17 } };
const compactLabelCol = { xs: { span: 24 }, sm: { span: 5 } };
const compactWrapperCol = { xs: { span: 24 }, sm: { span: 19 } };
@@ -224,8 +224,8 @@
const props = defineProps({
disabled: { type: Boolean, default: false },
});
const labelCol = { xs: { span: 24 }, sm: { span: 7 } };
const wrapperCol = { xs: { span: 24 }, sm: { span: 17 } };
const labelCol = { xs: { span: 24 }, sm: { span: 8 } };
const wrapperCol = { xs: { span: 24 }, sm: { span: 16 } };
function fillDeptFromLogin() {
const userInfo = (userStore.getUserInfo || {}) as Record<string, any>;
@@ -5,10 +5,11 @@
</template>
<script lang="ts" setup>
import { ref, nextTick, defineExpose } from 'vue';
import { ref, nextTick, defineExpose, inject, unref } from 'vue';
import BgXiSpeakFeedbackForm from './BgXiSpeakFeedbackForm.vue';
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
const mainId = inject('mainId');
const title = ref<string>('');
const width = ref<number>(800);
const visible = ref<boolean>(false);
@@ -12,8 +12,8 @@
v-bind="validateInfos.speakStatus"
id="BgXiSpeakForm-speakStatus"
name="speakStatus"
:labelCol="{ xs: { span: 24 }, sm: { span: 3 } }"
:wrapperCol="{ xs: { span: 24 }, sm: { span: 21 } }"
:labelCol="{ xs: { span: 24 }, sm: { span: 6 } }"
:wrapperCol="{ xs: { span: 24 }, sm: { span: 18 } }"
>
<a-textarea v-model:value="formData.speakStatus" :rows="3" placeholder="请输入习近平总书记重要讲话指示批示情况" allow-clear />
</a-form-item>