分配详情
This commit is contained in:
parent
88427cab99
commit
d64ce88ec8
|
|
@ -507,7 +507,7 @@ public class AllocationsController : BaseApiController
|
|||
/// 获取按单位汇总的上报数据
|
||||
/// </summary>
|
||||
[HttpGet("distributions/{distributionId}/summary")]
|
||||
public async Task<IActionResult> GetReportSummaryByUnit(int distributionId, [FromQuery] string? period = null)
|
||||
public async Task<IActionResult> GetReportSummaryByUnit(int distributionId, [FromQuery] string? period = null, [FromQuery] string? startDate = null, [FromQuery] string? endDate = null)
|
||||
{
|
||||
var unitId = GetCurrentUnitId();
|
||||
var unitLevel = GetCurrentUnitLevel();
|
||||
|
|
@ -521,23 +521,30 @@ public class AllocationsController : BaseApiController
|
|||
return NotFound(new { message = "配额分配记录不存在" });
|
||||
|
||||
// 计算时间范围
|
||||
DateTime? startDate = null;
|
||||
DateTime? endDate = null;
|
||||
if (!string.IsNullOrEmpty(period) && period != "all")
|
||||
DateTime? queryStartDate = null;
|
||||
DateTime? queryEndDate = null;
|
||||
|
||||
if (period == "custom" && !string.IsNullOrEmpty(startDate) && !string.IsNullOrEmpty(endDate))
|
||||
{
|
||||
endDate = DateTime.Now;
|
||||
startDate = period switch
|
||||
// 自定义时间范围
|
||||
queryStartDate = DateTime.Parse(startDate);
|
||||
queryEndDate = DateTime.Parse(endDate).AddDays(1).AddSeconds(-1);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(period) && period != "all")
|
||||
{
|
||||
"week" => endDate.Value.AddDays(-7),
|
||||
"month" => endDate.Value.AddMonths(-1),
|
||||
"halfYear" => endDate.Value.AddMonths(-6),
|
||||
"year" => endDate.Value.AddYears(-1),
|
||||
queryEndDate = DateTime.Now;
|
||||
queryStartDate = period switch
|
||||
{
|
||||
"week" => queryEndDate.Value.AddDays(-7),
|
||||
"month" => queryEndDate.Value.AddMonths(-1),
|
||||
"halfYear" => queryEndDate.Value.AddMonths(-6),
|
||||
"year" => queryEndDate.Value.AddYears(-1),
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
||||
// 获取按单位汇总的上报数据
|
||||
var summaries = await _allocationService.GetReportSummaryByUnitAsync(distributionId, unitId.Value, unitLevel.Value, startDate, endDate);
|
||||
var summaries = await _allocationService.GetReportSummaryByUnitAsync(distributionId, unitId.Value, unitLevel.Value, queryStartDate, queryEndDate);
|
||||
|
||||
return Ok(summaries);
|
||||
}
|
||||
|
|
@ -548,7 +555,7 @@ public class AllocationsController : BaseApiController
|
|||
/// </summary>
|
||||
[HttpGet("{id}/consumption-stats")]
|
||||
[Authorize(Policy = "DivisionLevel")]
|
||||
public async Task<IActionResult> GetConsumptionStats(int id, [FromQuery] string period = "month")
|
||||
public async Task<IActionResult> GetConsumptionStats(int id, [FromQuery] string period = "month", [FromQuery] string? startDate = null, [FromQuery] string? endDate = null)
|
||||
{
|
||||
var unitId = GetCurrentUnitId();
|
||||
var unitLevel = GetCurrentUnitLevel();
|
||||
|
|
@ -562,18 +569,30 @@ public class AllocationsController : BaseApiController
|
|||
return NotFound(new { message = "配额不存在" });
|
||||
|
||||
// 计算时间范围
|
||||
var endDate = DateTime.Now;
|
||||
var startDate = period switch
|
||||
DateTime queryEndDate;
|
||||
DateTime queryStartDate;
|
||||
|
||||
if (period == "custom" && !string.IsNullOrEmpty(startDate) && !string.IsNullOrEmpty(endDate))
|
||||
{
|
||||
"week" => endDate.AddDays(-7),
|
||||
"month" => endDate.AddMonths(-1),
|
||||
"halfYear" => endDate.AddMonths(-6),
|
||||
"year" => endDate.AddYears(-1),
|
||||
_ => endDate.AddMonths(-1)
|
||||
// 自定义时间范围
|
||||
queryStartDate = DateTime.Parse(startDate);
|
||||
queryEndDate = DateTime.Parse(endDate).AddDays(1).AddSeconds(-1); // 包含结束日期当天
|
||||
}
|
||||
else
|
||||
{
|
||||
queryEndDate = DateTime.Now;
|
||||
queryStartDate = period switch
|
||||
{
|
||||
"week" => queryEndDate.AddDays(-7),
|
||||
"month" => queryEndDate.AddMonths(-1),
|
||||
"halfYear" => queryEndDate.AddMonths(-6),
|
||||
"year" => queryEndDate.AddYears(-1),
|
||||
_ => queryEndDate.AddMonths(-1)
|
||||
};
|
||||
}
|
||||
|
||||
// 获取按单位汇总的消耗统计
|
||||
var stats = await _allocationService.GetConsumptionStatsByPeriodAsync(id, startDate, endDate);
|
||||
var stats = await _allocationService.GetConsumptionStatsByPeriodAsync(id, queryStartDate, queryEndDate);
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
|
|
@ -582,8 +601,8 @@ public class AllocationsController : BaseApiController
|
|||
unit = allocation.Unit,
|
||||
totalQuota = allocation.TotalQuota,
|
||||
period,
|
||||
startDate,
|
||||
endDate,
|
||||
startDate = queryStartDate,
|
||||
endDate = queryEndDate,
|
||||
unitStats = stats
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,16 +53,23 @@ export const allocationsApi = {
|
|||
return response.data
|
||||
},
|
||||
|
||||
async getReportSummaryByUnit(distributionId: number, period?: string): Promise<UnitReportSummary[]> {
|
||||
async getReportSummaryByUnit(distributionId: number, period?: string, startDate?: string, endDate?: string): Promise<UnitReportSummary[]> {
|
||||
const params: Record<string, string> = {}
|
||||
if (period) params.period = period
|
||||
if (startDate) params.startDate = startDate
|
||||
if (endDate) params.endDate = endDate
|
||||
const response = await apiClient.get<UnitReportSummary[]>(`/allocations/distributions/${distributionId}/summary`, {
|
||||
params: period ? { period } : undefined
|
||||
params: Object.keys(params).length > 0 ? params : undefined
|
||||
})
|
||||
return response.data
|
||||
},
|
||||
|
||||
async getConsumptionStats(allocationId: number, period: string): Promise<ConsumptionStatsResponse> {
|
||||
async getConsumptionStats(allocationId: number, period: string, startDate?: string, endDate?: string): Promise<ConsumptionStatsResponse> {
|
||||
const params: Record<string, string> = { period }
|
||||
if (startDate) params.startDate = startDate
|
||||
if (endDate) params.endDate = endDate
|
||||
const response = await apiClient.get<ConsumptionStatsResponse>(`/allocations/${allocationId}/consumption-stats`, {
|
||||
params: { period }
|
||||
params
|
||||
})
|
||||
return response.data
|
||||
}
|
||||
|
|
|
|||
|
|
@ -258,13 +258,51 @@
|
|||
<!-- 师部账号:时间范围筛选 -->
|
||||
<div v-if="authStore.canCreateAllocations" class="period-filter">
|
||||
<span class="filter-label">查看时间范围:</span>
|
||||
<el-radio-group v-model="selectedPeriod" size="small" @change="handlePeriodChange">
|
||||
<el-radio-button value="week">本周</el-radio-button>
|
||||
<el-radio-button value="month">本月</el-radio-button>
|
||||
<el-radio-button value="halfYear">半年</el-radio-button>
|
||||
<el-radio-button value="year">年度</el-radio-button>
|
||||
<el-radio-group v-model="periodType" size="small" @change="handlePeriodTypeChange">
|
||||
<el-radio-button value="week">按周</el-radio-button>
|
||||
<el-radio-button value="month">按月</el-radio-button>
|
||||
<el-radio-button value="halfYear">按半年</el-radio-button>
|
||||
<el-radio-button value="year">按年</el-radio-button>
|
||||
<el-radio-button value="all">全部</el-radio-button>
|
||||
</el-radio-group>
|
||||
<template v-if="periodType === 'week'">
|
||||
<el-date-picker
|
||||
v-model="selectedWeek"
|
||||
type="week"
|
||||
format="YYYY 第 ww 周"
|
||||
placeholder="选择周"
|
||||
size="small"
|
||||
style="width: 160px; margin-left: 12px;"
|
||||
@change="handleDateChange"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="periodType === 'month'">
|
||||
<el-date-picker
|
||||
v-model="selectedMonth"
|
||||
type="month"
|
||||
format="YYYY-MM"
|
||||
placeholder="选择月份"
|
||||
size="small"
|
||||
style="width: 140px; margin-left: 12px;"
|
||||
@change="handleDateChange"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="periodType === 'halfYear'">
|
||||
<el-select v-model="selectedHalfYear" placeholder="选择半年" size="small" style="width: 160px; margin-left: 12px;" @change="handleDateChange">
|
||||
<el-option v-for="item in halfYearOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else-if="periodType === 'year'">
|
||||
<el-date-picker
|
||||
v-model="selectedYear"
|
||||
type="year"
|
||||
format="YYYY"
|
||||
placeholder="选择年份"
|
||||
size="small"
|
||||
style="width: 120px; margin-left: 12px;"
|
||||
@change="handleDateChange"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- 师团级和团级显示分配列表,营部及以下隐藏 -->
|
||||
|
|
@ -382,13 +420,51 @@
|
|||
<!-- 师部账号:时间范围筛选 -->
|
||||
<div v-if="authStore.canCreateAllocations" class="period-filter">
|
||||
<span class="filter-label">查看时间范围:</span>
|
||||
<el-radio-group v-model="reportsPeriod" size="small" @change="handleReportsPeriodChange">
|
||||
<el-radio-button value="week">本周</el-radio-button>
|
||||
<el-radio-button value="month">本月</el-radio-button>
|
||||
<el-radio-button value="halfYear">半年</el-radio-button>
|
||||
<el-radio-button value="year">年度</el-radio-button>
|
||||
<el-radio-group v-model="reportsPeriodType" size="small" @change="handleReportsPeriodTypeChange">
|
||||
<el-radio-button value="week">按周</el-radio-button>
|
||||
<el-radio-button value="month">按月</el-radio-button>
|
||||
<el-radio-button value="halfYear">按半年</el-radio-button>
|
||||
<el-radio-button value="year">按年</el-radio-button>
|
||||
<el-radio-button value="all">全部</el-radio-button>
|
||||
</el-radio-group>
|
||||
<template v-if="reportsPeriodType === 'week'">
|
||||
<el-date-picker
|
||||
v-model="reportsSelectedWeek"
|
||||
type="week"
|
||||
format="YYYY 第 ww 周"
|
||||
placeholder="选择周"
|
||||
size="small"
|
||||
style="width: 160px; margin-left: 12px;"
|
||||
@change="handleReportsDateChange"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="reportsPeriodType === 'month'">
|
||||
<el-date-picker
|
||||
v-model="reportsSelectedMonth"
|
||||
type="month"
|
||||
format="YYYY-MM"
|
||||
placeholder="选择月份"
|
||||
size="small"
|
||||
style="width: 140px; margin-left: 12px;"
|
||||
@change="handleReportsDateChange"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="reportsPeriodType === 'halfYear'">
|
||||
<el-select v-model="reportsSelectedHalfYear" placeholder="选择半年" size="small" style="width: 160px; margin-left: 12px;" @change="handleReportsDateChange">
|
||||
<el-option v-for="item in halfYearOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else-if="reportsPeriodType === 'year'">
|
||||
<el-date-picker
|
||||
v-model="reportsSelectedYear"
|
||||
type="year"
|
||||
format="YYYY"
|
||||
placeholder="选择年份"
|
||||
size="small"
|
||||
style="width: 120px; margin-left: 12px;"
|
||||
@change="handleReportsDateChange"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<el-tabs v-model="reportsTabActive" class="reports-tabs">
|
||||
|
|
@ -505,6 +581,31 @@ const selectedDistribution = ref<AllocationDistribution | null>(null)
|
|||
const selectedPeriod = ref('all')
|
||||
const reportsPeriod = ref('all')
|
||||
|
||||
// 时间范围筛选相关
|
||||
const periodType = ref('all')
|
||||
const selectedWeek = ref<Date | null>(null)
|
||||
const selectedMonth = ref<Date | null>(null)
|
||||
const selectedYear = ref<Date | null>(null)
|
||||
const selectedHalfYear = ref('')
|
||||
|
||||
// 上报记录时间范围筛选相关
|
||||
const reportsPeriodType = ref('all')
|
||||
const reportsSelectedWeek = ref<Date | null>(null)
|
||||
const reportsSelectedMonth = ref<Date | null>(null)
|
||||
const reportsSelectedYear = ref<Date | null>(null)
|
||||
const reportsSelectedHalfYear = ref('')
|
||||
|
||||
// 生成半年选项(最近3年的上半年和下半年)
|
||||
const halfYearOptions = computed(() => {
|
||||
const options = []
|
||||
const currentYear = new Date().getFullYear()
|
||||
for (let year = currentYear; year >= currentYear - 2; year--) {
|
||||
options.push({ label: `${year}年下半年`, value: `${year}-H2` })
|
||||
options.push({ label: `${year}年上半年`, value: `${year}-H1` })
|
||||
}
|
||||
return options
|
||||
})
|
||||
|
||||
const pagination = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
|
|
@ -633,7 +734,7 @@ function getTotalDistributed(): number {
|
|||
|
||||
function getTotalConsumed(): number {
|
||||
// 如果有按时间范围筛选的统计数据,使用统计数据
|
||||
if (authStore.canCreateAllocations && selectedPeriod.value !== 'all' && consumptionStats.value.length > 0) {
|
||||
if (authStore.canCreateAllocations && consumptionStats.value.length > 0) {
|
||||
return consumptionStats.value.reduce((sum: number, s) => sum + s.totalConsumed, 0)
|
||||
}
|
||||
// 营部及以下级别使用后端计算的可见范围内的上报总和
|
||||
|
|
@ -656,10 +757,11 @@ function getTotalProgressPercentage(): number {
|
|||
|
||||
// 根据时间范围筛选后的分配数据
|
||||
const filteredDistributions = computed(() => {
|
||||
if (!authStore.canCreateAllocations || selectedPeriod.value === 'all') {
|
||||
if (!authStore.canCreateAllocations || (selectedPeriod.value === 'all' && periodType.value === 'all')) {
|
||||
return distributions.value
|
||||
}
|
||||
// 使用统计数据更新分配记录的消耗数据
|
||||
if (consumptionStats.value.length > 0) {
|
||||
return distributions.value.map(d => {
|
||||
const stat = consumptionStats.value.find((s: UnitConsumptionStat) => s.unitId === d.targetUnitId)
|
||||
if (stat) {
|
||||
|
|
@ -671,8 +773,90 @@ const filteredDistributions = computed(() => {
|
|||
}
|
||||
return { ...d, actualCompletion: 0, completionRate: 0 }
|
||||
})
|
||||
}
|
||||
return distributions.value
|
||||
})
|
||||
|
||||
// 处理时间类型切换
|
||||
function handlePeriodTypeChange() {
|
||||
// 重置选择
|
||||
selectedWeek.value = null
|
||||
selectedMonth.value = null
|
||||
selectedYear.value = null
|
||||
selectedHalfYear.value = ''
|
||||
|
||||
if (periodType.value === 'all') {
|
||||
selectedPeriod.value = 'all'
|
||||
consumptionStats.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 处理日期选择变化
|
||||
async function handleDateChange() {
|
||||
if (!selectedAllocation.value) return
|
||||
|
||||
let startDate: string | null = null
|
||||
let endDate: string | null = null
|
||||
|
||||
if (periodType.value === 'week' && selectedWeek.value) {
|
||||
// 获取选中周的起止日期
|
||||
const date = new Date(selectedWeek.value)
|
||||
const day = date.getDay()
|
||||
const diff = date.getDate() - day + (day === 0 ? -6 : 1) // 周一
|
||||
const monday = new Date(date.setDate(diff))
|
||||
const sunday = new Date(monday)
|
||||
sunday.setDate(monday.getDate() + 6)
|
||||
startDate = formatDateParam(monday)
|
||||
endDate = formatDateParam(sunday)
|
||||
} else if (periodType.value === 'month' && selectedMonth.value) {
|
||||
const date = new Date(selectedMonth.value)
|
||||
const firstDay = new Date(date.getFullYear(), date.getMonth(), 1)
|
||||
const lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0)
|
||||
startDate = formatDateParam(firstDay)
|
||||
endDate = formatDateParam(lastDay)
|
||||
} else if (periodType.value === 'halfYear' && selectedHalfYear.value) {
|
||||
const [year, half] = selectedHalfYear.value.split('-')
|
||||
if (half === 'H1') {
|
||||
startDate = `${year}-01-01`
|
||||
endDate = `${year}-06-30`
|
||||
} else {
|
||||
startDate = `${year}-07-01`
|
||||
endDate = `${year}-12-31`
|
||||
}
|
||||
} else if (periodType.value === 'year' && selectedYear.value) {
|
||||
const year = selectedYear.value.getFullYear()
|
||||
startDate = `${year}-01-01`
|
||||
endDate = `${year}-12-31`
|
||||
}
|
||||
|
||||
if (!startDate || !endDate) return
|
||||
|
||||
selectedPeriod.value = 'custom'
|
||||
loadingStats.value = true
|
||||
try {
|
||||
const response = await allocationsApi.getConsumptionStats(
|
||||
selectedAllocation.value.id,
|
||||
'custom',
|
||||
startDate,
|
||||
endDate
|
||||
)
|
||||
consumptionStats.value = response.unitStats
|
||||
} catch (error) {
|
||||
console.error('加载消耗统计失败', error)
|
||||
ElMessage.error('加载消耗统计失败')
|
||||
consumptionStats.value = []
|
||||
} finally {
|
||||
loadingStats.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function formatDateParam(date: Date): string {
|
||||
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}`
|
||||
}
|
||||
|
||||
async function handlePeriodChange() {
|
||||
if (!selectedAllocation.value || selectedPeriod.value === 'all') {
|
||||
consumptionStats.value = []
|
||||
|
|
@ -732,6 +916,11 @@ async function handleViewReports(distribution: AllocationDistribution) {
|
|||
showReportsDialog.value = true
|
||||
reportsTabActive.value = 'summary'
|
||||
reportsPeriod.value = 'all'
|
||||
reportsPeriodType.value = 'all'
|
||||
reportsSelectedWeek.value = null
|
||||
reportsSelectedMonth.value = null
|
||||
reportsSelectedYear.value = null
|
||||
reportsSelectedHalfYear.value = ''
|
||||
loadingReports.value = true
|
||||
try {
|
||||
// 同时加载汇总数据和明细数据
|
||||
|
|
@ -756,6 +945,76 @@ function getReportsTotalConsumed(): number {
|
|||
return unitSummaries.value.reduce((sum, s) => sum + s.totalReported, 0)
|
||||
}
|
||||
|
||||
// 上报记录时间类型切换
|
||||
function handleReportsPeriodTypeChange() {
|
||||
reportsSelectedWeek.value = null
|
||||
reportsSelectedMonth.value = null
|
||||
reportsSelectedYear.value = null
|
||||
reportsSelectedHalfYear.value = ''
|
||||
|
||||
if (reportsPeriodType.value === 'all') {
|
||||
reportsPeriod.value = 'all'
|
||||
handleReportsPeriodChange()
|
||||
}
|
||||
}
|
||||
|
||||
// 上报记录日期选择变化
|
||||
async function handleReportsDateChange() {
|
||||
if (!selectedDistribution.value) return
|
||||
|
||||
let startDate: string | null = null
|
||||
let endDate: string | null = null
|
||||
|
||||
if (reportsPeriodType.value === 'week' && reportsSelectedWeek.value) {
|
||||
const date = new Date(reportsSelectedWeek.value)
|
||||
const day = date.getDay()
|
||||
const diff = date.getDate() - day + (day === 0 ? -6 : 1)
|
||||
const monday = new Date(date.setDate(diff))
|
||||
const sunday = new Date(monday)
|
||||
sunday.setDate(monday.getDate() + 6)
|
||||
startDate = formatDateParam(monday)
|
||||
endDate = formatDateParam(sunday)
|
||||
} else if (reportsPeriodType.value === 'month' && reportsSelectedMonth.value) {
|
||||
const date = new Date(reportsSelectedMonth.value)
|
||||
const firstDay = new Date(date.getFullYear(), date.getMonth(), 1)
|
||||
const lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0)
|
||||
startDate = formatDateParam(firstDay)
|
||||
endDate = formatDateParam(lastDay)
|
||||
} else if (reportsPeriodType.value === 'halfYear' && reportsSelectedHalfYear.value) {
|
||||
const [year, half] = reportsSelectedHalfYear.value.split('-')
|
||||
if (half === 'H1') {
|
||||
startDate = `${year}-01-01`
|
||||
endDate = `${year}-06-30`
|
||||
} else {
|
||||
startDate = `${year}-07-01`
|
||||
endDate = `${year}-12-31`
|
||||
}
|
||||
} else if (reportsPeriodType.value === 'year' && reportsSelectedYear.value) {
|
||||
const year = reportsSelectedYear.value.getFullYear()
|
||||
startDate = `${year}-01-01`
|
||||
endDate = `${year}-12-31`
|
||||
}
|
||||
|
||||
if (!startDate || !endDate) return
|
||||
|
||||
reportsPeriod.value = 'custom'
|
||||
loadingReports.value = true
|
||||
try {
|
||||
const summaries = await allocationsApi.getReportSummaryByUnit(
|
||||
selectedDistribution.value.id,
|
||||
'custom',
|
||||
startDate,
|
||||
endDate
|
||||
)
|
||||
unitSummaries.value = summaries
|
||||
} catch (error) {
|
||||
console.error('加载上报记录失败', error)
|
||||
ElMessage.error('加载上报记录失败')
|
||||
} finally {
|
||||
loadingReports.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 上报记录时间范围筛选变化
|
||||
async function handleReportsPeriodChange() {
|
||||
if (!selectedDistribution.value) return
|
||||
|
|
@ -807,6 +1066,11 @@ async function loadAllocations() {
|
|||
async function handleViewDistribution(allocation: MaterialAllocation) {
|
||||
selectedAllocation.value = allocation
|
||||
selectedPeriod.value = 'all'
|
||||
periodType.value = 'all'
|
||||
selectedWeek.value = null
|
||||
selectedMonth.value = null
|
||||
selectedYear.value = null
|
||||
selectedHalfYear.value = ''
|
||||
consumptionStats.value = []
|
||||
// 对于非师团级账号,只显示本单位及下级单位的分配记录
|
||||
if (authStore.canCreateAllocations) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user