fix: 修复采购交易申请日期查询条件未生效问题
问题描述: - 前后端参数格式不匹配导致日期查询条件无法生效 - 后端期望 applyDateStart/applyDateEnd,前端发送 params.beginApplyDate/params.endApplyDate - Mapper XML 中同时存在两套参数导致混乱 修复方案: 统一使用扁平化参数格式 applyDateStart/applyDateEnd 前端修改: 1. 新增 addDateRangeFlat 工具方法 (ruoyi-ui/src/utils/ruoyi.js) - 支持扁平化日期参数格式,不使用 params 包装 - 参数: addDateRangeFlat(params, dateRange, startPropName, endPropName) 2. 全局注册新方法 (ruoyi-ui/src/main.js) - 导入并挂载到 Vue.prototype.addDateRangeFlat 3. 采购交易页面使用新方法 (ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue) - 将 addDateRange() 改为 addDateRangeFlat() - 传入参数: 'applyDateStart', 'applyDateEnd' 后端修改: - 删除 Mapper XML 中 params.beginApplyDate/params.endApplyDate 相关条件 - 保留 applyDateStart/applyDateEnd 条件 测试: - 添加测试脚本 doc/test-data/purchase_transaction/test-date-query.js - 支持多种日期范围查询场景测试 影响范围: - 仅影响采购交易管理模块 - 保留原有 addDateRange 方法,其他模块不受影响 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
278
doc/test-data/purchase_transaction/test-date-query.js
Normal file
278
doc/test-data/purchase_transaction/test-date-query.js
Normal file
@@ -0,0 +1,278 @@
|
||||
/**
|
||||
* 采购交易申请日期查询功能测试脚本
|
||||
*
|
||||
* 测试目的: 验证申请日期查询条件修复后能正常工作
|
||||
* 问题描述: 之前申请日期查询条件未生效,原因是 Mapper XML 中存在两套参数名导致混乱
|
||||
* 修复方案: 统一使用 applyDateStart 和 applyDateEnd 作为日期查询参数
|
||||
*/
|
||||
|
||||
const axios = require('axios');
|
||||
const fs = require('fs');
|
||||
|
||||
const BASE_URL = 'http://localhost:8080';
|
||||
|
||||
// 测试配置
|
||||
const TEST_CONFIG = {
|
||||
// 使用固定的测试账号
|
||||
username: 'admin',
|
||||
password: 'admin123',
|
||||
};
|
||||
|
||||
/**
|
||||
* 登录获取 token
|
||||
*/
|
||||
async function login() {
|
||||
try {
|
||||
console.log('📝 正在登录...');
|
||||
const response = await axios.post(`${BASE_URL}/login/test`, {
|
||||
username: TEST_CONFIG.username,
|
||||
password: TEST_CONFIG.password
|
||||
});
|
||||
|
||||
if (response.data.code === 200) {
|
||||
const token = response.data.data.token;
|
||||
console.log('✅ 登录成功!');
|
||||
console.log(` Token: ${token.substring(0, 20)}...`);
|
||||
return token;
|
||||
} else {
|
||||
throw new Error(`登录失败: ${response.data.msg}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ 登录失败:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试申请日期查询功能
|
||||
*/
|
||||
async function testDateQuery(token) {
|
||||
const testResults = [];
|
||||
const config = {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
console.log('\n📊 开始测试申请日期查询功能...\n');
|
||||
|
||||
// 测试1: 不带日期查询条件(获取所有数据)
|
||||
console.log('测试1: 不带日期查询条件');
|
||||
const response1 = await axios.get(`${BASE_URL}/ccdi/purchaseTransaction/list`, {
|
||||
...config,
|
||||
params: {
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
});
|
||||
|
||||
const totalRecords = response1.data.total;
|
||||
console.log(` 总记录数: ${totalRecords}`);
|
||||
testResults.push({
|
||||
test: '无日期条件查询',
|
||||
status: response1.data.code === 200 ? '✅ 通过' : '❌ 失败',
|
||||
total: totalRecords
|
||||
});
|
||||
|
||||
if (totalRecords === 0) {
|
||||
console.log('⚠️ 数据库中没有数据,无法继续测试日期查询功能');
|
||||
return testResults;
|
||||
}
|
||||
|
||||
// 测试2: 查询2024年的申请日期
|
||||
console.log('\n测试2: 查询2024-01-01到2024-12-31的申请日期');
|
||||
const response2 = await axios.get(`${BASE_URL}/ccdi/purchaseTransaction/list`, {
|
||||
...config,
|
||||
params: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
applyDateStart: '2024-01-01',
|
||||
applyDateEnd: '2024-12-31'
|
||||
}
|
||||
});
|
||||
|
||||
const records2024 = response2.data.total;
|
||||
console.log(` 2024年记录数: ${records2024}`);
|
||||
testResults.push({
|
||||
test: '2024年日期查询',
|
||||
status: response2.data.code === 200 ? '✅ 通过' : '❌ 失败',
|
||||
total: records2024,
|
||||
params: 'applyDateStart=2024-01-01, applyDateEnd=2024-12-31'
|
||||
});
|
||||
|
||||
// 测试3: 查询2025年的申请日期
|
||||
console.log('\n测试3: 查询2025-01-01到2025-12-31的申请日期');
|
||||
const response3 = await axios.get(`${BASE_URL}/ccdi/purchaseTransaction/list`, {
|
||||
...config,
|
||||
params: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
applyDateStart: '2025-01-01',
|
||||
applyDateEnd: '2025-12-31'
|
||||
}
|
||||
});
|
||||
|
||||
const records2025 = response3.data.total;
|
||||
console.log(` 2025年记录数: ${records2025}`);
|
||||
testResults.push({
|
||||
test: '2025年日期查询',
|
||||
status: response3.data.code === 200 ? '✅ 通过' : '❌ 失败',
|
||||
total: records2025,
|
||||
params: 'applyDateStart=2025-01-01, applyDateEnd=2025-12-31'
|
||||
});
|
||||
|
||||
// 测试4: 查询2026年2月的申请日期
|
||||
console.log('\n测试4: 查询2026-02-01到2026-02-28的申请日期');
|
||||
const response4 = await axios.get(`${BASE_URL}/ccdi/purchaseTransaction/list`, {
|
||||
...config,
|
||||
params: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
applyDateStart: '2026-02-01',
|
||||
applyDateEnd: '2026-02-28'
|
||||
}
|
||||
});
|
||||
|
||||
const recordsFeb2026 = response4.data.total;
|
||||
console.log(` 2026年2月记录数: ${recordsFeb2026}`);
|
||||
testResults.push({
|
||||
test: '2026年2月日期查询',
|
||||
status: response4.data.code === 200 ? '✅ 通过' : '❌ 失败',
|
||||
total: recordsFeb2026,
|
||||
params: 'applyDateStart=2026-02-01, applyDateEnd=2026-02-28'
|
||||
});
|
||||
|
||||
// 测试5: 只传入开始日期
|
||||
console.log('\n测试5: 只传入开始日期(2024-01-01)');
|
||||
const response5 = await axios.get(`${BASE_URL}/ccdi/purchaseTransaction/list`, {
|
||||
...config,
|
||||
params: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
applyDateStart: '2024-01-01'
|
||||
}
|
||||
});
|
||||
|
||||
const recordsFrom2024 = response5.data.total;
|
||||
console.log(` 2024-01-01之后记录数: ${recordsFrom2024}`);
|
||||
testResults.push({
|
||||
test: '只有开始日期查询',
|
||||
status: response5.data.code === 200 ? '✅ 通过' : '❌ 失败',
|
||||
total: recordsFrom2024,
|
||||
params: 'applyDateStart=2024-01-01'
|
||||
});
|
||||
|
||||
// 测试6: 只传入结束日期
|
||||
console.log('\n测试6: 只传入结束日期(2024-12-31)');
|
||||
const response6 = await axios.get(`${BASE_URL}/ccdi/purchaseTransaction/list`, {
|
||||
...config,
|
||||
params: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
applyDateEnd: '2024-12-31'
|
||||
}
|
||||
});
|
||||
|
||||
const recordsUntil2024 = response6.data.total;
|
||||
console.log(` 2024-12-31之前记录数: ${recordsUntil2024}`);
|
||||
testResults.push({
|
||||
test: '只有结束日期查询',
|
||||
status: response6.data.code === 200 ? '✅ 通过' : '❌ 失败',
|
||||
total: recordsUntil2024,
|
||||
params: 'applyDateEnd=2024-12-31'
|
||||
});
|
||||
|
||||
// 验证: 日期查询是否生效
|
||||
console.log('\n🔍 验证结果:');
|
||||
console.log(` 总记录数: ${totalRecords}`);
|
||||
console.log(` 2024年: ${records2024}条`);
|
||||
console.log(` 2025年: ${records2025}条`);
|
||||
console.log(` 2026年2月: ${recordsFeb2026}条`);
|
||||
|
||||
const dateQueryWorks = (records2024 !== totalRecords) ||
|
||||
(records2025 !== totalRecords) ||
|
||||
(recordsFeb2026 !== totalRecords);
|
||||
|
||||
if (dateQueryWorks) {
|
||||
console.log(' ✅ 日期查询功能正常!不同日期范围返回不同的记录数');
|
||||
} else {
|
||||
console.log(' ⚠️ 日期查询可能未生效,所有日期范围返回相同记录数');
|
||||
console.log(' 提示: 如果数据库中所有记录的申请日期都在同一个范围内,这是正常现象');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 测试失败:', error.message);
|
||||
if (error.response) {
|
||||
console.error(' 响应数据:', error.response.data);
|
||||
}
|
||||
testResults.push({
|
||||
test: '异常',
|
||||
status: '❌ 失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
|
||||
return testResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成测试报告
|
||||
*/
|
||||
function generateReport(testResults, testResultsPath) {
|
||||
const report = {
|
||||
testDate: new Date().toISOString(),
|
||||
description: '采购交易申请日期查询功能测试报告',
|
||||
issue: '申请日期查询条件未生效',
|
||||
fix: '统一使用 applyDateStart 和 applyDateEnd 作为日期查询参数',
|
||||
results: testResults
|
||||
};
|
||||
|
||||
fs.writeFileSync(testResultsPath, JSON.stringify(report, null, 2));
|
||||
console.log(`\n📄 测试报告已保存: ${testResultsPath}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 主函数
|
||||
*/
|
||||
async function main() {
|
||||
console.log('=================================');
|
||||
console.log('采购交易申请日期查询功能测试');
|
||||
console.log('=================================\n');
|
||||
|
||||
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
|
||||
const testResultsPath = `doc/test-results/purchase-transaction-date-query-${timestamp}.json`;
|
||||
|
||||
// 确保测试结果目录存在
|
||||
const testResultsDir = 'doc/test-results';
|
||||
if (!fs.existsSync(testResultsDir)) {
|
||||
fs.mkdirSync(testResultsDir, { recursive: true });
|
||||
}
|
||||
|
||||
try {
|
||||
// 登录获取token
|
||||
const token = await login();
|
||||
|
||||
// 测试日期查询功能
|
||||
const testResults = await testDateQuery(token);
|
||||
|
||||
// 生成测试报告
|
||||
generateReport(testResults, testResultsPath);
|
||||
|
||||
console.log('\n=================================');
|
||||
console.log('✅ 测试完成!');
|
||||
console.log('=================================\n');
|
||||
|
||||
// 显示汇总
|
||||
const passedTests = testResults.filter(r => r.status.includes('通过')).length;
|
||||
const totalTests = testResults.length;
|
||||
console.log(`测试结果: ${passedTests}/${totalTests} 通过`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('\n❌ 测试失败:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// 运行测试
|
||||
main();
|
||||
@@ -18,7 +18,7 @@ import './assets/icons' // icon
|
||||
import './permission' // permission control
|
||||
import { getDicts } from "@/api/system/dict/data"
|
||||
import { getConfigKey } from "@/api/system/config"
|
||||
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi"
|
||||
import { parseTime, resetForm, addDateRange, addDateRangeFlat, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi"
|
||||
// 分页组件
|
||||
import Pagination from "@/components/Pagination"
|
||||
// 自定义表格工具组件
|
||||
@@ -42,6 +42,7 @@ Vue.prototype.getConfigKey = getConfigKey
|
||||
Vue.prototype.parseTime = parseTime
|
||||
Vue.prototype.resetForm = resetForm
|
||||
Vue.prototype.addDateRange = addDateRange
|
||||
Vue.prototype.addDateRangeFlat = addDateRangeFlat
|
||||
Vue.prototype.selectDictLabel = selectDictLabel
|
||||
Vue.prototype.selectDictLabels = selectDictLabels
|
||||
Vue.prototype.download = download
|
||||
|
||||
@@ -66,6 +66,18 @@ export function addDateRange(params, dateRange, propName) {
|
||||
return search
|
||||
}
|
||||
|
||||
// 添加日期范围(扁平化参数格式)
|
||||
// 使用场景: 后端DTO直接定义了 startDate/endDate 字段,而不是使用 params 包装
|
||||
export function addDateRangeFlat(params, dateRange, startPropName, endPropName) {
|
||||
let search = params
|
||||
dateRange = Array.isArray(dateRange) ? dateRange : []
|
||||
if (typeof (startPropName) !== 'undefined' && typeof (endPropName) !== 'undefined') {
|
||||
search[startPropName] = dateRange[0]
|
||||
search[endPropName] = dateRange[1]
|
||||
}
|
||||
return search
|
||||
}
|
||||
|
||||
// 回显数据字典
|
||||
export function selectDictLabel(datas, value) {
|
||||
if (value === undefined) {
|
||||
|
||||
@@ -769,7 +769,7 @@ export default {
|
||||
/** 查询采购交易列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
const params = this.addDateRange(this.queryParams, this.dateRange, 'applyDate');
|
||||
const params = this.addDateRangeFlat(this.queryParams, this.dateRange, 'applyDateStart', 'applyDateEnd');
|
||||
listTransaction(params).then(response => {
|
||||
this.transactionList = response.rows;
|
||||
this.total = response.total;
|
||||
|
||||
Reference in New Issue
Block a user