174 lines
5.2 KiB
Plaintext
174 lines
5.2 KiB
Plaintext
<template>
|
||
<cl-page title="提交月报">
|
||
<view class="p-4">
|
||
<!-- 月份选择 -->
|
||
<view class="mb-4">
|
||
<text class="text-base font-bold mb-2">月份</text>
|
||
<cl-input v-model="form.month" placeholder="例如:2025-11" />
|
||
</view>
|
||
|
||
<!-- 原始内容输入 -->
|
||
<view class="mb-4">
|
||
<text class="text-base font-bold mb-2">工作内容(可选)</text>
|
||
<cl-input v-model="originalText" placeholder="请输入本月工作要点(可选)" :maxlength="4000" />
|
||
</view>
|
||
|
||
<!-- 从周报生成 -->
|
||
<view class="mb-4">
|
||
<cl-button type="primary" size="large" block @tap="generateFromWeekly" :loading="isGenerating">
|
||
{{ isGenerating ? '生成中...' : '🧩 从我的周报生成' }}
|
||
</cl-button>
|
||
</view>
|
||
|
||
<!-- AI格式化 -->
|
||
<view v-if="originalText" class="mb-4">
|
||
<cl-button type="success" size="large" block @tap="formatWithAI" :loading="isFormatting">
|
||
{{ isFormatting ? 'AI生成中...' : '🤖 AI格式化' }}
|
||
</cl-button>
|
||
</view>
|
||
|
||
<!-- AI结果与最终编辑 -->
|
||
<view v-if="aiFormattedContent" class="mb-4">
|
||
<text class="text-base font-bold mb-2">AI生成的月报</text>
|
||
<view class="p-3 bg-green-50 rounded-lg mb-2"><cl-markdown :content="aiFormattedContent" /></view>
|
||
<cl-input v-model="userEditedContent" placeholder="请编辑最终月报内容" :maxlength="6000" />
|
||
</view>
|
||
|
||
<!-- 操作按钮 -->
|
||
<view class="flex gap-3">
|
||
<cl-button type="default" class="flex-1" @tap="saveDraft" :loading="saving">保存草稿</cl-button>
|
||
<cl-button type="primary" class="flex-1" @tap="submitReport" :loading="submitting">提交</cl-button>
|
||
</view>
|
||
</view>
|
||
</cl-page>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, onMounted } from 'vue';
|
||
import { request, useStore, router } from '@/cool';
|
||
import { useUi } from '@/uni_modules/cool-ui';
|
||
|
||
const ui = useUi();
|
||
const { user } = useStore();
|
||
|
||
const form = ref<any>({ month: '' });
|
||
const originalText = ref('');
|
||
const aiFormattedContent = ref('');
|
||
const userEditedContent = ref('');
|
||
const isFormatting = ref(false);
|
||
const isGenerating = ref(false);
|
||
const saving = ref(false);
|
||
const submitting = ref(false);
|
||
|
||
onMounted(async () => {
|
||
if (user.token) {
|
||
try { await user.get(); } catch {}
|
||
}
|
||
});
|
||
|
||
function ensureMonth(): string | null {
|
||
const v = (form.value.month || '').trim();
|
||
if (!/^\d{4}-\d{2}$/.test(v)) {
|
||
ui.showToast({ message: '请输入有效月份,如 2025-11', type: 'error' });
|
||
return null;
|
||
}
|
||
return v;
|
||
}
|
||
|
||
async function generateFromWeekly() {
|
||
const month = ensureMonth();
|
||
if (!month) return;
|
||
if (!user.info.value?.id) {
|
||
ui.showToast({ message: '请先登录', type: 'error' });
|
||
router.to('/pages/user/login');
|
||
return;
|
||
}
|
||
try {
|
||
isGenerating.value = true;
|
||
const res = await request({
|
||
url: '/app/monthlyreport/report/generateFromWeekly',
|
||
method: 'POST',
|
||
data: {
|
||
userId: user.info.value.id,
|
||
month,
|
||
templateKey: 'monthly_report_format'
|
||
}
|
||
});
|
||
aiFormattedContent.value = res.formattedContent || '';
|
||
userEditedContent.value = aiFormattedContent.value;
|
||
} catch (e: any) {
|
||
ui.showToast({ message: e.message || '生成失败', type: 'error' });
|
||
} finally {
|
||
isGenerating.value = false;
|
||
}
|
||
}
|
||
|
||
async function formatWithAI() {
|
||
const month = ensureMonth();
|
||
if (!month) return;
|
||
try {
|
||
isFormatting.value = true;
|
||
const res = await request({
|
||
url: '/app/monthlyreport/report/aiFormat',
|
||
method: 'POST',
|
||
data: { originalText: originalText.value, templateKey: 'monthly_report_format', month }
|
||
});
|
||
aiFormattedContent.value = res.formattedContent || '';
|
||
userEditedContent.value = aiFormattedContent.value;
|
||
} catch (e: any) {
|
||
ui.showToast({ message: e.message || 'AI格式化失败', type: 'error' });
|
||
} finally {
|
||
isFormatting.value = false;
|
||
}
|
||
}
|
||
|
||
async function saveDraft() {
|
||
const month = ensureMonth();
|
||
if (!month || !user.info.value?.id) return;
|
||
try {
|
||
saving.value = true;
|
||
await request({
|
||
url: '/app/monthlyreport/report/saveDraft',
|
||
method: 'POST',
|
||
data: {
|
||
userId: user.info.value.id,
|
||
month,
|
||
originalText: originalText.value,
|
||
aiFormattedContent: aiFormattedContent.value,
|
||
userEditedContent: userEditedContent.value,
|
||
inputType: 0
|
||
}
|
||
});
|
||
ui.showToast({ message: '已保存草稿', type: 'success' });
|
||
} catch (e: any) {
|
||
ui.showToast({ message: e.message || '保存失败', type: 'error' });
|
||
} finally { saving.value = false; }
|
||
}
|
||
|
||
async function submitReport() {
|
||
const month = ensureMonth();
|
||
if (!month || !user.info.value?.id) return;
|
||
try {
|
||
submitting.value = true;
|
||
await request({
|
||
url: '/app/monthlyreport/report/submit',
|
||
method: 'POST',
|
||
data: {
|
||
userId: user.info.value.id,
|
||
month,
|
||
originalText: originalText.value,
|
||
aiFormattedContent: aiFormattedContent.value,
|
||
userEditedContent: userEditedContent.value,
|
||
inputType: 0
|
||
}
|
||
});
|
||
ui.showToast({ message: '提交成功', type: 'success' });
|
||
router.back();
|
||
} catch (e: any) {
|
||
ui.showToast({ message: e.message || '提交失败', type: 'error' });
|
||
} finally { submitting.value = false; }
|
||
}
|
||
</script>
|
||
|
||
<style scoped></style>
|