27 changed files with 1002 additions and 80 deletions
@ -1,3 +1,3 @@ |
|||
NODE_ENV=development |
|||
VITE_APP_TITLE='律师公益法律服务活动申报与管理平台' |
|||
VITE_APP_TITLE='律师公益法律服务活动申报子系统' |
|||
VITE_APP_API_URL='/api' |
|||
@ -1,3 +1,3 @@ |
|||
NODE_ENV=development |
|||
VITE_APP_TITLE='律师公益法律服务活动申报与管理平台' |
|||
VITE_APP_TITLE='律师公益法律服务活动申报子系统' |
|||
VITE_APP_API_URL='/api' |
|||
|
|||
@ -1,3 +1,3 @@ |
|||
NODE_ENV=production |
|||
VITE_APP_TITLE='律师公益法律服务活动申报与管理平台' |
|||
VITE_APP_API_URL='https://preview.smartadmin.vip/smart-admin-api' |
|||
VITE_APP_TITLE='律师公益法律服务活动申报子系统' |
|||
VITE_APP_API_URL='/api' |
|||
@ -1,3 +1,3 @@ |
|||
NODE_ENV=production |
|||
VITE_APP_TITLE='律师公益法律服务活动申报与管理平台' |
|||
VITE_APP_TITLE='律师公益法律服务活动申报子系统' |
|||
VITE_APP_API_URL='/api' |
|||
@ -1,3 +1,3 @@ |
|||
NODE_ENV=production |
|||
VITE_APP_TITLE='律师公益法律服务活动申报与管理平台' |
|||
VITE_APP_TITLE='律师公益法律服务活动申报子系统' |
|||
VITE_APP_API_URL='/api' |
|||
|
|||
@ -0,0 +1,48 @@ |
|||
/** |
|||
* 律师事务所年度经营报表 api 封装 |
|||
* |
|||
* @Author: wzh |
|||
* @Date: 2026-01-07 15:57:43 |
|||
* @Copyright 1.0 |
|||
*/ |
|||
import { postRequest, getRequest } from '/@/lib/axios'; |
|||
|
|||
export const firmReportsApi = { |
|||
|
|||
/** |
|||
* 分页查询 @author wzh |
|||
*/ |
|||
queryPage : (param) => { |
|||
return postRequest('/firmReports/queryPage', param); |
|||
}, |
|||
|
|||
/** |
|||
* 增加 @author wzh |
|||
*/ |
|||
add: (param) => { |
|||
return postRequest('/firmReports/add', param); |
|||
}, |
|||
|
|||
/** |
|||
* 修改 @author wzh |
|||
*/ |
|||
update: (param) => { |
|||
return postRequest('/firmReports/update', param); |
|||
}, |
|||
|
|||
|
|||
/** |
|||
* 删除 @author wzh |
|||
*/ |
|||
delete: (id) => { |
|||
return getRequest(`/firmReports/delete/${id}`); |
|||
}, |
|||
|
|||
/** |
|||
* 批量删除 @author wzh |
|||
*/ |
|||
batchDelete: (idList) => { |
|||
return postRequest('/firmReports/batchDelete', idList); |
|||
}, |
|||
|
|||
}; |
|||
@ -0,0 +1,59 @@ |
|||
/* |
|||
* 成本管理常量 |
|||
*/ |
|||
|
|||
// 季度枚举
|
|||
export const QUARTER_ENUM = { |
|||
Q1: { |
|||
value: 'Q1', |
|||
desc: '第一季度', |
|||
}, |
|||
Q2: { |
|||
value: 'Q2', |
|||
desc: '第二季度', |
|||
}, |
|||
Q3: { |
|||
value: 'Q3', |
|||
desc: '第三季度', |
|||
}, |
|||
Q4: { |
|||
value: 'Q4', |
|||
desc: '第四季度', |
|||
}, |
|||
}; |
|||
|
|||
// 审核状态枚举
|
|||
export const REVIEW_STATUS_ENUM = { |
|||
DRAFT: { |
|||
value: 0, |
|||
desc: '待提交', |
|||
}, |
|||
SUBMITTED: { |
|||
value: 1, |
|||
desc: '待审批', |
|||
}, |
|||
APPROVED: { |
|||
value: 2, |
|||
desc: '审批中', |
|||
}, |
|||
REJECTED: { |
|||
value: 3, |
|||
desc: '已通过', |
|||
}, |
|||
REFUSE: { |
|||
value: 4, |
|||
desc: '拒绝', |
|||
}, |
|||
}; |
|||
|
|||
// 成本类型枚举
|
|||
export const COST_TYPE_ENUM = { |
|||
PUBLIC_WELFARE: { |
|||
value: 1, |
|||
desc: '公益活动成本', |
|||
}, |
|||
OTHER: { |
|||
value: 2, |
|||
desc: '其他成本', |
|||
}, |
|||
}; |
|||
@ -0,0 +1,255 @@ |
|||
<!-- |
|||
* 律师事务所年度经营报表 |
|||
* |
|||
* @Author: wzh |
|||
* @Date: 2026-01-07 15:57:43 |
|||
* @Copyright 1.0 |
|||
--> |
|||
<template> |
|||
<a-modal |
|||
:title="form.id ? '编辑成本填报' : '新建成本填报'" |
|||
:width="600" |
|||
:open="visibleFlag" |
|||
@cancel="onClose" |
|||
:maskClosable="false" |
|||
:destroyOnClose="true" |
|||
> |
|||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 6 }" > |
|||
<a-form-item label="律师事务所"> |
|||
<a-input v-model:value="departmentName" placeholder="律师事务所" disabled /> |
|||
</a-form-item> |
|||
|
|||
<a-form-item label="季度" name="declareQuarter"> |
|||
<DictSelect |
|||
dict-code="QUARTER" |
|||
v-model:value="form.declareQuarter" |
|||
placeholder="请选择季度" |
|||
@change="calculateCosts" |
|||
style="width: 100%" |
|||
/> |
|||
</a-form-item> |
|||
|
|||
<a-form-item label="律所收入(万元)" name="revenue"> |
|||
<a-input-number |
|||
style="width: 100%" |
|||
v-model:value="form.revenue" |
|||
placeholder="请输入律所总收入" |
|||
:min="0" |
|||
:precision="2" |
|||
@change="calculateCosts" |
|||
addon-after="万元" |
|||
/> |
|||
</a-form-item> |
|||
|
|||
<a-form-item label="公益活动成本(万元)" name="publicWelfareCost"> |
|||
<a-input-number |
|||
style="width: 100%" |
|||
v-model:value="form.publicWelfareCost" |
|||
placeholder="请输入公益活动成本" |
|||
:min="0" |
|||
:precision="2" |
|||
@change="calculateCosts" |
|||
addon-after="万元" |
|||
/> |
|||
</a-form-item> |
|||
|
|||
<a-form-item label="其他成本(万元)" name="otherCost"> |
|||
<a-input-number |
|||
style="width: 100%" |
|||
v-model:value="form.otherCost" |
|||
placeholder="请输入其他成本" |
|||
:min="0" |
|||
:precision="2" |
|||
@change="calculateCosts" |
|||
addon-after="万元" |
|||
/> |
|||
</a-form-item> |
|||
|
|||
<a-row> |
|||
<a-col :span="12"> |
|||
<a-form-item label="总成本(万元)" :label-col="{ span: 12 }" :wrapper-col="{ span: 12 }"> |
|||
<a-input-number |
|||
style="width: 100%" |
|||
v-model:value="form.totalCost" |
|||
:precision="2" |
|||
disabled |
|||
addon-after="万元" |
|||
/> |
|||
</a-form-item> |
|||
</a-col> |
|||
<a-col :span="12"> |
|||
<a-form-item label="成本/收入比例" :label-col="{ span: 12 }" :wrapper-col="{ span: 12 }"> |
|||
<a-input |
|||
style="width: 100%" |
|||
v-model:value="form.costIncomeRatio" |
|||
disabled |
|||
addon-after="%" |
|||
/> |
|||
</a-form-item> |
|||
</a-col> |
|||
</a-row> |
|||
|
|||
<a-form-item label="报表年份" name="declareYear"> |
|||
<a-input-number |
|||
style="width: 100%" |
|||
v-model:value="form.declareYear" |
|||
placeholder="请输入报表年份" |
|||
disabled |
|||
:min="2000" |
|||
:max="2100" |
|||
/> |
|||
</a-form-item> |
|||
</a-form> |
|||
|
|||
<template #footer> |
|||
<a-space> |
|||
<a-button @click="onClose">取消</a-button> |
|||
<a-button @click="saveAsDraft" type="default" v-if="!form.id">保存草稿</a-button> |
|||
<a-button type="primary" @click="submitForReview">提交审核</a-button> |
|||
</a-space> |
|||
</template> |
|||
</a-modal> |
|||
</template> |
|||
<script setup> |
|||
import { reactive, ref, nextTick, computed } from 'vue'; |
|||
import _ from 'lodash'; |
|||
import { message } from 'ant-design-vue'; |
|||
import { SmartLoading } from '/@/components/framework/smart-loading'; |
|||
import { firmReportsApi } from '/@/api/business/cost/firm-reports-api'; |
|||
import { smartSentry } from '/@/lib/smart-sentry'; |
|||
import { useUserStore } from '/@/store/modules/system/user'; |
|||
import DictSelect from '/@/components/support/dict-select/index.vue'; |
|||
|
|||
// ------------------------ 事件 ------------------------ |
|||
|
|||
const emits = defineEmits(['reloadList']); |
|||
|
|||
// ------------------------ 用户信息 ------------------------ |
|||
const userStore = useUserStore(); |
|||
|
|||
// 律师事务所名称(部门名称) |
|||
const departmentName = computed(() => userStore.departmentName); |
|||
|
|||
// 部门ID |
|||
const departmentId = computed(() => userStore.departmentId); |
|||
|
|||
// ------------------------ 显示与隐藏 ------------------------ |
|||
// 是否显示 |
|||
const visibleFlag = ref(false); |
|||
|
|||
function show(rowData) { |
|||
Object.assign(form, formDefault); |
|||
|
|||
// 设置律师事务所ID(部门ID) |
|||
form.firmId = departmentId.value; |
|||
|
|||
if (rowData && !_.isEmpty(rowData)) { |
|||
Object.assign(form, rowData); |
|||
} |
|||
|
|||
visibleFlag.value = true; |
|||
nextTick(() => { |
|||
formRef.value.clearValidate(); |
|||
// 初始化计算 |
|||
calculateCosts(); |
|||
}); |
|||
} |
|||
|
|||
function onClose() { |
|||
Object.assign(form, formDefault); |
|||
visibleFlag.value = false; |
|||
} |
|||
|
|||
// ------------------------ 表单 ------------------------ |
|||
|
|||
// 组件ref |
|||
const formRef = ref(); |
|||
|
|||
const formDefault = { |
|||
id: undefined, |
|||
firmId: undefined, // 律师事务所ID(部门ID) |
|||
declareYear: new Date().getFullYear(), // 报表年份 |
|||
declareQuarter: undefined, // 季度ID (1,2,3,4) |
|||
revenue: undefined, // 营业收入(万元) |
|||
totalCost: 0, // 总成本支出(万元) |
|||
publicWelfareCost: undefined, // 公益成本支出(万元) |
|||
costIncomeRatio: '0.00', // 成本收入比(%) |
|||
}; |
|||
|
|||
let form = reactive({ ...formDefault }); |
|||
|
|||
const rules = { |
|||
declareQuarter: [{ required: true, message: '请选择季度' }], |
|||
declareYear: [{ required: true, message: '请输入报表年份' }], |
|||
revenue: [{ required: true, message: '请输入律所收入' }], |
|||
publicWelfareCost: [{ required: true, message: '请输入公益活动成本' }], |
|||
}; |
|||
|
|||
// 自动计算总成本和成本/收入比例 |
|||
function calculateCosts() { |
|||
const revenue = parseFloat(form.revenue) || 0; |
|||
const publicWelfareCost = parseFloat(form.publicWelfareCost) || 0; |
|||
const otherCost = parseFloat(form.otherCost) || 0; |
|||
|
|||
// 计算总成本 |
|||
const totalCost = publicWelfareCost + otherCost; |
|||
form.totalCost = totalCost; |
|||
|
|||
// 计算成本/收入比例 |
|||
if (revenue > 0) { |
|||
const ratio = (totalCost / revenue) * 100; |
|||
form.costIncomeRatio = ratio.toFixed(2); |
|||
} else { |
|||
form.costIncomeRatio = '0.00'; |
|||
} |
|||
} |
|||
|
|||
// 保存草稿 |
|||
async function saveAsDraft() { |
|||
try { |
|||
await formRef.value.validateFields(['declareQuarter', 'declareYear', 'revenue', 'publicWelfareCost']); |
|||
form.approvalStatus = '0'; // 草稿状态 |
|||
await save(); |
|||
message.success('保存草稿成功'); |
|||
} catch (err) { |
|||
message.error('请填写必填字段后再保存草稿!'); |
|||
} |
|||
} |
|||
|
|||
// 提交审核 |
|||
async function submitForReview() { |
|||
try { |
|||
await formRef.value.validateFields(); |
|||
form.approvalStatus = '1'; // 待审核状态 |
|||
await save(); |
|||
message.success('提交审核成功'); |
|||
} catch (err) { |
|||
message.error('参数验证错误,请仔细填写表单数据!'); |
|||
} |
|||
} |
|||
|
|||
// 新建、编辑API |
|||
async function save() { |
|||
SmartLoading.show(); |
|||
try { |
|||
// 确保计算最新的数据 |
|||
calculateCosts(); |
|||
|
|||
if (form.id) { |
|||
await firmReportsApi.update(form); |
|||
} else { |
|||
await firmReportsApi.add(form); |
|||
} |
|||
emits('reloadList'); |
|||
onClose(); |
|||
} catch (err) { |
|||
smartSentry.captureError(err); |
|||
} finally { |
|||
SmartLoading.hide(); |
|||
} |
|||
} |
|||
|
|||
defineExpose({ |
|||
show, |
|||
}); |
|||
</script> |
|||
@ -0,0 +1,403 @@ |
|||
<!-- |
|||
* 律师事务所年度经营报表 |
|||
* |
|||
* @Author: wzh |
|||
* @Date: 2026-01-07 15:57:43 |
|||
* @Copyright 1.0 |
|||
--> |
|||
<template> |
|||
<!---------- 查询表单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: 150px" v-model:value="queryForm.firmId" placeholder="请选择律师事务所" /> |
|||
</a-form-item> |
|||
<a-form-item label="报表年份" class="smart-query-form-item"> |
|||
<a-input style="width: 150px" v-model:value="queryForm.declareYear" placeholder="请输入报表年份" /> |
|||
</a-form-item> |
|||
<a-form-item label="报表季度" class="smart-query-form-item"> |
|||
<DictSelect |
|||
dict-code="QUARTER" |
|||
v-model:value="queryForm.declareQuarter" |
|||
placeholder="请选择季度" |
|||
style="width: 100px" |
|||
/> |
|||
</a-form-item> |
|||
<a-form-item class="smart-query-form-item" style="margin-left: 120px;"> |
|||
<a-button 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"> |
|||
<a-button @click="showForm" type="primary" > |
|||
<template #icon> |
|||
<PlusOutlined /> |
|||
</template> |
|||
新建 |
|||
</a-button> |
|||
<a-button @click="confirmBatchDelete" type="primary" danger :disabled="selectedRowKeyList.length == 0"> |
|||
<template #icon> |
|||
<DeleteOutlined /> |
|||
</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="{ y: 800 }" |
|||
:dataSource="tableData" |
|||
:columns="columns" |
|||
rowKey="id" |
|||
bordered |
|||
:loading="tableLoading" |
|||
:pagination="false" |
|||
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }" |
|||
> |
|||
<template #bodyCell="{ text, record, column }"> |
|||
<template v-if="column.dataIndex === 'action'"> |
|||
<div class="smart-table-operate"> |
|||
<!--<a-button v-if="record.approvalStatus === 0 || record.approvalStatus === 4" @click="showForm(record)" type="link">编辑</a-button>--> |
|||
<a-button v-if="record.approvalStatus === 0" @click="onSubmit(record)" type="link">提交</a-button> |
|||
<a-button v-if="record.approvalStatus === 1 || record.approvalStatus === 2" @click="showAuditModal(record)" type="link">审核</a-button> |
|||
<a-button @click="onDelete(record)" danger type="link">删除</a-button> |
|||
</div> |
|||
</template> |
|||
</template> |
|||
</a-table> |
|||
<!---------- 表格 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> |
|||
|
|||
<FirmReportsForm ref="formRef" @reloadList="queryData"/> |
|||
|
|||
</a-card> |
|||
</template> |
|||
<script setup> |
|||
import { reactive, ref, onMounted } from 'vue'; |
|||
import { message, Modal } from 'ant-design-vue'; |
|||
import { SmartLoading } from '/@/components/framework/smart-loading'; |
|||
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'; |
|||
import FirmReportsForm from './firm-reports-form.vue'; |
|||
import { REVIEW_STATUS_ENUM } from '/@/constants/business/erp/cost-const'; |
|||
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue'; |
|||
import DictSelect from '/@/components/support/dict-select/index.vue'; |
|||
|
|||
// ---------------------------- 表格列 ---------------------------- |
|||
|
|||
const columns = ref([ |
|||
{ |
|||
title: '律师事务所', |
|||
dataIndex: 'firmName', |
|||
ellipsis: true, |
|||
}, |
|||
{ |
|||
title: '报表年份', |
|||
dataIndex: 'declareYear', |
|||
ellipsis: true, |
|||
}, |
|||
{ |
|||
title: '报表季度', |
|||
dataIndex: 'declareQuarter', |
|||
ellipsis: true, |
|||
}, |
|||
{ |
|||
title: '营业收入(单位:万元)', |
|||
dataIndex: 'revenue', |
|||
ellipsis: true, |
|||
}, |
|||
{ |
|||
title: '总成本支出(单位:万元)', |
|||
dataIndex: 'totalCost', |
|||
ellipsis: true, |
|||
}, |
|||
{ |
|||
title: '公益成本支出(单位:万元)', |
|||
dataIndex: 'publicWelfareCost', |
|||
ellipsis: true, |
|||
}, |
|||
{ |
|||
title: '成本收入比', |
|||
dataIndex: 'costIncomeRatio', |
|||
ellipsis: true, |
|||
customRender: ({ text }) => { |
|||
return text ? `${text}%` : ''; |
|||
}, |
|||
}, |
|||
{ |
|||
title: '审批状态', |
|||
dataIndex: 'approvalStatus', |
|||
ellipsis: true, |
|||
customRender: ({ text }) => { |
|||
const status = Object.values(REVIEW_STATUS_ENUM).find(item => item.value === text); |
|||
return status ? status.desc : text; |
|||
}, |
|||
}, |
|||
{ |
|||
title: '提交时间', |
|||
dataIndex: 'submissionTime', |
|||
ellipsis: true, |
|||
}, |
|||
{ |
|||
title: '审批人', |
|||
dataIndex: 'approverId', |
|||
ellipsis: true, |
|||
}, |
|||
{ |
|||
title: '操作', |
|||
dataIndex: 'action', |
|||
fixed: 'right', |
|||
width: 150, |
|||
}, |
|||
]); |
|||
|
|||
// ---------------------------- 查询数据表单和方法 ---------------------------- |
|||
|
|||
const queryFormState = { |
|||
pageNum: 1, |
|||
pageSize: 10, |
|||
firmId: undefined, // 律师事务所ID |
|||
declareYear: undefined, // 报表年份 |
|||
declareQuarter: undefined, // 报表季度 |
|||
}; |
|||
// 查询表单form |
|||
const queryForm = reactive({ ...queryFormState }); |
|||
// 表格加载loading |
|||
const tableLoading = ref(false); |
|||
// 表格数据 |
|||
const tableData = ref([]); |
|||
// 总数 |
|||
const total = ref(0); |
|||
|
|||
// 重置查询条件 |
|||
function resetQuery() { |
|||
let pageSize = queryForm.pageSize; |
|||
Object.assign(queryForm, queryFormState); |
|||
queryForm.pageSize = pageSize; |
|||
queryData(); |
|||
} |
|||
|
|||
// 搜索 |
|||
function onSearch(){ |
|||
queryForm.pageNum = 1; |
|||
queryData(); |
|||
} |
|||
|
|||
// 查询数据 |
|||
async function queryData() { |
|||
tableLoading.value = true; |
|||
try { |
|||
let queryResult = await firmReportsApi.queryPage(queryForm); |
|||
tableData.value = queryResult.data.list; |
|||
total.value = queryResult.data.total; |
|||
} catch (e) { |
|||
smartSentry.captureError(e); |
|||
} finally { |
|||
tableLoading.value = false; |
|||
} |
|||
} |
|||
|
|||
// ---------------------------- 单个提交 ---------------------------- |
|||
//确认提交 |
|||
function onSubmit(data){ |
|||
Modal.confirm({ |
|||
title: '提示', |
|||
content: '确定要提交该成本报表吗?', |
|||
okText: '提交', |
|||
okType: 'primary', |
|||
onOk() { |
|||
requestSubmit(data); |
|||
}, |
|||
cancelText: '取消', |
|||
onCancel() {}, |
|||
}); |
|||
} |
|||
|
|||
//请求提交 |
|||
async function requestSubmit(data){ |
|||
try { |
|||
SmartLoading.show(); |
|||
await firmReportsApi.submit(data.reportId); |
|||
message.success('提交成功'); |
|||
queryData(); |
|||
} catch (e) { |
|||
smartSentry.captureError(e); |
|||
} finally { |
|||
SmartLoading.hide(); |
|||
} |
|||
} |
|||
|
|||
// ---------------------------- 审核相关 ---------------------------- |
|||
// 审核相关状态 |
|||
const auditModalVisible = ref(false); |
|||
const auditLoading = ref(false); |
|||
const currentAuditRecord = ref(null); |
|||
const auditForm = reactive({ |
|||
auditResult: 3, // 默认同意 |
|||
auditRemark: '' |
|||
}); |
|||
|
|||
// 显示审核弹框 |
|||
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 = { |
|||
reportId: currentAuditRecord.value.reportId, |
|||
approvalStatus: auditForm.auditResult |
|||
}; |
|||
|
|||
try { |
|||
await firmReportsApi.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 = ''; |
|||
} |
|||
|
|||
onMounted(queryData); |
|||
|
|||
// ---------------------------- 添加/修改 ---------------------------- |
|||
const formRef = ref(); |
|||
|
|||
function showForm(data) { |
|||
formRef.value.show(data); |
|||
} |
|||
|
|||
// ---------------------------- 单个删除 ---------------------------- |
|||
//确认删除 |
|||
function onDelete(data){ |
|||
Modal.confirm({ |
|||
title: '提示', |
|||
content: '确定要删除选吗?', |
|||
okText: '删除', |
|||
okType: 'danger', |
|||
onOk() { |
|||
requestDelete(data); |
|||
}, |
|||
cancelText: '取消', |
|||
onCancel() {}, |
|||
}); |
|||
} |
|||
|
|||
//请求删除 |
|||
async function requestDelete(data){ |
|||
SmartLoading.show(); |
|||
try { |
|||
await firmReportsApi.delete(data.id); |
|||
message.success('删除成功'); |
|||
queryData(); |
|||
} catch (e) { |
|||
smartSentry.captureError(e); |
|||
} finally { |
|||
SmartLoading.hide(); |
|||
} |
|||
} |
|||
|
|||
// ---------------------------- 批量删除 ---------------------------- |
|||
|
|||
// 选择表格行 |
|||
const selectedRowKeyList = ref([]); |
|||
|
|||
function onSelectChange(selectedRowKeys) { |
|||
// 限制只能选择一行,如果选择了多行,只保留最后选择的一行 |
|||
if (selectedRowKeys.length > 1) { |
|||
selectedRowKeyList.value = [selectedRowKeys[selectedRowKeys.length - 1]]; |
|||
} else { |
|||
selectedRowKeyList.value = selectedRowKeys; |
|||
} |
|||
} |
|||
|
|||
// 批量删除 |
|||
function confirmBatchDelete() { |
|||
Modal.confirm({ |
|||
title: '提示', |
|||
content: '确定要批量删除这些数据吗?', |
|||
okText: '删除', |
|||
okType: 'danger', |
|||
onOk() { |
|||
requestBatchDelete(); |
|||
}, |
|||
cancelText: '取消', |
|||
onCancel() {}, |
|||
}); |
|||
} |
|||
|
|||
//请求批量删除 |
|||
async function requestBatchDelete() { |
|||
try { |
|||
SmartLoading.show(); |
|||
await firmReportsApi.batchDelete(selectedRowKeyList.value); |
|||
message.success('删除成功'); |
|||
queryData(); |
|||
} catch (e) { |
|||
smartSentry.captureError(e); |
|||
} finally { |
|||
SmartLoading.hide(); |
|||
} |
|||
} |
|||
</script> |
|||
@ -0,0 +1,198 @@ |
|||
<template> |
|||
<a-modal |
|||
v-model:visible="visible" |
|||
:title="noticeDetail.title || '平台协议'" |
|||
width="800px" |
|||
:maskClosable="false" |
|||
:keyboard="false" |
|||
:closable="false" |
|||
> |
|||
<a-spin :spinning="loading"> |
|||
<div class="agreement-content"> |
|||
<div v-if="noticeDetail.title" class="agreement-text"> |
|||
<div class="content-header"> |
|||
<h3>{{ noticeDetail.title }}</h3> |
|||
<div class="content-header-info"> |
|||
<span v-if="noticeDetail.author">作者:{{ noticeDetail.author }}</span> |
|||
<span v-if="noticeDetail.source">来源:{{ noticeDetail.source }}</span> |
|||
<span v-if="noticeDetail.publishTime">发布时间:{{ noticeDetail.publishTime }}</span> |
|||
</div> |
|||
</div> |
|||
<div class="content-html" v-html="noticeDetail.contentHtml"></div> |
|||
<div v-if="!noticeDetail.contentHtml" class="default-content"> |
|||
<p>欢迎使用本系统!在开始使用前,请仔细阅读以下协议内容:</p> |
|||
|
|||
<h4>一、服务条款</h4> |
|||
<p>1. 您在使用本系统时,必须遵守相关法律法规和平台规定。</p> |
|||
<p>2. 不得利用本系统从事任何违法或不当行为。</p> |
|||
|
|||
<h4>二、隐私政策</h4> |
|||
<p>1. 我们将保护您的个人信息安全,仅用于系统功能使用。</p> |
|||
<p>2. 未经您同意,我们不会向第三方泄露您的个人信息。</p> |
|||
|
|||
<h4>三、使用规范</h4> |
|||
<p>1. 请妥善保管您的账号密码,避免泄露。</p> |
|||
<p>2. 如发现异常情况,请及时联系系统管理员。</p> |
|||
</div> |
|||
<p class="important">请仔细阅读以上协议内容,点击"同意并继续"表示您已阅读并同意本协议。</p> |
|||
</div> |
|||
<div v-else class="agreement-text"> |
|||
<h3>用户协议与隐私政策</h3> |
|||
<div class="default-content"> |
|||
<p>欢迎使用本系统!在开始使用前,请仔细阅读以下协议内容:</p> |
|||
|
|||
<h4>一、服务条款</h4> |
|||
<p>1. 您在使用本系统时,必须遵守相关法律法规和平台规定。</p> |
|||
<p>2. 不得利用本系统从事任何违法或不当行为。</p> |
|||
|
|||
<h4>二、隐私政策</h4> |
|||
<p>1. 我们将保护您的个人信息安全,仅用于系统功能使用。</p> |
|||
<p>2. 未经您同意,我们不会向第三方泄露您的个人信息。</p> |
|||
|
|||
<h4>三、使用规范</h4> |
|||
<p>1. 请妥善保管您的账号密码,避免泄露。</p> |
|||
<p>2. 如发现异常情况,请及时联系系统管理员。</p> |
|||
</div> |
|||
<p class="important">请仔细阅读以上协议内容,点击"同意并继续"表示您已阅读并同意本协议。</p> |
|||
</div> |
|||
</div> |
|||
</a-spin> |
|||
|
|||
<template #footer> |
|||
<a-button @click="handleCancel" size="large">不同意</a-button> |
|||
<a-button type="primary" @click="handleConfirm" size="large">同意并继续</a-button> |
|||
</template> |
|||
</a-modal> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref, onMounted, reactive } from 'vue'; |
|||
import { noticeApi } from '/@/api/business/oa/notice-api'; |
|||
import { smartSentry } from '/@/lib/smart-sentry'; |
|||
|
|||
const emit = defineEmits(['confirm', 'cancel']); |
|||
const visible = ref(false); |
|||
const loading = ref(false); |
|||
|
|||
// 公告详情数据 |
|||
const noticeDetail = reactive({ |
|||
title: '', |
|||
contentHtml: '', |
|||
author: '', |
|||
source: '', |
|||
publishTime: '' |
|||
}); |
|||
|
|||
onMounted(() => { |
|||
visible.value = true; |
|||
// 获取首页第一条公告的详情 |
|||
getFirstNoticeDetail(); |
|||
}); |
|||
|
|||
// 获取首页第一条公告的详情 |
|||
async function getFirstNoticeDetail() { |
|||
try { |
|||
loading.value = true; |
|||
// 查询首页公告列表(公告类型ID为1) |
|||
const queryForm = { |
|||
noticeTypeId: 1, |
|||
pageNum: 1, |
|||
pageSize: 1, |
|||
searchCount: false, |
|||
}; |
|||
|
|||
const result = await noticeApi.queryEmployeeNotice(queryForm); |
|||
|
|||
if (result.data && result.data.list && result.data.list.length > 0) { |
|||
const firstNotice = result.data.list[0]; |
|||
|
|||
// 获取公告详情 |
|||
const detailResult = await noticeApi.view(firstNotice.noticeId); |
|||
if (detailResult.data) { |
|||
Object.assign(noticeDetail, detailResult.data); |
|||
} |
|||
} |
|||
} catch (err) { |
|||
smartSentry.captureError(err); |
|||
console.error('获取公告详情失败:', err); |
|||
} finally { |
|||
loading.value = false; |
|||
} |
|||
} |
|||
|
|||
const handleConfirm = () => { |
|||
emit('confirm'); |
|||
visible.value = false; |
|||
}; |
|||
|
|||
const handleCancel = () => { |
|||
emit('cancel'); |
|||
visible.value = false; |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.agreement-content { |
|||
max-height: 400px; |
|||
overflow-y: auto; |
|||
padding: 0 10px; |
|||
} |
|||
|
|||
.agreement-text { |
|||
line-height: 1.6; |
|||
} |
|||
|
|||
.content-header { |
|||
border-bottom: 1px solid #e8e8e8; |
|||
padding-bottom: 15px; |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.content-header h3 { |
|||
text-align: center; |
|||
color: #1890ff; |
|||
margin-bottom: 10px; |
|||
font-size: 18px; |
|||
} |
|||
|
|||
.content-header-info { |
|||
text-align: center; |
|||
color: #666; |
|||
font-size: 12px; |
|||
} |
|||
|
|||
.content-header-info span { |
|||
margin: 0 10px; |
|||
} |
|||
|
|||
.content-html { |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.content-html >>> p { |
|||
margin-bottom: 10px; |
|||
line-height: 1.6; |
|||
} |
|||
|
|||
.content-html >>> h4 { |
|||
color: #333; |
|||
margin: 15px 0 10px 0; |
|||
} |
|||
|
|||
.default-content h4 { |
|||
color: #333; |
|||
margin: 15px 0 10px 0; |
|||
} |
|||
|
|||
.default-content p { |
|||
margin-bottom: 8px; |
|||
color: #666; |
|||
} |
|||
|
|||
.important { |
|||
color: #ff4d4f !important; |
|||
font-weight: bold; |
|||
margin-top: 20px !important; |
|||
text-align: center; |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue