import common from '../../utils/util'; import main from '../../utils/main'; import constant1 from '../../utils/constant'; Page({ data: { wordList: [], selectedWords: [], difficulty: 0, difficulties: constant1.arrHardLevel, generatedArticle: '', articleTranslation: '', generating: false, generatingImage: false, Content:"", }, onLoad: function(options) { let that=this; that.setData({ Containnerheight: main.getWindowHeight(), IsShowTranslate:false, }); if (options.words) { try { const wordList = options.words.split(","); this.setData({ wordList }); } catch (e) { wx.showToast({ title: '数据加载失败', icon: 'none' }); } } }, onDifficultyChange: function(e) { this.setData({ difficulty: Number(e.detail.value) }); }, generateArticle: async function() { let that=this; this.setData({ generating: true }); try { let url = common.Encrypt("GenerateArticle"); url="https://www.kylx365.com/apiData/"+url; let words=that.data.wordList; const cloudRes = await new Promise((resolve, reject) => { wx.request({ url: url, method: "POST", data: { Words:JSON.stringify(words), Level:that.data.difficulty }, success: resolve, fail: reject, }) }); console.log(cloudRes); let result=cloudRes.data.result.choices[0].message.content; let content=JSON.parse(result); for(let i=0;i { let punctuation = match.match(/[.,!?;:]$/); let punc = punctuation ? punctuation[0] : ''; let wordPart = match.replace(/[.,!?;:]$/, ''); return `${wordPart}${punc}`; }); } } content.ArticleEnglishStr=content.ArticleEnglish.join(""); for(let i=0;i { const canvas = res[0].node; const ctx = canvas.getContext('2d'); // 基本设置 canvas.width = 595; canvas.height = 842; const margin = 40; const lineHeight = 24; const articleWidth = canvas.width - 2 * margin; // 计算内容高度的函数 const calculateHeight = () => { let yPos = 40; // 标题高度 yPos += 40; // 文章高度 ctx.font = '16px Arial'; let articleText = that.data.Content.ArticleEnglish.join(" "); articleText = articleText.replace(/]*>(.*?)<\/span>/g, '###BOLD###$1###BOLD###'); const words = articleText.split(/\s+/); let lineWidth = 0; words.forEach(word => { if (!word) return; let wordToDraw = word.includes('###BOLD###') ? word.replace(/###BOLD###/g, '') : word; if (/[.,!?;:]$/.test(wordToDraw)) { wordToDraw = wordToDraw.slice(0, -1); } const spaceWidth = ctx.measureText(' ').width; const wordWidth = ctx.measureText(wordToDraw).width; const puncWidth = /[.,!?;:]$/.test(word) ? ctx.measureText(word.slice(-1)).width : 0; if (lineWidth + wordWidth + puncWidth + (lineWidth > 0 ? spaceWidth : 0) > articleWidth) { yPos += lineHeight; lineWidth = 0; } lineWidth += wordWidth + puncWidth + (lineWidth > 0 ? spaceWidth : 0); }); yPos += lineHeight * 2; // 分隔线和问题标题高度 yPos += lineHeight * 2.5; // 问题高度 const questions = that.data.Content.Question; questions.forEach(question => { //debugger; // 问题文本高度 const questionText = question.QuestionEnglish || ''; let textWidth = 0; const words = questionText.split(' '); words.forEach(word => { const wordWidth = ctx.measureText(word + ' ').width; if (textWidth + wordWidth > articleWidth) { yPos += lineHeight; textWidth = wordWidth; } else { textWidth += wordWidth; } }); yPos += lineHeight; // 选项高度 if (question.OptionsEnglish && Array.isArray(question.OptionsEnglish)) { question.OptionsEnglish.forEach(option => { if (!option) return; textWidth = 20; // 选项缩进 const words = option.split(' '); words.forEach(word => { const wordWidth = ctx.measureText(word + ' ').width; if (textWidth + wordWidth > articleWidth) { yPos += lineHeight; textWidth = 20 + wordWidth; } else { textWidth += wordWidth; } }); yPos += lineHeight; }); } yPos += lineHeight / 2; }); return yPos + margin; }; // 计算所需高度 const requiredHeight = calculateHeight(); canvas.height = Math.max(842, requiredHeight); // 绘制背景 ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = '#000000'; ctx.textBaseline = 'top'; // 绘制标题 let yPos = 40; ctx.font = 'bold 20px Arial'; const title = that.data.Content.Title || "English Reading Practice"; const titleWidth = ctx.measureText(title).width; ctx.fillText(title, (canvas.width - titleWidth) / 2, yPos); yPos += 40; // 绘制文章 ctx.font = '16px Arial'; let articleText = that.data.Content.ArticleEnglish.join(" "); articleText = articleText.replace(/]*>(.*?)<\/span>/g, '###BOLD###$1###BOLD###'); const words = articleText.split(/\s+/); let xPos = margin; let lineWidth = 0; words.forEach(word => { if (!word) return; // 处理加粗和标点 let isBold = word.includes('###BOLD###'); let wordToDraw = isBold ? word.replace(/###BOLD###/g, '') : word; let punctuation = ''; if (/[.,!?;:]$/.test(wordToDraw)) { punctuation = wordToDraw.slice(-1); wordToDraw = wordToDraw.slice(0, -1); } // 设置字体 ctx.font = isBold ? 'bold 16px Arial' : '16px Arial'; // 计算宽度 const spaceWidth = ctx.measureText(' ').width; const wordWidth = ctx.measureText(wordToDraw).width; const puncWidth = punctuation ? ctx.measureText(punctuation).width : 0; const totalWidth = wordWidth + puncWidth; // 检查换行 if (lineWidth + totalWidth + (lineWidth > 0 ? spaceWidth : 0) > articleWidth) { xPos = margin; yPos += lineHeight; lineWidth = 0; } // 添加空格 if (lineWidth > 0) { xPos += spaceWidth; lineWidth += spaceWidth; } // 绘制单词 ctx.fillText(wordToDraw, xPos, yPos); // 绘制标点 if (punctuation) { ctx.font = '16px Arial'; ctx.fillText(punctuation, xPos + wordWidth, yPos); } xPos += totalWidth; lineWidth += totalWidth; }); // 添加分隔线 yPos += lineHeight * 2; ctx.beginPath(); ctx.moveTo(margin, yPos); ctx.lineTo(canvas.width - margin, yPos); ctx.stroke(); yPos += lineHeight; // 绘制问题标题 ctx.font = 'bold 16px Arial'; ctx.fillText("Reading Comprehension Questions:", margin, yPos); yPos += lineHeight * 1.5; // 绘制问题 const questions = that.data.Content.Question; questions.forEach((question, index) => { // 绘制问题 ctx.font = 'bold 16px Arial'; const questionText = `${index + 1}. ${question.QuestionEnglish || ''}`; const words = questionText.split(' '); let line = ''; let testLine = ''; words.forEach(word => { testLine = line + (line ? ' ' : '') + word; if (ctx.measureText(testLine).width > articleWidth) { ctx.fillText(line, margin, yPos); yPos += lineHeight; line = word; } else { line = testLine; } }); if (line) { ctx.fillText(line, margin, yPos); yPos += lineHeight; } // 绘制选项 ctx.font = '16px Arial'; if (question.OptionsEnglish && Array.isArray(question.OptionsEnglish)) { question.OptionsEnglish.forEach((option, optIndex) => { if (!option) return; const optionText = `${option}`; const optionWords = optionText.split(' '); line = ''; testLine = ''; optionWords.forEach(word => { testLine = line + (line ? ' ' : '') + word; if (ctx.measureText(testLine).width > articleWidth - 20) { ctx.fillText(line, margin + 20, yPos); yPos += lineHeight; line = word; } else { line = testLine; } }); if (line) { ctx.fillText(line, margin + 20, yPos); yPos += lineHeight; } }); } yPos += lineHeight / 2; }); // 保存图片 wx.canvasToTempFilePath({ canvas: canvas, width: canvas.width, height: canvas.height, destWidth: canvas.width * 2, destHeight: canvas.height * 2, fileType: 'jpg', quality: 0.9, success(res) { wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success() { wx.showToast({ title: '图片已保存到相册', icon: 'success', duration: 2000 }); that.setData({ generatingImage: false }); }, fail(err) { console.error('保存图片失败:', err); if (err.errMsg.indexOf('auth deny') >= 0 || err.errMsg.indexOf('authorize') >= 0) { wx.showModal({ title: '提示', content: '需要您授权保存图片到相册', showCancel: false, success() { wx.openSetting({ success(res) { console.log('设置结果', res); } }); } }); } else { wx.showToast({ title: '保存图片失败', icon: 'none' }); } that.setData({ generatingImage: false }); } }); }, fail(err) { console.error('生成图片失败:', err); wx.showToast({ title: '生成图片失败', icon: 'none' }); that.setData({ generatingImage: false }); } }); }); } catch (error) { console.error('生成图片过程出错:', error); wx.showToast({ title: '生成图片失败', icon: 'none' }); this.setData({ generatingImage: false }); } } });