feat(performance、notify、weekly): 添加绩效考核功能、通知跳转链接、优化工作日志分割逻辑。

This commit is contained in:
dk
2026-07-07 16:51:34 +08:00
parent c1f710fbd8
commit a0dcd39c23
6 changed files with 330 additions and 34 deletions

View File

@@ -27,19 +27,25 @@ interface Props {
mode: 'view' | 'edit' | 'create';
subordinateOptions?: SubordinateOption[];
showApprovalFooter?: boolean;
initialEmployeeId?: string;
initialPeriodMonth?: string;
hideDraftAction?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
rowData: null,
subordinateOptions: () => [],
showApprovalFooter: false
showApprovalFooter: false,
initialEmployeeId: '',
initialPeriodMonth: '',
hideDraftAction: false
});
const visible = defineModel<boolean>('visible', { default: false });
const emit = defineEmits<{
saved: [];
savedAndSent: [];
saved: [payload: PerformanceSheetSavePayload];
savedAndSent: [payload: PerformanceSheetSavePayload];
startApproval: [];
}>();
@@ -60,6 +66,13 @@ const createForm = reactive({
employeeId: ''
});
interface PerformanceSheetSavePayload {
sheet: Api.Performance.Sheet.Sheet;
actualScoreTotal: string;
baseScoreTotal: string;
extraScoreTotal: string;
}
const createFormRules = computed<FormRules>(() => ({
periodMonth: [createRequiredRule('请选择绩效月份')],
employeeId: [createRequiredRule('请选择下属')]
@@ -526,7 +539,16 @@ async function ensureCreatedSheet() {
return sheetResult.data;
}
async function executeSave(): Promise<Api.Performance.Sheet.Sheet | null> {
function createInitialPeriodMonth() {
return props.initialPeriodMonth || createDefaultPeriodMonth();
}
function initializeCreateForm() {
createForm.periodMonth = createInitialPeriodMonth();
createForm.employeeId = props.initialEmployeeId || '';
}
async function executeSave(): Promise<PerformanceSheetSavePayload | null> {
const workbook = getActiveWorkbook();
if (!workbook) return null;
@@ -573,18 +595,23 @@ async function executeSave(): Promise<Api.Performance.Sheet.Sheet | null> {
return null;
}
return sheet;
return {
sheet,
actualScoreTotal: scores.actualScoreTotal,
baseScoreTotal: scores.baseScoreTotal,
extraScoreTotal: scores.extraScoreTotal
};
}
async function handleSaveDraft() {
saving.value = true;
try {
const sheet = await executeSave();
if (!sheet) return;
const saveResult = await executeSave();
if (!saveResult) return;
window.$message?.success(isCreateMode.value ? '绩效表已保存为草稿' : '绩效 Excel 已保存');
visible.value = false;
emit('saved');
emit('saved', saveResult);
} catch (error) {
window.$message?.error(error instanceof Error ? error.message : '绩效 Excel 保存失败');
} finally {
@@ -595,15 +622,15 @@ async function handleSaveDraft() {
async function handleSaveAndSend() {
sending.value = true;
try {
const sheet = await executeSave();
if (!sheet) return;
const saveResult = await executeSave();
if (!saveResult) return;
const sendResult = await sendPerformanceSheet(sheet.id);
const sendResult = await sendPerformanceSheet(saveResult.sheet.id);
if (sendResult.error) return;
window.$message?.success('绩效表已保存并发送');
visible.value = false;
emit('savedAndSent');
emit('savedAndSent', saveResult);
} catch (error) {
window.$message?.error(error instanceof Error ? error.message : '绩效表发送失败');
} finally {
@@ -616,12 +643,14 @@ watch(visible, async isVisible => {
disposeUniver();
currentSheet.value = null;
currentTemplate.value = null;
// 重置创建表单
createForm.periodMonth = createDefaultPeriodMonth();
createForm.employeeId = '';
initializeCreateForm();
return;
}
if (isCreateMode.value) {
initializeCreateForm();
}
await nextTick();
await loadWorkbook();
});
@@ -698,7 +727,9 @@ onMounted(() => {
<template v-if="canSave || showApprovalFooter" #footer>
<div class="performance-excel-editor__footer">
<template v-if="canSave">
<ElButton :loading="saving" :disabled="sending" @click="handleSaveDraft">保存草稿</ElButton>
<ElButton v-if="!props.hideDraftAction" :loading="saving" :disabled="sending" @click="handleSaveDraft">
保存草稿
</ElButton>
<ElButton type="primary" :loading="sending" :disabled="saving" @click="handleSaveAndSend">发送绩效</ElButton>
</template>
<template v-else-if="showApprovalFooter">