diff --git a/src/api/base/wjApi.ts b/src/api/base/wjApi.ts index 714ea7e..b86aa40 100644 --- a/src/api/base/wjApi.ts +++ b/src/api/base/wjApi.ts @@ -74,3 +74,17 @@ export const questionnaireAnalyzeWithAIApi = async (params: any) => { return await post("/api/questionnaireAnswer/analyzeWithAI", params); }; +/** + * 保存问卷AI分析结果 + */ +export const questionnaireAnalysisSaveApi = async (params: any) => { + return await post("/api/questionnaireAnalysis/save", params); +}; + +/** + * 查询问卷AI分析结果(分页) + */ +export const questionnaireAnalysisFindPageApi = async (params: any) => { + return await get("/api/questionnaireAnalysis/findPage", params); +}; + diff --git a/src/pages.json b/src/pages.json index 05769a3..72b58a2 100644 --- a/src/pages.json +++ b/src/pages.json @@ -157,6 +157,13 @@ "enablePullDownRefresh": false } }, + { + "path": "pages/base/wj/wjEvaluate", + "style": { + "navigationBarTitleText": "AI分析", + "enablePullDownRefresh": false + } + }, { "path": "pages/base/xk/index", "style": { diff --git a/src/pages/base/wj/indexwb.vue b/src/pages/base/wj/indexwb.vue index 027619c..d21012b 100644 --- a/src/pages/base/wj/indexwb.vue +++ b/src/pages/base/wj/indexwb.vue @@ -284,28 +284,17 @@ {{ formatTime(new Date()) }} 您已成功提交问卷 - - - - - - AI分析中,请稍候... - - - - - - - AI分析报告 - - - {{ analysisResult }} - - + + @@ -327,6 +316,19 @@ 已填写 您已经填写过此问卷 + + + + + + + @@ -352,7 +354,7 @@ import { questionnaireQuestionFindPageApi, questionnaireAnswerSaveApi, questionnaireAnswerFindByUserApi, - questionnaireAnalyzeWithAIApi + questionnaireAnswerFindDetailApi } from '@/api/base/wjApi'; import { useUserStore } from '@/store/modules/user'; import { attachmentUpload } from '@/api/system/upload'; @@ -394,10 +396,6 @@ const fileUploadData = reactive(null); const signTitle = ref("问卷签名"); @@ -405,6 +403,14 @@ const sign_file = ref(""); const showSignature = ref(false); const currentSignatureQuestionId = ref(""); // 当前正在签名的题目ID +// 提交批次ID,用于查看AI分析报告 +const submitId = ref(''); + +// 控制是否显示AI智能分析按钮 +const showAIAnalysisButton = ref(false); +// 控制是否允许重复提交 +const allowResubmit = ref(false); + onLoad(async (params) => { options.value = params; openId.value = params?.openId || ''; @@ -445,6 +451,17 @@ const initializePage = async () => { const questionnaireResult = await questionnaireFindByIdApi({ id: questionnaireId.value }); if (questionnaireResult && questionnaireResult.resultCode === 1) { questionnaireInfo.value = questionnaireResult.result || questionnaireResult.data; + console.log('【问卷信息】questionnaireInfo.value:', questionnaireInfo.value); + console.log('【allowAnalysis值】', questionnaireInfo.value?.allowAnalysis); + // 判断是否显示AI智能分析按钮:如果 allowAnalysis = 1,则显示(兼容字符串和数字) + const allowAnalysisValue = questionnaireInfo.value?.allowAnalysis; + showAIAnalysisButton.value = allowAnalysisValue === 1 || allowAnalysisValue === '1'; + console.log('【是否显示AI按钮】showAIAnalysisButton.value:', showAIAnalysisButton.value); + + // 判断是否允许重复提交:如果 allowResubmit = 1,则允许(兼容字符串和数字) + const allowResubmitValue = questionnaireInfo.value?.allowResubmit; + allowResubmit.value = allowResubmitValue === 1 || allowResubmitValue === '1'; + console.log('【是否允许重复提交】allowResubmit.value:', allowResubmit.value); } else { throw new Error('获取问卷信息失败'); } @@ -481,8 +498,8 @@ const initializePage = async () => { throw new Error('检查权限失败'); } - // 4. 检查是否已填写 - if (questionnaireInfo.value.allowResubmit !== 1) { + // 4. 检查是否已填写(如果不允许重复提交) + if (!allowResubmit.value) { const answerResult = await questionnaireAnswerFindByUserApi({ questionnaireId: questionnaireId.value }); @@ -577,6 +594,11 @@ const initializePage = async () => { }; } }); + + // 6. 如果允许重复提交,尝试加载已填写的答案进行回显 + if (allowResubmit.value) { + await loadExistingAnswers(allQuestions); + } } currentStep.value = 'fill'; @@ -1074,6 +1096,11 @@ const doSubmitQuestionnaire = async () => { const result = await questionnaireAnswerSaveApi(submitParams); if (result && result.resultCode === 1) { + // 保存 submitId(从返回结果中获取) + const resultData = result.result || result.data || {}; + if (resultData.submitId) { + submitId.value = resultData.submitId; + } currentStep.value = 'success'; } else { throw new Error(result?.message || '提交失败'); @@ -1102,70 +1129,117 @@ const formatTime = (time: string | Date) => { }); }; -// AI分析函数 -const analyzeWithAI = async () => { +// 查看AI分析报告 +const viewAIAnalysisReport = () => { + // 获取当前用户ID + const currentUserId = userStore.userdata?.id || userStore.userdata?.userId || ''; + // 直接跳转到分析页面,由分析页面负责调用AI接口并保存结果 + uni.navigateTo({ + url: `/pages/base/wj/wjEvaluate?questionnaireId=${questionnaireId.value}&userId=${currentUserId}` + }); +}; + +// 加载已填写的答案(用于回显) +const loadExistingAnswers = async (allQuestions: any[]) => { try { - analyzing.value = true; - analysisResult.value = ''; + // 获取当前用户ID + const currentUserId = userStore.userdata?.id || userStore.userdata?.userId || ''; + if (!currentUserId) { + console.log('未找到用户ID,跳过加载已填写答案'); + return; + } - // 构造发送给AI的问卷数据,包含所有分页的题目 - const allQuestions: any[] = []; - pageList.value.forEach(page => { - allQuestions.push(...page.questions); + // 获取已填写的答案 + const answerResult = await questionnaireAnswerFindDetailApi({ + questionnaireId: questionnaireId.value, + userId: currentUserId }); - const questionnaireData = { - questionnaireId: questionnaireId.value, - title: questionnaireInfo.value?.title, - description: questionnaireInfo.value?.description, - questions: allQuestions.map((q: any) => { - let answerValue = answers[q.id]?.value; + if (answerResult && answerResult.resultCode === 1) { + const answerList = answerResult.result || answerResult.data || []; + if (answerList && answerList.length > 0) { + console.log('找到已填写的答案,开始回显:', answerList); - // 处理不同类型的答案格式 - if (q.questionType === 'CHECKBOX' && Array.isArray(answerValue)) { - answerValue = answerValue.join(','); - } else if (q.questionType === 'FILE') { - const uploadData = fileUploadData[q.id]; - const imageUrls = (uploadData?.imageList || []).filter(img => img.url).map(img => img.url); - const fileUrls = (uploadData?.fileList || []).filter(file => file.url).map(file => file.url); - answerValue = [...imageUrls, ...fileUrls].join(','); - } else if (q.questionType === 'VIDEO') { - const uploadData = fileUploadData[q.id]; - const videoUrls = (uploadData?.videoList || []).filter(video => video.url).map(video => video.url); - answerValue = videoUrls.join(','); - } else if (q.questionType === 'SIGNATURE') { - answerValue = answerValue ? '[已签名]' : '[未签名]'; - } + // 将答案按题目ID建立映射 + const answerMap = new Map(); + answerList.forEach((answer: any) => { + answerMap.set(answer.questionId, answer); + }); - // 获取分页名称和排序 - const pageName = q.pageName || '第一部分'; - const pageSortOrder = q.pageSortOrder !== undefined ? q.pageSortOrder : 0; + // 回显答案到表单 + allQuestions.forEach((question: any) => { + const existingAnswer = answerMap.get(question.id); + if (existingAnswer && existingAnswer.answerContent) { + const answerContent = existingAnswer.answerContent; + + if (question.questionType === 'CHECKBOX') { + // 多选框:逗号分隔的字符串转为数组 + if (answerContent) { + answers[question.id].value = answerContent.split(',').map((v: string) => v.trim()).filter((v: string) => v); + } + } else if (question.questionType === 'FILE') { + // 文件类型:解析URL字符串 + if (answerContent) { + const urls = answerContent.split(',').map((v: string) => v.trim()).filter((v: string) => v); + const imageUrls: string[] = []; + const fileUrls: string[] = []; + + urls.forEach((url: string) => { + const lowerUrl = url.toLowerCase(); + // 判断是图片还是文档 + if (lowerUrl.match(/\.(jpg|jpeg|png|gif|bmp|webp)$/i)) { + imageUrls.push(url); + } else { + fileUrls.push(url); + } + }); + + // 设置到文件上传数据 + if (fileUploadData[question.id]) { + fileUploadData[question.id].imageList = imageUrls.map(url => ({ url, name: url.split('/').pop() || '' })); + fileUploadData[question.id].fileList = fileUrls.map(url => ({ url, name: url.split('/').pop() || '' })); + } + } + } else if (question.questionType === 'VIDEO') { + // 视频类型:解析URL字符串 + if (answerContent) { + const urls = answerContent.split(',').map((v: string) => v.trim()).filter((v: string) => v); + if (fileUploadData[question.id]) { + fileUploadData[question.id].videoList = urls.map(url => ({ url, name: url.split('/').pop() || '' })); + } + } + } else if (question.questionType === 'SIGNATURE') { + // 签名类型:直接使用base64字符串 + answers[question.id].value = answerContent; + } else { + // 其他类型(TEXT, TEXTAREA, NUMBER, DATE, RADIO, SELECT):直接赋值 + answers[question.id].value = answerContent; + } + } + }); - return { - content: q.questionContent, - type: q.questionType, - answer: answerValue || '[未填写]', - pageName: pageName, - pageSortOrder: pageSortOrder - }; - }) - }; - - // 调用后端AI分析接口 - const response = await questionnaireAnalyzeWithAIApi(questionnaireData); - - if (response && response.resultCode === 1) { - analysisResult.value = response.result || response.data || '分析完成'; - } else { - throw new Error(response?.message || 'AI分析失败'); + // 如果有问卷级别的签名,也需要回显 + // 注意:问卷级别的签名可能不在答案列表中,需要单独处理 + // 这里暂时不处理,因为签名通常存储在单独的字段中 + + console.log('答案回显完成'); + } else { + console.log('未找到已填写的答案'); + } } } catch (error: any) { - console.error('AI分析失败:', error); - uni.showToast({ title: error.message || 'AI分析失败,请稍后重试', icon: 'none', duration: 2000 }); - } finally { - analyzing.value = false; + console.error('加载已填写答案失败:', error); + // 加载失败不影响主流程,继续显示空白表单 } }; + +// 重新填写问卷 +const handleResubmit = async () => { + // 重置状态,允许重新填写 + currentStep.value = 'fill'; + // 重新初始化页面(会自动加载并回显已填写的答案) + await initializePage(); +}; +