| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- 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<content.ArticleEnglish.length;i++){
- for(let j=0;j<content.FormsOfWords.length;j++){
- let word = content.FormsOfWords[j];
- let regex = new RegExp(`\\b${word}\\b[.,!?;:]?`, 'gi');
- content.ArticleEnglish[i] = content.ArticleEnglish[i].replace(regex, match => {
- let punctuation = match.match(/[.,!?;:]$/);
- let punc = punctuation ? punctuation[0] : '';
- let wordPart = match.replace(/[.,!?;:]$/, '');
- return `<span class='highlight'>${wordPart}</span>${punc}`;
- });
- }
- }
- content.ArticleEnglishStr=content.ArticleEnglish.join("");
- for(let i=0;i<content.Question.length;i++){
- for(let j=0;j<content.Question[i].OptionsEnglish.length;j++){
- let str=content.Question[i].OptionsChinese[j];
- content.Question[i].OptionsChinese[j]=str.substr(2);
- }
- }
- this.setData({
- Content:content,
- generating: false
- });
- } catch (error) {
- console.error('生成文章失败:', error);
- wx.showToast({
- title: '生成文章失败',
- icon: 'none'
- });
- this.setData({ generating: false });
- }
- },
- showTranslate:function(e){
- this.setData({
- IsShowTranslate:!this.data.IsShowTranslate,
- })
- },
- generateImage: async function() {
- const that = this;
- this.setData({ generatingImage: true });
-
- try {
- const query = wx.createSelectorQuery();
- query.select('#articleCanvas')
- .fields({ node: true, size: true })
- .exec((res) => {
- 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[^>]*>(.*?)<\/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[^>]*>(.*?)<\/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 });
- }
- }
- });
|