blockly.html 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <script src="blockly/blockly_compressed.js"></script>
  6. <script src="blockly/blocks_compressed.js"></script>
  7. <script src="blockly/javascript_compressed.js"></script>
  8. <script src="blockly/msg/zh-hans.js"></script>
  9. <style>
  10. html,
  11. body,
  12. #blocklyDiv {
  13. height: 100%;
  14. width: 100%;
  15. overflow: hidden;
  16. margin: 0;
  17. }
  18. </style>
  19. </head>
  20. <body>
  21. <!-- <br> -->
  22. <div style="z-index: 100;position: fixed;bottom: 0;">
  23. <button onclick="showCode()">显示等效代码</button>
  24. <button onclick="runCode()">载入至闻达</button>
  25. <button onclick="saveCodeAsAuto()">保存至闻达</button>
  26. <button onclick="analyzeCode()">智能分析</button>
  27. <!-- <button
  28. onclick="localStorage['wenda_blockly_prog']=JSON.stringify(Blockly.serialization.workspaces.save(demoWorkspace))">
  29. 保存</button>
  30. <button
  31. onclick="Blockly.serialization.workspaces.load(JSON.parse(localStorage['wenda_blockly_prog']), demoWorkspace)">
  32. 读取</button> -->
  33. <button onclick="另存为(JSON.stringify(Blockly.serialization.workspaces.save(demoWorkspace)))">
  34. 另存为</button>
  35. <input type="file" onchange="打开(this.files)"></input>
  36. </div>
  37. <div id="blocklyDiv" style="width: 100%;"></div>
  38. <script>
  39. 另存为 = (stringData) => {
  40. const blob = new Blob([stringData], {
  41. type: "text/plain;charset=utf-8"
  42. })
  43. const objectURL = URL.createObjectURL(blob)
  44. const aTag = document.createElement('a')
  45. aTag.href = objectURL
  46. aTag.download = Date.now() + ".wenda_cat"
  47. aTag.click()
  48. URL.revokeObjectURL(objectURL)
  49. }
  50. 打开 = (files) => {
  51. var file = files[0];
  52. var reader = new FileReader();
  53. reader.onload = function (e) {
  54. var contents = e.target.result;
  55. console.log(contents)
  56. Blockly.serialization.workspaces.load(JSON.parse(contents), demoWorkspace)
  57. // 处理读取到的文件内容
  58. // ...
  59. };
  60. reader.readAsText(file);
  61. }
  62. // s = document.documentElement.clientHeight / 600;
  63. // document.body.style.zoom = s;
  64. Blockly.Blocks['发送'] = {
  65. init: function () {
  66. this.jsonInit({
  67. "message0": '发送 %1 至闻达',
  68. "args0": [
  69. {
  70. "type": "input_value",
  71. "name": "VALUE",
  72. "check": "String"
  73. }
  74. ],
  75. previousStatement: null,
  76. nextStatement: null,
  77. "output": "String",
  78. "colour": "purple",
  79. "tooltip": "发送",
  80. });
  81. }
  82. }
  83. Blockly.JavaScript['发送'] = function (block) {
  84. var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
  85. Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
  86. return ["await send(" + argument0 + ')', Blockly.JavaScript.ORDER_MEMBER];
  87. }
  88. Blockly.Blocks['添加用户会话'] = {
  89. init: function () {
  90. this.jsonInit({
  91. "message0": '添加用户会话 %1',
  92. "args0": [
  93. {
  94. "type": "input_value",
  95. "name": "VALUE"
  96. }
  97. ],
  98. previousStatement: null,
  99. nextStatement: null,
  100. "colour": "purple",
  101. "tooltip": "添加用户会话",
  102. });
  103. }
  104. }
  105. Blockly.JavaScript['添加用户会话'] = function (block) {
  106. var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
  107. Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
  108. return "add_conversation(\"user\"," + argument0 + ')\n';
  109. }
  110. Blockly.Blocks['使用知识库回答'] = {
  111. init: function () {
  112. this.jsonInit({
  113. "message0": '使用知识库回答 %1',
  114. "args0": [
  115. {
  116. "type": "input_value",
  117. "name": "VALUE"
  118. }
  119. ],
  120. previousStatement: null,
  121. nextStatement: null,
  122. "output": "String",
  123. "colour": "purple",
  124. "tooltip": "使用知识库回答",
  125. });
  126. }
  127. }
  128. Blockly.JavaScript['使用知识库回答'] = function (block) {
  129. var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
  130. Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
  131. return ["await answer_with_zsk(" + argument0 + ')\n', Blockly.JavaScript.ORDER_MEMBER];
  132. }
  133. Blockly.Blocks['使用快速知识库回答'] = {
  134. init: function () {
  135. this.jsonInit({
  136. "message0": '使用快速知识库回答 %1',
  137. "args0": [
  138. {
  139. "type": "input_value",
  140. "name": "VALUE"
  141. }
  142. ],
  143. previousStatement: null,
  144. nextStatement: null,
  145. "output": "String",
  146. "colour": "purple",
  147. "tooltip": "使用快速知识库回答",
  148. });
  149. }
  150. }
  151. Blockly.JavaScript['使用快速知识库回答'] = function (block) {
  152. var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
  153. Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
  154. return ["await answer_with_fast_zsk(" + argument0 + ')\n', Blockly.JavaScript.ORDER_MEMBER];
  155. }
  156. // { message0: module$contents$Blockly$libraryBlocks$texts_Msg.TEXT_PRINT_TITLE,
  157. // args0: [{ type: "input_value", name: "TEXT" }],
  158. // previousStatement: null,
  159. // nextStatement: null,
  160. // style: "text_blocks",
  161. // tooltip: module$contents$Blockly$libraryBlocks$texts_Msg.TEXT_PRINT_TOOLTIP,
  162. // helpUrl: module$contents$Blockly$libraryBlocks$texts_Msg.TEXT_PRINT_HELPURL }
  163. Blockly.Blocks['添加AI会话'] = {
  164. init: function () {
  165. this.jsonInit({
  166. "message0": '添加AI会话 %1',
  167. "args0": [
  168. {
  169. "type": "input_value",
  170. "name": "VALUE",
  171. }
  172. ],
  173. previousStatement: null,
  174. nextStatement: null,
  175. "colour": "purple",
  176. "tooltip": "添加AI会话",
  177. });
  178. }
  179. }
  180. Blockly.JavaScript['添加AI会话'] = function (block) {
  181. var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
  182. Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
  183. return "add_conversation(\"AI\"," + argument0 + ')\n';
  184. }
  185. Blockly.Blocks['用户输入'] = {
  186. init: function () {
  187. this.jsonInit({
  188. "message0": '用户输入',
  189. "args0": [
  190. ],
  191. "output": "String",
  192. "colour": "purple",
  193. "tooltip": "Returns number of letters in the provided text.",
  194. });
  195. }
  196. }
  197. Blockly.JavaScript['用户输入'] = function (block) {
  198. var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE',
  199. Blockly.JavaScript.ORDER_FUNCTION_CALL) || '\'\'';
  200. return ["get_user_input()", Blockly.JavaScript.ORDER_MEMBER];
  201. }
  202. var toolbox = {
  203. "kind": "categoryToolbox",
  204. "contents": [
  205. {
  206. "kind": "category",
  207. "name": "逻辑判断",
  208. "categorystyle": "logic_category",
  209. "contents": [
  210. {
  211. "kind": "block",
  212. "type": "controls_if"
  213. },
  214. {
  215. "kind": "block",
  216. "type": "controls_if",
  217. "extraState": {
  218. "hasElse": "true"
  219. }
  220. },
  221. {
  222. "kind": "block",
  223. "type": "controls_if",
  224. "extraState": {
  225. "hasElse": "true",
  226. "elseIfCount": 1
  227. }
  228. },
  229. {
  230. "kind": "block",
  231. "type": "logic_compare"
  232. },
  233. {
  234. "kind": "block",
  235. "type": "logic_operation"
  236. },
  237. {
  238. "kind": "block",
  239. "type": "logic_negate"
  240. },
  241. {
  242. "kind": "block",
  243. "type": "logic_boolean"
  244. },
  245. {
  246. "kind": "block",
  247. "type": "logic_null"
  248. },
  249. {
  250. "kind": "block",
  251. "type": "logic_ternary"
  252. }
  253. ]
  254. },
  255. {
  256. "kind": "category",
  257. "name": "循环",
  258. "categorystyle": "loop_category",
  259. "contents": [
  260. {
  261. "kind": "block",
  262. "type": "controls_repeat_ext",
  263. "inputs": {
  264. "TIMES": {
  265. "block": {
  266. "type": "math_number",
  267. "fields": {
  268. "NUM": 10
  269. }
  270. }
  271. }
  272. }
  273. },
  274. {
  275. "kind": "block",
  276. "type": "controls_whileUntil"
  277. },
  278. {
  279. "kind": "block",
  280. "type": "controls_for",
  281. "fields": {
  282. "VAR": "i"
  283. },
  284. "inputs": {
  285. "FROM": {
  286. "block": {
  287. "type": "math_number",
  288. "fields": {
  289. "NUM": 1
  290. }
  291. }
  292. },
  293. "TO": {
  294. "block": {
  295. "type": "math_number",
  296. "fields": {
  297. "NUM": 10
  298. }
  299. }
  300. },
  301. "BY": {
  302. "block": {
  303. "type": "math_number",
  304. "fields": {
  305. "NUM": 1
  306. }
  307. }
  308. }
  309. }
  310. },
  311. {
  312. "kind": "block",
  313. "type": "controls_forEach"
  314. },
  315. {
  316. "kind": "block",
  317. "type": "controls_flow_statements"
  318. }
  319. ]
  320. },
  321. {
  322. "kind": "category",
  323. "name": "数学计算",
  324. "categorystyle": "math_category",
  325. "contents": [
  326. {
  327. "kind": "block",
  328. "type": "math_number",
  329. "fields": {
  330. "NUM": 123
  331. }
  332. },
  333. {
  334. "kind": "block",
  335. "type": "math_arithmetic",
  336. "fields": {
  337. "OP": "ADD"
  338. }
  339. },
  340. {
  341. "kind": "block",
  342. "type": "math_single",
  343. "fields": {
  344. "OP": "ROOT"
  345. }
  346. },
  347. {
  348. "kind": "block",
  349. "type": "math_trig",
  350. "fields": {
  351. "OP": "SIN"
  352. }
  353. },
  354. {
  355. "kind": "block",
  356. "type": "math_constant",
  357. "fields": {
  358. "CONSTANT": "PI"
  359. }
  360. },
  361. {
  362. "kind": "block",
  363. "type": "math_number_property",
  364. "extraState": "<mutation divisor_input=\"false\"></mutation>",
  365. "fields": {
  366. "PROPERTY": "EVEN"
  367. }
  368. },
  369. {
  370. "kind": "block",
  371. "type": "math_round",
  372. "fields": {
  373. "OP": "ROUND"
  374. }
  375. },
  376. {
  377. "kind": "block",
  378. "type": "math_on_list",
  379. "extraState": "<mutation op=\"SUM\"></mutation>",
  380. "fields": {
  381. "OP": "SUM"
  382. }
  383. },
  384. {
  385. "kind": "block",
  386. "type": "math_modulo"
  387. },
  388. {
  389. "kind": "block",
  390. "type": "math_constrain",
  391. "inputs": {
  392. "LOW": {
  393. "block": {
  394. "type": "math_number",
  395. "fields": {
  396. "NUM": 1
  397. }
  398. }
  399. },
  400. "HIGH": {
  401. "block": {
  402. "type": "math_number",
  403. "fields": {
  404. "NUM": 100
  405. }
  406. }
  407. }
  408. }
  409. },
  410. {
  411. "kind": "block",
  412. "type": "math_random_int",
  413. "inputs": {
  414. "FROM": {
  415. "block": {
  416. "type": "math_number",
  417. "fields": {
  418. "NUM": 1
  419. }
  420. }
  421. },
  422. "TO": {
  423. "block": {
  424. "type": "math_number",
  425. "fields": {
  426. "NUM": 100
  427. }
  428. }
  429. }
  430. }
  431. },
  432. {
  433. "kind": "block",
  434. "type": "math_random_float"
  435. },
  436. {
  437. "kind": "block",
  438. "type": "math_atan2"
  439. }
  440. ]
  441. },
  442. {
  443. "kind": "category",
  444. "name": "文本处理",
  445. "categorystyle": "text_category",
  446. "contents": [
  447. {
  448. "kind": "block",
  449. "type": "text"
  450. },
  451. {
  452. "kind": "block",
  453. "type": "text_length"
  454. },
  455. {
  456. "kind": "block",
  457. "type": "text_print"
  458. }
  459. ]
  460. },
  461. {
  462. "kind": "sep"
  463. },
  464. {
  465. "kind": "category",
  466. "name": "列表",
  467. "categorystyle": "list_category",
  468. "contents": [
  469. {
  470. "kind": "block",
  471. "type": "lists_create_empty"
  472. },
  473. {
  474. "kind": "block",
  475. "type": "lists_create_with",
  476. "extraState": {
  477. "itemCount": 3
  478. }
  479. },
  480. {
  481. "kind": "block",
  482. "type": "lists_repeat",
  483. "inputs": {
  484. "NUM": {
  485. "block": {
  486. "type": "math_number",
  487. "fields": {
  488. "NUM": 5
  489. }
  490. }
  491. }
  492. }
  493. },
  494. {
  495. "kind": "block",
  496. "type": "lists_length"
  497. },
  498. {
  499. "kind": "block",
  500. "type": "lists_isEmpty"
  501. },
  502. {
  503. "kind": "block",
  504. "type": "lists_indexOf",
  505. "fields": {
  506. "END": "FIRST"
  507. }
  508. },
  509. {
  510. "kind": "block",
  511. "type": "lists_getIndex",
  512. "fields": {
  513. "MODE": "GET",
  514. "WHERE": "FROM_START"
  515. }
  516. },
  517. {
  518. "kind": "block",
  519. "type": "lists_setIndex",
  520. "fields": {
  521. "MODE": "SET",
  522. "WHERE": "FROM_START"
  523. }
  524. }
  525. ]
  526. },
  527. {
  528. "kind": "category",
  529. "name": "变量",
  530. "categorystyle": "variable_category",
  531. "custom": "VARIABLE"
  532. },
  533. {
  534. "kind": "category",
  535. "name": "函数",
  536. "categorystyle": "procedure_category",
  537. "custom": "PROCEDURE"
  538. },
  539. {
  540. "kind": "sep"
  541. },
  542. {
  543. "kind": "category",
  544. "name": "闻达",
  545. "colour": "purple",
  546. "contents": [
  547. {
  548. "kind": "block",
  549. "type": "发送"
  550. },
  551. {
  552. "kind": "block",
  553. "type": "用户输入"
  554. },
  555. {
  556. "kind": "block",
  557. "type": "添加用户会话"
  558. },
  559. {
  560. "kind": "block",
  561. "type": "添加AI会话"
  562. },
  563. {
  564. "kind": "block",
  565. "type": "使用知识库回答"
  566. },
  567. {
  568. "kind": "block",
  569. "type": "使用快速知识库回答"
  570. },
  571. ]
  572. }
  573. ]
  574. }
  575. var demoWorkspace = Blockly.inject('blocklyDiv',
  576. {
  577. media: 'blockly/media/',
  578. toolbox: toolbox
  579. });
  580. var startBlocks ={"blocks":{"languageVersion":0,"blocks":[{"type":"添加用户会话","id":",g8fJD_C.6HD9wZ*THui","x":355,"y":187,"inputs":{"VALUE":{"block":{"type":"text","id":"zPSMY@7;Z{.E{X+JE@?W","fields":{"TEXT":"程序开始运行"}}}},"next":{"block":{"type":"controls_if","id":"iT,pk#nrYYiuU8PKx;X$","inline":false,"extraState":{"hasElse":true},"inputs":{"IF0":{"block":{"type":"logic_compare","id":"T4+ttZ~C_b*QO*3rX{Em","fields":{"OP":"EQ"},"inputs":{"A":{"block":{"type":"用户输入","id":"o@rNb@2m,1jCereA^pDz"}},"B":{"block":{"type":"text","id":"/|Fut]UGF$5;,^1oyrZ.","fields":{"TEXT":"你好"}}}}}},"DO0":{"block":{"type":"text_print","id":"1o4/30[sgFM*ilp0v48=","inline":false,"inputs":{"TEXT":{"block":{"type":"发送","id":"|bJf6;$KtPy=XjT5cnnQ","inputs":{"VALUE":{"block":{"type":"text","id":"zzQT`a;U(lNXXnBbcy](","fields":{"TEXT":"你好,闻达"}}}}}}}}},"ELSE":{"block":{"type":"text_print","id":"|?MKt8g%`aXLu=ixEn4X","inline":false,"inputs":{"TEXT":{"block":{"type":"发送","id":"A3X`8{7G)$yWJjE`H$~G","inputs":{"VALUE":{"block":{"type":"用户输入","id":"iEy-%[lUSX}vAu3Y~xgB"}}}}}}}}},"next":{"block":{"type":"添加AI会话","id":"-LB?JxOhy({t)+htNW}+","inputs":{"VALUE":{"block":{"type":"text","id":"aY=xvk~..+ub7M#D,V|3","fields":{"TEXT":"程序结束运行"}}}}}}}}}]}}
  581. Blockly.serialization.workspaces.load(startBlocks, demoWorkspace);
  582. function showCode() {
  583. // Generate JavaScript code and display it.
  584. Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
  585. var code = Blockly.JavaScript.workspaceToCode(demoWorkspace);
  586. alert(code);
  587. }
  588. function runCode() {
  589. // Generate JavaScript code and run it.
  590. window.LoopTrap = 1000;
  591. Blockly.JavaScript.INFINITE_LOOP_TRAP =
  592. 'if (--window.LoopTrap < 0) throw "Infinite loop.";\n';
  593. var code = Blockly.JavaScript.workspaceToCode(demoWorkspace);
  594. Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
  595. parent.postMessage({ from: '猫猫也会的图块化编程', data: code }, '/')
  596. }
  597. function saveCodeAsAuto() {
  598. // Generate JavaScript code and run it.
  599. window.LoopTrap = 1000;
  600. Blockly.JavaScript.INFINITE_LOOP_TRAP =
  601. 'if (--window.LoopTrap < 0) throw "Infinite loop.";\n';
  602. var code = Blockly.JavaScript.workspaceToCode(demoWorkspace);
  603. Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
  604. parent.postMessage({ from: '猫猫也会的图块化编程_保存', data: code }, '/')
  605. }
  606. function analyzeCode() {
  607. // Generate JavaScript code and run it.
  608. window.LoopTrap = 1000;
  609. Blockly.JavaScript.INFINITE_LOOP_TRAP =
  610. 'if (--window.LoopTrap < 0) throw "Infinite loop.";\n';
  611. var code = Blockly.JavaScript.workspaceToCode(demoWorkspace);
  612. Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
  613. parent.postMessage({ from: '猫猫也会的图块化编程_分析', data: code }, '/')
  614. }
  615. </script>
  616. </body>
  617. </html>
粤ICP备19079148号