article.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. import common from '../../utils/util';
  2. import main from '../../utils/main';
  3. import animation from '../../utils/animation';
  4. const Theme=[{
  5. "Name":"DarkColor",
  6. "backgroundColor": "#004433",
  7. "color":"#C1E1C1",
  8. "frontColor": '#ffffff',
  9. },{
  10. "Name":"LightColor",
  11. "backgroundColor": "#D0ECD3",
  12. "color":"#151815",
  13. "frontColor": '#000000',
  14. }
  15. ];
  16. const app = getApp();
  17. Page({
  18. data: {
  19. Words:"",
  20. IsShowFirstOpen:true,
  21. IsBuilding:false,
  22. IsBuildError:false,
  23. IsShowLightColor:false,
  24. IsShowKeyword:true,//显示关键词
  25. IsShowQuestion:false,
  26. IsShowTranslate:false,
  27. IsShowSetting:false,
  28. IsShowRemind:false,
  29. remindAnimation: "", // 翻译弹窗动画类
  30. CurrentQuestionIndex:0,
  31. swiperHeight: "526rpx",
  32. lastTapTime: 0, // 记录上一次点击的时间,用于检测双击
  33. CountDown:30,//倒计时秒数
  34. },
  35. onLoad: function (options) {
  36. let that = this;
  37. let words=app.globalData.SelectedWords.join(",");
  38. let wordsStr=app.globalData.SelectedWords.join(" ");
  39. const hiddenhelp=wx.getStorageSync('HiddenArticleFirstOpen');
  40. let IsShowKeyword=wx.getStorageSync('IsShowKeyword');
  41. if (IsShowKeyword===""){
  42. IsShowKeyword=true;
  43. wx.setStorageSync('IsShowKeyword', true);
  44. }
  45. let IsShowLightColor=wx.getStorageSync('IsShowLightColor');
  46. if (!IsShowLightColor){
  47. IsShowLightColor=false;
  48. }
  49. that.setData({
  50. Containnerheight: main.getWindowHeight(),
  51. Words:words,
  52. WordsStr:wordsStr,
  53. IsShowFirstOpen:!hiddenhelp,
  54. IsShowLightColor:IsShowLightColor,
  55. IsShowKeyword:IsShowKeyword,
  56. IsBuildError:false,
  57. Level:options.Level,
  58. ArticleStyle:options.ArticleStyle,
  59. IsBuilding:false,
  60. });
  61. if (options.ID)
  62. that.getArticleByID(options.ID);
  63. else
  64. that.init(options);
  65. that.setTheme();
  66. },
  67. getArticleByID:function(id){
  68. let that=this;
  69. main.getData('GetYJBDCArticleList?UserID=' + app.globalData.userInfo.UserID+'&ID='+id, function (data) {
  70. if (data) {
  71. data=data[0];
  72. that.setData({
  73. Words:data.Words,
  74. Level:data.Level,
  75. ArticleStyle:data.ArticleStyle,
  76. CreateTime:data.CreateTime,
  77. ID:id,
  78. });
  79. let content=data.JSONString;
  80. that.updateData(content);
  81. }
  82. });
  83. },
  84. init:function(options){
  85. let that=this;
  86. let interval=0;
  87. //小学初中文章生成时间短
  88. that.data.CountDown=30;
  89. //高中大学文章生成时间长
  90. if (that.data.Level>=2){
  91. that.setData({
  92. CountDown:60,
  93. });
  94. }
  95. interval = setInterval(function(){
  96. that.setData({
  97. CountDown:--that.data.CountDown,
  98. });
  99. if (that.data.CountDown<=0)
  100. clearInterval(interval);
  101. },1200);
  102. that.setData({
  103. IsBuilding:true
  104. });
  105. let words=app.globalData.SelectedWords.join(",");
  106. main.postData('GenerateArticle?UserID='+app.globalData.userInfo.UserID, {
  107. Words:words,
  108. Level:that.data.Level,
  109. ArticleStyle:that.data.ArticleStyle
  110. }, function (data) {
  111. if (data){
  112. if (data=="-1"){
  113. that.setData({
  114. IsBuildError:true,
  115. CreateTime:common.formatDateCHS(common.formatTime(new Date()),true),
  116. });
  117. }
  118. else{
  119. let content=data;
  120. that.updateData(content);
  121. that.setData({
  122. IsBuilding:false,
  123. });
  124. }
  125. clearInterval(interval);
  126. }
  127. });
  128. },
  129. updateData:function(content){
  130. let that=this;
  131. //console.log(content);
  132. if (typeof content === 'string') {
  133. content = JSON.parse(content);
  134. }
  135. if (typeof content === 'string') {
  136. content = JSON.parse(content);
  137. }
  138. let hl = that.data.IsShowKeyword ? "highlight" : "nonelight";
  139. // 初始化ArticleEnglishArr数组
  140. content.ArticleEnglishArr = [];
  141. for(let i=0; i<content.ArticleEnglish.length; i++){
  142. // 确保每个句子末尾有空格,避免和下一句紧挨着
  143. const sentence = content.ArticleEnglish[i] + " ";
  144. // 按长度从长到短排序单词,确保先匹配较长的词组
  145. const sortedWords = [...content.FormsOfWords].sort((a, b) => b.length - a.length);
  146. // 创建一个句子的分段数组
  147. let segments = [{
  148. Sentence: sentence,
  149. CSS: ""
  150. }];
  151. // 对每个单词进行处理
  152. for(let j=0; j<sortedWords.length; j++){
  153. const word = sortedWords[j];
  154. // 创建一个新的分段数组,用于存储处理后的结果
  155. let newSegments = [];
  156. // 处理每个现有分段
  157. for(let k=0; k<segments.length; k++){
  158. const segment = segments[k];
  159. // 如果当前分段已经被标记为高亮,则不再处理
  160. if(segment.CSS !== ""){
  161. newSegments.push(segment);
  162. continue;
  163. }
  164. const text = segment.Sentence;
  165. // 使用正则表达式查找单词边界
  166. const regex = new RegExp(`\\b${word}\\b`, 'gi');
  167. let lastIndex = 0;
  168. let match;
  169. // 查找所有匹配项
  170. while((match = regex.exec(text)) !== null){
  171. // 添加匹配前的文本
  172. if(match.index > lastIndex){
  173. newSegments.push({
  174. Sentence: text.substring(lastIndex, match.index),
  175. CSS: ""
  176. });
  177. }
  178. // 添加匹配的单词(高亮)
  179. newSegments.push({
  180. Sentence: match[0],
  181. CSS: hl
  182. });
  183. lastIndex = match.index + match[0].length;
  184. }
  185. // 添加最后一个匹配后的文本
  186. if(lastIndex < text.length){
  187. newSegments.push({
  188. Sentence: text.substring(lastIndex),
  189. CSS: ""
  190. });
  191. }
  192. }
  193. // 更新分段数组
  194. segments = newSegments;
  195. }
  196. // 将分段数组添加到ArticleEnglishArr
  197. content.ArticleEnglishArr.push(segments);
  198. }
  199. for(let i=0;i<content.Question.length;i++){
  200. for(let j=0;j<content.Question[i].OptionsEnglish.length;j++){
  201. let str=content.Question[i].OptionsChinese[j];
  202. content.Question[i].OptionsChinese[j]=str.substr(2);
  203. }
  204. let char = content.Question[i].Answer;
  205. let asciiCode = char.charCodeAt(0);
  206. content.Question[i].AnswerNumber=asciiCode-65;
  207. content.Question[i].IsShowAnswer=false;
  208. }
  209. that.setData({
  210. Content:content,
  211. });
  212. },
  213. setTheme:function(){
  214. let that=this;
  215. const css=Theme[that.data.IsShowLightColor?1:0];
  216. wx.setNavigationBarColor({
  217. frontColor: css.frontColor,
  218. backgroundColor: css.backgroundColor,
  219. });
  220. wx.setBackgroundColor({
  221. backgroundColor: css.backgroundColor,
  222. backgroundColorTop:css.backgroundColor,
  223. backgroundColorBottom:css.backgroundColor,
  224. });
  225. that.setData({
  226. ThemeCSS:css.Name,
  227. });
  228. wx.setStorageSync('IsShowLightColor', that.data.IsShowLightColor);
  229. },
  230. closeHelp:function(){
  231. this.setData({
  232. IsShowFirstOpen:false,
  233. });
  234. wx.setStorageSync('HiddenArticleFirstOpen', true);
  235. },
  236. selectedAnswer:function(e){
  237. let that=this;
  238. const question=e.currentTarget.dataset.question;
  239. const index=e.currentTarget.dataset.index;
  240. if (that.data.Content.Question[question].UserAnswer==index)
  241. that.data.Content.Question[question].UserAnswer=-1;
  242. else
  243. that.data.Content.Question[question].UserAnswer=index;
  244. that.setData({
  245. Content:that.data.Content,
  246. });
  247. },
  248. showData:function(e){
  249. let that=this;
  250. let name=e.currentTarget.dataset.name;
  251. this.data[name] = !this.data[name];
  252. this.setData(this.data);
  253. if (name=="IsShowKeyword"){
  254. that.setShowKeyword();
  255. }
  256. else if (name=="IsShowLightColor"){
  257. that.setTheme();
  258. }
  259. else if (name=="IsShowAnswer"){
  260. let index=e.currentTarget.dataset.index;
  261. let content=that.data.Content;
  262. content.Question[index].IsShowAnswer=!content.Question[index].IsShowAnswer;
  263. that.setData({
  264. Content:content,
  265. });
  266. }
  267. },
  268. setShowKeyword:function(){
  269. let that=this;
  270. let content=that.data.Content;
  271. let source="highlight",target="nonelight";
  272. if (that.data["IsShowKeyword"]){
  273. source="nonelight";
  274. target="highlight";
  275. }
  276. for(let i=0;i<content.ArticleEnglishArr.length;i++){
  277. let obj=content.ArticleEnglishArr[i];
  278. let arr=[];
  279. for(let j=0;j<obj.length;j++){
  280. if (obj[j].CSS==source)
  281. obj[j].CSS=target;
  282. }
  283. }
  284. for(let i=0;i<content.ArticleEnglish.length;i++){
  285. content.ArticleEnglish[i]=common.ReplaceAllString(content.ArticleEnglish[i],source,target);
  286. }
  287. that.setData({
  288. Content:content,
  289. });
  290. wx.setStorageSync('IsShowKeyword', that.data.IsShowKeyword);
  291. },
  292. nextQuestion:function(e){
  293. if (this.data.CurrentQuestionIndex+1<this.data.Content.Question.length){
  294. this.data.CurrentQuestionIndex=this.data.CurrentQuestionIndex+1;
  295. this.setData({
  296. CurrentQuestionIndex:this.data.CurrentQuestionIndex,
  297. });
  298. }
  299. },
  300. updateQuestionIndex:function(e){
  301. this.setData({
  302. CurrentQuestionIndex:e.detail.current,
  303. });
  304. console.log(e.detail.current);
  305. },
  306. onContainerTap: function() {
  307. const currentTime = new Date().getTime();
  308. const lastTapTime = this.data.lastTapTime;
  309. const timeDiff = currentTime - lastTapTime;
  310. // 如果两次点击的时间间隔小于300毫秒,则认为是双击
  311. if (timeDiff < 300 && timeDiff > 0) {
  312. console.log('双击事件触发');
  313. // 在这里添加双击事件的处理逻辑
  314. // 例如:切换翻译显示状态
  315. this.showData({currentTarget:{dataset:{name:"IsShowTranslate"}}});
  316. }
  317. // 更新上一次点击的时间
  318. this.setData({
  319. lastTapTime: currentTime
  320. });
  321. },
  322. //生成PDF文件
  323. //访问服务器的GeneratePDF接口,提交this.data.Content数据,获得一个生成好的pdf文件,服务端的代码已经生成好
  324. generatePDF: function(e) {
  325. let that = this;
  326. //debugger;
  327. that.data.Content.Words=that.data.Words;
  328. that.data.Content.Level=that.data.Level;
  329. that.data.Content.ArticleStyle=that.data.ArticleStyle;
  330. that.data.Content.CreateTime=that.data.CreateTime;
  331. let url = common.Encrypt("GeneratePDF");
  332. url =app.globalData.serverUrl + url;
  333. wx.request({
  334. url: url,
  335. method: "POST",
  336. data: {
  337. Content: that.data.Content,
  338. },
  339. responseType: 'arraybuffer', // 确保响应类型为arraybuffer
  340. success: function(res) {
  341. // 将arraybuffer转为临时文件
  342. const fsm = wx.getFileSystemManager();
  343. const tempFilePath = `${wx.env.USER_DATA_PATH}/temp_${Date.now()}.pdf`;
  344. try {
  345. fsm.writeFileSync(
  346. tempFilePath,
  347. res.data,
  348. 'binary'
  349. );
  350. // 直接使用临时文件路径,不再尝试永久保存
  351. console.log('文件已生成:', tempFilePath);
  352. // 打开PDF文件预览
  353. wx.openDocument({
  354. filePath: tempFilePath,
  355. fileType: 'pdf',
  356. showMenu: true, // 显示右上角菜单,可以分享
  357. success: function() {
  358. },
  359. fail: function(error) {
  360. console.error('打开文档失败:', error);
  361. wx.showToast({
  362. title: '打开文件失败',
  363. icon: 'none'
  364. });
  365. }
  366. });
  367. } catch (error) {
  368. console.error('写入文件失败:', error);
  369. wx.showToast({
  370. title: '写入文件失败',
  371. icon: 'none'
  372. });
  373. }
  374. },
  375. fail: function(err) {
  376. console.error('请求GeneratePDF接口失败:', err);
  377. wx.showToast({
  378. title: '网络错误,请稍候重试',
  379. icon: 'none'
  380. });
  381. }
  382. });
  383. },
  384. // 处理导航栏返回按钮点击事件
  385. back: function() {
  386. if (this.data.IsBuilding) {
  387. return; // 如果正在生成文章,不执行返回操作
  388. }
  389. if (!this.data.ID){
  390. wx.navigateBack({
  391. delta: 1,
  392. });
  393. }
  394. },
  395. onLongPress: function(e) {
  396. let that = this;
  397. let strType=e.currentTarget.dataset.strtype;
  398. let selectedIndex=e.currentTarget.dataset.index;
  399. let selectedIndex2=e.currentTarget.dataset.index2;
  400. let engSentence,chnSentence;
  401. if (strType=="article"){
  402. //console.log("选中的句子索引:", selectedIndex);
  403. //console.log("选中的句子:", that.data.Content.ArticleEnglish[selectedIndex]);
  404. engSentence=that.data.Content.ArticleEnglish[selectedIndex];
  405. chnSentence=that.data.Content.ArticleChinese[selectedIndex];
  406. }
  407. else if (strType=="question"){
  408. engSentence=that.data.Content.Question[selectedIndex].QuestionEnglish;
  409. chnSentence=that.data.Content.Question[selectedIndex].QuestionChinese;
  410. }
  411. else if (strType=="option"){
  412. engSentence=that.data.Content.Question[selectedIndex].OptionsEnglish[selectedIndex2];
  413. chnSentence=that.data.Content.Question[selectedIndex].OptionsChinese[selectedIndex2];
  414. }
  415. this.setData({
  416. EnglishSentence:engSentence,
  417. ChineseSentence:chnSentence,
  418. });
  419. // 使用动画工具函数显示弹窗,并指定显示动画
  420. animation.toggleRemindWithAnimation(this, {
  421. showAnimation: 'remind-slide-up'
  422. });
  423. },
  424. showRemind:function(e){
  425. animation.toggleRemindWithAnimation(this, {
  426. showAnimation: 'remind-slide-down'
  427. });
  428. },
  429. onShareAppMessage: function () {
  430. return {
  431. title: app.globalData.ShareTitle,
  432. path: app.globalData.SharePath + '?UserID=' + app.globalData.userInfo.UserID,
  433. imageUrl: app.globalData.ShareImage,
  434. }
  435. },
  436. })