feat: Spring Boot 3.5.14 全量升级 + 组件升级
核心升级: - Spring Boot 2.7.18 → 3.5.14 - MyBatis Plus 3.5.5 → 3.5.16 (spring-boot3-starter) - Springdoc 1.8.0 → 2.8.6 (OpenAPI 3) - Flowable 6.8.0 → 7.1.0 - Druid 1.2.x → 1.2.28 (boot3-starter) - kotlin-reflect 1.9.10 → 1.9.25 迁移适配: - javax → jakarta 命名空间 (620+ 文件) - Swagger 注解迁移到 OpenAPI 3 (@Tag/@Schema/@Operation/@Parameter) - Spring Security 6.2 适配 (antMatchers→requestMatchers, EnableMethodSecurity) - Druid 包名迁移 (boot→boot3) - Redis 配置路径迁移 (spring.redis→spring.data.redis) - Flyway 适配 (flyway-database-postgresql) - Flowable 7.x 适配 (MULE_TASK_IMAGE 移除) 修复: - spring-boot-maven-plugin 2.5.15→3.5.14 (SPI服务发现失效) - mybatis-plus-boot-starter 3.5.5→3.5.16 (kotlin-reflect+fastjson2冲突) - Flowable database-schema-update 启用自动建表 验证: 23/23 测试通过, 1374 API端点正常
This commit is contained in:
@@ -0,0 +1,525 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 顶部查询条件 -->
|
||||
<div class="table-header">
|
||||
<el-select
|
||||
v-model="searchParams.locationId"
|
||||
class="table-header-search"
|
||||
placeholder="请选择库房"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in locationOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
v-model="searchParams.startTime"
|
||||
type="date"
|
||||
placeholder="选择开始时间"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="margin-right: 15px"
|
||||
/>
|
||||
|
||||
<el-date-picker
|
||||
v-model="searchParams.endTime"
|
||||
class="table-header-search"
|
||||
type="date"
|
||||
placeholder="选择结束时间"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
<el-button
|
||||
class="table-header-button"
|
||||
type="primary"
|
||||
@click="handleSearch"
|
||||
>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button
|
||||
class="table-header-button"
|
||||
@click="resetForm"
|
||||
>
|
||||
重置
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="reconciliationData"
|
||||
style="width: 100%"
|
||||
border
|
||||
>
|
||||
<el-table-column
|
||||
prop="locationId_dictText"
|
||||
label="库房"
|
||||
min-width="150"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="initialAmount"
|
||||
label="期初金额"
|
||||
min-width="160"
|
||||
align="right"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="finalAmount"
|
||||
label="期末金额"
|
||||
min-width="160"
|
||||
align="right"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div
|
||||
style="color: dodgerblue;cursor: pointer;"
|
||||
@click="skipToPage(scope, 1)"
|
||||
>
|
||||
{{ scope.row.finalAmount }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="expectFinalAmount"
|
||||
label="预期期末金额"
|
||||
min-width="160"
|
||||
align="right"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="offsetAmount"
|
||||
label="偏移量"
|
||||
min-width="100"
|
||||
align="right"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="purchaseInAmount"
|
||||
label="采购入库金额"
|
||||
min-width="120"
|
||||
align="right"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div
|
||||
style="color: dodgerblue;cursor: pointer;"
|
||||
@click="skipToPage(scope, 2)"
|
||||
>
|
||||
{{ scope.row.purchaseInAmount }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="purchaseInNumber"
|
||||
label="采购入库单据数"
|
||||
min-width="120"
|
||||
align="right"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="purchaseReturnAmount"
|
||||
label="采购出库金额"
|
||||
min-width="120"
|
||||
align="right"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div
|
||||
style="color: dodgerblue;cursor: pointer;"
|
||||
@click="skipToPage(scope, 3)"
|
||||
>
|
||||
{{ scope.row.purchaseReturnAmount }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="purchaseReturnNumber"
|
||||
label="采购出库单据数"
|
||||
min-width="120"
|
||||
align="right"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="applyOutAmount"
|
||||
label="领用出库金额"
|
||||
min-width="120"
|
||||
align="right"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div
|
||||
style="color: dodgerblue;cursor: pointer;"
|
||||
@click="skipToPage(scope, 4)"
|
||||
>
|
||||
{{ scope.row.applyOutAmount }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="applyOutNumber"
|
||||
label="领用出库单据数"
|
||||
min-width="120"
|
||||
align="right"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="applyReturnAmount"
|
||||
label="领用退货金额"
|
||||
min-width="120"
|
||||
align="right"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div
|
||||
style="color: dodgerblue;cursor: pointer;"
|
||||
@click="skipToPage(scope, 5)"
|
||||
>
|
||||
{{ scope.row.applyReturnAmount }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="applyReturnNumber"
|
||||
label="领用退货单据数"
|
||||
min-width="120"
|
||||
align="right"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="transferInAmount"
|
||||
label="调拨入库金额"
|
||||
min-width="120"
|
||||
align="right"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div
|
||||
style="color: dodgerblue;cursor: pointer;"
|
||||
@click="skipToPage(scope, 6)"
|
||||
>
|
||||
{{ scope.row.transferInAmount }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="transferInNumber"
|
||||
label="调拨入库单据数"
|
||||
min-width="120"
|
||||
align="right"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="transferOutAmount"
|
||||
label="调拨出库金额"
|
||||
min-width="120"
|
||||
align="right"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div
|
||||
style="color: dodgerblue;cursor: pointer;"
|
||||
@click="skipToPage(scope, 10)"
|
||||
>
|
||||
{{ scope.row.transferOutAmount }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="transferOutNumber"
|
||||
label="调拨出库单据数"
|
||||
min-width="120"
|
||||
align="right"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="checkProfitLossAmount"
|
||||
label="盘点盈亏金额"
|
||||
min-width="120"
|
||||
align="right"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div
|
||||
style="color: dodgerblue;cursor: pointer;"
|
||||
@click="skipToPage(scope, 7)"
|
||||
>
|
||||
{{ scope.row.checkProfitLossAmount }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="checkProfitLossNumber"
|
||||
label="盘点盈亏单据数"
|
||||
min-width="120"
|
||||
align="right"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="lossAmount"
|
||||
label="报损金额"
|
||||
min-width="100"
|
||||
align="right"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div
|
||||
style="color: dodgerblue;cursor: pointer;"
|
||||
@click="skipToPage(scope, 8)"
|
||||
>
|
||||
{{ scope.row.lossAmount }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="lossNumber"
|
||||
label="报损单据数"
|
||||
min-width="100"
|
||||
align="right"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="drugIssueAmount"
|
||||
label="药品发放金额"
|
||||
min-width="120"
|
||||
align="right"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div
|
||||
style="color: dodgerblue;cursor: pointer;"
|
||||
@click="skipToPage(scope, 9)"
|
||||
>
|
||||
{{ scope.row.drugIssueAmount }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {onMounted, reactive, ref} from 'vue';
|
||||
import {ElMessage} from 'element-plus';
|
||||
// 导入路由钩子
|
||||
import {useRouter} from 'vue-router';
|
||||
// 假设API模块存在,实际项目中需要根据实际情况导入
|
||||
import {getList, getPharmacyList} from './components/api.js';
|
||||
|
||||
// 创建路由实例
|
||||
const router = useRouter();
|
||||
|
||||
// 搜索参数
|
||||
const searchParams = reactive({
|
||||
locationId: '',
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
});
|
||||
|
||||
// 搜索表单引用
|
||||
const searchFormRef = ref(null);
|
||||
|
||||
// 库房选项
|
||||
const locationOptions = ref([]);
|
||||
|
||||
// 对账数据
|
||||
const reconciliationData = ref([]);
|
||||
|
||||
// 加载状态
|
||||
const loading = ref(false);
|
||||
|
||||
// 格式化金额
|
||||
const formatMoney = (value) => {
|
||||
if (value === null || value === undefined) return '0.00';
|
||||
return Number(value).toFixed(2);
|
||||
};
|
||||
|
||||
// 格式化日期为YYYY-MM-DD
|
||||
const formatDate = (date) => {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
};
|
||||
|
||||
// 设置默认日期范围(今日之前一个月)
|
||||
const setDefaultDateRange = () => {
|
||||
const today = new Date();
|
||||
// 结束时间为昨天
|
||||
const endDate = new Date(today);
|
||||
endDate.setDate(today.getDate() - 1);
|
||||
|
||||
// 开始时间为一个月前的今天
|
||||
const startDate = new Date(today);
|
||||
startDate.setMonth(today.getMonth() - 1);
|
||||
|
||||
// 处理月份溢出(如1月减1个月变为12月)
|
||||
if (startDate.getMonth() === 11 && today.getMonth() === 0) {
|
||||
startDate.setFullYear(today.getFullYear() - 1);
|
||||
}
|
||||
|
||||
// 确保日期有效性(处理不同月份天数差异)
|
||||
const lastDayOfMonth = new Date(startDate.getFullYear(), startDate.getMonth() + 1, 0).getDate();
|
||||
if (startDate.getDate() > lastDayOfMonth) {
|
||||
startDate.setDate(lastDayOfMonth);
|
||||
}
|
||||
|
||||
searchParams.startTime = formatDate(startDate);
|
||||
searchParams.endTime = formatDate(endDate);
|
||||
};
|
||||
|
||||
// 查询数据
|
||||
const handleSearch = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
// 构建查询参数并拼接时间
|
||||
const params = {
|
||||
locationId: searchParams.locationId
|
||||
};
|
||||
|
||||
// 处理开始时间,拼接 00:00:00
|
||||
if (searchParams.startTime) {
|
||||
params.startTime = searchParams.startTime + ' 00:00:00';
|
||||
}
|
||||
|
||||
// 处理结束时间,拼接 00:00:00
|
||||
if (searchParams.endTime) {
|
||||
params.endTime = searchParams.endTime + ' 00:00:00';
|
||||
}
|
||||
|
||||
// 调用API获取数据,实际项目中替换为真实API调用
|
||||
const response = await getList(params);
|
||||
loading.value = false;
|
||||
console.log('查询结果:', response)
|
||||
reconciliationData.value = [];
|
||||
reconciliationData.value.push(response.data.data)
|
||||
|
||||
} catch (error) {
|
||||
ElMessage.error('获取对账数据失败: ' + (error.message || '未知错误'));
|
||||
console.error('Failed to get reconciliation data:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
searchFormRef.value?.resetFields();
|
||||
// 重置后重新设置默认日期范围
|
||||
setDefaultDateRange();
|
||||
};
|
||||
|
||||
// 获取库房列表
|
||||
const getLocationList = async () => {
|
||||
try {
|
||||
// 调用API获取库房数据,实际项目中替换为真实API调用
|
||||
const response = await getPharmacyList();
|
||||
locationOptions.value = response.data.locationListOptions || [];
|
||||
|
||||
// 默认选择第一个库房
|
||||
if (locationOptions.value.length > 0) {
|
||||
searchParams.locationId = locationOptions.value[0].value;
|
||||
}
|
||||
handleSearch()
|
||||
} catch (error) {
|
||||
ElMessage.error('获取库房数据失败: ' + (error.message || '未知错误'));
|
||||
console.error('Failed to get location list:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 跳转到对应页面的函数
|
||||
const skipToPage = (records, index) => {
|
||||
// 获取当前选中的库房ID和日期范围
|
||||
const { startTime, endTime } = searchParams;
|
||||
console.log(records.row)
|
||||
const { locationId } = records.row;
|
||||
// 根据index跳转到不同页面
|
||||
let path = '';
|
||||
switch (index) {
|
||||
case 1:
|
||||
path = '/aa/4/chkstockPartDetails'; // 库存
|
||||
break;
|
||||
case 2:
|
||||
path = '/aa/4/purchaseDocumentDetsils'; // 采购入库页
|
||||
break;
|
||||
case 3:
|
||||
path = '/aa/4/purchaseReturnDetsils'; // 采购退货页
|
||||
break;
|
||||
case 4:
|
||||
path = '/aa/4/requisitionDetails'; // 领用出库页
|
||||
break;
|
||||
case 5:
|
||||
path = '/aa/4/returnOrutboundDetails'; // 领用退库页
|
||||
break;
|
||||
case 6:
|
||||
case 10:
|
||||
path = '/aa/4/transferManagentDetails'; // 调拨页
|
||||
break;
|
||||
case 7:
|
||||
path = '/aa/4/chkstockPartDetails'; // 盘点页
|
||||
break;
|
||||
case 8:
|
||||
path = '/aa/4/lossReportingDetails'; // 报损页
|
||||
break;
|
||||
case 9:
|
||||
path = '/aa/3/medicationDetails'; // 药品发放
|
||||
break;
|
||||
default:
|
||||
ElMessage.warning('无效的页面索引');
|
||||
return;
|
||||
}
|
||||
|
||||
// 跳转到对应页面并传递参数
|
||||
if(index === 10) {
|
||||
router.push({
|
||||
path: path,
|
||||
query: {
|
||||
sourceLocationId: locationId,
|
||||
occurrenceTimeSTime: startTime,
|
||||
occurrenceTimeETime: endTime,
|
||||
}
|
||||
});
|
||||
}else if(index ===1) {
|
||||
router.push({
|
||||
path: path,
|
||||
query: {
|
||||
sourceLocationId: locationId,
|
||||
time: endTime,
|
||||
type: '1'
|
||||
}
|
||||
});
|
||||
}else {
|
||||
router.push({
|
||||
path: path,
|
||||
query: {
|
||||
purposeLocationId: locationId,
|
||||
occurrenceTimeSTime: startTime,
|
||||
occurrenceTimeETime: endTime
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 组件初始化
|
||||
onMounted(() => {
|
||||
// 设置默认日期范围
|
||||
setDefaultDateRange();
|
||||
getLocationList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.table-header-search {
|
||||
width: 200px;
|
||||
float: left;
|
||||
margin-right: 15px;
|
||||
}
|
||||
.table-header {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 15px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.table-header-button {
|
||||
float: right;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
background-color: #fff;
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.text-red {
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
.text-green {
|
||||
color: #67c23a;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user