-
+
+
+
+
+
+
+
+
+
+
+
+ 全部
+
+ {{ status.desc }}
+
+
+
+
+
+
+
+
+ 查询
+
+
+
+
+
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
showForm('user')" type="primary" v-if="isUser">
+
+
+
+ 申请无处分证明
+
+
+
showForm('personal')" type="primary" v-if="isCto">
+
+
+
+ 申请个人无处分证明
+
+
+
showForm('firm')" type="primary" v-if="isCto || isFirmAdmin">
+
+
+
+ 申请律所无处分证明
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 审批
+ 预览
+
+
+ 审批
+
+
+ 下载
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
![]()
-
-
-
-
-
-
-
-
-
- 同意
- 拒绝
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ 同意
+ 拒绝
+
+
+
+
+
diff --git a/src/views/business/erp/service/firm-statistics-detail.vue b/src/views/business/erp/service/firm-statistics-detail.vue
index d7f644c..ca95e35 100644
--- a/src/views/business/erp/service/firm-statistics-detail.vue
+++ b/src/views/business/erp/service/firm-statistics-detail.vue
@@ -30,7 +30,11 @@
- 导出
+ 律师明细导出
+
+
+
+ 律所汇总导出
@@ -144,6 +148,8 @@ import { ExportOutlined, ArrowLeftOutlined, DownOutlined, RightOutlined, SearchO
import { message } from 'ant-design-vue';
import { serviceApplicationsApi } from '/@/api/business/service-applications/service-applications-api';
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
+import { getRoleInfo } from '/@/utils/role-util';
+import { useUserStore } from '/@/store/modules/system/user';
// 展开/折叠状态管理
const expandedRows = ref(new Set());
@@ -177,9 +183,15 @@ const props = defineProps({
});
const exportLoading = ref(false);
+const exportDepartmentLoading = ref(false);
const tableData = ref([]);
const loading = ref(false);
+// 角色判断
+const userStore = useUserStore();
+const roleInfo = getRoleInfo(userStore.roleCode);
+const isAssociationRole = roleInfo.isAssociationRole;
+
// 分页配置
const pagination = reactive({
pageNum: 1,
@@ -381,6 +393,33 @@ async function handleExport() {
}
}
+// 律所汇总导出(仅律协角色可见)
+async function handleExportDepartment() {
+ if (!tableData.value || tableData.value.length === 0) {
+ message.warning('暂无数据可导出');
+ return;
+ }
+
+ exportDepartmentLoading.value = true;
+ try {
+ console.log('开始导出律所汇总统计...');
+ const exportParams = {
+ quarter: queryForm.quarter,
+ year: queryForm.year,
+ firmId: queryForm.firmId
+ };
+
+ await serviceApplicationsApi.exportLawyerByDepartment(exportParams);
+ message.success('导出成功');
+ console.log('律所汇总统计导出成功');
+ } catch (error) {
+ message.error('导出失败');
+ console.error('导出律所汇总统计失败:', error);
+ } finally {
+ exportDepartmentLoading.value = false;
+ }
+}
+
// 监听参数变化,重新获取数据
watch(() => props.params, (newParams) => {
if (newParams) {
diff --git a/src/views/business/erp/service/service-applications-form.vue b/src/views/business/erp/service/service-applications-form.vue
index a144566..3121168 100644
--- a/src/views/business/erp/service/service-applications-form.vue
+++ b/src/views/business/erp/service/service-applications-form.vue
@@ -7,266 +7,358 @@
-->
-
-
-
-
-
- 一、基础信息
+
+
+
+
+
+ 一、基础信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 二、服务信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 注:仅显示本所已签署有效申报承诺书的律师;不选择则仅申报本人。
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+ 服务时长(小时)
+ 可通过时间选择也可手动填写
+
+
-
-
-
-
-
-
- 二、服务信息
+
+ 注:不足30分钟(含30分钟)的,按照0.5小时填报,超过30分钟不足1小时的(含1小时),按照1小时填报。
+
-
-
+
+
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 服务时长(小时)
- 可通过时间选择也可手动填写
-
-
-
- 注:不足30分钟(含30分钟)的,按照0.5小时填报,超过30分钟不足1小时的(含1小时),按照1小时填报。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 服务时长(小时)
- 请在{{ currentActivity.price }}范围内填写
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
+
+
+
+
+
+ 服务时长(小时)
+ 请在{{ currentActivity.price }}范围内填写
+
+
-
-
-
-
-
-
+
+
+
+
-
-
-
+
+
+
+
+
+
-
-
-
- 服务内容描述
- 注:内容描述需要包括的内容主要是时间、地点、主题、参与人员、服务内容、活动效果等
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
- 证明材料
- 注:(请上传活动方案、活动记录、照片、新闻报道等材料)支持图片(JPG/PNG)、文档(PDF/Word/PPT)格式,单文件最大10MB,最多上传5个文件
-
-
-
-
-
- 无证明材料
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 服务内容描述
+ 注:内容描述需要包括的内容主要是时间、地点、主题、参与人员、服务内容、活动效果等
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 证明材料
+
+ 注:(请上传活动方案、活动记录、照片、新闻报道等材料)支持图片(JPG/PNG)、文档(PDF/Word/PPT)格式,单文件最大10MB,最多上传5个文件
+
+
+
+
+
+ 无证明材料
+
+
+
+
@@ -278,7 +370,7 @@
diff --git a/src/views/business/erp/service/service-applications-list.vue b/src/views/business/erp/service/service-applications-list.vue
index ae25cd6..3ebda2a 100644
--- a/src/views/business/erp/service/service-applications-list.vue
+++ b/src/views/business/erp/service/service-applications-list.vue
@@ -63,7 +63,7 @@
-
+
@@ -172,11 +172,21 @@
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
>
+
+ {{ record.userName }}
+
+ 由 {{ record.declarerName || '同行律师' }} 代报批
+
+
+ 同行统一代报批 (包含: {{ record.participantNames || '多人' }})
+
+
详情
-
-
编辑
+
+
编辑
+
提交
审核
@@ -457,7 +467,7 @@ import dayjs from 'dayjs';
},
{
title: '备案编号',
- dataIndex: 'filingNo',
+ dataIndex: 'recordNo',
ellipsis: true,
width: 150,
},
@@ -483,7 +493,7 @@ import dayjs from 'dayjs';
firmAuditStatus: undefined, // 执业机构审核状态
firmAuditTimeRange: undefined, // 执业机构审核时间范围
associationAuditStatus: undefined, // 协会审核状态
- filingNo: undefined, // 备案编号
+ recordNo: undefined, // 用户填写的备案/案件编号
selfFirmFilter: undefined, // 本人本所筛选条件
};
// 查询表单form
@@ -679,31 +689,20 @@ import dayjs from 'dayjs';
return;
}
- // 如果已签署律所承诺书,检查成本权限
+ // 成本权限按律所判断:本所任一有效人员具备权限即视为本所有权限
if (loginInfo.value && loginInfo.value.lawFirmAgreementSignFlag === true) {
- // 检查是否有成本查询权限
- if (loginInfo.value.costVisibleFlag === true) {
+ const permissionResult = await firmReportsApi.firmHasCostPermission();
+ if (permissionResult.data === true) {
try {
- // 先检查是否有未审核的数据
const hasUnreviewedData = await checkUnreviewedData();
if (hasUnreviewedData) {
message.warning('有律师提交的数据尚未审核,请先完成审核后再进行批量上报。');
return;
}
-
- const costPermissionResult = await firmReportsApi.query();
- if (costPermissionResult.data === false) {
- // 成本权限检查返回false,需要先填报成本报表
- message.warning('您需要先填报和提交律所收入,才能进行服务上报。');
- // 调用成本管理新增弹框
- showCostReportForm();
- return;
- }
} catch (error) {
console.error('检查成本权限失败:', error);
}
}
- // 如果没有成本查询权限,直接跳过成本检查
}
// 检查选中的记录是否符合上报条件
@@ -712,7 +711,14 @@ import dayjs from 'dayjs';
);
if (canReportRecords.length === 0) {
- message.warning('选中的记录不符合上报条件,只能上报上个季度的数据');
+ message.warning('选中的记录不符合上报条件,请选择已通过律所审核且尚未上报的记录');
+ return;
+ }
+
+ const missingPeriods = await queryMissingIncomePeriods(canReportRecords);
+ if (missingPeriods.length > 0) {
+ message.warning(`以下活动所属季度尚未提交营业收入:${missingPeriods.map(item => item.label).join('、')},请完成填报后再上报律协`);
+ showCostReportForm(missingPeriods[0]);
return;
}
@@ -733,60 +739,41 @@ import dayjs from 'dayjs';
const isAuditPassed = record.firmAuditStatus === 3 &&
(record.associationAuditStatus === 0 || record.associationAuditStatus === 4);
- // 如果有成本查询权限,需要检查季度限制;否则不限制
- const hasCostPermission = loginInfo.value && loginInfo.value.costVisibleFlag === true;
-
- if (hasCostPermission) {
- // 有成本权限:只能上报上个季度的数据
- // 律协要求:二季度上报一季度的数据,三季度上报二季度的数据
- const isLastQuarterData = isLastQuarterRecord(record);
- return isAuditPassed && isLastQuarterData;
- } else {
- // 无成本权限:不限制季度,可以上报所有数据
- return isAuditPassed;
- }
+ // 活动季度及对应收入报表由后端按 serviceEnd 统一校验
+ return isAuditPassed;
}
-
- // 判断记录是否为上个季度的数据
- function isLastQuarterRecord(record) {
- if (!record.reportTime) return false;
-
- const currentDate = new Date();
- const currentYear = currentDate.getFullYear();
- const currentMonth = currentDate.getMonth() + 1;
- const currentQuarter = Math.ceil(currentMonth / 3);
-
- // 计算上个季度
- let lastQuarter = currentQuarter - 1;
- let lastQuarterYear = currentYear;
-
- if (lastQuarter === 0) {
- lastQuarter = 4;
- lastQuarterYear = currentYear - 1;
+
+ async function queryMissingIncomePeriods(records) {
+ const periodMap = new Map();
+ records.forEach(record => {
+ if (!record.serviceEnd) return;
+ const activityDate = dayjs(record.serviceEnd);
+ const year = activityDate.year();
+ const quarter = Math.ceil((activityDate.month() + 1) / 3);
+ periodMap.set(`${year}-${quarter}`, { year, quarter });
+ });
+
+ const missing = [];
+ for (const period of periodMap.values()) {
+ const result = await firmReportsApi.queryByQuarter(period.year, period.quarter);
+ if (result.data !== true) {
+ missing.push({
+ ...period,
+ label: `${period.year}年第${period.quarter}季度`,
+ });
+ }
}
-
- // 解析记录的提交时间
- const reportDate = new Date(record.reportTime);
- const reportYear = reportDate.getFullYear();
- const reportMonth = reportDate.getMonth() + 1;
- const reportQuarter = Math.ceil(reportMonth / 3);
-
- // 检查是否为上个季度的数据
- return reportYear === lastQuarterYear && reportQuarter === lastQuarter;
+ return missing;
}
-
- // 检查是否有未审核的数据
+
+ // 检查当前律所是否有未审核的数据
async function checkUnreviewedData() {
try {
- // 调用后端提供的专门接口查询是否有未审核的数据
const result = await serviceApplicationsApi.queryNoReview();
-
- // 如果返回的数据大于0,说明有未审核的记录
return result.data && result.data > 0;
-
} catch (error) {
console.error('检查未审核数据失败:', error);
- return false; // 出错时默认返回false,避免阻塞用户操作
+ return false;
}
}
@@ -1057,9 +1044,9 @@ import dayjs from 'dayjs';
}
// ---------------------------- 成本报表 ----------------------------
- function showCostReportForm() {
+ function showCostReportForm(period) {
// 打开成本报表新增弹框
- costReportFormRef.value.show();
+ costReportFormRef.value.show(period);
}
// ---------------------------- 详情 ----------------------------
diff --git a/src/views/business/erp/service/service-applications-report-list.vue b/src/views/business/erp/service/service-applications-report-list.vue
index ea2d1b5..d19b184 100644
--- a/src/views/business/erp/service/service-applications-report-list.vue
+++ b/src/views/business/erp/service/service-applications-report-list.vue
@@ -253,6 +253,7 @@ import { useRoute, useRouter } from 'vue-router';
import { message, Modal } from 'ant-design-vue';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { serviceApplicationsApi } from '/@/api/business/service-applications/service-applications-api';
+import { firmReportsApi } from '/@/api/business/cost/firm-reports-api';
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
import { smartSentry } from '/@/lib/smart-sentry';
import TableOperator from '/@/components/support/table-operator/index.vue';
@@ -562,7 +563,7 @@ import { getRoleInfo } from '/@/utils/role-util';
}
// 批量上报
- function batchReport() {
+ async function batchReport() {
if (selectedRowKeyList.value.length === 0) {
message.warning('请选择要上报的记录');
return;
@@ -577,6 +578,26 @@ import { getRoleInfo } from '/@/utils/role-util';
message.warning('选中的记录不符合上报条件');
return;
}
+
+ const periods = new Map();
+ canReportRecords.forEach(record => {
+ if (!record.serviceEnd) return;
+ const date = dayjs(record.serviceEnd);
+ const year = date.year();
+ const quarter = Math.ceil((date.month() + 1) / 3);
+ periods.set(`${year}-${quarter}`, { year, quarter });
+ });
+ const missingPeriods = [];
+ for (const period of periods.values()) {
+ const result = await firmReportsApi.queryByQuarter(period.year, period.quarter);
+ if (result.data !== true) {
+ missingPeriods.push(`${period.year}年第${period.quarter}季度`);
+ }
+ }
+ if (missingPeriods.length > 0) {
+ message.warning(`以下活动所属季度尚未提交营业收入:${missingPeriods.join('、')},请完成填报后再上报律协`);
+ return;
+ }
// 确认上报
Modal.confirm({
@@ -591,9 +612,9 @@ import { getRoleInfo } from '/@/utils/role-util';
// 判断记录是否符合上报条件
function canReportRecord(record) {
// 只能上报已通过执业机构审核的记录(状态为3:已通过)
- // 且协会审核状态必须是未提交(0)
+ // 且协会审核状态必须是未提交(0)或被驳回(4)
return record.firmAuditStatus === 3 &&
- record.associationAuditStatus === 0;
+ (record.associationAuditStatus === 0 || record.associationAuditStatus === 4);
}
// 执行批量上报
diff --git a/src/views/mobile/service/create.vue b/src/views/mobile/service/create.vue
index 8e4eeea..8e5c3bf 100644
--- a/src/views/mobile/service/create.vue
+++ b/src/views/mobile/service/create.vue
@@ -7,9 +7,7 @@
←
-
+
@@ -20,38 +18,23 @@