|
|
|
@ -28,16 +28,28 @@ |
|
|
|
:max="2100" |
|
|
|
/> |
|
|
|
</a-form-item> |
|
|
|
<a-form-item label="季度" name="declareQuarter"> |
|
|
|
<DictSelect |
|
|
|
dict-code="QUARTER" |
|
|
|
v-model:value="form.declareQuarter" |
|
|
|
placeholder="请选择季度" |
|
|
|
@change="onQuarterChange" |
|
|
|
<a-form-item label="月份" name="declareMonth"> |
|
|
|
<a-select |
|
|
|
v-model:value="form.declareMonth" |
|
|
|
placeholder="请选择月份" |
|
|
|
@change="onMonthChange" |
|
|
|
style="width: 100%" |
|
|
|
/> |
|
|
|
> |
|
|
|
<a-select-option v-for="month in monthOptions" :key="month.value" :value="month.value"> |
|
|
|
{{ month.label }} |
|
|
|
</a-select-option> |
|
|
|
</a-select> |
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
<!-- 本年度已填报收入信息 |
|
|
|
<a-form-item v-if="!form.id" :wrapper-col="{ offset: 8 }"> |
|
|
|
<div style="background: #f5f5f5; padding: 8px 12px; border-radius: 4px; font-size: 12px;"> |
|
|
|
<div style="color: #666;">本年度已填报收入:</div> |
|
|
|
<div style="font-weight: bold; color: #1890ff; font-size: 14px;">{{ annualIncomeInfo.revenue || 0 }} 万元</div> |
|
|
|
<div style="color: #666; margin-top: 4px;">本年度已填报总成本:{{ annualIncomeInfo.totalCost || 0 }} 万元</div> |
|
|
|
</div> |
|
|
|
</a-form-item>--> |
|
|
|
|
|
|
|
<a-form-item label="律所收入(万元)" name="revenue"> |
|
|
|
<a-input-number |
|
|
|
style="width: 100%" |
|
|
|
@ -48,6 +60,10 @@ |
|
|
|
@change="calculateCosts" |
|
|
|
addon-after="万元" |
|
|
|
/> |
|
|
|
<div style="font-size: 12px; color: #666; margin-top: 4px;"> |
|
|
|
本年度已填报收入:{{ annualIncomeInfo.revenue || 0 }} 万元 |
|
|
|
<span v-if="annualIncomeInfo.revenue > 0 && form.revenue">,合计:{{ formatNumber((annualIncomeInfo.revenue || 0) + (form.revenue || 0)) }} 万元</span> |
|
|
|
</div> |
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
<a-form-item label="公益活动成本(万元)" name="publicWelfareCost"> |
|
|
|
@ -116,7 +132,6 @@ |
|
|
|
import { serviceApplicationsApi } from '/@/api/business/service-applications/service-applications-api'; |
|
|
|
import { smartSentry } from '/@/lib/smart-sentry'; |
|
|
|
import { useUserStore } from '/@/store/modules/system/user'; |
|
|
|
import DictSelect from '/@/components/support/dict-select/index.vue'; |
|
|
|
|
|
|
|
// ------------------------ 事件 ------------------------ |
|
|
|
|
|
|
|
@ -135,9 +150,71 @@ |
|
|
|
// 是否显示 |
|
|
|
const visibleFlag = ref(false); |
|
|
|
|
|
|
|
// 本年度已填报收入信息 |
|
|
|
const annualIncomeInfo = ref({ |
|
|
|
revenue: 0, // 营业收入 |
|
|
|
totalCost: 0 // 总成本支出 |
|
|
|
}); |
|
|
|
|
|
|
|
// 月份选项(只能填报上一个月) |
|
|
|
const monthOptions = ref([]); |
|
|
|
|
|
|
|
// 初始化月份选项,只能选择上一个月 |
|
|
|
async function initMonthOptions() { |
|
|
|
const currentDate = new Date(); |
|
|
|
const currentYear = currentDate.getFullYear(); |
|
|
|
const currentMonth = currentDate.getMonth() + 1; // 当前月份(1-12) |
|
|
|
|
|
|
|
// 计算上一个月 |
|
|
|
let lastMonth = currentMonth - 1; |
|
|
|
let lastMonthYear = currentYear; |
|
|
|
|
|
|
|
if (lastMonth === 0) { |
|
|
|
lastMonth = 12; |
|
|
|
lastMonthYear = currentYear - 1; |
|
|
|
} |
|
|
|
|
|
|
|
// 设置默认年份为上一个月所在的年份 |
|
|
|
form.declareYear = lastMonthYear; |
|
|
|
|
|
|
|
// 只能选择上一个月 |
|
|
|
monthOptions.value = [ |
|
|
|
{ label: `${lastMonth}月`, value: `${lastMonth}月` } |
|
|
|
]; |
|
|
|
|
|
|
|
// 默认选中上一个月 |
|
|
|
form.declareMonth = `${lastMonth}月`; |
|
|
|
|
|
|
|
// 设置默认月份后,立即获取公益成本数据 |
|
|
|
await getPublicWelfareCost(); |
|
|
|
} |
|
|
|
|
|
|
|
// 格式化数字 |
|
|
|
function formatNumber(value) { |
|
|
|
if (value === null || value === undefined) return '-'; |
|
|
|
const num = Number(value); |
|
|
|
return isNaN(num) ? '-' : num.toFixed(2); |
|
|
|
} |
|
|
|
|
|
|
|
// 获取本年度已填报收入 |
|
|
|
async function fetchAnnualIncome() { |
|
|
|
try { |
|
|
|
const result = await firmReportsApi.income(); |
|
|
|
if (result.data) { |
|
|
|
annualIncomeInfo.value = { |
|
|
|
revenue: result.data.revenue || 0, |
|
|
|
totalCost: result.data.totalCost || 0 |
|
|
|
}; |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.error('获取本年度已填报收入失败:', error); |
|
|
|
annualIncomeInfo.value = { revenue: 0, totalCost: 0 }; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 获取系统计算的公益成本 |
|
|
|
async function getPublicWelfareCost() { |
|
|
|
console.log('开始获取公益成本,部门ID:', departmentId.value, '年份:', form.declareYear, '季度:', form.declareQuarter); |
|
|
|
console.log('开始获取公益成本,部门ID:', departmentId.value, '年份:', form.declareYear, '月份:', form.declareMonth); |
|
|
|
|
|
|
|
if (!departmentId.value) { |
|
|
|
message.warning('无法获取机构信息,请重新登录'); |
|
|
|
@ -150,20 +227,28 @@ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (!form.declareQuarter) { |
|
|
|
console.log('季度未选择,跳过API调用'); |
|
|
|
if (!form.declareMonth) { |
|
|
|
console.log('月份未选择,跳过API调用'); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
// 将季度字符串转换为数字(Q1 -> 1, Q2 -> 2, Q3 -> 3, Q4 -> 4) |
|
|
|
const quarterNumber = form.declareQuarter.replace('Q', ''); |
|
|
|
// 将月度字符串转换为数字(如"1月" -> 1, "2月" -> 2, ..., "12月" -> 12) |
|
|
|
let monthNumber; |
|
|
|
if (typeof form.declareMonth === 'string') { |
|
|
|
const monthMatch = form.declareMonth.match(/^(\d+)/); |
|
|
|
if (monthMatch && monthMatch[1]) { |
|
|
|
monthNumber = parseInt(monthMatch[1]); |
|
|
|
} |
|
|
|
} else if (typeof form.declareMonth === 'number') { |
|
|
|
monthNumber = form.declareMonth; |
|
|
|
} |
|
|
|
|
|
|
|
// 构建请求参数:包含部门ID、年份和季度数字 |
|
|
|
// 构建请求参数:包含部门ID、年份和月度数字 |
|
|
|
const queryForm = { |
|
|
|
firmId: departmentId.value, |
|
|
|
year: form.declareYear, // 后端期望的year字段 |
|
|
|
quarter: parseInt(quarterNumber) // 季度字段转换为数字 |
|
|
|
month: monthNumber // 月度字段转换为数字 |
|
|
|
}; |
|
|
|
|
|
|
|
console.log('调用接口: /serviceApplications/statistics/cost, 参数:', queryForm); |
|
|
|
@ -198,20 +283,23 @@ |
|
|
|
console.log('编辑模式,使用现有数据'); |
|
|
|
Object.assign(form, rowData); |
|
|
|
|
|
|
|
// 确保declareQuarter字段格式与字典系统匹配 |
|
|
|
if (form.declareQuarter && typeof form.declareQuarter === 'number') { |
|
|
|
// 确保declareMonth字段格式与字典系统匹配 |
|
|
|
if (form.declareMonth && typeof form.declareMonth === 'number') { |
|
|
|
// 如果后端返回的是数字格式,转换为字典期望的字符串格式 |
|
|
|
form.declareQuarter = 'Q' + form.declareQuarter; |
|
|
|
} else if (form.declareQuarter && form.declareQuarter.includes('(')) { |
|
|
|
// 如果返回的是显示名称格式(如"第一季度 (Q1)"),提取字典值 |
|
|
|
const match = form.declareQuarter.match(/\(([^)]+)\)/); |
|
|
|
form.declareMonth = form.declareMonth + '月'; |
|
|
|
} else if (form.declareMonth && form.declareMonth.includes('(')) { |
|
|
|
// 如果返回的是显示名称格式(如"1月 (1)"),提取字典值 |
|
|
|
const match = form.declareMonth.match(/\(([^)]+)\)/); |
|
|
|
if (match && match[1]) { |
|
|
|
form.declareQuarter = match[1]; // 提取Q1这样的字典值 |
|
|
|
form.declareMonth = match[1] + '月'; // 提取数字并添加"月"后缀 |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
console.log('新建模式,等待用户选择季度后获取公益成本'); |
|
|
|
// 新建时不立即获取公益成本,等待用户选择季度 |
|
|
|
console.log('新建模式,等待用户选择月份后获取公益成本'); |
|
|
|
// 新建模式下初始化月份选项(只能选择上一个月) |
|
|
|
initMonthOptions(); |
|
|
|
// 新建模式下获取本年度已填报收入 |
|
|
|
fetchAnnualIncome(); |
|
|
|
} |
|
|
|
|
|
|
|
visibleFlag.value = true; |
|
|
|
@ -236,7 +324,7 @@ |
|
|
|
id: undefined, |
|
|
|
firmId: undefined, // 律师事务所ID(部门ID) |
|
|
|
declareYear: new Date().getFullYear(), // 报表年份 |
|
|
|
declareQuarter: undefined, // 季度ID (1,2,3,4) |
|
|
|
declareMonth: undefined, // 月度ID (1,2,3,4,5,6,7,8,9,10,11,12) |
|
|
|
revenue: undefined, // 营业收入(万元) |
|
|
|
//totalCost: 0, // 总成本支出(万元) |
|
|
|
publicWelfareCost: undefined, // 公益成本支出(万元) |
|
|
|
@ -246,7 +334,7 @@ |
|
|
|
let form = reactive({ ...formDefault }); |
|
|
|
|
|
|
|
const rules = { |
|
|
|
declareQuarter: [{ required: true, message: '请选择季度' }], |
|
|
|
declareMonth: [{ required: true, message: '请选择月份' }], |
|
|
|
declareYear: [{ required: true, message: '请输入报表年份' }], |
|
|
|
revenue: [{ required: true, message: '请输入律所收入' }], |
|
|
|
publicWelfareCost: [{ required: true, message: '系统正在计算公益成本,请稍后' }], |
|
|
|
@ -257,12 +345,12 @@ |
|
|
|
const showCostWarning = ref(false); |
|
|
|
const costRatio = ref(0); // 当前成本比例 |
|
|
|
|
|
|
|
// 季度选择变化时的处理 |
|
|
|
function onQuarterChange() { |
|
|
|
console.log('季度选择变化:', form.declareQuarter); |
|
|
|
// 月份选择变化时的处理 |
|
|
|
function onMonthChange() { |
|
|
|
console.log('月份选择变化:', form.declareMonth); |
|
|
|
|
|
|
|
// 只有当选择了季度时才获取公益成本 |
|
|
|
if (form.declareQuarter) { |
|
|
|
// 只有当选择了月份时才获取公益成本 |
|
|
|
if (form.declareMonth) { |
|
|
|
getPublicWelfareCost(); |
|
|
|
} |
|
|
|
|
|
|
|
@ -272,12 +360,21 @@ |
|
|
|
|
|
|
|
// 自动计算总成本和成本/收入比例 |
|
|
|
function calculateCosts() { |
|
|
|
const revenue = parseFloat(form.revenue) || 0; |
|
|
|
const publicWelfareCost = parseFloat(form.publicWelfareCost) || 0; |
|
|
|
// 安全转换数值,防止NaN |
|
|
|
const currentRevenue = safeParseFloat(form.revenue); |
|
|
|
const publicWelfareCost = safeParseFloat(form.publicWelfareCost); |
|
|
|
const annualRevenue = safeParseFloat(annualIncomeInfo.value.revenue); |
|
|
|
const annualTotalCost = safeParseFloat(annualIncomeInfo.value.totalCost); |
|
|
|
|
|
|
|
// 计算当前成本比例 |
|
|
|
if (revenue > 0) { |
|
|
|
costRatio.value = (publicWelfareCost / revenue) * 100; |
|
|
|
// 计算总收入:当前填写的收入 + 本年度已填报收入 |
|
|
|
const totalRevenue = currentRevenue + annualRevenue; |
|
|
|
|
|
|
|
// 计算年度累计成本:当前填报成本 + 本年度已填报成本 |
|
|
|
const totalCost = publicWelfareCost + annualTotalCost; |
|
|
|
|
|
|
|
// 计算年度成本比例 |
|
|
|
if (totalRevenue > 0) { |
|
|
|
costRatio.value = (totalCost / totalRevenue) * 100; |
|
|
|
|
|
|
|
// 检查是否达到或超过20%阈值 |
|
|
|
if (costRatio.value >= 20) { |
|
|
|
@ -285,21 +382,25 @@ |
|
|
|
|
|
|
|
// 如果超过25%上限,按25%计算 |
|
|
|
if (costRatio.value > 25) { |
|
|
|
const maxAllowedCost = revenue * 0.25; // 25%上限 |
|
|
|
calculatedPublicWelfareCost.value = maxAllowedCost.toFixed(2); |
|
|
|
const maxAllowedAnnualCost = totalRevenue * 0.25; // 年度成本上限 |
|
|
|
const remainingAllowedCost = Math.max(0, maxAllowedAnnualCost - annualTotalCost); |
|
|
|
|
|
|
|
// 当前填报允许的最大成本 |
|
|
|
calculatedPublicWelfareCost.value = Math.min(publicWelfareCost, remainingAllowedCost).toFixed(2); |
|
|
|
|
|
|
|
// 计算成本/收入比例(使用上限值) |
|
|
|
const ratio = (maxAllowedCost / revenue) * 100; |
|
|
|
const actualAnnualCost = annualTotalCost + parseFloat(calculatedPublicWelfareCost.value); |
|
|
|
const ratio = (actualAnnualCost / totalRevenue) * 100; |
|
|
|
form.costIncomeRatio = ratio.toFixed(2); |
|
|
|
} else { |
|
|
|
// 达到20%但未超过25%,使用实际值 |
|
|
|
calculatedPublicWelfareCost.value = publicWelfareCost; |
|
|
|
calculatedPublicWelfareCost.value = publicWelfareCost.toFixed(2); |
|
|
|
form.costIncomeRatio = costRatio.value.toFixed(2); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// 未达到20%,隐藏警告 |
|
|
|
showCostWarning.value = false; |
|
|
|
calculatedPublicWelfareCost.value = publicWelfareCost; |
|
|
|
calculatedPublicWelfareCost.value = publicWelfareCost.toFixed(2); |
|
|
|
form.costIncomeRatio = costRatio.value.toFixed(2); |
|
|
|
} |
|
|
|
} else { |
|
|
|
@ -307,18 +408,24 @@ |
|
|
|
showCostWarning.value = false; |
|
|
|
costRatio.value = 0; |
|
|
|
form.costIncomeRatio = '0.00'; |
|
|
|
calculatedPublicWelfareCost.value = publicWelfareCost; |
|
|
|
calculatedPublicWelfareCost.value = publicWelfareCost.toFixed(2); |
|
|
|
} |
|
|
|
|
|
|
|
// 设置总成本 |
|
|
|
form.totalCost = showCostWarning.value ? parseFloat(calculatedPublicWelfareCost.value) : publicWelfareCost; |
|
|
|
} |
|
|
|
|
|
|
|
// 计算总成本(只包含公益活动成本) |
|
|
|
const totalCost = showCostWarning.value ? parseFloat(calculatedPublicWelfareCost.value) : publicWelfareCost; |
|
|
|
form.totalCost = totalCost; |
|
|
|
// 安全的数值转换函数 |
|
|
|
function safeParseFloat(value) { |
|
|
|
if (value === null || value === undefined || value === '') return 0; |
|
|
|
const num = parseFloat(value); |
|
|
|
return isNaN(num) ? 0 : num; |
|
|
|
} |
|
|
|
|
|
|
|
// 保存草稿 |
|
|
|
async function saveAsDraft() { |
|
|
|
try { |
|
|
|
await formRef.value.validateFields(['declareQuarter', 'declareYear', 'revenue', 'publicWelfareCost']); |
|
|
|
await formRef.value.validateFields(['declareMonth', 'declareYear', 'revenue', 'publicWelfareCost']); |
|
|
|
form.approvalStatus = '0'; // 草稿状态 |
|
|
|
await save(); |
|
|
|
} catch (err) { |
|
|
|
@ -348,6 +455,19 @@ |
|
|
|
// 准备保存的数据,如果超过上限则使用计算值 |
|
|
|
const saveData = { ...form }; |
|
|
|
|
|
|
|
// 将月份格式转换为数字格式(如"1月" -> 1, "2月" -> 2) |
|
|
|
if (saveData.declareMonth && typeof saveData.declareMonth === 'string') { |
|
|
|
const monthMatch = saveData.declareMonth.match(/^(\d+)/); |
|
|
|
if (monthMatch && monthMatch[1]) { |
|
|
|
saveData.declareMonth = parseInt(monthMatch[1]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 确保年份是整数类型 |
|
|
|
if (saveData.declareYear) { |
|
|
|
saveData.declareYear = parseInt(saveData.declareYear); |
|
|
|
} |
|
|
|
|
|
|
|
if (showCostWarning.value) { |
|
|
|
// 使用计算后的公益成本值 |
|
|
|
saveData.publicWelfareCost = parseFloat(calculatedPublicWelfareCost.value); |
|
|
|
|