|
|
|
|
<!--
|
|
|
|
|
* 服务申报表
|
|
|
|
|
*
|
|
|
|
|
* @Author: wzh
|
|
|
|
|
* @Date: 2025-12-20 14:44:06
|
|
|
|
|
* @Copyright 1.0
|
|
|
|
|
-->
|
|
|
|
|
<template>
|
|
|
|
|
<!-- 默认直接显示服务记录列表,所有角色都显示 -->
|
|
|
|
|
<div>
|
|
|
|
|
<!---------- 查询表单form begin ----------->
|
|
|
|
|
<a-form class="smart-query-form">
|
|
|
|
|
<a-row class="smart-query-form-row">
|
|
|
|
|
<a-form-item label="执业机构" class="smart-query-form-item">
|
|
|
|
|
<DepartmentTreeSelect style="width: 250px" v-model:value="queryForm.firmId" placeholder="请选择执业机构" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="律师名称" class="smart-query-form-item">
|
|
|
|
|
<a-select
|
|
|
|
|
v-model:value="queryForm.userId"
|
|
|
|
|
style="width: 150px"
|
|
|
|
|
placeholder="请选择律师"
|
|
|
|
|
:showSearch="true"
|
|
|
|
|
:allowClear="true"
|
|
|
|
|
@focus="loadAllEmployees"
|
|
|
|
|
>
|
|
|
|
|
<a-select-option v-for="item in employeeList" :key="item.employeeId" :value="item.employeeId">
|
|
|
|
|
{{ item.actualName }}
|
|
|
|
|
<template v-if="item.departmentName"> ({{ item.departmentName }}) </template>
|
|
|
|
|
</a-select-option>
|
|
|
|
|
</a-select>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="服务开始时间" class="smart-query-form-item">
|
|
|
|
|
<a-date-picker style="width: 150px" v-model:value="queryForm.serviceStart" placeholder="开始时间" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="服务结束时间" class="smart-query-form-item">
|
|
|
|
|
<a-date-picker style="width: 150px" v-model:value="queryForm.serviceEnd" placeholder="结束时间" />
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="组织单位名称" class="smart-query-form-item">
|
|
|
|
|
<a-input style="width: 150px" v-model:value="queryForm.organizerName" placeholder="组织单位名称" />
|
|
|
|
|
</a-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-option v-for="status in Object.values(REVIEW_ENUM)" :key="status.value" :value="status.value">
|
|
|
|
|
{{ status.desc }}
|
|
|
|
|
</a-select-option>
|
|
|
|
|
</a-select>
|
|
|
|
|
</a-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-option v-for="status in Object.values(REVIEW_ENUM)" :key="status.value" :value="status.value">
|
|
|
|
|
{{ status.desc }}
|
|
|
|
|
</a-select-option>
|
|
|
|
|
</a-select>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item class="smart-query-form-item smart-margin-left10">
|
|
|
|
|
<a-button v-privilege="'serviceApplications:query'" type="primary" @click="onSearch">
|
|
|
|
|
<template #icon>
|
|
|
|
|
<SearchOutlined />
|
|
|
|
|
</template>
|
|
|
|
|
查询
|
|
|
|
|
</a-button>
|
|
|
|
|
<a-button @click="resetQuery" class="smart-margin-left10">
|
|
|
|
|
<template #icon>
|
|
|
|
|
<ReloadOutlined />
|
|
|
|
|
</template>
|
|
|
|
|
重置
|
|
|
|
|
</a-button>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
</a-row>
|
|
|
|
|
</a-form>
|
|
|
|
|
<!---------- 查询表单form end ----------->
|
|
|
|
|
|
|
|
|
|
<a-card size="small" :bordered="false" :hoverable="true">
|
|
|
|
|
<!---------- 表格操作行 begin ----------->
|
|
|
|
|
<a-row class="smart-table-btn-block">
|
|
|
|
|
<div class="smart-table-operate-block">
|
|
|
|
|
|
|
|
|
|
<!-- 新建申报按钮:非协会角色且非CEO角色显示 -->
|
|
|
|
|
<a-button v-if="!isAssociationRole && !isCeo" @click="showForm" type="primary">
|
|
|
|
|
<template #icon>
|
|
|
|
|
<PlusOutlined />
|
|
|
|
|
</template>
|
|
|
|
|
新建申报
|
|
|
|
|
</a-button>
|
|
|
|
|
|
|
|
|
|
<!-- 批量提交按钮:非CEO角色显示 -->
|
|
|
|
|
<a-button v-if="!isCeo" @click="batchSubmit" type="primary" :disabled="selectedRowKeyList.length == 0">
|
|
|
|
|
<template #icon>
|
|
|
|
|
<SendOutlined />
|
|
|
|
|
</template>
|
|
|
|
|
批量提交
|
|
|
|
|
</a-button>
|
|
|
|
|
|
|
|
|
|
<!-- 批量审核按钮(不是user角色显示) -->
|
|
|
|
|
<a-button
|
|
|
|
|
v-if="isNotUser"
|
|
|
|
|
@click="batchAudit"
|
|
|
|
|
type="primary"
|
|
|
|
|
:disabled="selectedRowKeyList.length == 0"
|
|
|
|
|
>
|
|
|
|
|
<template #icon>
|
|
|
|
|
<CheckCircleOutlined />
|
|
|
|
|
</template>
|
|
|
|
|
批量审核
|
|
|
|
|
</a-button>
|
|
|
|
|
|
|
|
|
|
<!-- 批量上报按钮(cto角色显示) -->
|
|
|
|
|
<a-button
|
|
|
|
|
v-if="isCtoRole"
|
|
|
|
|
@click="batchReport"
|
|
|
|
|
type="primary"
|
|
|
|
|
:disabled="selectedRowKeyList.length == 0"
|
|
|
|
|
>
|
|
|
|
|
<template #icon>
|
|
|
|
|
<UploadOutlined />
|
|
|
|
|
</template>
|
|
|
|
|
批量上报
|
|
|
|
|
</a-button>
|
|
|
|
|
|
|
|
|
|
<a-button v-if="!isCeo" @click="confirmBatchDelete" type="primary" danger :disabled="!canBatchDelete()">
|
|
|
|
|
<template #icon>
|
|
|
|
|
<DeleteOutlined />
|
|
|
|
|
</template>
|
|
|
|
|
批量删除
|
|
|
|
|
</a-button>
|
|
|
|
|
<!--<a-button @click="showImportModal" type="primary">
|
|
|
|
|
<template #icon>
|
|
|
|
|
<ImportOutlined />
|
|
|
|
|
</template>
|
|
|
|
|
导入
|
|
|
|
|
</a-button>-->
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
<div class="smart-table-setting-block">
|
|
|
|
|
<TableOperator v-model="columns" :tableId="null" :refresh="queryData" />
|
|
|
|
|
</div>
|
|
|
|
|
</a-row>
|
|
|
|
|
<!---------- 表格操作行 end ----------->
|
|
|
|
|
|
|
|
|
|
<!---------- 表格 begin ----------->
|
|
|
|
|
<a-table
|
|
|
|
|
size="small"
|
|
|
|
|
:scroll="{ x: 1800, y: 800 }"
|
|
|
|
|
:dataSource="tableData"
|
|
|
|
|
:columns="columns"
|
|
|
|
|
rowKey="applicationId"
|
|
|
|
|
bordered
|
|
|
|
|
:loading="tableLoading"
|
|
|
|
|
:pagination="false"
|
|
|
|
|
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
|
|
|
|
|
>
|
|
|
|
|
<template #bodyCell="{ record, column }">
|
|
|
|
|
<template v-if="column.dataIndex === 'action'">
|
|
|
|
|
<div class="smart-table-operate">
|
|
|
|
|
<a-button @click="showDetail(record)" type="link">详情</a-button>
|
|
|
|
|
<!-- 执业机构审核状态为拒绝时,只显示详情按钮 -->
|
|
|
|
|
<template v-if="record.firmAuditStatus !== 4">
|
|
|
|
|
<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>
|
|
|
|
|
<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>
|
|
|
|
|
</template>
|
|
|
|
|
</template>
|
|
|
|
|
</a-table>
|
|
|
|
|
<!---------- 表格 end ----------->
|
|
|
|
|
|
|
|
|
|
<!---------- 审核弹框 begin ----------->
|
|
|
|
|
<a-modal
|
|
|
|
|
v-model:visible="auditModalVisible"
|
|
|
|
|
title="服务申报审核"
|
|
|
|
|
:confirm-loading="auditLoading"
|
|
|
|
|
@ok="handleAudit"
|
|
|
|
|
@cancel="handleAuditCancel"
|
|
|
|
|
width="400px"
|
|
|
|
|
>
|
|
|
|
|
<div style="text-align: center; padding: 20px 0;">
|
|
|
|
|
<p style="margin-bottom: 20px; font-size: 16px;">请选择审核结果:</p>
|
|
|
|
|
<a-radio-group v-model:value="auditForm.auditResult" size="large">
|
|
|
|
|
<a-radio :value="3" style="margin-right: 30px;">
|
|
|
|
|
<span style="font-size: 16px;">同意</span>
|
|
|
|
|
</a-radio>
|
|
|
|
|
<a-radio :value="4">
|
|
|
|
|
<span style="font-size: 16px;">拒绝</span>
|
|
|
|
|
</a-radio>
|
|
|
|
|
</a-radio-group>
|
|
|
|
|
</div>
|
|
|
|
|
</a-modal>
|
|
|
|
|
<!---------- 审核弹框 end ----------->
|
|
|
|
|
|
|
|
|
|
<!---------- 批量审核弹框 begin ----------->
|
|
|
|
|
<a-modal
|
|
|
|
|
v-model:visible="batchAuditModalVisible"
|
|
|
|
|
title="批量审核服务申报"
|
|
|
|
|
:confirm-loading="batchAuditLoading"
|
|
|
|
|
@ok="handleBatchAudit"
|
|
|
|
|
@cancel="handleBatchAuditCancel"
|
|
|
|
|
width="500px"
|
|
|
|
|
>
|
|
|
|
|
<a-form :model="batchAuditForm" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
|
|
|
|
|
<a-form-item label="审核结果" required>
|
|
|
|
|
<a-radio-group v-model:value="batchAuditForm.auditResult">
|
|
|
|
|
<a-radio :value="3">同意</a-radio>
|
|
|
|
|
<a-radio :value="4">拒绝</a-radio>
|
|
|
|
|
</a-radio-group>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
<a-form-item label="选中记录">
|
|
|
|
|
<span style="color: #1890ff;">{{ selectedRowKeyList.length }} 条记录</span>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
</a-form>
|
|
|
|
|
</a-modal>
|
|
|
|
|
<!---------- 批量审核弹框 end ----------->
|
|
|
|
|
|
|
|
|
|
<!---------- 驳回弹框 begin ----------->
|
|
|
|
|
<a-modal
|
|
|
|
|
v-model:visible="rejectModalVisible"
|
|
|
|
|
title="驳回服务申报"
|
|
|
|
|
:confirm-loading="rejectLoading"
|
|
|
|
|
@ok="handleReject"
|
|
|
|
|
@cancel="handleRejectCancel"
|
|
|
|
|
width="500px"
|
|
|
|
|
>
|
|
|
|
|
<a-form :model="rejectForm" layout="vertical">
|
|
|
|
|
<a-form-item label="驳回原因" required>
|
|
|
|
|
<a-textarea
|
|
|
|
|
v-model:value="rejectForm.rejectReason"
|
|
|
|
|
placeholder="请输入驳回原因"
|
|
|
|
|
rows="4"
|
|
|
|
|
:maxlength="200"
|
|
|
|
|
show-count
|
|
|
|
|
style="resize: vertical;"
|
|
|
|
|
/>
|
|
|
|
|
</a-form-item>
|
|
|
|
|
</a-form>
|
|
|
|
|
</a-modal>
|
|
|
|
|
<!---------- 驳回弹框 end ----------->
|
|
|
|
|
|
|
|
|
|
<div class="smart-query-table-page">
|
|
|
|
|
<a-pagination
|
|
|
|
|
showSizeChanger
|
|
|
|
|
showQuickJumper
|
|
|
|
|
show-less-items
|
|
|
|
|
:pageSizeOptions="PAGE_SIZE_OPTIONS"
|
|
|
|
|
:defaultPageSize="queryForm.pageSize"
|
|
|
|
|
v-model:current="queryForm.pageNum"
|
|
|
|
|
v-model:pageSize="queryForm.pageSize"
|
|
|
|
|
:total="total"
|
|
|
|
|
@change="queryData"
|
|
|
|
|
@showSizeChange="queryData"
|
|
|
|
|
:show-total="(total) => `共${total}条`"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<ServiceApplicationsForm ref="formRef" @reloadList="queryData"/>
|
|
|
|
|
<AgreementModal ref="agreementModalRef" @confirm="handleAgreementConfirm" />
|
|
|
|
|
|
|
|
|
|
<!-- 导入弹窗 -->
|
|
|
|
|
<a-modal v-model:open="importModalShowFlag" title="导入" @onCancel="hideImportModal" @ok="hideImportModal">
|
|
|
|
|
<div style="text-align: center; width: 400px; margin: 0 auto">
|
|
|
|
|
<a-button @click="downloadExcel">
|
|
|
|
|
<DownloadOutlined />
|
|
|
|
|
第一步:下载模板
|
|
|
|
|
</a-button>
|
|
|
|
|
<br />
|
|
|
|
|
<br />
|
|
|
|
|
<a-upload
|
|
|
|
|
v-model:fileList="fileList"
|
|
|
|
|
name="file"
|
|
|
|
|
:multiple="false"
|
|
|
|
|
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
|
|
|
|
|
accept=".xls,.xlsx"
|
|
|
|
|
:before-upload="beforeUpload"
|
|
|
|
|
@remove="handleRemove"
|
|
|
|
|
>
|
|
|
|
|
<a-button>
|
|
|
|
|
<UploadOutlined />
|
|
|
|
|
第二步:选择文件
|
|
|
|
|
</a-button>
|
|
|
|
|
</a-upload>
|
|
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
<a-button @click="onImport">
|
|
|
|
|
<ImportOutlined />
|
|
|
|
|
第三步:开始导入
|
|
|
|
|
</a-button>
|
|
|
|
|
</div>
|
|
|
|
|
</a-modal>
|
|
|
|
|
|
|
|
|
|
</a-card>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<script setup>
|
|
|
|
|
import { reactive, ref, onMounted } from 'vue';
|
|
|
|
|
import { useRoute } 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 { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
|
|
|
|
import { smartSentry } from '/@/lib/smart-sentry';
|
|
|
|
|
import TableOperator from '/@/components/support/table-operator/index.vue';
|
|
|
|
|
import ServiceApplicationsForm from './service-applications-form.vue';
|
|
|
|
|
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
|
|
|
|
|
import { employeeApi } from '/@/api/system/employee-api';
|
|
|
|
|
import { REVIEW_ENUM } from '/@/constants/system/review-const';
|
|
|
|
|
import { PlusOutlined, DeleteOutlined, SendOutlined, ImportOutlined, ExportOutlined, DownloadOutlined, UploadOutlined, CheckCircleOutlined } from '@ant-design/icons-vue';
|
|
|
|
|
import { loginApi } from '/@/api/system/login-api';
|
|
|
|
|
import AgreementModal from '/@/views/system/home/components/agreement-modal.vue';
|
|
|
|
|
// ---------------------------- 表格列 ----------------------------
|
|
|
|
|
|
|
|
|
|
const columns = ref([
|
|
|
|
|
{
|
|
|
|
|
title: '执业机构',
|
|
|
|
|
dataIndex: 'departmentName',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
width: 180,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '律师名称',
|
|
|
|
|
dataIndex: 'userName',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '职务名称',
|
|
|
|
|
dataIndex: 'positionName',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
width: 100,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '服务开始时间',
|
|
|
|
|
dataIndex: 'serviceStart',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
width: 100,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '服务结束时间',
|
|
|
|
|
dataIndex: 'serviceEnd',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
width: 100,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '服务时长(小时)',
|
|
|
|
|
dataIndex: 'serviceDuration',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '金额',
|
|
|
|
|
dataIndex: 'workloadScore',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '案号',
|
|
|
|
|
dataIndex: 'recordNo',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '参加人数(受益人数)',
|
|
|
|
|
dataIndex: 'beneficiaryCount',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '组织单位名称',
|
|
|
|
|
dataIndex: 'organizerName',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '服务对象负责人/联系人姓名',
|
|
|
|
|
dataIndex: 'organizerContact',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '联系方式',
|
|
|
|
|
dataIndex: 'organizerPhone',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '执业机构审核状态',
|
|
|
|
|
dataIndex: 'firmAuditStatus',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
customRender: ({ text }) => {
|
|
|
|
|
const status = Object.values(REVIEW_ENUM).find(item => item.value === text);
|
|
|
|
|
return status ? status.desc : text;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '执业机构审核人',
|
|
|
|
|
dataIndex: 'firmAuditUserName',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '执业机构审核时间',
|
|
|
|
|
dataIndex: 'firmAuditTime',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '协会审核状态',
|
|
|
|
|
dataIndex: 'associationAuditStatus',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
customRender: ({ text }) => {
|
|
|
|
|
const status = Object.values(REVIEW_ENUM).find(item => item.value === text);
|
|
|
|
|
return status ? status.desc : text;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '协会审核意见',
|
|
|
|
|
dataIndex: 'associationAuditOpinion',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '协会审核人',
|
|
|
|
|
dataIndex: 'associationAuditUserName',
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
title: '操作',
|
|
|
|
|
dataIndex: 'action',
|
|
|
|
|
fixed: 'right',
|
|
|
|
|
width: 150,
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// ---------------------------- 查询数据表单和方法 ----------------------------
|
|
|
|
|
|
|
|
|
|
const queryFormState = {
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
firmId: undefined, // 执业机构ID
|
|
|
|
|
userId: undefined, // 律师ID
|
|
|
|
|
serviceStart: undefined, // 服务开始时间
|
|
|
|
|
serviceEnd: undefined, // 服务结束时间
|
|
|
|
|
organizerName: undefined, // 组织单位名称
|
|
|
|
|
managerName: undefined, // 负责人姓名
|
|
|
|
|
firmAuditStatus: undefined, // 执业机构审核状态
|
|
|
|
|
associationAuditStatus: undefined, // 协会审核状态
|
|
|
|
|
selfFirmFilter: undefined, // 本人本所筛选条件
|
|
|
|
|
};
|
|
|
|
|
// 查询表单form
|
|
|
|
|
const queryForm = reactive({ ...queryFormState });
|
|
|
|
|
// 表格加载loading
|
|
|
|
|
const tableLoading = ref(false);
|
|
|
|
|
// 表格数据
|
|
|
|
|
const tableData = ref([]);
|
|
|
|
|
|
|
|
|
|
// 员工列表数据
|
|
|
|
|
const employeeList = ref([]);
|
|
|
|
|
|
|
|
|
|
// 审核相关状态
|
|
|
|
|
const auditModalVisible = ref(false);
|
|
|
|
|
const auditLoading = ref(false);
|
|
|
|
|
const currentAuditRecord = ref(null);
|
|
|
|
|
const auditForm = reactive({
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 批量审核相关状态
|
|
|
|
|
const batchAuditModalVisible = ref(false);
|
|
|
|
|
const batchAuditLoading = ref(false);
|
|
|
|
|
const batchAuditForm = reactive({
|
|
|
|
|
applicationIds: '', // 选中的申请ID列表,用逗号分隔
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 登录用户信息
|
|
|
|
|
const loginInfo = ref(null);
|
|
|
|
|
|
|
|
|
|
// 判断用户是否为user角色(不是user则显示批量审核)
|
|
|
|
|
const isNotUser = ref(false);
|
|
|
|
|
|
|
|
|
|
// 判断用户是否为cto角色(cto则额外显示批量上报)
|
|
|
|
|
const isCtoRole = ref(false);
|
|
|
|
|
|
|
|
|
|
// 判断用户是否为协会角色(协会角色显示驳回按钮)
|
|
|
|
|
const isAssociationRole = ref(false);
|
|
|
|
|
|
|
|
|
|
// 判断用户是否为CEO角色(CEO显示律所统计概览)
|
|
|
|
|
const isCeo = ref(false);
|
|
|
|
|
|
|
|
|
|
// 判断用户是否为律所角色
|
|
|
|
|
const isFirmRole = ref(false);
|
|
|
|
|
|
|
|
|
|
// 获取登录信息
|
|
|
|
|
async function getLoginInfo() {
|
|
|
|
|
try {
|
|
|
|
|
const res = await loginApi.getLoginInfo();
|
|
|
|
|
loginInfo.value = res.data;
|
|
|
|
|
checkUserRole(); // 获取登录信息后检查用户角色
|
|
|
|
|
console.log('登录信息:', res.data);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('获取登录信息失败:', e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查用户角色
|
|
|
|
|
function checkUserRole() {
|
|
|
|
|
if (loginInfo.value) {
|
|
|
|
|
// 根据用户角色判断权限
|
|
|
|
|
const userRole = loginInfo.value.roleCode || loginInfo.value.roleName || '';
|
|
|
|
|
const roleLower = userRole.toLowerCase();
|
|
|
|
|
|
|
|
|
|
// 不是user角色则显示批量审核按钮
|
|
|
|
|
isNotUser.value = roleLower != 'user';
|
|
|
|
|
|
|
|
|
|
// cto角色则额外显示批量上报按钮
|
|
|
|
|
isCtoRole.value = roleLower === 'cto';
|
|
|
|
|
|
|
|
|
|
// 协会角色(协会角色显示驳回按钮)
|
|
|
|
|
isAssociationRole.value = roleLower.includes('协会') ||
|
|
|
|
|
roleLower.includes('association') ||
|
|
|
|
|
roleLower.includes('律协') ||
|
|
|
|
|
roleLower.includes('律师协会');
|
|
|
|
|
|
|
|
|
|
// 律所角色判断
|
|
|
|
|
isFirmRole.value = roleLower.includes('律所') ||
|
|
|
|
|
roleLower.includes('firm') ||
|
|
|
|
|
roleLower.includes('lawyer') ||
|
|
|
|
|
roleLower.includes('律师');
|
|
|
|
|
|
|
|
|
|
// CEO角色判断(CEO不显示新建申报和批量提交按钮)
|
|
|
|
|
isCeo.value = roleLower === 'ceo';
|
|
|
|
|
|
|
|
|
|
console.log('用户角色:', userRole, '不是user:', isNotUser.value, '是cto:', isCtoRole.value, '是协会角色:', isAssociationRole.value, '是CEO:', isCeo.value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查用户是否已签约
|
|
|
|
|
function checkUserSigned() {
|
|
|
|
|
if (!loginInfo.value) {
|
|
|
|
|
console.log('未获取到登录信息');
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从用户信息接口获取agreementSignFlag字段
|
|
|
|
|
const agreementSignFlag = loginInfo.value.agreementSignFlag;
|
|
|
|
|
console.log('用户签约状态 agreementSignFlag:', agreementSignFlag);
|
|
|
|
|
|
|
|
|
|
// true代表已签约,不需要弹框
|
|
|
|
|
// false或undefined代表未签约,需要弹框
|
|
|
|
|
return agreementSignFlag === true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 批量审核
|
|
|
|
|
function batchAudit() {
|
|
|
|
|
if (selectedRowKeyList.value.length === 0) {
|
|
|
|
|
message.warning('请选择要审核的记录');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查选中的记录是否都有审核权限
|
|
|
|
|
const canAuditRecords = tableData.value.filter(record =>
|
|
|
|
|
selectedRowKeyList.value.includes(record.applicationId) && canAuditRecord(record)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (canAuditRecords.length === 0) {
|
|
|
|
|
message.warning('选中的记录不符合审核条件,请选择待审核状态的记录');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 显示批量审核弹窗
|
|
|
|
|
batchAuditModalVisible.value = true;
|
|
|
|
|
batchAuditForm.applicationIds = selectedRowKeyList.value.join(',');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 判断用户是否有权限审核某条记录
|
|
|
|
|
function canAuditRecord(record) {
|
|
|
|
|
if (!loginInfo.value || !isNotUser.value) return false;
|
|
|
|
|
|
|
|
|
|
const userRole = (loginInfo.value.roleCode || loginInfo.value.roleName || '').toLowerCase();
|
|
|
|
|
|
|
|
|
|
// ceo角色:只能审核协会审核状态为待审核(1)的记录
|
|
|
|
|
if (userRole === 'ceo') {
|
|
|
|
|
return record.associationAuditStatus === 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// cto角色:只能审核执业机构审核状态为待审核(1)的记录
|
|
|
|
|
if (userRole === 'cto') {
|
|
|
|
|
return record.firmAuditStatus === 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 批量审核确认
|
|
|
|
|
async function handleBatchAudit() {
|
|
|
|
|
if (!batchAuditForm.auditResult) {
|
|
|
|
|
message.warning('请选择审核结果');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查选中的记录是否都有审核权限
|
|
|
|
|
const canAuditRecords = tableData.value.filter(record =>
|
|
|
|
|
selectedRowKeyList.value.includes(record.applicationId) && canAuditRecord(record)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (canAuditRecords.length !== selectedRowKeyList.value.length) {
|
|
|
|
|
message.warning('部分选中的记录不符合审核条件,请重新选择');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
batchAuditLoading.value = true;
|
|
|
|
|
try {
|
|
|
|
|
// 根据角色使用不同的审核状态字段
|
|
|
|
|
// 协会角色使用associationAuditStatus,其他角色使用firmAuditStatus
|
|
|
|
|
const auditData = {
|
|
|
|
|
...batchAuditForm,
|
|
|
|
|
auditStatusField: isAssociationRole.value ? 'associationAuditStatus' : 'firmAuditStatus'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
await serviceApplicationsApi.batchReview(auditData);
|
|
|
|
|
message.success('批量审核成功');
|
|
|
|
|
batchAuditModalVisible.value = false;
|
|
|
|
|
queryData(); // 刷新数据
|
|
|
|
|
selectedRowKeyList.value = []; // 清空选中
|
|
|
|
|
|
|
|
|
|
// 重置表单
|
|
|
|
|
batchAuditForm.auditResult = undefined;
|
|
|
|
|
batchAuditForm.auditRemark = '';
|
|
|
|
|
batchAuditForm.applicationIds = '';
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('批量审核失败:', error);
|
|
|
|
|
message.error('批量审核失败');
|
|
|
|
|
} finally {
|
|
|
|
|
batchAuditLoading.value = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 批量审核取消
|
|
|
|
|
function handleBatchAuditCancel() {
|
|
|
|
|
batchAuditModalVisible.value = false;
|
|
|
|
|
batchAuditForm.auditResult = undefined;
|
|
|
|
|
batchAuditForm.auditRemark = '';
|
|
|
|
|
batchAuditForm.applicationIds = '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 批量上报
|
|
|
|
|
function batchReport() {
|
|
|
|
|
if (selectedRowKeyList.value.length === 0) {
|
|
|
|
|
message.warning('请选择要上报的记录');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查选中的记录是否符合上报条件
|
|
|
|
|
const canReportRecords = tableData.value.filter(record =>
|
|
|
|
|
selectedRowKeyList.value.includes(record.applicationId) && canReportRecord(record)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (canReportRecords.length === 0) {
|
|
|
|
|
message.warning('选中的记录不符合上报条件');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 确认上报
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
title: '批量上报确认',
|
|
|
|
|
content: `确定要将选中的 ${canReportRecords.length} 条符合条件的记录上报到协会审核吗?`,
|
|
|
|
|
onOk: () => handleBatchReport(canReportRecords),
|
|
|
|
|
okText: '确定上报',
|
|
|
|
|
cancelText: '取消'
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 判断记录是否符合上报条件
|
|
|
|
|
function canReportRecord(record) {
|
|
|
|
|
// 只能上报已通过执业机构审核的记录(状态为3:已通过)
|
|
|
|
|
// 且协会审核状态必须是未提交(0)
|
|
|
|
|
return record.firmAuditStatus === 3 &&
|
|
|
|
|
record.associationAuditStatus === 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 执行批量上报
|
|
|
|
|
async function handleBatchReport(validRecords) {
|
|
|
|
|
try {
|
|
|
|
|
SmartLoading.show();
|
|
|
|
|
|
|
|
|
|
// 从符合条件的记录中提取ID列表
|
|
|
|
|
const idList = validRecords.map(record => record.applicationId).map(id => Number(id));
|
|
|
|
|
|
|
|
|
|
if (idList.length === 0) {
|
|
|
|
|
message.warning('没有符合条件的记录可以上报');
|
|
|
|
|
SmartLoading.hide();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log('批量上报参数:', idList);
|
|
|
|
|
|
|
|
|
|
const res = await serviceApplicationsApi.batchSubmitAsFirm(idList);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 清空选中状态
|
|
|
|
|
selectedRowKeyList.value = [];
|
|
|
|
|
// 刷新数据
|
|
|
|
|
queryData();
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
smartSentry.captureError(error);
|
|
|
|
|
} finally {
|
|
|
|
|
SmartLoading.hide();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 加载所有员工数据
|
|
|
|
|
async function loadAllEmployees() {
|
|
|
|
|
try {
|
|
|
|
|
if (employeeList.value.length === 0) {
|
|
|
|
|
let resp = await employeeApi.queryAll();
|
|
|
|
|
employeeList.value = resp.data;
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('加载员工数据失败:', e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 总数
|
|
|
|
|
const total = ref(0);
|
|
|
|
|
|
|
|
|
|
// 重置查询条件
|
|
|
|
|
function resetQuery() {
|
|
|
|
|
let pageSize = queryForm.pageSize;
|
|
|
|
|
Object.assign(queryForm, queryFormState);
|
|
|
|
|
queryForm.pageSize = pageSize;
|
|
|
|
|
queryData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理查询参数,将时间范围转换为开始结束时间
|
|
|
|
|
function processQueryParams(params) {
|
|
|
|
|
const processedParams = { ...params };
|
|
|
|
|
|
|
|
|
|
// 处理执业机构审核时间范围
|
|
|
|
|
if (params.firmAuditTimeRange && params.firmAuditTimeRange.length === 2) {
|
|
|
|
|
processedParams.firmAuditTimeStart = params.firmAuditTimeRange[0];
|
|
|
|
|
processedParams.firmAuditTimeEnd = params.firmAuditTimeRange[1];
|
|
|
|
|
delete processedParams.firmAuditTimeRange;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理协会审核时间范围
|
|
|
|
|
if (params.associationAuditTimeRange && params.associationAuditTimeRange.length === 2) {
|
|
|
|
|
processedParams.associationAuditTimeStart = params.associationAuditTimeRange[0];
|
|
|
|
|
processedParams.associationAuditTimeEnd = params.associationAuditTimeRange[1];
|
|
|
|
|
delete processedParams.associationAuditTimeRange;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return processedParams;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 搜索
|
|
|
|
|
function onSearch(){
|
|
|
|
|
queryForm.pageNum = 1;
|
|
|
|
|
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() {
|
|
|
|
|
tableLoading.value = true;
|
|
|
|
|
try {
|
|
|
|
|
// 处理查询参数
|
|
|
|
|
let query = processQueryParams({ ...queryForm });
|
|
|
|
|
// 处理本人本所筛选条件
|
|
|
|
|
query = processSelfFirmFilter(query);
|
|
|
|
|
let queryResult = await serviceApplicationsApi.queryPage(query);
|
|
|
|
|
tableData.value = queryResult.data.list;
|
|
|
|
|
total.value = queryResult.data.total;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
smartSentry.captureError(e);
|
|
|
|
|
} finally {
|
|
|
|
|
tableLoading.value = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取路由实例
|
|
|
|
|
const route = useRoute();
|
|
|
|
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
|
await getLoginInfo();
|
|
|
|
|
|
|
|
|
|
// 检查URL查询参数中是否有firmId
|
|
|
|
|
const firmId = route.query.firmId;
|
|
|
|
|
if (firmId) {
|
|
|
|
|
// 如果有firmId,则设置查询条件
|
|
|
|
|
queryForm.firmId = firmId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询数据
|
|
|
|
|
queryData();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// ---------------------------- 承诺书弹框 ----------------------------
|
|
|
|
|
const agreementModalRef = ref();
|
|
|
|
|
const pendingFormData = ref(null); // 暂存表单数据
|
|
|
|
|
|
|
|
|
|
// 显示承诺书弹框
|
|
|
|
|
function showAgreementModal(data) {
|
|
|
|
|
pendingFormData.value = data;
|
|
|
|
|
agreementModalRef.value.showDrawer();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 承诺书确认回调
|
|
|
|
|
function handleAgreementConfirm() {
|
|
|
|
|
// 用户同意协议,继续显示表单
|
|
|
|
|
if (pendingFormData.value) {
|
|
|
|
|
formRef.value.show(pendingFormData.value);
|
|
|
|
|
} else {
|
|
|
|
|
formRef.value.show();
|
|
|
|
|
}
|
|
|
|
|
pendingFormData.value = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------- 添加/修改 ----------------------------
|
|
|
|
|
const formRef = ref();
|
|
|
|
|
|
|
|
|
|
function showForm(data) {
|
|
|
|
|
// 检查用户是否已签约
|
|
|
|
|
if (checkUserSigned()) {
|
|
|
|
|
// 已签约,直接显示表单
|
|
|
|
|
formRef.value.show(data);
|
|
|
|
|
} else {
|
|
|
|
|
// 未签约,先显示承诺书弹框
|
|
|
|
|
showAgreementModal(data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------- 详情 ----------------------------
|
|
|
|
|
async function showDetail(record) {
|
|
|
|
|
try {
|
|
|
|
|
SmartLoading.show();
|
|
|
|
|
const detailResult = await serviceApplicationsApi.queryDetail(record.applicationId);
|
|
|
|
|
if (detailResult.data) {
|
|
|
|
|
formRef.value.show(detailResult.data, true);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
smartSentry.captureError(error);
|
|
|
|
|
message.error('获取详情失败');
|
|
|
|
|
} finally {
|
|
|
|
|
SmartLoading.hide();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------- 单个提交 ----------------------------
|
|
|
|
|
//确认提交
|
|
|
|
|
function onSubmit(data){
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
title: '提示',
|
|
|
|
|
content: '确定要提交该申报记录吗?',
|
|
|
|
|
okText: '提交',
|
|
|
|
|
okType: 'primary',
|
|
|
|
|
onOk() {
|
|
|
|
|
requestSubmit(data);
|
|
|
|
|
},
|
|
|
|
|
cancelText: '取消',
|
|
|
|
|
onCancel() {},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//请求提交
|
|
|
|
|
async function requestSubmit(data){
|
|
|
|
|
try {
|
|
|
|
|
SmartLoading.show();
|
|
|
|
|
// 传递完整的表单数据进行提交
|
|
|
|
|
await serviceApplicationsApi.submit(data);
|
|
|
|
|
message.success('提交成功');
|
|
|
|
|
queryData();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
smartSentry.captureError(e);
|
|
|
|
|
} finally {
|
|
|
|
|
SmartLoading.hide();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------- 单个删除 ----------------------------
|
|
|
|
|
//确认删除
|
|
|
|
|
function onDelete(data){
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
title: '提示',
|
|
|
|
|
content: '确定要删除选吗?',
|
|
|
|
|
okText: '删除',
|
|
|
|
|
okType: 'danger',
|
|
|
|
|
onOk() {
|
|
|
|
|
requestDelete(data);
|
|
|
|
|
},
|
|
|
|
|
cancelText: '取消',
|
|
|
|
|
onCancel() {},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//请求删除
|
|
|
|
|
async function requestDelete(data){
|
|
|
|
|
SmartLoading.show();
|
|
|
|
|
try {
|
|
|
|
|
let deleteForm = {
|
|
|
|
|
goodsIdList: selectedRowKeyList.value,
|
|
|
|
|
};
|
|
|
|
|
await serviceApplicationsApi.delete(data.applicationId);
|
|
|
|
|
message.success('删除成功');
|
|
|
|
|
queryData();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
smartSentry.captureError(e);
|
|
|
|
|
} finally {
|
|
|
|
|
SmartLoading.hide();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 显示审核弹框
|
|
|
|
|
function showAuditModal(record) {
|
|
|
|
|
currentAuditRecord.value = record;
|
|
|
|
|
auditForm.auditResult = 3; // 默认同意
|
|
|
|
|
auditForm.auditRemark = '';
|
|
|
|
|
auditModalVisible.value = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理审核
|
|
|
|
|
async function handleAudit() {
|
|
|
|
|
if (!currentAuditRecord.value) {
|
|
|
|
|
message.error('未选择审核记录');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auditLoading.value = true;
|
|
|
|
|
|
|
|
|
|
const auditData = {
|
|
|
|
|
applicationId: currentAuditRecord.value.applicationId,
|
|
|
|
|
firmAuditStatus: auditForm.auditResult
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
await serviceApplicationsApi.review(auditData);
|
|
|
|
|
message.success('审核成功');
|
|
|
|
|
auditModalVisible.value = false;
|
|
|
|
|
queryData();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
message.error('审核失败');
|
|
|
|
|
console.error('审核失败:', error);
|
|
|
|
|
} finally {
|
|
|
|
|
auditLoading.value = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 取消审核
|
|
|
|
|
function handleAuditCancel() {
|
|
|
|
|
auditModalVisible.value = false;
|
|
|
|
|
currentAuditRecord.value = null;
|
|
|
|
|
auditForm.auditResult = 3;
|
|
|
|
|
auditForm.auditRemark = '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------- 批量删除 ----------------------------
|
|
|
|
|
|
|
|
|
|
// 选择表格行
|
|
|
|
|
const selectedRowKeyList = ref([]);
|
|
|
|
|
|
|
|
|
|
function onSelectChange(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() {
|
|
|
|
|
if (selectedRowKeyList.value.length === 0) {
|
|
|
|
|
message.warning('请先选择要删除的数据');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取选中的记录
|
|
|
|
|
const selectedRecords = tableData.value.filter(record =>
|
|
|
|
|
selectedRowKeyList.value.includes(record.applicationId)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 检查是否有不符合删除条件的记录(只能删除未提交状态的数据)
|
|
|
|
|
const invalidRecords = selectedRecords.filter(record =>
|
|
|
|
|
record.firmAuditStatus !== 0
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (invalidRecords.length > 0) {
|
|
|
|
|
message.warning('只能删除未提交状态的数据');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
title: '提示',
|
|
|
|
|
content: '确定要批量删除这些未提交状态的数据吗?',
|
|
|
|
|
okText: '删除',
|
|
|
|
|
okType: 'danger',
|
|
|
|
|
onOk() {
|
|
|
|
|
requestBatchDelete();
|
|
|
|
|
},
|
|
|
|
|
cancelText: '取消',
|
|
|
|
|
onCancel() {},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//请求批量删除
|
|
|
|
|
async function requestBatchDelete() {
|
|
|
|
|
try {
|
|
|
|
|
SmartLoading.show();
|
|
|
|
|
await serviceApplicationsApi.batchDelete(selectedRowKeyList.value);
|
|
|
|
|
message.success('删除成功');
|
|
|
|
|
queryData();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
smartSentry.captureError(e);
|
|
|
|
|
} finally {
|
|
|
|
|
SmartLoading.hide();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ------------------------------- 导出和导入 ---------------------------------
|
|
|
|
|
// 导入弹窗
|
|
|
|
|
const importModalShowFlag = ref(false);
|
|
|
|
|
|
|
|
|
|
const fileList = ref([]);
|
|
|
|
|
// 显示导入
|
|
|
|
|
function showImportModal() {
|
|
|
|
|
fileList.value = [];
|
|
|
|
|
importModalShowFlag.value = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 关闭 导入
|
|
|
|
|
function hideImportModal() {
|
|
|
|
|
importModalShowFlag.value = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleChange() {}
|
|
|
|
|
|
|
|
|
|
function handleDrop() {}
|
|
|
|
|
|
|
|
|
|
function handleRemove(file) {
|
|
|
|
|
const index = fileList.value.indexOf(file);
|
|
|
|
|
const newFileList = fileList.value.slice();
|
|
|
|
|
newFileList.splice(index, 1);
|
|
|
|
|
fileList.value = newFileList;
|
|
|
|
|
}
|
|
|
|
|
function beforeUpload(file) {
|
|
|
|
|
fileList.value = [...(fileList.value || []), file];
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function downloadExcel() {
|
|
|
|
|
serviceApplicationsApi.downloadTemplate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function onImport() {
|
|
|
|
|
const formData = new FormData();
|
|
|
|
|
fileList.value.forEach((file) => {
|
|
|
|
|
formData.append('file', file.originFileObj);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SmartLoading.show();
|
|
|
|
|
try {
|
|
|
|
|
let res = await serviceApplicationsApi.importServiceApplications(formData);
|
|
|
|
|
message.success(res.msg);
|
|
|
|
|
hideImportModal();
|
|
|
|
|
queryData();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
smartSentry.captureError(e);
|
|
|
|
|
} finally {
|
|
|
|
|
SmartLoading.hide();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function onExport() {
|
|
|
|
|
await serviceApplicationsApi.exportServiceApplications();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------- 批量提交 ----------------------------
|
|
|
|
|
|
|
|
|
|
// 批量提交
|
|
|
|
|
function batchSubmit() {
|
|
|
|
|
// 检查所有选中的记录是否都是未提交状态
|
|
|
|
|
const selectedRecords = tableData.value.filter(record =>
|
|
|
|
|
selectedRowKeyList.value.includes(record.applicationId)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const nonSubmitRecords = selectedRecords.filter(record => record.firmAuditStatus !== 0);
|
|
|
|
|
|
|
|
|
|
if (nonSubmitRecords.length > 0) {
|
|
|
|
|
message.warning(`选中的记录中有 ${nonSubmitRecords.length} 条不是未提交状态,无法批量提交`);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
title: '提示',
|
|
|
|
|
content: `确定要批量提交选中的 ${selectedRowKeyList.value.length} 条申报记录吗?`,
|
|
|
|
|
okText: '提交',
|
|
|
|
|
okType: 'primary',
|
|
|
|
|
onOk() {
|
|
|
|
|
requestBatchSubmit();
|
|
|
|
|
},
|
|
|
|
|
cancelText: '取消',
|
|
|
|
|
onCancel() {},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 请求批量提交
|
|
|
|
|
async function requestBatchSubmit() {
|
|
|
|
|
try {
|
|
|
|
|
SmartLoading.show();
|
|
|
|
|
await serviceApplicationsApi.batchSubmit(selectedRowKeyList.value);
|
|
|
|
|
message.success('批量提交成功');
|
|
|
|
|
queryData();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
smartSentry.captureError(e);
|
|
|
|
|
} finally {
|
|
|
|
|
SmartLoading.hide();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 提交
|
|
|
|
|
|
|
|
|
|
// ---------------------------- CEO功能 ----------------------------
|
|
|
|
|
|
|
|
|
|
// CEO角色相关状态
|
|
|
|
|
const showFirmStatistics = ref(true);
|
|
|
|
|
const selectedFirmData = ref(null);
|
|
|
|
|
|
|
|
|
|
// 返回律所统计
|
|
|
|
|
function backToFirmStatistics() {
|
|
|
|
|
console.log('返回律所统计,当前showFirmStatistics值:', showFirmStatistics.value);
|
|
|
|
|
|
|
|
|
|
showFirmStatistics.value = true;
|
|
|
|
|
selectedFirmData.value = null;
|
|
|
|
|
|
|
|
|
|
// 重置查询条件
|
|
|
|
|
queryForm.firmId = undefined;
|
|
|
|
|
queryForm.year = undefined;
|
|
|
|
|
queryForm.quarter = undefined;
|
|
|
|
|
|
|
|
|
|
// 重置分页
|
|
|
|
|
queryForm.pageNum = 1;
|
|
|
|
|
|
|
|
|
|
console.log('返回后showFirmStatistics值:', showFirmStatistics.value);
|
|
|
|
|
|
|
|
|
|
// 重新加载数据(显示所有数据)
|
|
|
|
|
queryData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理律所选择
|
|
|
|
|
function handleFirmSelected(firmData) {
|
|
|
|
|
console.log('选择的律所:', firmData);
|
|
|
|
|
console.log('当前showFirmStatistics值:', showFirmStatistics.value);
|
|
|
|
|
|
|
|
|
|
// 设置选中的律所信息
|
|
|
|
|
selectedFirmData.value = firmData;
|
|
|
|
|
|
|
|
|
|
// 设置查询条件:只显示该律所的数据
|
|
|
|
|
queryForm.firmId = firmData.firmId;
|
|
|
|
|
|
|
|
|
|
// 如果有年度和季度信息,也设置到查询条件中
|
|
|
|
|
if (firmData.year) {
|
|
|
|
|
queryForm.year = firmData.year;
|
|
|
|
|
}
|
|
|
|
|
if (firmData.quarter) {
|
|
|
|
|
queryForm.quarter = firmData.quarter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重置分页
|
|
|
|
|
queryForm.pageNum = 1;
|
|
|
|
|
|
|
|
|
|
// 显示详细服务记录,隐藏统计概览
|
|
|
|
|
showFirmStatistics.value = false;
|
|
|
|
|
console.log('切换后showFirmStatistics值:', showFirmStatistics.value);
|
|
|
|
|
|
|
|
|
|
// 重新加载数据
|
|
|
|
|
queryData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------- 驳回功能 ----------------------------
|
|
|
|
|
|
|
|
|
|
// 驳回相关状态
|
|
|
|
|
const rejectModalVisible = ref(false);
|
|
|
|
|
const rejectLoading = ref(false);
|
|
|
|
|
const currentRejectRecord = ref(null);
|
|
|
|
|
const rejectForm = reactive({
|
|
|
|
|
rejectReason: '',
|
|
|
|
|
approvalRemark: ''
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 判断记录是否可以驳回
|
|
|
|
|
function canRejectRecord(record) {
|
|
|
|
|
// 1. 必须是协会角色、CEO角色或CTO角色
|
|
|
|
|
if (!isAssociationRole.value && !isCeo.value && !isCtoRole.value) {
|
|
|
|
|
console.log('驳回按钮不显示:不是协会角色、CEO角色或CTO角色');
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. 根据角色类型设置不同的驳回条件
|
|
|
|
|
if (isAssociationRole.value || isCeo.value) {
|
|
|
|
|
// 协会角色和CEO角色:协会审核状态必须是通过(3)且在18个月内
|
|
|
|
|
if (record.associationAuditStatus !== 3) {
|
|
|
|
|
console.log('驳回按钮不显示:协会审核状态不是通过', record.associationAuditStatus);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 必须有协会审核时间
|
|
|
|
|
if (!record.associationAuditTime) {
|
|
|
|
|
console.log('驳回按钮不显示:没有协会审核时间');
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 判断协会审核时间距离当前时间是否在18个月内
|
|
|
|
|
const auditDate = new Date(record.associationAuditTime);
|
|
|
|
|
const now = new Date();
|
|
|
|
|
const monthsDiff = (now.getFullYear() - auditDate.getFullYear()) * 12 + (now.getMonth() - auditDate.getMonth());
|
|
|
|
|
|
|
|
|
|
console.log('协会审核时间:', record.associationAuditTime, '月份差:', monthsDiff);
|
|
|
|
|
|
|
|
|
|
const canReject = monthsDiff <= 18;
|
|
|
|
|
if (!canReject) {
|
|
|
|
|
console.log('驳回按钮不显示:超过18个月');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return canReject;
|
|
|
|
|
} else if (isCtoRole.value) {
|
|
|
|
|
// CTO角色:协会审核状态必须是驳回(4)且执业机构审核状态不能是驳回(4)
|
|
|
|
|
if (record.associationAuditStatus !== 4) {
|
|
|
|
|
console.log('驳回按钮不显示:协会审核状态不是驳回', record.associationAuditStatus);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 执业机构审核状态不能是驳回(4)
|
|
|
|
|
if (record.firmAuditStatus === 4) {
|
|
|
|
|
console.log('驳回按钮不显示:执业机构审核状态是驳回', record.firmAuditStatus);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 显示驳回弹框
|
|
|
|
|
function showRejectModal(record) {
|
|
|
|
|
currentRejectRecord.value = record;
|
|
|
|
|
rejectForm.rejectReason = '';
|
|
|
|
|
rejectForm.approvalRemark = '';
|
|
|
|
|
rejectModalVisible.value = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理驳回
|
|
|
|
|
async function handleReject() {
|
|
|
|
|
if (!currentRejectRecord.value) {
|
|
|
|
|
message.error('未选择驳回记录');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!rejectForm.rejectReason.trim()) {
|
|
|
|
|
message.warning('请输入驳回原因');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rejectLoading.value = true;
|
|
|
|
|
|
|
|
|
|
const rejectData = {
|
|
|
|
|
applicationId: currentRejectRecord.value.applicationId,
|
|
|
|
|
associationAuditStatus: 4, // 驳回状态
|
|
|
|
|
associationAuditOpinion: rejectForm.rejectReason,
|
|
|
|
|
approvalRemark: rejectForm.approvalRemark
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
await serviceApplicationsApi.review(rejectData);
|
|
|
|
|
message.success('驳回成功');
|
|
|
|
|
rejectModalVisible.value = false;
|
|
|
|
|
queryData();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
message.error('驳回失败');
|
|
|
|
|
console.error('驳回失败:', error);
|
|
|
|
|
} finally {
|
|
|
|
|
rejectLoading.value = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 取消驳回
|
|
|
|
|
function handleRejectCancel() {
|
|
|
|
|
rejectModalVisible.value = false;
|
|
|
|
|
currentRejectRecord.value = null;
|
|
|
|
|
rejectForm.rejectReason = '';
|
|
|
|
|
rejectForm.approvalRemark = '';
|
|
|
|
|
}
|
|
|
|
|
</script>
|