Files
hzdyjs/出国申请详情职务字段未显示问题诊断报告.md
T
2025-10-14 16:41:19 +08:00

9.9 KiB
Raw Blame History

出国申请详情职务字段未显示问题诊断报告

问题发现时间: 2025-10-09
问题类型: 前端显示问题
影响范围: 出国申请详情查看功能
诊断状态: ✅ 已完成分析


📋 问题描述

问题现象

在出国申请管理页面中,点击"查看详情"按钮,弹窗界面中的职务字段显示为"-",但用户反馈数据库中该字段有数据。


🔍 完整诊断分析

✅ 1. 数据库层面检查(用户确认:有数据)

数据库表: rs_overseas_application

  • ✅ 表结构中存在 position 字段
  • ✅ 用户确认数据库中 position 字段有数据
-- 检查表结构
SHOW COLUMNS FROM rs_overseas_application LIKE 'position';
-- 结果: position varchar(100) DEFAULT NULL COMMENT '职务职称'

-- 查看数据
SELECT application_id, applicant_name, position FROM rs_overseas_application;
-- 用户确认: position字段有数据

✅ 2. 后端实体类检查(正确)

Java实体类: RsOverseasApplication.java(第99-103行)

/**
 * 职务职称
 */
@ExcelProperty(value = "职务职称")
private String position;

✅ 结论: 实体类包含 position 字段。


✅ 3. 后端VO类检查(正确)

VO类: RsOverseasApplicationVo.java(第92-95行)

/**
 * 职务职称
 */
private String position;

✅ 结论: VO类包含 position 字段。


✅ 4. 后端Mapper XML检查(正确)

Mapper XML: RsOverseasApplicationMapper.xml

① ResultMap映射(第19行)

<result property="position" column="position"/>

② SQL查询语句(第82行)

<sql id="selectOverseasApplicationVo">
    select oa.application_id, oa.serial_number, oa.applicant_id, oa.applicant_name, 
    oa.gender, oa.birth_date, oa.photo, oa.id_number, oa.political_status, oa.registered_address,
    oa.department, oa.position, oa.professional_title, ...
    from rs_overseas_application oa
</sql>

③ 查询详情方法(第274-277行)

<select id="selectOverseasApplicationById" parameterType="Long" resultMap="RsOverseasApplicationVoResult">
    <include refid="selectOverseasApplicationVo"/>
    where oa.application_id = #{applicationId} and oa.deleted = '0'
</select>

✅ 结论: Mapper XML配置正确,查询语句包含 position 字段。


✅ 5. 后端Service层检查(正确)

Service实现: RsOverseasApplicationServiceImpl.java(第136-138行)

@Override
public RsOverseasApplicationVo queryById(Long applicationId) {
    return baseMapper.selectOverseasApplicationById(applicationId);
}

✅ 结论: Service层调用正确。


✅ 6. 后端Controller层检查(正确)

Controller: RsOverseasApplicationController.java(第175-177行)

@SaCheckPermission("rs:overseas:query")
@GetMapping("/{applicationId}")
public R<RsOverseasApplicationVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long applicationId) {
    return R.ok(applicationService.queryById(applicationId));
}

✅ 结论: Controller接口正确。


✅ 7. 前端TypeScript接口检查(正确)

前端API接口: web/src/api/rs/overseas.ts(第37行)

export interface OverseasApplicationVO {
  applicationId: number | string;
  applicantName: string;
  department: string;
  position?: string; // ✅ 职务字段已定义
  professionalTitle?: string;
  // ... 其他字段
}

✅ 结论: TypeScript接口定义正确。


✅ 8. 前端模板检查(正确)

前端详情弹窗: web/src/views/rs/overseas/index.vue(第837行)

<el-descriptions-item label="职务" :span="2">
  {{ state.viewData.position || '-' }}
</el-descriptions-item>

✅ 结论: 前端模板正确引用了 position 字段。


✅ 9. 前端数据获取方法检查(正确)

查看详情方法: web/src/views/rs/overseas/index.vue(第1595-1604行)

const handleViewApplication = async (row: OverseasApplicationVO) => {
  try {
    const response = await getOverseasApplication(row.applicationId);
    state.viewData = response.data;  // 直接赋值响应数据
    state.viewDialog.title = '出国申请详情';
    state.viewDialog.visible = true;
  } catch (error) {
    console.error('获取申请详情失败:', error);
  }
};

✅ 结论: 前端数据获取方法正确。


🎯 问题根本原因分析

所有代码层面都是正确的!

经过完整的9个层面的检查:

  1. ✅ 数据库表结构
  2. ✅ 后端实体类
  3. ✅ 后端VO类
  4. ✅ Mapper XML映射
  5. ✅ Service层
  6. ✅ Controller层
  7. ✅ 前端TS接口
  8. ✅ 前端Vue模板
  9. ✅ 前端数据获取

所有代码都是正确的!


🔬 可能的原因

原因1:数据库中该记录的 position 字段确实为空

虽然用户说数据库中有数据,但可能:

  • ✅ 某些记录有数据
  • ❌ 查看的这条记录没有数据(NULL 或空字符串)

原因2:缓存问题

  • 后端可能有缓存(但检查代码没有发现缓存配置)
  • 前端浏览器缓存了旧的API响应

原因3:数据隔离问题

  • 多租户数据隔离
  • 逻辑删除标志(deleted字段)
  • 权限过滤

🛠️ 诊断步骤(请用户执行)

步骤1:确认数据库中具体记录的数据

请执行以下SQL,找到您查看详情的那条记录:

-- 替换 {application_id} 为您实际查看的申请ID
SELECT 
    application_id,
    applicant_name,
    department,
    position,
    professional_title,
    status,
    deleted,
    tenant_id,
    LENGTH(position) as position_length,
    HEX(position) as position_hex
FROM rs_overseas_application
WHERE application_id = {application_id};

关键检查:

  • position 字段值是什么?
  • position_length 是否为 0 或 NULL?
  • deleted 字段值是什么?(必须是 '0')

步骤2:查看后端API响应

  1. 打开浏览器开发者工具(F12)
  2. 切换到 Network(网络) 标签页
  3. 点击查看详情按钮
  4. 找到请求URL:/rs/overseas/application/{applicationId}
  5. 查看响应内容(Response)

检查响应JSON:

{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "applicationId": 123,
    "applicantName": "张三",
    "department": "智能控制学院",
    "position": "???",  // <-- 这里的值是什么?
    "professionalTitle": "高级职称"
  }
}

关键问题:

  • position 字段在响应中存在吗?
  • 如果存在,值是什么?(NULL / "" / 实际值)

步骤3:清除缓存重新测试

  1. 清除浏览器缓存:Ctrl+Shift+Delete(Windows)或 Cmd+Shift+Delete(Mac)
  2. 强制刷新页面:Ctrl+F5(Windows)或 Cmd+Shift+R(Mac)
  3. 重启后端服务(如果怀疑有后端缓存)
  4. 重新测试查看详情功能

步骤4:直接调用API测试

使用Postman或curl直接测试后端API:

# 替换 {token} 和 {application_id}
curl -X GET \
  'http://localhost:8080/rs/overseas/application/{application_id}' \
  -H 'Authorization: Bearer {token}' \
  -H 'clientid: your-client-id'

或者在浏览器控制台执行:

// 在已登录的页面中执行
fetch('/rs/overseas/application/123', {
  headers: {
    'Authorization': localStorage.getItem('token')
  }
})
.then(res => res.json())
.then(data => console.log('position值:', data.data.position));

📊 诊断决策树

数据库中position字段有数据?
├─ 是 → API响应中有position字段?
│        ├─ 是 → position值是什么?
│        │      ├─ NULL/空字符串 → **数据库该记录position确实为空**
│        │      └─ 有值 → 前端赋值问题(需要检查state.viewData)
│        └─ 否 → **后端序列化问题**(检查VO类的Getter方法)
│
└─ 否 → **数据库该记录position确实为空**
         → 需要更新数据库数据或在新增/编辑时填写职务字段

✅ 临时解决方案(如果数据确实为空)

方案1:批量更新现有数据

如果数据库中很多记录的 position 字段为空,可以批量更新:

-- 示例:根据职称自动填充职务
UPDATE rs_overseas_application
SET position = CASE 
    WHEN professional_title LIKE '%教授%' THEN '教授'
    WHEN professional_title LIKE '%副教授%' THEN '副教授'
    WHEN professional_title LIKE '%讲师%' THEN '讲师'
    WHEN professional_title LIKE '%主任%' THEN '主任'
    ELSE '教师'
END
WHERE (position IS NULL OR position = '')
  AND deleted = '0';

方案2:前端表单新增/编辑时强制填写

在前端表单中将 position 字段设为必填项:

<!-- web/src/views/rs/overseas/index.vue -->
<el-form-item label="职务" prop="position">
  <el-input v-model="applicationForm.position" placeholder="请输入职务" />
</el-form-item>

<!-- 表单验证规则 -->
<script setup lang="ts">
const rules = {
  position: [
    { required: true, message: '请输入职务', trigger: 'blur' }
  ]
};
</script>

📝 总结

代码层面

✅ 所有代码都是正确的,从数据库到前端的完整链路都没有问题。

问题本质

❓ 最可能的原因:数据库中查看的这条记录的 position 字段确实为空(NULL或空字符串)。

下一步

请用户按照诊断步骤执行检查,确认:

  1. 数据库中该记录的 position 字段实际值
  2. 后端API响应中的 position 字段值
  3. 是否有缓存影响

📁 附件文件

已生成以下诊断文件:

  • ✅ 检查职务字段数据.sql - 数据库诊断SQL脚本

诊断完成时间: 2025-10-09
诊断结论: 代码层面无问题,需要确认数据库实际数据
文档版本: v1.0