fix(加班申请): 去掉撤销相关的状态和动作。
feat(工作报告): 开发工作报告功能
This commit is contained in:
241
src/views/personal-center/work-report/index.vue
Normal file
241
src/views/personal-center/work-report/index.vue
Normal file
@@ -0,0 +1,241 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { onBeforeRouteLeave } from 'vue-router';
|
||||
import { fetchGetProjectReportOwnerProjectOptions } from '@/service/api';
|
||||
import { useAuth } from '@/hooks/business/auth';
|
||||
import WorkReportCreateDialog from './shared/components/create-dialog.vue';
|
||||
import WorkReportPrototypePageDialog from './shared/components/prototype-page-dialog.vue';
|
||||
import WorkReportTabs from './shared/components/tabs.vue';
|
||||
import {
|
||||
WORK_REPORT_PROJECT_OWNER_PERMISSION,
|
||||
WORK_REPORT_TYPE_LABEL,
|
||||
type WorkReportRow,
|
||||
type WorkReportType
|
||||
} from './shared/types';
|
||||
import WeeklyReportIndex from './weekly/index.vue';
|
||||
import WeeklyReportApprovalRecordDialog from './weekly/modules/approval-record-dialog.vue';
|
||||
import MonthlyReportIndex from './monthly/index.vue';
|
||||
import MonthlyReportApprovalRecordDialog from './monthly/modules/approval-record-dialog.vue';
|
||||
import ProjectReportIndex from './project/index.vue';
|
||||
import ProjectReportApprovalRecordDialog from './project/modules/approval-record-dialog.vue';
|
||||
|
||||
defineOptions({ name: 'PersonalCenterWorkReport' });
|
||||
|
||||
type PageDialogMode = 'add' | 'edit' | 'detail';
|
||||
type ReportListExpose = {
|
||||
reload: (page?: number) => Promise<void>;
|
||||
};
|
||||
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
const activeTab = ref<WorkReportType>('weekly');
|
||||
const createVisible = ref(false);
|
||||
const pageDialogVisible = ref(false);
|
||||
const pageDialogMode = ref<PageDialogMode>('detail');
|
||||
const approvalRecordVisible = ref(false);
|
||||
const currentReportType = ref<WorkReportType>('weekly');
|
||||
const currentRow = ref<WorkReportRow | null>(null);
|
||||
const initialPeriod = ref<{
|
||||
periodKey: string;
|
||||
periodLabel: string;
|
||||
periodStartDate: string;
|
||||
periodEndDate: string;
|
||||
} | null>(null);
|
||||
const initialProjectId = ref('');
|
||||
const initialFlag = ref(1);
|
||||
const projectOptions = ref<Api.WorkReport.Project.ProjectReportOwnerProjectOption[]>([]);
|
||||
|
||||
const weeklyRef = ref<ReportListExpose | null>(null);
|
||||
const monthlyRef = ref<ReportListExpose | null>(null);
|
||||
const projectRef = ref<ReportListExpose | null>(null);
|
||||
|
||||
const canShowProjectTab = computed(() => hasAuth(WORK_REPORT_PROJECT_OWNER_PERMISSION));
|
||||
|
||||
/** 项目选项是否加载成功(用于项目半月报列表内部判断) */
|
||||
const projectOptionsLoaded = ref(false);
|
||||
|
||||
const visibleTabs = computed<Array<{ label: string; name: WorkReportType }>>(() => {
|
||||
const tabs: Array<{ label: string; name: WorkReportType }> = [
|
||||
{ label: WORK_REPORT_TYPE_LABEL.weekly, name: 'weekly' },
|
||||
{ label: WORK_REPORT_TYPE_LABEL.monthly, name: 'monthly' }
|
||||
];
|
||||
|
||||
if (canShowProjectTab.value) {
|
||||
tabs.push({ label: WORK_REPORT_TYPE_LABEL.project, name: 'project' });
|
||||
}
|
||||
|
||||
return tabs;
|
||||
});
|
||||
|
||||
const currentApprovalRecordDialogComponent = computed(() => {
|
||||
if (currentReportType.value === 'monthly') return MonthlyReportApprovalRecordDialog;
|
||||
if (currentReportType.value === 'project') return ProjectReportApprovalRecordDialog;
|
||||
return WeeklyReportApprovalRecordDialog;
|
||||
});
|
||||
|
||||
function getListRef(reportType: WorkReportType) {
|
||||
if (reportType === 'monthly') return monthlyRef.value;
|
||||
if (reportType === 'project') return projectRef.value;
|
||||
return weeklyRef.value;
|
||||
}
|
||||
|
||||
async function loadProjectOptions() {
|
||||
if (!canShowProjectTab.value) return;
|
||||
|
||||
const { error, data } = await fetchGetProjectReportOwnerProjectOptions();
|
||||
projectOptions.value = error || !data ? [] : data;
|
||||
projectOptionsLoaded.value = !error;
|
||||
}
|
||||
|
||||
function openCreate(reportType: WorkReportType) {
|
||||
currentReportType.value = reportType;
|
||||
createVisible.value = true;
|
||||
}
|
||||
|
||||
function handleCreateConfirm(
|
||||
payload:
|
||||
| { reportType: 'weekly' | 'monthly'; period: typeof initialPeriod.value extends infer T ? T : never }
|
||||
| {
|
||||
reportType: 'project';
|
||||
projectId: string;
|
||||
flag: number;
|
||||
period: typeof initialPeriod.value extends infer T ? T : never;
|
||||
}
|
||||
) {
|
||||
currentReportType.value = payload.reportType;
|
||||
pageDialogMode.value = 'add';
|
||||
currentRow.value = null;
|
||||
initialPeriod.value = payload.period as typeof initialPeriod.value;
|
||||
initialProjectId.value = 'projectId' in payload ? payload.projectId : '';
|
||||
initialFlag.value = 'flag' in payload ? payload.flag : 1;
|
||||
pageDialogVisible.value = true;
|
||||
}
|
||||
|
||||
function openEdit(reportType: WorkReportType, row: WorkReportRow) {
|
||||
currentReportType.value = reportType;
|
||||
pageDialogMode.value = 'edit';
|
||||
currentRow.value = row;
|
||||
initialPeriod.value = null;
|
||||
pageDialogVisible.value = true;
|
||||
}
|
||||
|
||||
function openDetail(reportType: WorkReportType, row: WorkReportRow) {
|
||||
currentReportType.value = reportType;
|
||||
pageDialogMode.value = 'detail';
|
||||
currentRow.value = row;
|
||||
initialPeriod.value = null;
|
||||
pageDialogVisible.value = true;
|
||||
}
|
||||
|
||||
function openApprovalRecord(reportType: WorkReportType, row: WorkReportRow) {
|
||||
currentReportType.value = reportType;
|
||||
currentRow.value = row;
|
||||
approvalRecordVisible.value = true;
|
||||
}
|
||||
|
||||
function handleTabChange(tab: WorkReportType) {
|
||||
activeTab.value = tab;
|
||||
getListRef(tab)?.reload(1);
|
||||
}
|
||||
|
||||
async function reloadReport(reportType = currentReportType.value) {
|
||||
await getListRef(reportType)?.reload();
|
||||
}
|
||||
|
||||
function handleSubmitted() {
|
||||
pageDialogVisible.value = false;
|
||||
reloadReport(currentReportType.value);
|
||||
}
|
||||
|
||||
function closeFloatingPanels() {
|
||||
createVisible.value = false;
|
||||
pageDialogVisible.value = false;
|
||||
approvalRecordVisible.value = false;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await loadProjectOptions();
|
||||
});
|
||||
|
||||
onBeforeRouteLeave(() => {
|
||||
closeFloatingPanels();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="work-report-page-shell min-h-560px gap-16px overflow-hidden xl:grid xl:grid-cols-[240px_minmax(0,1fr)] lt-xl:flex lt-xl:flex-col lt-xl:overflow-auto"
|
||||
>
|
||||
<!-- 左侧:报告类型导航 -->
|
||||
<div class="flex-col-stretch gap-16px xl:min-h-0">
|
||||
<WorkReportTabs :active-tab="activeTab" :tabs="visibleTabs" @update:active-tab="handleTabChange" />
|
||||
</div>
|
||||
|
||||
<!-- 右侧:搜索区 + 列表区 -->
|
||||
<div class="flex-col-stretch gap-16px xl:min-h-0">
|
||||
<WeeklyReportIndex
|
||||
v-show="activeTab === 'weekly'"
|
||||
ref="weeklyRef"
|
||||
class="flex-1-hidden"
|
||||
@create="openCreate('weekly')"
|
||||
@edit="openEdit('weekly', $event)"
|
||||
@detail="openDetail('weekly', $event)"
|
||||
@approval-record="openApprovalRecord('weekly', $event)"
|
||||
/>
|
||||
|
||||
<MonthlyReportIndex
|
||||
v-show="activeTab === 'monthly'"
|
||||
ref="monthlyRef"
|
||||
class="flex-1-hidden"
|
||||
@create="openCreate('monthly')"
|
||||
@edit="openEdit('monthly', $event)"
|
||||
@detail="openDetail('monthly', $event)"
|
||||
@approval-record="openApprovalRecord('monthly', $event)"
|
||||
/>
|
||||
|
||||
<ProjectReportIndex
|
||||
v-if="canShowProjectTab"
|
||||
v-show="activeTab === 'project'"
|
||||
ref="projectRef"
|
||||
class="flex-1-hidden"
|
||||
:project-options="projectOptions"
|
||||
:project-options-loaded="projectOptionsLoaded"
|
||||
@create="openCreate('project')"
|
||||
@edit="openEdit('project', $event)"
|
||||
@detail="openDetail('project', $event)"
|
||||
@approval-record="openApprovalRecord('project', $event)"
|
||||
/>
|
||||
</div>
|
||||
<WorkReportCreateDialog
|
||||
v-model:visible="createVisible"
|
||||
:default-report-type="currentReportType"
|
||||
:project-visible="canShowProjectTab"
|
||||
:project-options="projectOptions"
|
||||
@confirm="handleCreateConfirm"
|
||||
/>
|
||||
|
||||
<WorkReportPrototypePageDialog
|
||||
v-model:visible="pageDialogVisible"
|
||||
:mode="pageDialogMode"
|
||||
scene="fill"
|
||||
:report-type="currentReportType"
|
||||
:row-data="currentRow"
|
||||
:initial-period="initialPeriod"
|
||||
:initial-project-id="initialProjectId"
|
||||
:initial-flag="initialFlag"
|
||||
@submitted="handleSubmitted"
|
||||
/>
|
||||
|
||||
<component
|
||||
:is="currentApprovalRecordDialogComponent"
|
||||
v-model:visible="approvalRecordVisible"
|
||||
:row-data="currentRow"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.work-report-page-shell {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user