Browse Source

fix:服务修改

master
wang 6 days ago
parent
commit
94f913dbcd
  1. 7
      src/api/business/cost/firm-reports-api.js
  2. 182
      src/views/business/erp/cost/firm-reports-form.vue
  3. 145
      src/views/business/erp/cost/firm-reports-list.vue
  4. 17
      src/views/business/erp/letter/letter-list.vue
  5. 28
      src/views/business/erp/penalty-apply/penalty-apply-list.vue
  6. 74
      src/views/business/erp/service/ceo-service-detail.vue
  7. 11
      src/views/business/erp/service/law-firm-service-report-statistics.vue
  8. 2
      src/views/business/erp/service/service-applications-count.vue
  9. 110
      src/views/business/erp/service/service-applications-list.vue
  10. 77
      src/views/business/erp/service/service-applications-report-list.vue

7
src/api/business/cost/firm-reports-api.js

@ -73,4 +73,11 @@ export const firmReportsApi = {
return postRequest('/firmReports/review', param); return postRequest('/firmReports/review', param);
}, },
/**
* 驳回 @author wzh
*/
reject: (idList) => {
return postRequest('/firmReports/reject', idList);
},
}; };

182
src/views/business/erp/cost/firm-reports-form.vue

@ -28,15 +28,15 @@
:max="2100" :max="2100"
/> />
</a-form-item> </a-form-item>
<a-form-item label="月份" name="declareMonth"> <a-form-item label="季度" name="declareQuarter">
<a-select <a-select
v-model:value="form.declareMonth" v-model:value="form.declareQuarter"
placeholder="请选择月份" placeholder="请选择季度"
@change="onMonthChange" @change="onQuarterChange"
style="width: 100%" style="width: 100%"
> >
<a-select-option v-for="month in monthOptions" :key="month.value" :value="month.value"> <a-select-option v-for="quarter in quarterOptions" :key="quarter.value" :value="quarter.value">
{{ month.label }} {{ quarter.label }}
</a-select-option> </a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
@ -62,7 +62,7 @@
/> />
<div style="font-size: 12px; color: #666; margin-top: 4px;"> <div style="font-size: 12px; color: #666; margin-top: 4px;">
本年度已填报收入{{ annualIncomeInfo.revenue || 0 }} 万元 本年度已填报收入{{ annualIncomeInfo.revenue || 0 }} 万元
<span v-if="annualIncomeInfo.revenue > 0 && form.revenue">合计{{ formatNumber((annualIncomeInfo.revenue || 0) + (form.revenue || 0)) }} 万元</span> <span v-if="annualIncomeInfo.revenue > 0 && form.revenue">合计{{ formatNumber(parseFloat(annualIncomeInfo.revenue || 0) + parseFloat(form.revenue || 0)) }} 万元</span>
</div> </div>
</a-form-item> </a-form-item>
@ -156,37 +156,37 @@
totalCost: 0 // totalCost: 0 //
}); });
// //
const monthOptions = ref([]); const quarterOptions = ref([]);
// //
async function initMonthOptions() { async function initQuarterOptions() {
const currentDate = new Date(); const currentDate = new Date();
const currentYear = currentDate.getFullYear(); const currentYear = currentDate.getFullYear();
const currentMonth = currentDate.getMonth() + 1; // 1-12 const currentMonth = currentDate.getMonth() + 1;
// //
let lastMonth = currentMonth - 1; const currentQuarter = Math.ceil(currentMonth / 3);
let lastMonthYear = currentYear;
if (lastMonth === 0) { //
lastMonth = 12; let lastQuarter = currentQuarter - 1;
lastMonthYear = currentYear - 1; let lastQuarterYear = currentYear;
if (lastQuarter === 0) {
lastQuarter = 4;
lastQuarterYear = currentYear - 1;
} }
// //
form.declareYear = lastMonthYear; form.declareYear = lastQuarterYear;
// //
monthOptions.value = [ quarterOptions.value = [
{ label: `${lastMonth}`, value: `${lastMonth}` } { label: `${lastQuarter}季度`, value: lastQuarter }
]; ];
// //
form.declareMonth = `${lastMonth}`; form.declareQuarter = lastQuarter;
//
await getPublicWelfareCost();
} }
// //
@ -202,8 +202,8 @@
const result = await firmReportsApi.income(); const result = await firmReportsApi.income();
if (result.data) { if (result.data) {
annualIncomeInfo.value = { annualIncomeInfo.value = {
revenue: result.data.revenue || 0, revenue: parseFloat(result.data.revenue) || 0,
totalCost: result.data.totalCost || 0 totalCost: parseFloat(result.data.totalCost) || 0
}; };
} }
} catch (error) { } catch (error) {
@ -212,9 +212,9 @@
} }
} }
// //
async function getPublicWelfareCost() { async function getPublicWelfareCost() {
console.log('开始获取公益成本,部门ID:', departmentId.value, '年份:', form.declareYear, '月份:', form.declareMonth); console.log('开始获取公益成本,部门ID:', departmentId.value, '年份:', form.declareYear, '季度:', form.declareQuarter);
if (!departmentId.value) { if (!departmentId.value) {
message.warning('无法获取机构信息,请重新登录'); message.warning('无法获取机构信息,请重新登录');
@ -227,40 +227,49 @@
return; return;
} }
if (!form.declareMonth) { if (!form.declareQuarter) {
console.log('月份未选择,跳过API调用'); console.log('季度未选择,跳过API调用');
return; return;
} }
try { // 1-4" (Q1)"
// "1" -> 1, "2" -> 2, ..., "12" -> 12 let quarterNum = form.declareQuarter;
let monthNumber; if (typeof quarterNum === 'string') {
if (typeof form.declareMonth === 'string') { // " (Q1)"1
const monthMatch = form.declareMonth.match(/^(\d+)/); const match = quarterNum.match(/(\d+)/);
if (monthMatch && monthMatch[1]) { if (match) {
monthNumber = parseInt(monthMatch[1]); quarterNum = parseInt(match[1], 10);
} } else {
} else if (typeof form.declareMonth === 'number') { console.error('无法解析季度字符串:', quarterNum);
monthNumber = form.declareMonth; return;
} }
}
try {
//
const startMonth = (quarterNum - 1) * 3 + 1;
const endMonth = startMonth + 2;
// 3
let totalCost = 0;
for (let month = startMonth; month <= endMonth; month++) {
const queryForm = {
firmId: departmentId.value,
year: form.declareYear,
month: month
};
// ID console.log('调用接口: /serviceApplications/statistics/cost, 参数:', queryForm);
const queryForm = { const response = await serviceApplicationsApi.getServiceApplicationsCost(queryForm);
firmId: departmentId.value, console.log(`${month}月接口返回数据:`, response);
year: form.declareYear, // year
month: monthNumber //
};
console.log('调用接口: /serviceApplications/statistics/cost, 参数:', queryForm); totalCost += parseFloat(response.data) || 0;
const response = await serviceApplicationsApi.getServiceApplicationsCost(queryForm); }
console.log('接口返回数据:', response);
// API form.publicWelfareCost = totalCost;
const costInYuan = response.data; //
//const costInWanYuan = costInYuan / 10000; //
form.publicWelfareCost = costInYuan;
console.log('转换后的公益成本:', form.publicWelfareCost, '万元'); console.log('季度累计公益成本:', form.publicWelfareCost, '万元');
calculateCosts(); calculateCosts();
} catch (error) { } catch (error) {
message.error('获取公益成本失败'); message.error('获取公益成本失败');
@ -270,7 +279,7 @@
} }
} }
function show(rowData) { async function show(rowData) {
console.log('表单show函数被调用,rowData:', rowData); console.log('表单show函数被调用,rowData:', rowData);
Object.assign(form, formDefault); Object.assign(form, formDefault);
@ -280,26 +289,22 @@
// rowDataid // rowDataid
if (rowData && typeof rowData === 'object' && rowData.id) { if (rowData && typeof rowData === 'object' && rowData.id) {
console.log('编辑模式,使用现有数据'); console.log('编辑模式,使用现有数据:', rowData);
//
Object.assign(form, rowData); Object.assign(form, rowData);
//
// declareMonth //
if (form.declareMonth && typeof form.declareMonth === 'number') { await nextTick();
// console.log('编辑模式表单数据:', form.declareYear, form.declareQuarter);
form.declareMonth = form.declareMonth + '月'; await getPublicWelfareCost();
} else if (form.declareMonth && form.declareMonth.includes('(')) {
// "1 (1)"
const match = form.declareMonth.match(/\(([^)]+)\)/);
if (match && match[1]) {
form.declareMonth = match[1] + '月'; // ""
}
}
} else { } else {
console.log('新建模式,等待用户选择月份后获取公益成本'); console.log('新建模式,等待用户选择季度后获取公益成本');
// //
initMonthOptions(); await initQuarterOptions();
// //
fetchAnnualIncome(); await fetchAnnualIncome();
//
await getPublicWelfareCost();
} }
visibleFlag.value = true; visibleFlag.value = true;
@ -324,7 +329,7 @@
id: undefined, id: undefined,
firmId: undefined, // IDID firmId: undefined, // IDID
declareYear: new Date().getFullYear(), // declareYear: new Date().getFullYear(), //
declareMonth: undefined, // ID (1,2,3,4,5,6,7,8,9,10,11,12) declareQuarter: undefined, // (1,2,3,4)
revenue: undefined, // revenue: undefined, //
//totalCost: 0, // //totalCost: 0, //
publicWelfareCost: undefined, // publicWelfareCost: undefined, //
@ -334,7 +339,7 @@
let form = reactive({ ...formDefault }); let form = reactive({ ...formDefault });
const rules = { const rules = {
declareMonth: [{ required: true, message: '请选择月份' }], declareQuarter: [{ required: true, message: '请选择季度' }],
declareYear: [{ required: true, message: '请输入报表年份' }], declareYear: [{ required: true, message: '请输入报表年份' }],
revenue: [{ required: true, message: '请输入律所收入' }], revenue: [{ required: true, message: '请输入律所收入' }],
publicWelfareCost: [{ required: true, message: '系统正在计算公益成本,请稍后' }], publicWelfareCost: [{ required: true, message: '系统正在计算公益成本,请稍后' }],
@ -345,12 +350,12 @@
const showCostWarning = ref(false); const showCostWarning = ref(false);
const costRatio = ref(0); // const costRatio = ref(0); //
// //
function onMonthChange() { function onQuarterChange() {
console.log('月份选择变化:', form.declareMonth); console.log('季度选择变化:', form.declareQuarter);
// //
if (form.declareMonth) { if (form.declareQuarter) {
getPublicWelfareCost(); getPublicWelfareCost();
} }
@ -425,7 +430,7 @@
// 稿 // 稿
async function saveAsDraft() { async function saveAsDraft() {
try { try {
await formRef.value.validateFields(['declareMonth', 'declareYear', 'revenue', 'publicWelfareCost']); await formRef.value.validateFields(['declareQuarter', 'declareYear', 'revenue', 'publicWelfareCost']);
form.approvalStatus = '0'; // 稿 form.approvalStatus = '0'; // 稿
await save(); await save();
} catch (err) { } catch (err) {
@ -455,12 +460,9 @@
// 使 // 使
const saveData = { ...form }; const saveData = { ...form };
// "1" -> 1, "2" -> 2 //
if (saveData.declareMonth && typeof saveData.declareMonth === 'string') { if (saveData.declareQuarter) {
const monthMatch = saveData.declareMonth.match(/^(\d+)/); saveData.declareQuarter = parseInt(saveData.declareQuarter);
if (monthMatch && monthMatch[1]) {
saveData.declareMonth = parseInt(monthMatch[1]);
}
} }
// //

145
src/views/business/erp/cost/firm-reports-list.vue

@ -14,16 +14,24 @@
<DepartmentTreeSelect style="width: 250px" 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-input style="width: 150px" v-model:value="queryForm.declareYear" placeholder="请输入报表年份" /> <a-select
v-model:value="queryForm.declareYear"
placeholder="请选择年份"
style="width: 120px"
>
<a-select-option v-for="year in yearOptions" :key="year" :value="year">
{{ year }}
</a-select-option>
</a-select>
</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
v-model:value="queryForm.declareMonth" v-model:value="queryForm.declareQuarter"
placeholder="请选择月份" placeholder="请选择季度"
style="width: 100px" style="width: 120px"
> >
<a-select-option v-for="month in monthOptions" :key="month.value" :value="month.value"> <a-select-option v-for="quarter in quarterOptions" :key="quarter.value" :value="quarter.value">
{{ month.label }} {{ quarter.label }}
</a-select-option> </a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
@ -85,7 +93,7 @@
<div class="smart-table-operate"> <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 || record.approvalStatus === 4" @click="showForm(record)" type="link">编辑</a-button>
<a-button v-if="isCto && record.approvalStatus === 0 && (record.userId == currentUserId || !record.userId)" @click="onSubmit(record)" type="link">提交</a-button> <a-button v-if="isCto && record.approvalStatus === 0 && (record.userId == currentUserId || !record.userId)" @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 v-if="isCeo && record.approvalStatus === 3" @click="confirmReject(record)" danger type="link">驳回</a-button>
<a-button v-if="isCto && record.approvalStatus === 0 && (record.userId == currentUserId || !record.userId)" @click="onDelete(record)" danger type="link">删除</a-button> <a-button v-if="isCto && record.approvalStatus === 0 && (record.userId == currentUserId || !record.userId)" @click="onDelete(record)" danger type="link">删除</a-button>
</div> </div>
</template> </template>
@ -111,6 +119,8 @@
<FirmReportsForm ref="formRef" @reloadList="queryData"/> <FirmReportsForm ref="formRef" @reloadList="queryData"/>
</a-card> </a-card>
</template> </template>
<script setup> <script setup>
@ -142,7 +152,7 @@
// //
const role = (res.data?.roleCode || res.data?.roleName || '').toLowerCase(); const role = (res.data?.roleCode || res.data?.roleName || '').toLowerCase();
isCto.value = role === 'cto'; isCto.value = role === 'cto' || role === 'staff';
isCeo.value = role === 'ceo'; isCeo.value = role === 'ceo';
} catch (e) { } catch (e) {
@ -164,9 +174,12 @@
ellipsis: true, ellipsis: true,
}, },
{ {
title: '月份', title: '季度',
dataIndex: 'declareMonth', dataIndex: 'declareQuarter',
ellipsis: true, ellipsis: true,
customRender: ({ text }) => {
return text ? `${text}` : '';
},
}, },
{ {
title: '营业收入(万元)', title: '营业收入(万元)',
@ -225,24 +238,29 @@
pageSize: 10, pageSize: 10,
firmId: undefined, // ID firmId: undefined, // ID
declareYear: undefined, // declareYear: undefined, //
declareMonth: undefined, // declareQuarter: undefined, //
}; };
// //
const monthOptions = ref([ const quarterOptions = ref([
{ label: '1月', value: '1月' }, { label: '第1季度', value: 1 },
{ label: '2月', value: '2月' }, { label: '第2季度', value: 2 },
{ label: '3月', value: '3月' }, { label: '第3季度', value: 3 },
{ label: '4月', value: '4月' }, { label: '第4季度', value: 4 }
{ label: '5月', value: '5月' },
{ label: '6月', value: '6月' },
{ label: '7月', value: '7月' },
{ label: '8月', value: '8月' },
{ label: '9月', value: '9月' },
{ label: '10月', value: '10月' },
{ label: '11月', value: '11月' },
{ label: '12月', value: '12月' }
]); ]);
// 5
const yearOptions = ref([]);
//
function initYearOptions() {
const currentYear = new Date().getFullYear();
const years = [];
for (let i = 0; i < 5; i++) {
years.push(currentYear - i);
}
yearOptions.value = years;
}
// form // form
const queryForm = reactive({ ...queryFormState }); const queryForm = reactive({ ...queryFormState });
// loading // loading
@ -270,17 +288,9 @@
async function queryData() { async function queryData() {
tableLoading.value = true; tableLoading.value = true;
try { try {
// //
const queryParams = { ...queryForm }; const queryParams = { ...queryForm };
// "2" -> 2
if (queryParams.declareMonth && typeof queryParams.declareMonth === 'string') {
const monthMatch = queryParams.declareMonth.match(/^(\d+)/);
if (monthMatch && monthMatch[1]) {
queryParams.declareMonth = parseInt(monthMatch[1]);
}
}
let queryResult = await firmReportsApi.queryPage(queryParams); let queryResult = await firmReportsApi.queryPage(queryParams);
tableData.value = queryResult.data.list; tableData.value = queryResult.data.list;
total.value = queryResult.data.total; total.value = queryResult.data.total;
@ -329,60 +339,37 @@
} }
} }
// ---------------------------- ---------------------------- // ---------------------------- ----------------------------
//
const auditModalVisible = ref(false);
const auditLoading = ref(false);
const currentAuditRecord = ref(null);
const auditForm = reactive({
auditResult: 3, //
auditRemark: ''
});
// //
function showAuditModal(record) { function confirmReject(record) {
currentAuditRecord.value = record; Modal.confirm({
auditForm.auditResult = 3; title: '提示',
auditForm.auditRemark = ''; content: '确定要驳回该成本报表吗?',
auditModalVisible.value = true; okText: '确定',
okType: 'danger',
onOk() {
return handleReject(record);
},
cancelText: '取消',
});
} }
// //
async function handleAudit() { async function handleReject(record) {
if (!currentAuditRecord.value) {
message.error('未选择审核记录');
return;
}
auditLoading.value = true;
const auditData = {
reportId: currentAuditRecord.value.reportId,
approvalStatus: auditForm.auditResult
};
try { try {
await firmReportsApi.review(auditData); // id
message.success('审核成功'); await firmReportsApi.reject([record.id]);
auditModalVisible.value = false; message.success('驳回成功');
queryData(); queryData();
} catch (error) { } catch (error) {
message.error('审核失败'); message.error('驳回失败');
console.error('审核失败:', error); console.error('驳回失败:', error);
} finally {
auditLoading.value = false;
} }
} }
//
function handleAuditCancel() {
auditModalVisible.value = false;
currentAuditRecord.value = null;
auditForm.auditResult = 3;
auditForm.auditRemark = '';
}
onMounted(async () => { onMounted(async () => {
initYearOptions();
await getLoginInfo(); await getLoginInfo();
await queryData(); await queryData();
}); });

17
src/views/business/erp/letter/letter-list.vue

@ -75,17 +75,18 @@
<!---------- 表格操作行 begin -----------> <!---------- 表格操作行 begin ----------->
<a-row class="smart-table-btn-block"> <a-row class="smart-table-btn-block">
<div class="smart-table-operate-block"> <div class="smart-table-operate-block">
<!-- user角色只显示律师承诺书按钮 --> <!-- user角色律师只显示律师承诺书按钮 -->
<a-button type="primary" @click="handleLawyerUpload" :loading="proofUploadLoading" v-if="isLawyerRole && !isFirmRole"> <a-button type="primary" @click="handleLawyerUpload" :loading="proofUploadLoading" v-if="isLawyerRole && !isFirmRole">
<UploadOutlined /> <UploadOutlined />
上传律师承诺书 上传律师承诺书
</a-button> </a-button>
<!-- cto角色显示两个按钮 --> <!-- cto角色主任显示两个按钮 -->
<a-button type="primary" @click="handleLawyerUpload" :loading="proofUploadLoading" v-if="isFirmRole" style="margin-left: 8px;"> <a-button type="primary" @click="handleLawyerUpload" :loading="proofUploadLoading" v-if="isFirmRole && !isFirmAdmin" style="margin-left: 8px;">
<UploadOutlined /> <UploadOutlined />
上传律师承诺书 上传律师承诺书
</a-button> </a-button>
<!-- cto和staff都可以上传律所承诺书 -->
<a-button type="primary" @click="handleFirmUpload" :loading="proofUploadLoading" v-if="isFirmRole" style="margin-left: 8px;"> <a-button type="primary" @click="handleFirmUpload" :loading="proofUploadLoading" v-if="isFirmRole" style="margin-left: 8px;">
<UploadOutlined /> <UploadOutlined />
上传律所承诺书 上传律所承诺书
@ -513,8 +514,10 @@ import AgreementModal from '/@/views/system/home/components/agreement.vue';
const isCeo = ref(false); const isCeo = ref(false);
// //
const isLawyerRole = ref(false); const isLawyerRole = ref(false);
// // ctostaff
const isFirmRole = ref(false); const isFirmRole = ref(false);
//
const isFirmAdmin = ref(false);
// //
async function getLoginInfo() { async function getLoginInfo() {
@ -533,8 +536,10 @@ import AgreementModal from '/@/views/system/home/components/agreement.vue';
isCeo.value = roleLower === 'ceo'; isCeo.value = roleLower === 'ceo';
// user // user
isLawyerRole.value = roleLower === 'user' || userType === 'user'; isLawyerRole.value = roleLower === 'user' || userType === 'user';
// cto // staff
isFirmRole.value = roleLower === 'cto' || userType === 'cto'; isFirmAdmin.value = roleLower === 'staff';
// cto staff
isFirmRole.value = roleLower === 'cto' || roleLower === 'staff' || userType === 'cto';
} }
} catch (e) { } catch (e) {

28
src/views/business/erp/penalty-apply/penalty-apply-list.vue

@ -9,7 +9,7 @@
<!---------- 查询表单form begin -----------> <!---------- 查询表单form begin ----------->
<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" v-if="isCeo || isCto"> <a-form-item label="申请人" class="smart-query-form-item" v-if="isCeo || isCto || isFirmAdmin">
<a-input style="width: 150px" v-model:value="queryForm.userName" placeholder="请输入申请人" /> <a-input style="width: 150px" v-model:value="queryForm.userName" 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">
@ -45,13 +45,15 @@
<!---------- 表格操作行 begin -----------> <!---------- 表格操作行 begin ----------->
<a-row class="smart-table-btn-block"> <a-row class="smart-table-btn-block">
<div class="smart-table-operate-block"> <div class="smart-table-operate-block">
<a-button @click="() => showForm('user')" type="primary" v-if="!isCeo"> <!-- 申请律师无处罚证明只有user角色可以申请行政人员不能申请 -->
<a-button @click="() => showForm('user')" type="primary" v-if="isUser">
<template #icon> <template #icon>
<PlusOutlined /> <PlusOutlined />
</template> </template>
申请律师无处罚证明 申请律师无处罚证明
</a-button> </a-button>
<a-button @click="() => showForm('cto')" type="primary" v-if="isCto"> <!-- 申请律所无处罚证明cto和staff都可以申请 -->
<a-button @click="() => showForm('cto')" type="primary" v-if="isCto || isFirmAdmin">
<template #icon> <template #icon>
<PlusOutlined /> <PlusOutlined />
</template> </template>
@ -84,8 +86,8 @@
<a-button type="link" size="small" @click="showAuditModal(record)" :disabled="record.auditStatus !== 1" v-if="isCeo">审批</a-button> <a-button type="link" size="small" @click="showAuditModal(record)" :disabled="record.auditStatus !== 1" v-if="isCeo">审批</a-button>
<a-button type="link" size="small" @click="handlePreview(record)" v-if="isCeo">预览</a-button> <a-button type="link" size="small" @click="handlePreview(record)" v-if="isCeo">预览</a-button>
<!-- CTO角色判断status字段状态为1已提交时显示审批按钮 --> <!-- CTO角色和行政人员判断status字段状态为1已提交时显示审批按钮 -->
<a-button type="link" size="small" @click="showAuditModal(record)" :disabled="record.status !== 1" v-if="isCto">审批</a-button> <a-button type="link" size="small" @click="showAuditModal(record)" :disabled="record.status !== 1" v-if="isCto || isFirmAdmin">审批</a-button>
<!-- 用户角色当auditStatus为3已批准且当前用户是文件所有者时显示下载 --> <!-- 用户角色当auditStatus为3已批准且当前用户是文件所有者时显示下载 -->
<a-button type="link" size="small" @click="handleDownload(record)" v-if="record.auditStatus === 3 && !isCeo && record.userId === loginInfo?.userId">下载</a-button> <a-button type="link" size="small" @click="handleDownload(record)" v-if="record.auditStatus === 3 && !isCeo && record.userId === loginInfo?.userId">下载</a-button>
@ -341,9 +343,12 @@ import PenaltyApplyForm from './penalty-apply-form.vue';
// User // User
const isUser = ref(false); const isUser = ref(false);
// CTO // CTO
const isCto = ref(false); const isCto = ref(false);
//
const isFirmAdmin = ref(false);
// //
function resetQuery() { function resetQuery() {
let pageSize = queryForm.pageSize; let pageSize = queryForm.pageSize;
@ -414,10 +419,13 @@ import PenaltyApplyForm from './penalty-apply-form.vue';
// User // User
isUser.value = roleLower === 'user'; isUser.value = roleLower === 'user';
// CTO // CTO
isCto.value = roleLower === 'cto'; isCto.value = roleLower === 'cto';
console.log('用户角色:', userRole, 'isCeo:', isCeo.value, 'isUser:', isUser.value, 'isCto:', isCto.value); //
isFirmAdmin.value = roleLower === 'staff';
console.log('用户角色:', userRole, 'isCeo:', isCeo.value, 'isUser:', isUser.value, 'isCto:', isCto.value, 'isFirmAdmin:', isFirmAdmin.value);
} }
} }
@ -499,8 +507,8 @@ import PenaltyApplyForm from './penalty-apply-form.vue';
// 使 // 使
if (isCeo.value) { if (isCeo.value) {
auditData.auditStatusField = 'auditStatus'; // CEO使 auditData.auditStatusField = 'auditStatus'; // CEO使
} else if (isCto.value) { } else if (isCto.value || isFirmAdmin.value) {
auditData.auditStatusField = 'status'; // CTO使 auditData.auditStatusField = 'status'; // CTO使
} }
if (auditForm.auditRemark) { if (auditForm.auditRemark) {

74
src/views/business/erp/service/ceo-service-detail.vue

@ -109,9 +109,9 @@
批量审核 批量审核
</a-button> </a-button>
<!-- 批量上报按钮cto角色显示 --> <!-- 批量上报按钮cto角色和行政人员角色显示 -->
<a-button <a-button
v-if="isCtoRole" v-if="isCtoRole || isFirmAdmin"
@click="batchReport" @click="batchReport"
type="primary" type="primary"
:disabled="selectedRowKeyList.length == 0" :disabled="selectedRowKeyList.length == 0"
@ -265,9 +265,11 @@ import {
} from '@ant-design/icons-vue'; } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { serviceApplicationsApi } from '/@/api/business/service-applications/service-applications-api'; import { serviceApplicationsApi } from '/@/api/business/service-applications/service-applications-api';
import { loginApi } from '/@/api/system/login-api';
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue'; import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
import ServiceApplicationsForm from './service-applications-form.vue'; import ServiceApplicationsForm from './service-applications-form.vue';
import TableOperator from '/@/components/support/table-operator/index.vue'; import TableOperator from '/@/components/support/table-operator/index.vue';
import { getRoleInfo } from '/@/utils/role-util';
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
@ -279,6 +281,7 @@ const total = ref(0);
const selectedRowKeyList = ref([]); const selectedRowKeyList = ref([]);
const employeeList = ref([]); const employeeList = ref([]);
const loginInfo = ref({}); const loginInfo = ref({});
const roleInfo = ref(getRoleInfo(''));
// //
const auditModalVisible = ref(false); const auditModalVisible = ref(false);
@ -332,23 +335,54 @@ const REVIEW_ENUM = {
}; };
// //
const isNotUser = computed(() => { const isNotUser = computed(() => roleInfo.value.isNotUser);
// true const isCtoRole = computed(() => roleInfo.value.isCto);
return true; const isCeo = computed(() => roleInfo.value.isCeo);
}); const isFirmAdmin = computed(() => roleInfo.value.isFirmAdmin);
const isAssociationRole = computed(() => roleInfo.value.isAssociationRole);
const isCtoRole = computed(() => {
// CTO
return false;
});
// //
function canAuditRecord(record) { function canAuditRecord(record) {
return record.firmAuditStatus === 1 && isNotUser.value; const userRole = (loginInfo.value.roleCode || loginInfo.value.roleName || '').toLowerCase();
if (userRole === 'ceo') {
return record.associationAuditStatus === 1;
}
if (userRole === 'cto' || userRole === 'staff') {
return record.firmAuditStatus === 1;
}
return false;
} }
function canRejectRecord(record) { function canRejectRecord(record) {
return record.firmAuditStatus === 1 && isNotUser.value; if (!isAssociationRole.value && !isCeo.value && !isCtoRole.value && !isFirmAdmin.value) {
return false;
}
if (isAssociationRole.value || isCeo.value) {
if (record.associationAuditStatus !== 3) {
return false;
}
if (!record.associationAuditTime) {
return false;
}
const auditDate = new Date(record.associationAuditTime);
const now = new Date();
const monthsDiff = (now.getFullYear() - auditDate.getFullYear()) * 12 + (now.getMonth() - auditDate.getMonth());
return monthsDiff <= 18;
} else if (isCtoRole.value || isFirmAdmin.value) {
if (record.associationAuditStatus !== 4) {
return false;
}
if (record.firmAuditStatus === 4) {
return false;
}
return true;
}
return false;
} }
// //
@ -534,6 +568,7 @@ async function loadAllEmployees() {
// //
onMounted(() => { onMounted(() => {
getLoginInfo();
// //
const { firmId, firmName, year, quarter } = route.query; const { firmId, firmName, year, quarter } = route.query;
@ -546,6 +581,19 @@ onMounted(() => {
queryData(); queryData();
}); });
//
async function getLoginInfo() {
try {
const res = await loginApi.getLoginInfo();
loginInfo.value = res.data;
const userRole = res.data.roleCode || res.data.roleName || '';
roleInfo.value = getRoleInfo(userRole);
console.log('登录信息:', res.data);
} catch (e) {
console.error('获取登录信息失败:', e);
}
}
// //
const columns = ref([ const columns = ref([
{ {

11
src/views/business/erp/service/law-firm-service-report-statistics.vue

@ -133,6 +133,7 @@
showQuickJumper showQuickJumper
showTotal showTotal
@change="handleTableChange" @change="handleTableChange"
@showSizeChange="handleTableChange"
/> />
</div> </div>
</a-card> </a-card>
@ -264,11 +265,11 @@
queryData(); queryData();
} }
function handleTableChange(pag) { function handleTableChange(page, pageSize) {
pagination.current = pag.current; pagination.current = page;
pagination.pageSize = pag.pageSize; pagination.pageSize = pageSize;
queryForm.pageNum = pag.current; queryForm.pageNum = page;
queryForm.pageSize = pag.pageSize; queryForm.pageSize = pageSize;
queryData(); queryData();
} }

2
src/views/business/erp/service/service-applications-count.vue

@ -80,7 +80,7 @@ async function getLoginInfo() {
// CEOCTO // CEOCTO
const role = (res.data?.roleCode || res.data?.roleName || '').toLowerCase(); const role = (res.data?.roleCode || res.data?.roleName || '').toLowerCase();
isCeo.value = role === 'ceo'; isCeo.value = role === 'ceo';
isCto.value = role === 'cto'; isCto.value = role === 'cto' || role === 'staff';
// isAdmin使isCeoisCto // isAdmin使isCeoisCto
isAdmin.value = isCeo.value || isCto.value; isAdmin.value = isCeo.value || isCto.value;

110
src/views/business/erp/service/service-applications-list.vue

@ -113,9 +113,9 @@
<!-- 批量上报按钮cto角色显示 --> <!-- 批量上报按钮cto角色和行政人员角色显示 -->
<a-button <a-button
v-if="isCtoRole" v-if="isCtoRole || isFirmAdmin"
@click="batchReport" @click="batchReport"
type="primary" type="primary"
:disabled="selectedRowKeyList.length == 0" :disabled="selectedRowKeyList.length == 0"
@ -308,7 +308,7 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import { reactive, ref, onMounted } from 'vue'; import { reactive, ref, onMounted, computed } from 'vue';
import { useRoute } from 'vue-router'; 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';
@ -326,6 +326,7 @@ import { PlusOutlined, DeleteOutlined, SendOutlined, ImportOutlined, ExportOutli
import { loginApi } from '/@/api/system/login-api'; import { loginApi } from '/@/api/system/login-api';
import { firmReportsApi } from '/@/api/business/cost/firm-reports-api'; import { firmReportsApi } from '/@/api/business/cost/firm-reports-api';
import AgreementModal from '/@/views/system/home/components/agreement-modal.vue'; import AgreementModal from '/@/views/system/home/components/agreement-modal.vue';
import { getRoleInfo } from '/@/utils/role-util';
// ---------------------------- ---------------------------- // ---------------------------- ----------------------------
const columns = ref([ const columns = ref([
@ -480,20 +481,17 @@ import AgreementModal from '/@/views/system/home/components/agreement-modal.vue'
// //
const loginInfo = ref(null); const loginInfo = ref(null);
// useruser //
const isNotUser = ref(false); const roleInfo = ref(getRoleInfo(''));
// ctocto //
const isCtoRole = ref(false); const isNotUser = computed(() => roleInfo.value.isNotUser);
const isCtoRole = computed(() => roleInfo.value.isCto);
// const isAssociationRole = computed(() => roleInfo.value.isAssociationRole);
const isAssociationRole = ref(false); const isCeo = computed(() => roleInfo.value.isCeo);
const isFirmRole = computed(() => roleInfo.value.isFirmRole);
// CEOCEO const isFirmAdmin = computed(() => roleInfo.value.isFirmAdmin);
const isCeo = ref(false); const canCreateApplication = computed(() => roleInfo.value.canCreateApplication);
//
const isFirmRole = ref(false);
// //
async function getLoginInfo() { async function getLoginInfo() {
@ -510,32 +508,9 @@ import AgreementModal from '/@/views/system/home/components/agreement-modal.vue'
// //
function checkUserRole() { function checkUserRole() {
if (loginInfo.value) { if (loginInfo.value) {
//
const userRole = loginInfo.value.roleCode || loginInfo.value.roleName || ''; const userRole = loginInfo.value.roleCode || loginInfo.value.roleName || '';
const roleLower = userRole.toLowerCase(); roleInfo.value = getRoleInfo(userRole);
console.log('用户角色:', userRole, '角色信息:', roleInfo.value);
// 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('律师');
// CEOCEO
isCeo.value = roleLower === 'ceo';
console.log('用户角色:', userRole, '不是user:', isNotUser.value, '是cto:', isCtoRole.value, '是协会角色:', isAssociationRole.value, '是CEO:', isCeo.value);
} }
} }
@ -588,8 +563,8 @@ import AgreementModal from '/@/views/system/home/components/agreement-modal.vue'
return record.associationAuditStatus === 1; return record.associationAuditStatus === 1;
} }
// cto(1) // ctostaff(1)
if (userRole === 'cto') { if (userRole === 'cto' || userRole === 'staff') {
return record.firmAuditStatus === 1; return record.firmAuditStatus === 1;
} }
@ -702,7 +677,7 @@ import AgreementModal from '/@/views/system/home/components/agreement-modal.vue'
); );
if (canReportRecords.length === 0) { if (canReportRecords.length === 0) {
message.warning('选中的记录不符合上报条件,请勿提交其它月份数据'); message.warning('选中的记录不符合上报条件,只能上报上个季度的数据');
return; return;
} }
@ -719,47 +694,50 @@ import AgreementModal from '/@/views/system/home/components/agreement-modal.vue'
// //
function canReportRecord(record) { function canReportRecord(record) {
// 3 // 3
// 0 // 04
const isAuditPassed = record.firmAuditStatus === 3 && const isAuditPassed = record.firmAuditStatus === 3 &&
record.associationAuditStatus === 0; (record.associationAuditStatus === 0 || record.associationAuditStatus === 4);
// //
const hasCostPermission = loginInfo.value && loginInfo.value.costVisibleFlag === true; const hasCostPermission = loginInfo.value && loginInfo.value.costVisibleFlag === true;
if (hasCostPermission) { if (hasCostPermission) {
// //
const isLastMonthData = isLastMonthRecord(record); //
return isAuditPassed && isLastMonthData; const isLastQuarterData = isLastQuarterRecord(record);
return isAuditPassed && isLastQuarterData;
} else { } else {
// //
return isAuditPassed; return isAuditPassed;
} }
} }
// //
function isLastMonthRecord(record) { function isLastQuarterRecord(record) {
if (!record.reportTime) return false; if (!record.reportTime) return false;
const currentDate = new Date(); const currentDate = new Date();
const currentYear = currentDate.getFullYear(); const currentYear = currentDate.getFullYear();
const currentMonth = currentDate.getMonth() + 1; const currentMonth = currentDate.getMonth() + 1;
const currentQuarter = Math.ceil(currentMonth / 3);
// //
let lastMonth = currentMonth - 1; let lastQuarter = currentQuarter - 1;
let lastMonthYear = currentYear; let lastQuarterYear = currentYear;
if (lastMonth === 0) { if (lastQuarter === 0) {
lastMonth = 12; lastQuarter = 4;
lastMonthYear = currentYear - 1; lastQuarterYear = currentYear - 1;
} }
// //
const reportDate = new Date(record.reportTime); const reportDate = new Date(record.reportTime);
const reportYear = reportDate.getFullYear(); const reportYear = reportDate.getFullYear();
const reportMonth = reportDate.getMonth() + 1; const reportMonth = reportDate.getMonth() + 1;
const reportQuarter = Math.ceil(reportMonth / 3);
// //
return reportYear === lastMonthYear && reportMonth === lastMonth; return reportYear === lastQuarterYear && reportQuarter === lastQuarter;
} }
// //
@ -1358,9 +1336,9 @@ function showAuditModal(record) {
// //
function canRejectRecord(record) { function canRejectRecord(record) {
// 1. CEOCTO // 1. CEOCTO
if (!isAssociationRole.value && !isCeo.value && !isCtoRole.value) { if (!isAssociationRole.value && !isCeo.value && !isCtoRole.value && !isFirmAdmin.value) {
console.log('驳回按钮不显示:不是协会角色、CEO角色或CTO角色'); console.log('驳回按钮不显示:不是协会角色、CEO角色、CTO角色或行政人员角色');
return false; return false;
} }
@ -1391,8 +1369,8 @@ function showAuditModal(record) {
} }
return canReject; return canReject;
} else if (isCtoRole.value) { } else if (isCtoRole.value || isFirmAdmin.value) {
// CTO44 // CTO44
if (record.associationAuditStatus !== 4) { if (record.associationAuditStatus !== 4) {
console.log('驳回按钮不显示:协会审核状态不是驳回', record.associationAuditStatus); console.log('驳回按钮不显示:协会审核状态不是驳回', record.associationAuditStatus);
return false; return false;

77
src/views/business/erp/service/service-applications-report-list.vue

@ -58,8 +58,8 @@
<a-row class="smart-table-btn-block"> <a-row class="smart-table-btn-block">
<div class="smart-table-operate-block"> <div class="smart-table-operate-block">
<!-- 新建申报按钮非协会角色且非CEO角色显示 --> <!-- 新建申报按钮 -->
<a-button v-if="!isAssociationRole && !isCeo" @click="showForm()" type="primary"> <a-button v-if="canCreateApplication" @click="showForm()" type="primary">
<template #icon> <template #icon>
<PlusOutlined /> <PlusOutlined />
</template> </template>
@ -67,15 +67,15 @@
</a-button> </a-button>
<a-button v-if="!isCeo" @click="confirmBatchDelete" type="primary" danger :disabled="!canBatchDelete()"> <a-button v-if="!isCeo && !isFirmAdmin" @click="confirmBatchDelete" type="primary" danger :disabled="!canBatchDelete()">
<template #icon> <template #icon>
<DeleteOutlined /> <DeleteOutlined />
</template> </template>
批量删除 批量删除
</a-button> </a-button>
<!-- 导出按钮只有user用户显示 --> <!-- 导出按钮 -->
<a-button v-if="!isNotUser" @click="handleExport" type="primary"> <a-button v-if="isNotUser" @click="handleExport" type="primary">
<template #icon> <template #icon>
<ExportOutlined /> <ExportOutlined />
</template> </template>
@ -248,7 +248,7 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import { reactive, ref, onMounted } from 'vue'; import { reactive, ref, onMounted, computed } from 'vue';
import { useRoute } from 'vue-router'; 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';
@ -263,6 +263,7 @@ import { REVIEW_ENUM,SERVICEC_REVIEW_ENUM } from '/@/constants/system/review-con
import { PlusOutlined, DeleteOutlined, SendOutlined, ImportOutlined, ExportOutlined, DownloadOutlined, UploadOutlined, CheckCircleOutlined } from '@ant-design/icons-vue'; import { PlusOutlined, DeleteOutlined, SendOutlined, ImportOutlined, ExportOutlined, DownloadOutlined, UploadOutlined, CheckCircleOutlined } from '@ant-design/icons-vue';
import { loginApi } from '/@/api/system/login-api'; import { loginApi } from '/@/api/system/login-api';
import AgreementModal from '/@/views/system/home/components/agreement-modal.vue'; import AgreementModal from '/@/views/system/home/components/agreement-modal.vue';
import { getRoleInfo } from '/@/utils/role-util';
// ---------------------------- ---------------------------- // ---------------------------- ----------------------------
const columns = ref([ const columns = ref([
@ -415,20 +416,17 @@ import AgreementModal from '/@/views/system/home/components/agreement-modal.vue'
// //
const loginInfo = ref(null); const loginInfo = ref(null);
// useruser //
const isNotUser = ref(false); const roleInfo = ref(getRoleInfo(''));
// ctocto //
const isCtoRole = ref(false); const isNotUser = computed(() => roleInfo.value.isNotUser);
const isCtoRole = computed(() => roleInfo.value.isCto);
// const isAssociationRole = computed(() => roleInfo.value.isAssociationRole);
const isAssociationRole = ref(false); const isCeo = computed(() => roleInfo.value.isCeo);
const isFirmRole = computed(() => roleInfo.value.isFirmRole);
// CEOCEO const isFirmAdmin = computed(() => roleInfo.value.isFirmAdmin);
const isCeo = ref(false); const canCreateApplication = computed(() => roleInfo.value.canCreateApplication);
//
const isFirmRole = ref(false);
// //
async function getLoginInfo() { async function getLoginInfo() {
@ -445,32 +443,9 @@ import AgreementModal from '/@/views/system/home/components/agreement-modal.vue'
// //
function checkUserRole() { function checkUserRole() {
if (loginInfo.value) { if (loginInfo.value) {
//
const userRole = loginInfo.value.roleCode || loginInfo.value.roleName || ''; const userRole = loginInfo.value.roleCode || loginInfo.value.roleName || '';
const roleLower = userRole.toLowerCase(); roleInfo.value = getRoleInfo(userRole);
console.log('用户角色:', userRole, '角色信息:', roleInfo.value);
// 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('律师');
// CEOCEO
isCeo.value = roleLower === 'ceo';
console.log('用户角色:', userRole, '不是user:', isNotUser.value, '是cto:', isCtoRole.value, '是协会角色:', isAssociationRole.value, '是CEO:', isCeo.value);
} }
} }
@ -523,8 +498,8 @@ import AgreementModal from '/@/views/system/home/components/agreement-modal.vue'
return record.associationAuditStatus === 1; return record.associationAuditStatus === 1;
} }
// cto(1) // ctostaff(1)
if (userRole === 'cto') { if (userRole === 'cto' || userRole === 'staff') {
return record.firmAuditStatus === 1; return record.firmAuditStatus === 1;
} }
@ -1184,9 +1159,9 @@ function showAuditModal(record) {
// //
function canRejectRecord(record) { function canRejectRecord(record) {
// 1. CEOCTO // 1. CEOCTO
if (!isAssociationRole.value && !isCeo.value && !isCtoRole.value) { if (!isAssociationRole.value && !isCeo.value && !isCtoRole.value && !isFirmAdmin.value) {
console.log('驳回按钮不显示:不是协会角色、CEO角色或CTO角色'); console.log('驳回按钮不显示:不是协会角色、CEO角色、CTO角色或行政人员角色');
return false; return false;
} }
@ -1217,8 +1192,8 @@ function showAuditModal(record) {
} }
return canReject; return canReject;
} else if (isCtoRole.value) { } else if (isCtoRole.value || isFirmAdmin.value) {
// CTO44 // CTO44
if (record.associationAuditStatus !== 4) { if (record.associationAuditStatus !== 4) {
console.log('驳回按钮不显示:协会审核状态不是驳回', record.associationAuditStatus); console.log('驳回按钮不显示:协会审核状态不是驳回', record.associationAuditStatus);
return false; return false;

Loading…
Cancel
Save