send_memos.html 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
  6. <title>memos记录</title>
  7. <!-- 引入Quill样式 -->
  8. <link rel="stylesheet" href="./js/quill.snow.css">
  9. <script src="js/util.js"></script>
  10. <style>
  11. #editor {
  12. height: 150px;
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <a href="https://memos.tianyunperfect.cn/">memos主页</a><br><br>
  18. <div></div>
  19. <!-- 创建一个用于编辑的容器 -->
  20. <div id="editor"></div>
  21. <!-- 添加多选按钮 -->
  22. <div id="tags"></div>
  23. <!--<input type="checkbox" id="todo" name="category" value="todo" checked> <label for="todo">todo</label>-->
  24. <!--<input type="checkbox" id="work" name="category" value="工作">-->
  25. <!--<label for="work">工作</label>-->
  26. <!--<input type="checkbox" id="diary" name="category" value="日记">-->
  27. <!--<label for="diary">日记</label>-->
  28. <!--<input type="checkbox" id="dream" name="category" value="梦记">-->
  29. <!--<label for="dream">梦记</label>-->
  30. <!--<input type="checkbox" id="daily" name="category" value="日常">-->
  31. <!--<label for="daily">日常</label>-->
  32. <br>
  33. <br>
  34. <!-- 添加发送按钮 -->
  35. <button id="log" style="float: right; height: 100px;width: 200px; font-size: 40px" onclick="sendData()">记录</button>
  36. <!-- 引入Quill库 -->
  37. <script src="./js/cdn.quilljs.com_1.3.6_quill.js"></script>
  38. <!--异步请求示例:requestUtil.sync('https://jsonplaceholder.typicode.com/posts/1', 'post', data, headers) .then(data => console.log(data))-->
  39. <script>
  40. let authStr = "bearer eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0.eyJuYW1lIjoidGlhbnl1bnBlcmZlY3QiLCJpc3MiOiJtZW1vcyIsInN1YiI6IjEiLCJhdWQiOlsidXNlci5hY2Nlc3MtdG9rZW4iXSwiaWF0IjoxNzA5MTc5NTUyfQ.LFxWB4efya1sL7VoJ42xpXxbAip-udT_Kx2OwZ8Y3-E";
  41. let myHeaders = {
  42. 'Content-type': 'application/json',
  43. 'Authorization': authStr
  44. };
  45. // console.log(location.href)
  46. // console.log(location.href.indexOf(tag))
  47. // 设置多选按钮 标签
  48. requestUtil.async('https://memos.tianyunperfect.cn/api/v1/tag', 'get', null, {'Authorization': authStr}).then(res => {
  49. // console.log(res); ['tag1','tag2']
  50. // 在 id tags 里面拼接res数组 ,示例todo标签 <input type="checkbox" id="todo" name="category" value="todo" checked> <label for="todo">todo</label>
  51. let tags = document.getElementById('tags');
  52. res.forEach(tag => {
  53. let input = document.createElement('input');
  54. // 如果是location.href 包含tag,则设置为选中状态, href 要反编译以识别中文
  55. if (decodeURI(location.href).indexOf(tag) !== -1) {
  56. input.checked = true;
  57. }
  58. input.type = 'checkbox';
  59. input.id = tag;
  60. input.name = 'category';
  61. input.value = tag;
  62. let label = document.createElement('label');
  63. // 设置margin-right 20
  64. label.style.marginRight = '10px';
  65. label.htmlFor = tag;
  66. label.innerText = tag;
  67. tags.appendChild(input);
  68. tags.appendChild(label);
  69. });
  70. });
  71. const quill = new Quill('#editor', {
  72. theme: 'snow', // 指定使用的主题
  73. modules: {
  74. toolbar: [
  75. [{'header': [1, 2, false]}, 'bold', 'italic', 'blockquote', 'code-block', 'link'],
  76. [{'list': 'ordered'}, {'list': 'bullet'}, {'indent': '-1'}, {'indent': '+1'}, 'image', 'video'],
  77. ]
  78. }
  79. });
  80. quill.focus();
  81. let contentStr = 'content';
  82. // 从localStorage中获取内容
  83. let item = localStorage.getItem(contentStr);
  84. if (item != null) {
  85. quill.root.innerHTML = item;
  86. }
  87. quill.on('text-change', function (delta, oldDelta, source) {
  88. localStorage.setItem(contentStr, quill.root.innerHTML);
  89. });
  90. async function convertToWebPAsync(base64Image) {
  91. // 检查图像格式是否为WebP
  92. if (base64Image.startsWith('data:image/webp')) {
  93. // 如果是WebP格式,直接返回原始的base64字符串
  94. return base64Image;
  95. } else {
  96. // 将图像转换为WebP格式
  97. const image = new Image();
  98. image.src = base64Image;
  99. await new Promise((resolve, reject) => {
  100. image.onload = resolve;
  101. image.onerror = reject;
  102. });
  103. const canvas = document.createElement('canvas');
  104. canvas.width = image.width;
  105. canvas.height = image.height;
  106. const ctx = canvas.getContext('2d');
  107. ctx.drawImage(image, 0, 0);
  108. const webpData = canvas.toDataURL('image/webp');
  109. return webpData;
  110. }
  111. }
  112. /**
  113. * 获取 markdown 格式的内容
  114. * @param delta
  115. * @returns {string}
  116. */
  117. async function deltaToMarkdown(delta) {
  118. let markdown = '';
  119. for (const op of delta['ops']) {
  120. if (op.insert) {
  121. if (typeof op.insert === 'string') {
  122. markdown += op.insert;
  123. } else if (op.insert.image) {
  124. // 如果是图片,转换为webp
  125. const webpBase64 = await convertToWebPAsync(op.insert.image);
  126. markdown += `![${op.insert.alt}](${webpBase64})`;
  127. }
  128. }
  129. }
  130. return markdown;
  131. }
  132. // 获取编辑器内容
  133. // function getContent() {
  134. // const content = quill.root.innerHTML;
  135. // console.log(content);
  136. // }
  137. // 发送数据
  138. async function sendData() {
  139. // 使id=log 不可用
  140. let logBtn = document.getElementById('log');
  141. logBtn.disabled = true;
  142. logBtn.innerText = '正在发送...';
  143. const content = await deltaToMarkdown(quill.getContents());
  144. const categories = getSelectedCategories();
  145. // 添加多选按钮选择的分类到内容前面
  146. let updatedContent = content;
  147. if (categories.length > 0) {
  148. updatedContent = `#${categories.join(' ')} ${content}`;
  149. }
  150. // 调用数据备份接口
  151. const data = {
  152. content: updatedContent
  153. };
  154. // 发送异步请求
  155. requestUtil.async('https://memos.tianyunperfect.cn/api/v1/memo', 'post', data, myHeaders).then(res => {
  156. // alert(JSON.stringify(res));
  157. if (res['name']) {
  158. // window.location.href = `https://memos.tianyunperfect.cn/m/${res['name']}`;
  159. showMsg('记录成功', 1);
  160. }
  161. logBtn.disabled = false;
  162. logBtn.innerText = '记录';
  163. quill.root.innerHTML = '';
  164. localStorage.removeItem(contentStr);
  165. });
  166. }
  167. // 获取选择的分类
  168. function getSelectedCategories() {
  169. const checkboxes = document.querySelectorAll('input[name="category"]:checked');
  170. const categories = [];
  171. checkboxes.forEach(checkbox => {
  172. categories.push(checkbox.value);
  173. });
  174. return categories;
  175. }
  176. </script>
  177. </body>
  178. </html>