|
|
@ -12,7 +12,7 @@ |
|
|
<a-form class="smart-query-form"> |
|
|
<a-form class="smart-query-form"> |
|
|
<a-row class="smart-query-form-row"> |
|
|
<a-row class="smart-query-form-row"> |
|
|
<a-form-item label="执业机构" class="smart-query-form-item"> |
|
|
<a-form-item label="执业机构" class="smart-query-form-item"> |
|
|
<DepartmentTreeSelect style="width: 150px" v-model:value="queryForm.firmId" placeholder="请选择执业机构" /> |
|
|
<DepartmentTreeSelect style="width: 250px" v-model:value="queryForm.firmId" placeholder="请选择执业机构" /> |
|
|
</a-form-item> |
|
|
</a-form-item> |
|
|
<a-form-item label="律师名称" class="smart-query-form-item"> |
|
|
<a-form-item label="律师名称" class="smart-query-form-item"> |
|
|
<a-select |
|
|
<a-select |
|
|
@ -38,14 +38,20 @@ |
|
|
<a-form-item label="组织单位名称" class="smart-query-form-item"> |
|
|
<a-form-item label="组织单位名称" class="smart-query-form-item"> |
|
|
<a-input style="width: 150px" v-model:value="queryForm.organizerName" placeholder="组织单位名称" /> |
|
|
<a-input style="width: 150px" v-model:value="queryForm.organizerName" placeholder="组织单位名称" /> |
|
|
</a-form-item> |
|
|
</a-form-item> |
|
|
<a-form-item label="执业机构审核状态" v-if="isAssociationRole" class="smart-query-form-item"> |
|
|
<a-form-item label="执业机构审核状态" v-if="isCtoRole" class="smart-query-form-item"> |
|
|
<a-select style="width: 150px" v-model:value="queryForm.firmAuditStatus" placeholder="请选择审核状态"> |
|
|
<a-select style="width: 150px" v-model:value="queryForm.firmAuditStatus" placeholder="请选择审核状态"> |
|
|
<a-select-option v-for="status in Object.values(REVIEW_ENUM)" :key="status.value" :value="status.value"> |
|
|
<a-select-option v-for="status in Object.values(REVIEW_ENUM)" :key="status.value" :value="status.value"> |
|
|
{{ status.desc }} |
|
|
{{ status.desc }} |
|
|
</a-select-option> |
|
|
</a-select-option> |
|
|
</a-select> |
|
|
</a-select> |
|
|
</a-form-item> |
|
|
</a-form-item> |
|
|
<a-form-item label="协会审核状态" class="smart-query-form-item"> |
|
|
<a-form-item label="本人本所" v-if="isCtoRole" class="smart-query-form-item"> |
|
|
|
|
|
<a-select style="width: 150px" v-model:value="queryForm.selfFirmFilter" placeholder="请选择筛选条件"> |
|
|
|
|
|
<a-select-option value="self">本人</a-select-option> |
|
|
|
|
|
<a-select-option value="firm">本所</a-select-option> |
|
|
|
|
|
</a-select> |
|
|
|
|
|
</a-form-item> |
|
|
|
|
|
<a-form-item label="协会审核状态" v-if="isCeo" class="smart-query-form-item"> |
|
|
<a-select style="width: 150px" v-model:value="queryForm.associationAuditStatus" placeholder="请选择审核状态"> |
|
|
<a-select style="width: 150px" v-model:value="queryForm.associationAuditStatus" placeholder="请选择审核状态"> |
|
|
<a-select-option v-for="status in Object.values(REVIEW_ENUM)" :key="status.value" :value="status.value"> |
|
|
<a-select-option v-for="status in Object.values(REVIEW_ENUM)" :key="status.value" :value="status.value"> |
|
|
{{ status.desc }} |
|
|
{{ status.desc }} |
|
|
@ -117,7 +123,7 @@ |
|
|
批量上报 |
|
|
批量上报 |
|
|
</a-button> |
|
|
</a-button> |
|
|
|
|
|
|
|
|
<a-button v-if="!isCeo" @click="confirmBatchDelete" type="primary" danger :disabled="selectedRowKeyList.length == 0"> |
|
|
<a-button v-if="!isCeo" @click="confirmBatchDelete" type="primary" danger :disabled="!canBatchDelete()"> |
|
|
<template #icon> |
|
|
<template #icon> |
|
|
<DeleteOutlined /> |
|
|
<DeleteOutlined /> |
|
|
</template> |
|
|
</template> |
|
|
@ -153,11 +159,14 @@ |
|
|
<template v-if="column.dataIndex === 'action'"> |
|
|
<template v-if="column.dataIndex === 'action'"> |
|
|
<div class="smart-table-operate"> |
|
|
<div class="smart-table-operate"> |
|
|
<a-button @click="showDetail(record)" type="link">详情</a-button> |
|
|
<a-button @click="showDetail(record)" type="link">详情</a-button> |
|
|
<a-button v-if="(record.firmAuditStatus === 0 || record.firmAuditStatus === 4) && record.userId === loginInfo?.userId" @click="showForm(record)" type="link">编辑</a-button> |
|
|
<!-- 执业机构审核状态为拒绝时,只显示详情按钮 --> |
|
|
<a-button v-if="(record.firmAuditStatus === 0 && record.userId === loginInfo?.userId)" @click="onSubmit(record)" type="link">提交</a-button> |
|
|
<template v-if="record.firmAuditStatus !== 4"> |
|
|
<a-button v-if="canAuditRecord(record)" @click="showAuditModal(record)" type="link">审核</a-button> |
|
|
<a-button v-if="(record.firmAuditStatus === 0 || record.firmAuditStatus === 4) && record.userId === loginInfo?.userId" @click="showForm(record)" type="link">编辑</a-button> |
|
|
<a-button v-if="canRejectRecord(record)" @click="showRejectModal(record)" danger type="link">驳回</a-button> |
|
|
<a-button v-if="(record.firmAuditStatus === 0 && record.userId === loginInfo?.userId)" @click="onSubmit(record)" type="link">提交</a-button> |
|
|
<a-button v-if="record.firmAuditStatus === 0 && record.userId === loginInfo?.userId" @click="onDelete(record)" danger type="link">删除</a-button> |
|
|
<a-button v-if="canAuditRecord(record)" @click="showAuditModal(record)" type="link">审核</a-button> |
|
|
|
|
|
<a-button v-if="canRejectRecord(record)" @click="showRejectModal(record)" danger type="link">驳回</a-button> |
|
|
|
|
|
<a-button v-if="record.firmAuditStatus === 0 && record.userId === loginInfo?.userId" @click="onDelete(record)" danger type="link">删除</a-button> |
|
|
|
|
|
</template> |
|
|
</div> |
|
|
</div> |
|
|
</template> |
|
|
</template> |
|
|
</template> |
|
|
</template> |
|
|
@ -225,6 +234,8 @@ |
|
|
v-model:value="rejectForm.rejectReason" |
|
|
v-model:value="rejectForm.rejectReason" |
|
|
placeholder="请输入驳回原因" |
|
|
placeholder="请输入驳回原因" |
|
|
rows="4" |
|
|
rows="4" |
|
|
|
|
|
:maxlength="200" |
|
|
|
|
|
show-count |
|
|
style="resize: vertical;" |
|
|
style="resize: vertical;" |
|
|
/> |
|
|
/> |
|
|
</a-form-item> |
|
|
</a-form-item> |
|
|
@ -287,6 +298,7 @@ |
|
|
</template> |
|
|
</template> |
|
|
<script setup> |
|
|
<script setup> |
|
|
import { reactive, ref, onMounted } from 'vue'; |
|
|
import { reactive, ref, onMounted } from 'vue'; |
|
|
|
|
|
import { useRoute } from 'vue-router'; |
|
|
import { message, Modal } from 'ant-design-vue'; |
|
|
import { message, Modal } from 'ant-design-vue'; |
|
|
import { SmartLoading } from '/@/components/framework/smart-loading'; |
|
|
import { SmartLoading } from '/@/components/framework/smart-loading'; |
|
|
import { serviceApplicationsApi } from '/@/api/business/service-applications/service-applications-api'; |
|
|
import { serviceApplicationsApi } from '/@/api/business/service-applications/service-applications-api'; |
|
|
@ -306,6 +318,7 @@ import { loginApi } from '/@/api/system/login-api'; |
|
|
title: '执业机构', |
|
|
title: '执业机构', |
|
|
dataIndex: 'departmentName', |
|
|
dataIndex: 'departmentName', |
|
|
ellipsis: true, |
|
|
ellipsis: true, |
|
|
|
|
|
width: 180, |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
title: '律师名称', |
|
|
title: '律师名称', |
|
|
@ -316,16 +329,19 @@ import { loginApi } from '/@/api/system/login-api'; |
|
|
title: '职务名称', |
|
|
title: '职务名称', |
|
|
dataIndex: 'positionName', |
|
|
dataIndex: 'positionName', |
|
|
ellipsis: true, |
|
|
ellipsis: true, |
|
|
|
|
|
width: 100, |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
title: '服务开始时间', |
|
|
title: '服务开始时间', |
|
|
dataIndex: 'serviceStart', |
|
|
dataIndex: 'serviceStart', |
|
|
ellipsis: true, |
|
|
ellipsis: true, |
|
|
|
|
|
width: 100, |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
title: '服务结束时间', |
|
|
title: '服务结束时间', |
|
|
dataIndex: 'serviceEnd', |
|
|
dataIndex: 'serviceEnd', |
|
|
ellipsis: true, |
|
|
ellipsis: true, |
|
|
|
|
|
width: 100, |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
title: '服务时长(小时)', |
|
|
title: '服务时长(小时)', |
|
|
@ -412,6 +428,7 @@ import { loginApi } from '/@/api/system/login-api'; |
|
|
managerName: undefined, // 负责人姓名 |
|
|
managerName: undefined, // 负责人姓名 |
|
|
firmAuditStatus: undefined, // 执业机构审核状态 |
|
|
firmAuditStatus: undefined, // 执业机构审核状态 |
|
|
associationAuditStatus: undefined, // 协会审核状态 |
|
|
associationAuditStatus: undefined, // 协会审核状态 |
|
|
|
|
|
selfFirmFilter: undefined, // 本人本所筛选条件 |
|
|
}; |
|
|
}; |
|
|
// 查询表单form |
|
|
// 查询表单form |
|
|
const queryForm = reactive({ ...queryFormState }); |
|
|
const queryForm = reactive({ ...queryFormState }); |
|
|
@ -452,6 +469,9 @@ import { loginApi } from '/@/api/system/login-api'; |
|
|
// 判断用户是否为CEO角色(CEO显示律所统计概览) |
|
|
// 判断用户是否为CEO角色(CEO显示律所统计概览) |
|
|
const isCeo = ref(false); |
|
|
const isCeo = ref(false); |
|
|
|
|
|
|
|
|
|
|
|
// 判断用户是否为律所角色 |
|
|
|
|
|
const isFirmRole = ref(false); |
|
|
|
|
|
|
|
|
// 获取登录信息 |
|
|
// 获取登录信息 |
|
|
async function getLoginInfo() { |
|
|
async function getLoginInfo() { |
|
|
try { |
|
|
try { |
|
|
@ -484,6 +504,12 @@ import { loginApi } from '/@/api/system/login-api'; |
|
|
roleLower.includes('律协') || |
|
|
roleLower.includes('律协') || |
|
|
roleLower.includes('律师协会'); |
|
|
roleLower.includes('律师协会'); |
|
|
|
|
|
|
|
|
|
|
|
// 律所角色判断 |
|
|
|
|
|
isFirmRole.value = roleLower.includes('律所') || |
|
|
|
|
|
roleLower.includes('firm') || |
|
|
|
|
|
roleLower.includes('lawyer') || |
|
|
|
|
|
roleLower.includes('律师'); |
|
|
|
|
|
|
|
|
// CEO角色判断(CEO不显示新建申报和批量提交按钮) |
|
|
// CEO角色判断(CEO不显示新建申报和批量提交按钮) |
|
|
isCeo.value = roleLower === 'ceo'; |
|
|
isCeo.value = roleLower === 'ceo'; |
|
|
|
|
|
|
|
|
@ -622,8 +648,8 @@ import { loginApi } from '/@/api/system/login-api'; |
|
|
// 确认上报 |
|
|
// 确认上报 |
|
|
Modal.confirm({ |
|
|
Modal.confirm({ |
|
|
title: '批量上报确认', |
|
|
title: '批量上报确认', |
|
|
content: `确定要将选中的 ${selectedRowKeyList.value.length} 条记录上报到协会审核吗?`, |
|
|
content: `确定要将选中的 ${canReportRecords.length} 条符合条件的记录上报到协会审核吗?`, |
|
|
onOk: handleBatchReport, |
|
|
onOk: () => handleBatchReport(canReportRecords), |
|
|
okText: '确定上报', |
|
|
okText: '确定上报', |
|
|
cancelText: '取消' |
|
|
cancelText: '取消' |
|
|
}); |
|
|
}); |
|
|
@ -631,31 +657,27 @@ import { loginApi } from '/@/api/system/login-api'; |
|
|
|
|
|
|
|
|
// 判断记录是否符合上报条件 |
|
|
// 判断记录是否符合上报条件 |
|
|
function canReportRecord(record) { |
|
|
function canReportRecord(record) { |
|
|
// CTO角色只能上报已通过执业机构审核的记录(状态为3:已通过) |
|
|
// 只能上报已通过执业机构审核的记录(状态为3:已通过) |
|
|
// 且协会审核状态必须是未提交(0)或拒绝(4)才能上报 |
|
|
// 且协会审核状态必须是未提交(0) |
|
|
return record.firmAuditStatus === 3 && |
|
|
return record.firmAuditStatus === 3 && |
|
|
(record.associationAuditStatus === 0 || record.associationAuditStatus === 4); |
|
|
record.associationAuditStatus === 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 执行批量上报 |
|
|
// 执行批量上报 |
|
|
async function handleBatchReport() { |
|
|
async function handleBatchReport(validRecords) { |
|
|
try { |
|
|
try { |
|
|
SmartLoading.show(); |
|
|
SmartLoading.show(); |
|
|
|
|
|
|
|
|
console.log('批量上报参数:', selectedRowKeyList.value); |
|
|
// 从符合条件的记录中提取ID列表 |
|
|
|
|
|
const idList = validRecords.map(record => record.applicationId).map(id => Number(id)); |
|
|
|
|
|
|
|
|
// 后端接口接收 ValidateList<Long> idList,直接传递ID数组 |
|
|
if (idList.length === 0) { |
|
|
// 确保ID列表是有效的数字数组 |
|
|
message.warning('没有符合条件的记录可以上报'); |
|
|
const validIds = selectedRowKeyList.value.filter(id => id && !isNaN(id)); |
|
|
|
|
|
|
|
|
|
|
|
if (validIds.length === 0) { |
|
|
|
|
|
message.warning('请选择要上报的记录'); |
|
|
|
|
|
SmartLoading.hide(); |
|
|
SmartLoading.hide(); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// ValidateList<Long> 直接接收ID数组,不需要包装对象 |
|
|
console.log('批量上报参数:', idList); |
|
|
const idList = validIds.map(id => Number(id)); |
|
|
|
|
|
|
|
|
|
|
|
const res = await serviceApplicationsApi.batchSubmitAsFirm(idList); |
|
|
const res = await serviceApplicationsApi.batchSubmitAsFirm(idList); |
|
|
|
|
|
|
|
|
@ -721,12 +743,36 @@ import { loginApi } from '/@/api/system/login-api'; |
|
|
queryData(); |
|
|
queryData(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 处理本人本所筛选条件 |
|
|
|
|
|
function processSelfFirmFilter(params) { |
|
|
|
|
|
const processedParams = { ...params }; |
|
|
|
|
|
|
|
|
|
|
|
// 如果有本人本所筛选条件 |
|
|
|
|
|
if (loginInfo.value && params.selfFirmFilter) { |
|
|
|
|
|
if (params.selfFirmFilter === 'self') { |
|
|
|
|
|
// 本人:只显示当前用户的数据 |
|
|
|
|
|
processedParams.userId = loginInfo.value.userId; |
|
|
|
|
|
} else if (params.selfFirmFilter === 'firm') { |
|
|
|
|
|
// 本所:显示当前用户所在律所的所有数据 |
|
|
|
|
|
processedParams.firmId = loginInfo.value.departmentId; |
|
|
|
|
|
} |
|
|
|
|
|
// 如果是'all',则不需要特殊处理,显示全部数据 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 删除筛选条件字段,避免传递给后端 |
|
|
|
|
|
delete processedParams.selfFirmFilter; |
|
|
|
|
|
|
|
|
|
|
|
return processedParams; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 查询数据 |
|
|
// 查询数据 |
|
|
async function queryData() { |
|
|
async function queryData() { |
|
|
tableLoading.value = true; |
|
|
tableLoading.value = true; |
|
|
try { |
|
|
try { |
|
|
// 处理查询参数 |
|
|
// 处理查询参数 |
|
|
let query = processQueryParams({ ...queryForm }); |
|
|
let query = processQueryParams({ ...queryForm }); |
|
|
|
|
|
// 处理本人本所筛选条件 |
|
|
|
|
|
query = processSelfFirmFilter(query); |
|
|
let queryResult = await serviceApplicationsApi.queryPage(query); |
|
|
let queryResult = await serviceApplicationsApi.queryPage(query); |
|
|
tableData.value = queryResult.data.list; |
|
|
tableData.value = queryResult.data.list; |
|
|
total.value = queryResult.data.total; |
|
|
total.value = queryResult.data.total; |
|
|
@ -738,16 +784,17 @@ import { loginApi } from '/@/api/system/login-api'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(async () => { |
|
|
// 获取路由实例 |
|
|
|
|
|
const route = useRoute(); |
|
|
|
|
|
|
|
|
|
|
|
onMounted(async () => { |
|
|
await getLoginInfo(); |
|
|
await getLoginInfo(); |
|
|
|
|
|
|
|
|
// 检查sessionStorage中是否有serviceFirmId |
|
|
// 检查URL查询参数中是否有firmId |
|
|
const firmId = sessionStorage.getItem('serviceFirmId'); |
|
|
const firmId = route.query.firmId; |
|
|
if (firmId) { |
|
|
if (firmId) { |
|
|
// 如果有firmId,则设置查询条件 |
|
|
// 如果有firmId,则设置查询条件 |
|
|
queryForm.firmId = firmId; |
|
|
queryForm.firmId = firmId; |
|
|
// 清除sessionStorage中的firmId,避免下次页面加载时仍然使用该值 |
|
|
|
|
|
sessionStorage.removeItem('serviceFirmId'); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 查询数据 |
|
|
// 查询数据 |
|
|
@ -892,6 +939,25 @@ function showAuditModal(record) { |
|
|
selectedRowKeyList.value = selectedRowKeys; |
|
|
selectedRowKeyList.value = selectedRowKeys; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 判断是否可以批量删除(所有选中记录的执业机构审核状态必须为未提交) |
|
|
|
|
|
function canBatchDelete() { |
|
|
|
|
|
if (selectedRowKeyList.value.length === 0) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 获取选中的记录 |
|
|
|
|
|
const selectedRecords = tableData.value.filter(record => |
|
|
|
|
|
selectedRowKeyList.value.includes(record.applicationId) |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
// 检查所有记录是否都是未提交状态 |
|
|
|
|
|
const allUnsubmitted = selectedRecords.every(record => |
|
|
|
|
|
record.firmAuditStatus === 0 |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
return allUnsubmitted; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 批量删除 |
|
|
// 批量删除 |
|
|
function confirmBatchDelete() { |
|
|
function confirmBatchDelete() { |
|
|
if (selectedRowKeyList.value.length === 0) { |
|
|
if (selectedRowKeyList.value.length === 0) { |
|
|
@ -904,19 +970,19 @@ function showAuditModal(record) { |
|
|
selectedRowKeyList.value.includes(record.applicationId) |
|
|
selectedRowKeyList.value.includes(record.applicationId) |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
// 检查是否有不符合删除条件的记录 |
|
|
// 检查是否有不符合删除条件的记录(只能删除未提交状态的数据) |
|
|
const invalidRecords = selectedRecords.filter(record => |
|
|
const invalidRecords = selectedRecords.filter(record => |
|
|
record.firmAuditStatus !== 0 && record.firmAuditStatus !== 4 |
|
|
record.firmAuditStatus !== 0 |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
if (invalidRecords.length > 0) { |
|
|
if (invalidRecords.length > 0) { |
|
|
message.warning('只能删除未提交或拒绝状态的数据'); |
|
|
message.warning('只能删除未提交状态的数据'); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Modal.confirm({ |
|
|
Modal.confirm({ |
|
|
title: '提示', |
|
|
title: '提示', |
|
|
content: '确定要批量删除这些未提交或拒绝状态的数据吗?', |
|
|
content: '确定要批量删除这些未提交状态的数据吗?', |
|
|
okText: '删除', |
|
|
okText: '删除', |
|
|
okType: 'danger', |
|
|
okType: 'danger', |
|
|
onOk() { |
|
|
onOk() { |
|
|
@ -1148,12 +1214,18 @@ function showAuditModal(record) { |
|
|
|
|
|
|
|
|
return canReject; |
|
|
return canReject; |
|
|
} else if (isCtoRole.value) { |
|
|
} else if (isCtoRole.value) { |
|
|
// CTO角色:协会审核状态必须是驳回(4) |
|
|
// CTO角色:协会审核状态必须是驳回(4)且执业机构审核状态不能是驳回(4) |
|
|
if (record.associationAuditStatus !== 4) { |
|
|
if (record.associationAuditStatus !== 4) { |
|
|
console.log('驳回按钮不显示:协会审核状态不是驳回', record.associationAuditStatus); |
|
|
console.log('驳回按钮不显示:协会审核状态不是驳回', record.associationAuditStatus); |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 执业机构审核状态不能是驳回(4) |
|
|
|
|
|
if (record.firmAuditStatus === 4) { |
|
|
|
|
|
console.log('驳回按钮不显示:执业机构审核状态是驳回', record.firmAuditStatus); |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|